summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt4
-rw-r--r--core/java/android/app/ActivityThread.java2
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java5
-rw-r--r--core/java/android/hardware/display/DisplayTopology.java26
-rw-r--r--core/java/android/os/Build.java2
-rw-r--r--core/java/android/view/IWindowManager.aidl5
-rw-r--r--core/tests/coretests/src/android/hardware/display/DisplayTopologyTest.kt75
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/EventLogTags.logtags2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java75
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java122
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesTransitionObserver.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt15
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt52
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java3
-rw-r--r--libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/OpenAppFromAllAppsTest.kt27
-rw-r--r--libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/OpenAppFromTaskbarTest.kt27
-rw-r--r--libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/UnminimizeAppFromAllAppsTest.kt27
-rw-r--r--libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/UnminimizeAppFromTaskbarTest.kt27
-rw-r--r--libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/OpenAppFromAllApps.kt76
-rw-r--r--libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/OpenAppFromTaskbar.kt75
-rw-r--r--libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/UnminimizeAppFromAllApps.kt79
-rw-r--r--libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/UnminimizeAppFromTaskbar.kt78
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt34
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfEnterPipToOtherOrientation.kt22
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt64
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt42
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java8
-rw-r--r--packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java5
-rw-r--r--packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java139
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/satellite/SatelliteDialogUtilsTest.kt2
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java22
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java99
-rw-r--r--packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java118
-rw-r--r--packages/SystemUI/aconfig/systemui.aconfig10
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaContentPicker.kt4
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToNotificationsShadeTransition.kt15
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToQuickSettingsShadeTransition.kt5
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt4
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt59
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt4
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt4
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt61
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt84
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SharedElement.kt42
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt24
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/UserActionDistanceScopeImpl.kt2
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt76
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Overlay.kt7
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Scene.kt7
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/ui/util/IntIndexedMap.kt73
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt26
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MovableElementContentPickerTest.kt12
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MovableElementTest.kt12
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/OverlayTest.kt63
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/PredictiveBackHandlerTest.kt53
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt8
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedSceneTransitionLayoutTest.kt76
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedSharedElementTest.kt39
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/ui/util/IntIndexMapTest.kt92
-rw-r--r--packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestValues.kt4
-rw-r--r--packages/SystemUI/res/raw/trackpad_switch_apps_edu.json1
-rw-r--r--packages/SystemUI/res/raw/trackpad_switch_apps_success.json1
-rw-r--r--packages/SystemUI/res/values/strings.xml4
-rw-r--r--packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/ActionTutorialContent.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialScreenConfig.kt20
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt29
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/layout/StatusBarContentInsetsProvider.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StabilizeHeadsUpGroup.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/SwitchAppsGestureTutorialScreen.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/SwitchAppsGestureRecognizer.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/SwitchAppsGestureScreenViewModel.kt7
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/app/WallpaperManagerKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/SysUITestModule.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalSceneRepository.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/coroutines/TestCoroutineSchedulerUtils.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/ui/viewmodel/UdfpsAccessibilityOverlayViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/AuthRippleInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricAuthInteractorKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricSettingsInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricsAllowedInteractorKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthStatusInteractorKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFingerprintAuthInteractorKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntrySourceInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractorKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/FaceHelpMessageDeferralInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/OccludingAppDeviceEntryInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/ui/binder/LiftToRunFaceAuthBinderKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt1
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/DevicePostureInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardSmartspaceInteractorKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinderKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerMessageAreaViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToAodTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToDozingTransitionViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToGoneTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToLockscreenTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToOccludedTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModelKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToGoneTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlowsKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryFgIconViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGlanceableHubTransitionViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGoneTransitionViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToOccludedTransitionViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToAodTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGoneTransitionViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModelKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDozingTransitionViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToLockscreenTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModelKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAlternateBouncerTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToDozingTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToGoneTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/SideFpsProgressBarViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/taskswitcher/TaskSwitcherKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/resolver/SceneResolverKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/ScrimStartableKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/StatusBarStartableKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeControllerKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeTestUtil.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/AmbientStateKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/BiometricUnlockController.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/DozeServiceHostKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ManagedProfileControllerKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/util/coroutines/MainDispatcherRule.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/util/time/FakeSystemClockKosmos.kt2
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java4
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/MagnificationKeyHandler.java3
-rw-r--r--services/core/Android.bp1
-rw-r--r--services/core/java/com/android/server/display/DisplayTopologyStore.java33
-rw-r--r--services/core/java/com/android/server/display/DisplayTopologyXmlStore.java582
-rw-r--r--services/core/java/com/android/server/wm/SnapshotPersistQueue.java8
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java3
-rw-r--r--services/core/jni/com_android_server_vibrator_VibratorController.cpp4
-rw-r--r--services/core/xsd/Android.bp8
-rw-r--r--services/core/xsd/display-topology/OWNERS1
-rw-r--r--services/core/xsd/display-topology/display-topology.xsd65
-rw-r--r--services/core/xsd/display-topology/schema/current.txt64
-rw-r--r--services/core/xsd/display-topology/schema/last_current.txt0
-rw-r--r--services/core/xsd/display-topology/schema/last_removed.txt0
-rw-r--r--services/core/xsd/display-topology/schema/removed.txt1
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayTopologyXmlStoreTest.java388
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java12
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationKeyHandlerTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java11
-rw-r--r--tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/BottomHalfPipAppHelper.kt2
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/BottomHalfPipActivity.java2
-rw-r--r--tools/aapt/SdkConstants.h1
-rw-r--r--tools/aapt2/SdkConstants.h1
-rw-r--r--tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt2
-rw-r--r--tools/lint/framework/checks/src/main/java/com/google/android/lint/multiuser/PendingIntentGetActivityDetector.kt107
-rw-r--r--tools/lint/framework/checks/src/test/java/com/google/android/lint/multiuser/PendingIntentGetActivityDetectorTest.kt173
218 files changed, 3205 insertions, 956 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index 26c64bd7adbc..e0fc9590f9f7 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -33468,7 +33468,7 @@ package android.os {
public static class Build.VERSION_CODES {
ctor public Build.VERSION_CODES();
- field @FlaggedApi("android.sdk.major_minor_versioning_scheme") public static final int BAKLAVA = 10000; // 0x2710
+ field @FlaggedApi("android.sdk.major_minor_versioning_scheme") public static final int BAKLAVA = 36; // 0x24
field public static final int BASE = 1; // 0x1
field public static final int BASE_1_1 = 2; // 0x2
field public static final int CUPCAKE = 3; // 0x3
@@ -33508,7 +33508,7 @@ package android.os {
}
@FlaggedApi("android.sdk.major_minor_versioning_scheme") public static class Build.VERSION_CODES_FULL {
- field public static final int BAKLAVA = 1000000000; // 0x3b9aca00
+ field public static final int BAKLAVA = 3600000; // 0x36ee80
field public static final int BASE = 100000; // 0x186a0
field public static final int BASE_1_1 = 200000; // 0x30d40
field public static final int CUPCAKE = 300000; // 0x493e0
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 2cfba4b8468f..7b9ec4a7821e 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -7061,7 +7061,7 @@ public final class ActivityThread extends ClientTransactionHandler
Slog.w(TAG, "Low overhead tracing feature is not enabled");
break;
}
- VMDebug.startLowOverheadTrace();
+ VMDebug.startLowOverheadTraceForAllMethods();
break;
default:
try {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index c50452157d74..08719fc549f8 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -4051,10 +4051,13 @@ public class DevicePolicyManager {
public static final int EXEMPT_FROM_HIBERNATION = 3;
/**
- * Exempt an app from all power-related restrictions, including app standby and doze.
+ * Exempt an app from all power-related restrictions, including app standby.
* In addition, the app will be able to start foreground services from the background,
* and the user will not be able to stop foreground services run by the app.
*
+ * <p><strong>Note:</strong> This option does NOT exempt apps from Doze mode. In fact,
+ * DPC apps themselves are not automatically exempted from Doze mode either.
+ *
* @hide
*/
@SystemApi
diff --git a/core/java/android/hardware/display/DisplayTopology.java b/core/java/android/hardware/display/DisplayTopology.java
index 1d2f133ee759..b39bd8c10022 100644
--- a/core/java/android/hardware/display/DisplayTopology.java
+++ b/core/java/android/hardware/display/DisplayTopology.java
@@ -108,7 +108,6 @@ public final class DisplayTopology implements Parcelable {
public DisplayTopology() {}
- @VisibleForTesting
public DisplayTopology(TreeNode root, int primaryDisplayId) {
mRoot = root;
if (mRoot != null) {
@@ -275,7 +274,7 @@ public final class DisplayTopology implements Parcelable {
float offset;
int pos;
- if (Math.abs(xOverlap) > Math.abs(yOverlap)) {
+ if (xOverlap > yOverlap) {
// Deviation in each dimension is a penalty in the potential parenting. To
// get the X deviation, overlap is subtracted from the lesser width so that
// a maximum overlap results in a deviation of zero.
@@ -541,6 +540,19 @@ public final class DisplayTopology implements Parcelable {
}
@Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof DisplayTopology)) {
+ return false;
+ }
+ return obj.toString().equals(toString());
+ }
+
+ @Override
+ public int hashCode() {
+ return toString().hashCode();
+ }
+
+ @Override
public String toString() {
StringWriter out = new StringWriter();
PrintWriter writer = new PrintWriter(out);
@@ -610,7 +622,7 @@ public final class DisplayTopology implements Parcelable {
}
@Nullable
- private static TreeNode findDisplay(int displayId, @Nullable TreeNode startingNode) {
+ public static TreeNode findDisplay(int displayId, @Nullable TreeNode startingNode) {
if (startingNode == null) {
return null;
}
@@ -775,16 +787,22 @@ public final class DisplayTopology implements Parcelable {
*/
private float mOffset;
- private final List<TreeNode> mChildren = new ArrayList<>();
+ private final List<TreeNode> mChildren;
@VisibleForTesting
public TreeNode(int displayId, float width, float height, @Position int position,
float offset) {
+ this(displayId, width, height, position, offset, List.of());
+ }
+
+ public TreeNode(int displayId, float width, float height, int position,
+ float offset, List<TreeNode> children) {
mDisplayId = displayId;
mWidth = width;
mHeight = height;
mPosition = position;
mOffset = offset;
+ mChildren = new ArrayList<>(children);
}
public TreeNode(Parcel source) {
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index c51ad9e986ef..1e6469c57fa9 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -1271,7 +1271,7 @@ public class Build {
* Baklava.
*/
@FlaggedApi(Flags.FLAG_MAJOR_MINOR_VERSIONING_SCHEME)
- public static final int BAKLAVA = CUR_DEVELOPMENT;
+ public static final int BAKLAVA = 36;
}
/** @hide */
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 06eb0428bfcf..f58baffb1367 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -1145,4 +1145,9 @@ interface IWindowManager
* @param deviceId The id of the {@link InputDevice} that will handle the shortcut.
*/
KeyboardShortcutGroup getApplicationLaunchKeyboardShortcuts(int deviceId);
+
+ /**
+ * Returns whether the display with {@code displayId} ignores orientation request.
+ */
+ boolean getIgnoreOrientationRequest(int displayId);
}
diff --git a/core/tests/coretests/src/android/hardware/display/DisplayTopologyTest.kt b/core/tests/coretests/src/android/hardware/display/DisplayTopologyTest.kt
index 008db5ef114e..6d6b56754000 100644
--- a/core/tests/coretests/src/android/hardware/display/DisplayTopologyTest.kt
+++ b/core/tests/coretests/src/android/hardware/display/DisplayTopologyTest.kt
@@ -635,8 +635,7 @@ class DisplayTopologyTest {
// 222
RectF(0f, 0f, 30f, 30f),
RectF(40f, 10f, 70f, 40f),
- RectF(80.5f, 50f, 110f, 80f), // left+=0.5 to cause a preference for
- // TOP/BOTTOM attach
+ RectF(80.5f, 50f, 110f, 80f),
)
verifyDisplay(root, id = 0, width = 30f, height = 30f, noOfChildren = 1)
@@ -644,7 +643,7 @@ class DisplayTopologyTest {
root.children[0], id = 1, width = 30f, height = 30f, POSITION_RIGHT, offset = 10f,
noOfChildren = 1)
verifyDisplay(
- root.children[0].children[0], id = 2, width = 29.5f, height = 30f, POSITION_BOTTOM,
+ root.children[0].children[0], id = 2, width = 29.5f, height = 30f, POSITION_RIGHT,
offset = 30f, noOfChildren = 0)
}
@@ -702,6 +701,76 @@ class DisplayTopologyTest {
}
@Test
+ fun rearrange_preferLongHorizontalShiftOverAttachToCorner() {
+ // An earlier implementation decided vertical or horizontal clamp direction based on the abs
+ // value of the overlap in each dimension, rather than the raw overlap.
+
+ // This horizontal span is twice the height of displays, making abs(xOverlap) > yOverlap,
+ // i.e. abs(-60) > 30
+ // |
+ // |----|
+ // 000 111
+ // 000 111
+ // 000 111
+
+ // Before fix:
+ // 000
+ // 000
+ // 000
+ // 111
+ // 111
+ // 111
+
+ // After fix:
+ // 000111
+ // 000111
+ // 000111
+
+ val root = rearrangeRects(
+ RectF(0f, 0f, 30f, 30f),
+ RectF(90f, 0f, 120f, 30f),
+ )
+
+ verifyDisplay(root, id = 0, width = 30f, height = 30f, noOfChildren = 1)
+ verifyDisplay(
+ root.children[0], id = 1, width = 30f, height = 30f, POSITION_RIGHT,
+ offset = 0f, noOfChildren = 0)
+ }
+
+ @Test
+ fun rearrange_preferLongVerticalShiftOverAttachToCorner() {
+ // Before:
+ // 111
+ // 111
+ // 111
+ // |
+ // |- This vertical span is 40dp
+ // |
+ // |
+ // 000
+ // 000
+ // 000
+
+ // After:
+ // 111
+ // 111
+ // 111
+ // 000
+ // 000
+ // 000
+
+ val root = rearrangeRects(
+ RectF(20f, 70f, 50f, 100f),
+ RectF(00f, 0f, 30f, 30f),
+ )
+
+ verifyDisplay(root, id = 0, width = 30f, height = 30f, noOfChildren = 1)
+ verifyDisplay(
+ root.children[0], id = 1, width = 30f, height = 30f, POSITION_TOP,
+ offset = -20f, noOfChildren = 0)
+ }
+
+ @Test
fun copy() {
val display1 = DisplayTopology.TreeNode(/* displayId= */ 1, /* width= */ 200f,
/* height= */ 600f, /* position= */ 0, /* offset= */ 0f)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/EventLogTags.logtags b/libs/WindowManager/Shell/src/com/android/wm/shell/EventLogTags.logtags
index db960d15c526..b716e9e574fa 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/EventLogTags.logtags
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/EventLogTags.logtags
@@ -8,4 +8,4 @@ option java_package com.android.wm.shell
38500 wm_shell_enter_desktop_mode (EnterReason|1|5),(SessionId|1|5)
38501 wm_shell_exit_desktop_mode (ExitReason|1|5),(SessionId|1|5)
-38502 wm_shell_desktop_mode_task_update (TaskEvent|1|5),(InstanceId|1|5),(uid|1|5),(TaskHeight|1),(TaskWidth|1),(TaskX|1),(TaskY|1),(SessionId|1|5),(MinimiseReason|1|5),(UnminimiseReason|1|5),(VisibleTaskCount|1)
+38502 wm_shell_desktop_mode_task_update (TaskEvent|1|5),(InstanceId|1|5),(uid|1|5),(TaskHeight|1),(TaskWidth|1),(TaskX|1),(TaskY|1),(SessionId|1|5),(MinimiseReason|1|5),(UnminimiseReason|1|5),(VisibleTaskCount|1),(FocusReason|1|5)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 30d679006c98..4f9028e8aaf3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -477,24 +477,23 @@ public class BubbleController implements ConfigurationChangeListener,
@Override
public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) {
- for (Bubble b : mBubbleData.getBubbles()) {
- if (task.taskId == b.getTaskId()) {
- ProtoLog.d(WM_SHELL_BUBBLES,
- "onActivityRestartAttempt - taskId=%d selecting matching bubble=%s",
- task.taskId, b.getKey());
- mBubbleData.setSelectedBubbleAndExpandStack(b);
- return;
- }
+ final int taskId = task.taskId;
+ Bubble bubble = mBubbleData.getBubbleInStackWithTaskId(taskId);
+ if (bubble != null) {
+ ProtoLog.d(WM_SHELL_BUBBLES,
+ "onActivityRestartAttempt - taskId=%d selecting matching bubble=%s",
+ taskId, bubble.getKey());
+ mBubbleData.setSelectedBubbleAndExpandStack(bubble);
+ return;
}
- for (Bubble b : mBubbleData.getOverflowBubbles()) {
- if (task.taskId == b.getTaskId()) {
- ProtoLog.d(WM_SHELL_BUBBLES, "onActivityRestartAttempt - taskId=%d "
- + "selecting matching overflow bubble=%s",
- task.taskId, b.getKey());
- promoteBubbleFromOverflow(b);
- mBubbleData.setExpanded(true);
- return;
- }
+
+ bubble = mBubbleData.getOverflowBubbleWithTaskId(taskId);
+ if (bubble != null) {
+ ProtoLog.d(WM_SHELL_BUBBLES, "onActivityRestartAttempt - taskId=%d "
+ + "selecting matching overflow bubble=%s",
+ taskId, bubble.getKey());
+ promoteBubbleFromOverflow(bubble);
+ mBubbleData.setExpanded(true);
}
}
});
@@ -1296,8 +1295,8 @@ public class BubbleController implements ConfigurationChangeListener,
* @param timestamp the timestamp of the removal
*/
public void dragBubbleToDismiss(String bubbleKey, long timestamp) {
- String selectedBubbleKey = mBubbleData.getSelectedBubbleKey();
- Bubble bubbleToDismiss = mBubbleData.getAnyBubbleWithkey(bubbleKey);
+ final String selectedBubbleKey = mBubbleData.getSelectedBubbleKey();
+ final Bubble bubbleToDismiss = mBubbleData.getAnyBubbleWithKey(bubbleKey);
if (bubbleToDismiss != null) {
mBubbleData.dismissBubbleWithKey(
bubbleKey, Bubbles.DISMISS_USER_GESTURE_FROM_LAUNCHER, timestamp);
@@ -1330,11 +1329,11 @@ public class BubbleController implements ConfigurationChangeListener,
@VisibleForTesting
public boolean isBubbleNotificationSuppressedFromShade(String key, String groupKey) {
- boolean isSuppressedBubble = (mBubbleData.hasAnyBubbleWithKey(key)
- && !mBubbleData.getAnyBubbleWithkey(key).showInShade());
+ final boolean isSuppressedBubble = (mBubbleData.hasAnyBubbleWithKey(key)
+ && !mBubbleData.getAnyBubbleWithKey(key).showInShade());
- boolean isSuppressedSummary = mBubbleData.isSummarySuppressed(groupKey);
- boolean isSummary = key.equals(mBubbleData.getSummaryKey(groupKey));
+ final boolean isSuppressedSummary = mBubbleData.isSummarySuppressed(groupKey);
+ final boolean isSummary = key.equals(mBubbleData.getSummaryKey(groupKey));
return (isSummary && isSuppressedSummary) || isSuppressedBubble;
}
@@ -1362,8 +1361,6 @@ public class BubbleController implements ConfigurationChangeListener,
public void expandStackAndSelectBubbleFromLauncher(String key, int topOnScreen) {
mBubblePositioner.setBubbleBarTopOnScreen(topOnScreen);
- boolean wasExpanded = (mLayerView != null && mLayerView.isExpanded());
-
if (BubbleOverflow.KEY.equals(key)) {
mBubbleData.setSelectedBubbleFromLauncher(mBubbleData.getOverflow());
mLayerView.showExpandedView(mBubbleData.getOverflow());
@@ -1371,10 +1368,11 @@ public class BubbleController implements ConfigurationChangeListener,
return;
}
- Bubble b = mBubbleData.getAnyBubbleWithkey(key);
+ final Bubble b = mBubbleData.getAnyBubbleWithKey(key);
if (b == null) {
return;
}
+ final boolean wasExpanded = (mLayerView != null && mLayerView.isExpanded());
if (mBubbleData.hasBubbleInStackWithKey(b.getKey())) {
// already in the stack
mBubbleData.setSelectedBubbleFromLauncher(b);
@@ -1748,31 +1746,32 @@ public class BubbleController implements ConfigurationChangeListener,
public void updateBubble(BubbleEntry notif, boolean suppressFlyout, boolean showInShade) {
// If this is an interruptive notif, mark that it's interrupted
mSysuiProxy.setNotificationInterruption(notif.getKey());
- boolean isNonInterruptiveNotExpanding = !notif.getRanking().isTextChanged()
+ final boolean isNonInterruptiveNotExpanding = !notif.getRanking().isTextChanged()
&& (notif.getBubbleMetadata() != null
&& !notif.getBubbleMetadata().getAutoExpandBubble());
+ final Bubble bubble;
if (isNonInterruptiveNotExpanding
&& mBubbleData.hasOverflowBubbleWithKey(notif.getKey())) {
// Update the bubble but don't promote it out of overflow
- Bubble b = mBubbleData.getOverflowBubbleWithKey(notif.getKey());
+ bubble = mBubbleData.getOverflowBubbleWithKey(notif.getKey());
if (notif.isBubble()) {
notif.setFlagBubble(false);
}
- updateNotNotifyingEntry(b, notif, showInShade);
+ updateNotNotifyingEntry(bubble, notif, showInShade);
} else if (mBubbleData.hasAnyBubbleWithKey(notif.getKey())
&& isNonInterruptiveNotExpanding) {
- Bubble b = mBubbleData.getAnyBubbleWithkey(notif.getKey());
- if (b != null) {
- updateNotNotifyingEntry(b, notif, showInShade);
+ bubble = mBubbleData.getAnyBubbleWithKey(notif.getKey());
+ if (bubble != null) {
+ updateNotNotifyingEntry(bubble, notif, showInShade);
}
} else if (mBubbleData.isSuppressedWithLocusId(notif.getLocusId())) {
// Update the bubble but don't promote it out of overflow
- Bubble b = mBubbleData.getSuppressedBubbleWithKey(notif.getKey());
- if (b != null) {
- updateNotNotifyingEntry(b, notif, showInShade);
+ bubble = mBubbleData.getSuppressedBubbleWithKey(notif.getKey());
+ if (bubble != null) {
+ updateNotNotifyingEntry(bubble, notif, showInShade);
}
} else {
- Bubble bubble = mBubbleData.getOrCreateBubble(notif, null /* persistedBubble */);
+ bubble = mBubbleData.getOrCreateBubble(notif, null /* persistedBubble */);
if (notif.shouldSuppressNotificationList()) {
// If we're suppressing notifs for DND, we don't want the bubbles to randomly
// expand when DND turns off so flip the flag.
@@ -2323,12 +2322,12 @@ public class BubbleController implements ConfigurationChangeListener,
BubbleEntry summary, @Nullable List<BubbleEntry> children, IntConsumer removeCallback) {
if (children != null) {
for (int i = 0; i < children.size(); i++) {
- BubbleEntry child = children.get(i);
+ final BubbleEntry child = children.get(i);
if (mBubbleData.hasAnyBubbleWithKey(child.getKey())) {
// Suppress the bubbled child
// As far as group manager is concerned, once a child is no longer shown
// in the shade, it is essentially removed.
- Bubble bubbleChild = mBubbleData.getAnyBubbleWithkey(child.getKey());
+ final Bubble bubbleChild = mBubbleData.getAnyBubbleWithKey(child.getKey());
if (bubbleChild != null) {
bubbleChild.setSuppressNotification(true);
bubbleChild.setShowDot(false /* show */);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
index 76d91ede7aa3..74302094a296 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
@@ -27,7 +27,6 @@ import android.content.Intent;
import android.content.LocusId;
import android.content.pm.ShortcutInfo;
import android.os.UserHandle;
-import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
@@ -48,6 +47,7 @@ import com.android.wm.shell.shared.bubbles.RemovedBubble;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@@ -667,7 +667,7 @@ public class BubbleData {
/** Removes all bubbles for the given user. */
public void removeBubblesForUser(int userId) {
- List<Bubble> removedBubbles = filterAllBubbles(bubble ->
+ final List<Bubble> removedBubbles = filterAllBubbles(bubble ->
userId == bubble.getUser().getIdentifier());
for (Bubble b : removedBubbles) {
doRemove(b.getKey(), Bubbles.DISMISS_USER_ACCOUNT_REMOVED);
@@ -1162,7 +1162,7 @@ public class BubbleData {
@VisibleForTesting(visibility = PRIVATE)
@Nullable
- Bubble getAnyBubbleWithkey(String key) {
+ Bubble getAnyBubbleWithKey(String key) {
Bubble b = getBubbleInStackWithKey(key);
if (b == null) {
b = getOverflowBubbleWithKey(key);
@@ -1173,77 +1173,45 @@ public class BubbleData {
return b;
}
- /** @return any bubble (in the stack or the overflow) that matches the provided shortcutId. */
+ /** @return the bubble in the stack that matches the provided taskId. */
@Nullable
- Bubble getAnyBubbleWithShortcutId(String shortcutId) {
- if (TextUtils.isEmpty(shortcutId)) {
- return null;
- }
- for (int i = 0; i < mBubbles.size(); i++) {
- Bubble bubble = mBubbles.get(i);
- String bubbleShortcutId = bubble.getShortcutInfo() != null
- ? bubble.getShortcutInfo().getId()
- : bubble.getMetadataShortcutId();
- if (shortcutId.equals(bubbleShortcutId)) {
- return bubble;
- }
- }
-
- for (int i = 0; i < mOverflowBubbles.size(); i++) {
- Bubble bubble = mOverflowBubbles.get(i);
- String bubbleShortcutId = bubble.getShortcutInfo() != null
- ? bubble.getShortcutInfo().getId()
- : bubble.getMetadataShortcutId();
- if (shortcutId.equals(bubbleShortcutId)) {
- return bubble;
- }
- }
- return null;
+ Bubble getBubbleInStackWithTaskId(int taskId) {
+ return getBubbleWithPredicate(mBubbles, b -> b.getTaskId() == taskId);
}
- @VisibleForTesting(visibility = PRIVATE)
+ /** @return the bubble in the stack that matches the provided key. */
@Nullable
+ @VisibleForTesting(visibility = PRIVATE)
public Bubble getBubbleInStackWithKey(String key) {
- for (int i = 0; i < mBubbles.size(); i++) {
- Bubble bubble = mBubbles.get(i);
- if (bubble.getKey().equals(key)) {
- return bubble;
- }
- }
- return null;
+ return getBubbleWithPredicate(mBubbles, b -> b.getKey().equals(key));
}
+ /** @return the bubble in the stack that matches the provided locusId. */
@Nullable
- private Bubble getBubbleInStackWithLocusId(LocusId locusId) {
- if (locusId == null) return null;
- for (int i = 0; i < mBubbles.size(); i++) {
- Bubble bubble = mBubbles.get(i);
- if (locusId.equals(bubble.getLocusId())) {
- return bubble;
- }
+ private Bubble getBubbleInStackWithLocusId(@Nullable LocusId locusId) {
+ if (locusId == null) {
+ return null;
}
- return null;
+ return getBubbleWithPredicate(mBubbles, b -> locusId.equals(b.getLocusId()));
}
+ /** @return the bubble in the stack that matches the provided icon view. */
@Nullable
- Bubble getBubbleWithView(View view) {
- for (int i = 0; i < mBubbles.size(); i++) {
- Bubble bubble = mBubbles.get(i);
- if (bubble.getIconView() != null && bubble.getIconView().equals(view)) {
- return bubble;
- }
- }
- return null;
+ Bubble getBubbleInStackWithView(View view) {
+ return getBubbleWithPredicate(mBubbles, b ->
+ b.getIconView() != null && b.getIconView().equals(view));
+ }
+
+ /** @return the overflow bubble that matches the provided taskId. */
+ @Nullable
+ Bubble getOverflowBubbleWithTaskId(int taskId) {
+ return getBubbleWithPredicate(mOverflowBubbles, b -> b.getTaskId() == taskId);
}
+ /** @return the overflow bubble that matches the provided key. */
+ @Nullable
public Bubble getOverflowBubbleWithKey(String key) {
- for (int i = 0; i < mOverflowBubbles.size(); i++) {
- Bubble bubble = mOverflowBubbles.get(i);
- if (bubble.getKey().equals(key)) {
- return bubble;
- }
- }
- return null;
+ return getBubbleWithPredicate(mOverflowBubbles, b -> b.getKey().equals(key));
}
/**
@@ -1255,12 +1223,7 @@ public class BubbleData {
@Nullable
@VisibleForTesting(visibility = PRIVATE)
public Bubble getSuppressedBubbleWithKey(String key) {
- for (Bubble b : mSuppressedBubbles.values()) {
- if (b.getKey().equals(key)) {
- return b;
- }
- }
- return null;
+ return getBubbleWithPredicate(mSuppressedBubbles.values(), b -> b.getKey().equals(key));
}
/**
@@ -1269,11 +1232,32 @@ public class BubbleData {
* @param key notification key
* @return bubble that matches or null
*/
+ @Nullable
@VisibleForTesting(visibility = PRIVATE)
public Bubble getPendingBubbleWithKey(String key) {
- for (Bubble b : mPendingBubbles.values()) {
- if (b.getKey().equals(key)) {
- return b;
+ return getBubbleWithPredicate(mPendingBubbles.values(), b -> b.getKey().equals(key));
+ }
+
+ @Nullable
+ private static Bubble getBubbleWithPredicate(@NonNull final List<Bubble> bubbles,
+ @NonNull final Predicate<Bubble> predicate) {
+ // Uses an indexed for loop for optimized performance when iterating over ArrayLists.
+ for (int i = 0; i < bubbles.size(); i++) {
+ final Bubble bubble = bubbles.get(i);
+ if (predicate.test(bubble)) {
+ return bubble;
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ private static Bubble getBubbleWithPredicate(@NonNull final Collection<Bubble> bubbles,
+ @NonNull final Predicate<Bubble> predicate) {
+ // Uses an enhanced for loop for general collections, which may not support indexed access.
+ for (final Bubble bubble : bubbles) {
+ if (predicate.test(bubble)) {
+ return bubble;
}
}
return null;
@@ -1284,7 +1268,7 @@ public class BubbleData {
* bubbles (i.e. pending, suppressed, active, and overflowed).
*/
private List<Bubble> filterAllBubbles(Predicate<Bubble> predicate) {
- ArrayList<Bubble> matchingBubbles = new ArrayList<>();
+ final ArrayList<Bubble> matchingBubbles = new ArrayList<>();
for (Bubble b : mPendingBubbles.values()) {
if (predicate.test(b)) {
matchingBubbles.add(b);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 1094c290df06..4e7f87c48a86 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -497,7 +497,7 @@ public class BubbleStackView extends FrameLayout
view /* bubble */,
mDismissView.getHeight() /* translationYBy */,
() -> dismissBubbleIfExists(
- mBubbleData.getBubbleWithView(view)) /* after */);
+ mBubbleData.getBubbleInStackWithView(view)) /* after */);
}
mDismissView.hide();
@@ -558,7 +558,7 @@ public class BubbleStackView extends FrameLayout
return;
}
- final Bubble clickedBubble = mBubbleData.getBubbleWithView(view);
+ final Bubble clickedBubble = mBubbleData.getBubbleInStackWithView(view);
// If the bubble has since left us, ignore the click.
if (clickedBubble == null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesTransitionObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesTransitionObserver.java
index c1f704ab455d..1f3b1b6718f7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesTransitionObserver.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesTransitionObserver.java
@@ -33,11 +33,13 @@ import com.android.wm.shell.transition.Transitions;
*/
public class BubblesTransitionObserver implements Transitions.TransitionObserver {
- private BubbleController mBubbleController;
- private BubbleData mBubbleData;
+ @NonNull
+ private final BubbleController mBubbleController;
+ @NonNull
+ private final BubbleData mBubbleData;
- public BubblesTransitionObserver(BubbleController controller,
- BubbleData bubbleData) {
+ public BubblesTransitionObserver(@NonNull BubbleController controller,
+ @NonNull BubbleData bubbleData) {
mBubbleController = controller;
mBubbleData = bubbleData;
}
@@ -57,7 +59,7 @@ public class BubblesTransitionObserver implements Transitions.TransitionObserver
|| mBubbleData.getSelectedBubble() == null) {
continue;
}
- int expandedId = mBubbleData.getSelectedBubble().getTaskId();
+ final int expandedId = mBubbleData.getSelectedBubble().getTaskId();
// If the task id that's opening is the same as the expanded bubble, skip collapsing
// because it is our bubble that is opening.
if (expandedId != INVALID_TASK_ID && expandedId != taskInfo.taskId) {
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 c9890a5b4963..94e629a6887f 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
@@ -661,7 +661,9 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
if (android.view.inputmethod.Flags.refactorInsetsController()) {
setVisibleDirectly(false /* visible */, statsToken);
}
- ImeTracker.forLogging().onHidden(mStatsToken);
+ if (!android.view.inputmethod.Flags.refactorInsetsController()) {
+ ImeTracker.forLogging().onHidden(mStatsToken);
+ }
} else if (mAnimationDirection == DIRECTION_SHOW && !mCancelled) {
ImeTracker.forLogging().onShown(mStatsToken);
} else if (mCancelled) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
index 702c67473db2..7897c0aa35bc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
@@ -342,6 +342,7 @@ class DesktopModeEventLogger {
taskUpdate.unminimizeReason?.reason ?: UNSET_UNMINIMIZE_REASON,
/* visible_task_count */
taskUpdate.visibleTaskCount,
+ taskUpdate.focusReason?.reason ?: UNSET_FOCUS_REASON,
)
EventLogTags.writeWmShellDesktopModeTaskUpdate(
/* task_event */
@@ -364,6 +365,7 @@ class DesktopModeEventLogger {
taskUpdate.unminimizeReason?.reason ?: UNSET_UNMINIMIZE_REASON,
/* visible_task_count */
taskUpdate.visibleTaskCount,
+ taskUpdate.focusReason?.reason ?: UNSET_FOCUS_REASON,
)
}
@@ -408,6 +410,8 @@ class DesktopModeEventLogger {
* @property taskY y-coordinate of the top-left corner
* @property minimizeReason the reason the task was minimized
* @property unminimizeReason the reason the task was unminimized
+ * @property visibleTaskCount the number of visible tasks after this update
+ * @property focusReason the reason the task was focused
*/
data class TaskUpdate(
val instanceId: Int,
@@ -419,6 +423,7 @@ class DesktopModeEventLogger {
val minimizeReason: MinimizeReason? = null,
val unminimizeReason: UnminimizeReason? = null,
val visibleTaskCount: Int,
+ val focusReason: FocusReason? = null,
)
/**
@@ -509,6 +514,16 @@ class DesktopModeEventLogger {
),
}
+ // Default value used when the task was not unminimized.
+ @VisibleForTesting
+ const val UNSET_FOCUS_REASON =
+ FrameworkStatsLog.DESKTOP_MODE_SESSION_TASK_UPDATE__FOCUS_REASON__UNSET_FOCUS
+
+ /** The reason a task was unminimized. */
+ enum class FocusReason(val reason: Int) {
+ UNKNOWN(FrameworkStatsLog.DESKTOP_MODE_SESSION_TASK_UPDATE__FOCUS_REASON__FOCUS_UNKNOWN)
+ }
+
/**
* Enum EnterReason mapped to the EnterReason definition in
* stats/atoms/desktopmode/desktopmode_extensions_atoms.proto
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
index df4b1c4a66ec..a43358603bc3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
@@ -27,7 +27,9 @@ import android.os.Trace
import android.util.SparseArray
import android.view.SurfaceControl
import android.view.WindowManager
+import android.view.WindowManager.TRANSIT_OPEN
import android.window.TransitionInfo
+import android.window.TransitionInfo.FLAG_MOVED_TO_TOP
import androidx.annotation.VisibleForTesting
import androidx.core.util.containsKey
import androidx.core.util.forEach
@@ -39,6 +41,7 @@ import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.EnterReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ExitReason
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.FocusReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.MinimizeReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.TaskUpdate
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.UnminimizeReason
@@ -91,6 +94,8 @@ class DesktopModeLoggerTransitionObserver(
// following enter reason could be Screen On
private var wasPreviousTransitionExitByScreenOff: Boolean = false
+ private var focusedFreeformTask: TaskInfo? = null
+
@VisibleForTesting var isSessionActive: Boolean = false
fun onInit() {
@@ -151,6 +156,7 @@ class DesktopModeLoggerTransitionObserver(
transitionInfo = info,
preTransitionVisibleFreeformTasks = visibleFreeformTaskInfos,
postTransitionVisibleFreeformTasks = postTransitionVisibleFreeformTasks,
+ newFocusedFreeformTask = getNewFocusedFreeformTask(info),
)
wasPreviousTransitionExitToOverview = info.isExitToRecentsTransition()
}
@@ -161,6 +167,19 @@ class DesktopModeLoggerTransitionObserver(
override fun onTransitionFinished(transition: IBinder, aborted: Boolean) {}
+ // Returns null if there was no change in focused task
+ private fun getNewFocusedFreeformTask(info: TransitionInfo): TaskInfo? {
+ val freeformWindowChanges =
+ info.changes
+ .filter { it.taskInfo != null && it.requireTaskInfo().taskId != INVALID_TASK_ID }
+ .filter { it.requireTaskInfo().isFreeformWindow() }
+ return freeformWindowChanges
+ .findLast { change ->
+ change.hasFlags(FLAG_MOVED_TO_TOP) || change.mode == TRANSIT_OPEN
+ }
+ ?.taskInfo
+ }
+
private fun getPostTransitionVisibleFreeformTaskInfos(
info: TransitionInfo
): SparseArray<TaskInfo> {
@@ -238,6 +257,7 @@ class DesktopModeLoggerTransitionObserver(
transitionInfo: TransitionInfo,
preTransitionVisibleFreeformTasks: SparseArray<TaskInfo>,
postTransitionVisibleFreeformTasks: SparseArray<TaskInfo>,
+ newFocusedFreeformTask: TaskInfo?,
) {
if (
postTransitionVisibleFreeformTasks.isEmpty() &&
@@ -250,6 +270,7 @@ class DesktopModeLoggerTransitionObserver(
transitionInfo,
preTransitionVisibleFreeformTasks,
postTransitionVisibleFreeformTasks,
+ newFocusedFreeformTask,
)
desktopModeEventLogger.logSessionExit(getExitReason(transitionInfo))
@@ -268,6 +289,7 @@ class DesktopModeLoggerTransitionObserver(
transitionInfo,
preTransitionVisibleFreeformTasks,
postTransitionVisibleFreeformTasks,
+ newFocusedFreeformTask,
)
} else if (isSessionActive) {
// Session is neither starting, nor finishing, log task updates if there are any
@@ -276,12 +298,14 @@ class DesktopModeLoggerTransitionObserver(
transitionInfo,
preTransitionVisibleFreeformTasks,
postTransitionVisibleFreeformTasks,
+ newFocusedFreeformTask,
)
}
// update the state to the new version
visibleFreeformTaskInfos.clear()
visibleFreeformTaskInfos.putAll(postTransitionVisibleFreeformTasks)
+ focusedFreeformTask = newFocusedFreeformTask
}
/** Compare the old and new state of taskInfos and identify and log the changes */
@@ -290,10 +314,16 @@ class DesktopModeLoggerTransitionObserver(
transitionInfo: TransitionInfo,
preTransitionVisibleFreeformTasks: SparseArray<TaskInfo>,
postTransitionVisibleFreeformTasks: SparseArray<TaskInfo>,
+ newFocusedFreeformTask: TaskInfo?,
) {
postTransitionVisibleFreeformTasks.forEach { taskId, taskInfo ->
+ val focusChangedReason = getFocusChangedReason(taskId, newFocusedFreeformTask)
val currentTaskUpdate =
- buildTaskUpdateForTask(taskInfo, postTransitionVisibleFreeformTasks.size())
+ buildTaskUpdateForTask(
+ taskInfo,
+ postTransitionVisibleFreeformTasks.size(),
+ focusChangedReason = focusChangedReason,
+ )
val previousTaskInfo = preTransitionVisibleFreeformTasks[taskId]
when {
// new tasks added
@@ -314,11 +344,14 @@ class DesktopModeLoggerTransitionObserver(
postTransitionVisibleFreeformTasks.size().toString(),
)
}
+ focusChangedReason != null ->
+ desktopModeEventLogger.logTaskInfoChanged(currentTaskUpdate)
// old tasks that were resized or repositioned
// TODO(b/347935387): Log changes only once they are stable.
buildTaskUpdateForTask(
previousTaskInfo,
postTransitionVisibleFreeformTasks.size(),
+ focusChangedReason = focusChangedReason,
) != currentTaskUpdate ->
desktopModeEventLogger.logTaskInfoChanged(currentTaskUpdate)
}
@@ -373,11 +406,21 @@ class DesktopModeLoggerTransitionObserver(
return null
}
+ private fun getFocusChangedReason(
+ taskId: Int,
+ newFocusedFreeformTask: TaskInfo?,
+ ): FocusReason? {
+ val newFocusedTask = newFocusedFreeformTask ?: return null
+ if (taskId != newFocusedTask.taskId) return null
+ return if (newFocusedTask != focusedFreeformTask) FocusReason.UNKNOWN else null
+ }
+
private fun buildTaskUpdateForTask(
taskInfo: TaskInfo,
visibleTasks: Int,
minimizeReason: MinimizeReason? = null,
unminimizeReason: UnminimizeReason? = null,
+ focusChangedReason: FocusReason? = null,
): TaskUpdate {
val screenBounds = taskInfo.configuration.windowConfiguration.bounds
val positionInParent = taskInfo.positionInParent
@@ -393,6 +436,7 @@ class DesktopModeLoggerTransitionObserver(
visibleTaskCount = visibleTasks,
minimizeReason = minimizeReason,
unminimizeReason = unminimizeReason,
+ focusReason = focusChangedReason,
)
}
@@ -475,6 +519,12 @@ class DesktopModeLoggerTransitionObserver(
visibleFreeformTaskInfos.set(taskInfo.taskId, taskInfo)
}
+ /** Sets the focused task - only used for testing. */
+ @VisibleForTesting
+ fun setFocusedTaskForTesting(taskInfo: TaskInfo) {
+ focusedFreeformTask = taskInfo
+ }
+
private fun TransitionInfo.Change.requireTaskInfo(): RunningTaskInfo =
this.taskInfo ?: throw IllegalStateException("Expected TaskInfo in the Change")
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt
index 45d1281ba0e0..5757c6afd196 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt
@@ -33,7 +33,6 @@ import com.android.wm.shell.shared.annotations.ShellMainThread
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus.canEnterDesktopMode
import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource
import com.android.wm.shell.windowdecor.common.DecorThemeUtil
-import com.android.wm.shell.windowdecor.common.Theme
import com.android.wm.shell.windowdecor.education.DesktopWindowingEducationTooltipController
import com.android.wm.shell.windowdecor.education.DesktopWindowingEducationTooltipController.TooltipColorScheme
import com.android.wm.shell.windowdecor.education.DesktopWindowingEducationTooltipController.TooltipEducationViewConfig
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
index 08211ab5df9c..cc962acf1182 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
@@ -370,7 +370,8 @@ class SplashscreenWindowCreator extends AbsSplashWindowCreator {
private void removeWindowInner(@NonNull View decorView, boolean hideView) {
requestTopUi(false);
- if (!decorView.isAttachedToWindow()) {
+ if (decorView.getParent() == null) {
+ Slog.w(TAG, "This root view has no parent, never been added to a ViewRootImpl?");
return;
}
if (hideView) {
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/OpenAppFromAllAppsTest.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/OpenAppFromAllAppsTest.kt
new file mode 100644
index 000000000000..61af4a5f82d4
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/OpenAppFromAllAppsTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2025 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.functional
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.scenarios.OpenAppFromAllApps
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/* Functional test for [OpenAppsInDesktopMode]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+class OpenAppFromAllAppsTest : OpenAppFromAllApps() \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/OpenAppFromTaskbarTest.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/OpenAppFromTaskbarTest.kt
new file mode 100644
index 000000000000..bb5697e6ddfc
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/OpenAppFromTaskbarTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2025 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.functional
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.scenarios.OpenAppFromTaskbar
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/* Functional test for [OpenAppsInDesktopMode]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+class OpenAppFromTaskbarTest : OpenAppFromTaskbar() \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/UnminimizeAppFromAllAppsTest.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/UnminimizeAppFromAllAppsTest.kt
new file mode 100644
index 000000000000..0c681f94d7ef
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/UnminimizeAppFromAllAppsTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2025 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.functional
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.scenarios.UnminimizeAppFromAllApps
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/* Functional test for [OpenAppsInDesktopMode]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+class UnminimizeAppFromAllAppsTest : UnminimizeAppFromAllApps() \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/UnminimizeAppFromTaskbarTest.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/UnminimizeAppFromTaskbarTest.kt
new file mode 100644
index 000000000000..4e65ad092881
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/UnminimizeAppFromTaskbarTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2025 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.functional
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.scenarios.UnminimizeAppFromTaskbar
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/* Functional test for [OpenAppsInDesktopMode]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+class UnminimizeAppFromTaskbarTest : UnminimizeAppFromTaskbar() \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/OpenAppFromAllApps.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/OpenAppFromAllApps.kt
new file mode 100644
index 000000000000..36cdd5b26992
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/OpenAppFromAllApps.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2025 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.scenarios
+
+import android.app.Instrumentation
+import android.tools.NavBar
+import android.tools.flicker.rules.ChangeDisplayOrientationRule
+import android.tools.Rotation
+import android.tools.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.DesktopModeAppHelper
+import com.android.server.wm.flicker.helpers.MailAppHelper
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.window.flags.Flags
+import com.android.wm.shell.Utils
+import org.junit.After
+import org.junit.Assume
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+
+@Ignore("Test Base Class")
+abstract class OpenAppFromAllApps(val rotation: Rotation = Rotation.ROTATION_0) {
+
+ private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+ private val tapl = LauncherInstrumentation()
+ private val wmHelper = WindowManagerStateHelper(instrumentation)
+ private val device = UiDevice.getInstance(instrumentation)
+ private val testApp = DesktopModeAppHelper(SimpleAppHelper(instrumentation))
+ private val mailApp = MailAppHelper(instrumentation)
+
+ @Rule
+ @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
+
+ @Before
+ fun setup() {
+ Assume.assumeTrue(Flags.enableDesktopWindowingMode() && tapl.isTablet)
+ tapl.setEnableRotation(true)
+ tapl.setExpectedRotation(rotation.value)
+ tapl.enableTransientTaskbar(false)
+ ChangeDisplayOrientationRule.setRotation(rotation)
+ testApp.enterDesktopMode(wmHelper, device)
+ tapl.showTaskbarIfHidden()
+ }
+
+ @Test
+ open fun openApp() {
+ tapl.launchedAppState.taskbar
+ .openAllApps()
+ .getAppIcon(mailApp.appName)
+ .launch(mailApp.packageName)
+ }
+
+ @After
+ fun teardown() {
+ mailApp.exit(wmHelper)
+ testApp.exit(wmHelper)
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/OpenAppFromTaskbar.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/OpenAppFromTaskbar.kt
new file mode 100644
index 000000000000..2b456beff58f
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/OpenAppFromTaskbar.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2025 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.scenarios
+
+import android.app.Instrumentation
+import android.tools.NavBar
+import android.tools.Rotation
+import android.tools.device.apphelpers.BrowserAppHelper
+import android.tools.flicker.rules.ChangeDisplayOrientationRule
+import android.tools.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.DesktopModeAppHelper
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.window.flags.Flags
+import com.android.wm.shell.Utils
+import org.junit.After
+import org.junit.Assume
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+
+@Ignore("Test Base Class")
+abstract class OpenAppFromTaskbar(val rotation: Rotation = Rotation.ROTATION_0) {
+
+ private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+ private val tapl = LauncherInstrumentation()
+ private val wmHelper = WindowManagerStateHelper(instrumentation)
+ private val device = UiDevice.getInstance(instrumentation)
+ private val testApp = DesktopModeAppHelper(SimpleAppHelper(instrumentation))
+ private val browserApp = BrowserAppHelper(instrumentation)
+
+ @Rule
+ @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
+
+ @Before
+ fun setup() {
+ Assume.assumeTrue(Flags.enableDesktopWindowingMode() && tapl.isTablet)
+ tapl.setEnableRotation(true)
+ tapl.setExpectedRotation(rotation.value)
+ tapl.enableTransientTaskbar(false)
+ ChangeDisplayOrientationRule.setRotation(rotation)
+ testApp.enterDesktopMode(wmHelper, device)
+ tapl.showTaskbarIfHidden()
+ }
+
+ @Test
+ open fun openApp() {
+ tapl.launchedAppState.taskbar
+ .getAppIcon(browserApp.appName)
+ .launch(browserApp.packageName)
+ }
+
+ @After
+ fun teardown() {
+ browserApp.exit(wmHelper)
+ testApp.exit(wmHelper)
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/UnminimizeAppFromAllApps.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/UnminimizeAppFromAllApps.kt
new file mode 100644
index 000000000000..234b984a6cff
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/UnminimizeAppFromAllApps.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2025 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.scenarios
+
+import android.app.Instrumentation
+import android.tools.NavBar
+import android.tools.Rotation
+import android.tools.flicker.rules.ChangeDisplayOrientationRule
+import android.tools.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.DesktopModeAppHelper
+import com.android.server.wm.flicker.helpers.MailAppHelper
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.window.flags.Flags
+import com.android.wm.shell.Utils
+import org.junit.After
+import org.junit.Assume
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+
+@Ignore("Test Base Class")
+abstract class UnminimizeAppFromAllApps(val rotation: Rotation = Rotation.ROTATION_0) {
+
+ private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+ private val tapl = LauncherInstrumentation()
+ private val wmHelper = WindowManagerStateHelper(instrumentation)
+ private val device = UiDevice.getInstance(instrumentation)
+ private val testApp = DesktopModeAppHelper(SimpleAppHelper(instrumentation))
+ private val mailHelper = MailAppHelper(instrumentation)
+ private val mailApp = DesktopModeAppHelper(mailHelper)
+
+ @Rule
+ @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
+
+ @Before
+ fun setup() {
+ Assume.assumeTrue(Flags.enableDesktopWindowingMode() && tapl.isTablet)
+ tapl.setEnableRotation(true)
+ tapl.setExpectedRotation(rotation.value)
+ tapl.enableTransientTaskbar(false)
+ ChangeDisplayOrientationRule.setRotation(rotation)
+ testApp.enterDesktopMode(wmHelper, device)
+ tapl.showTaskbarIfHidden()
+ mailApp.launchViaIntent(wmHelper)
+ mailApp.minimizeDesktopApp(wmHelper, device)
+ }
+
+ @Test
+ open fun unminimizeApp() {
+ tapl.launchedAppState.taskbar
+ .openAllApps()
+ .getAppIcon(mailHelper.appName)
+ .launch(mailApp.packageName)
+ }
+
+ @After
+ fun teardown() {
+ testApp.exit(wmHelper)
+ mailApp.exit(wmHelper)
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/UnminimizeAppFromTaskbar.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/UnminimizeAppFromTaskbar.kt
new file mode 100644
index 000000000000..3e98e4342b3f
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/UnminimizeAppFromTaskbar.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2025 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.scenarios
+
+import android.app.Instrumentation
+import android.tools.NavBar
+import android.tools.Rotation
+import android.tools.device.apphelpers.BrowserAppHelper
+import android.tools.flicker.rules.ChangeDisplayOrientationRule
+import android.tools.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.DesktopModeAppHelper
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.window.flags.Flags
+import com.android.wm.shell.Utils
+import org.junit.After
+import org.junit.Assume
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+
+@Ignore("Test Base Class")
+abstract class UnminimizeAppFromTaskbar(val rotation: Rotation = Rotation.ROTATION_0) {
+
+ private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+ private val tapl = LauncherInstrumentation()
+ private val wmHelper = WindowManagerStateHelper(instrumentation)
+ private val device = UiDevice.getInstance(instrumentation)
+ private val testApp = DesktopModeAppHelper(SimpleAppHelper(instrumentation))
+ private val browserHelper = BrowserAppHelper(instrumentation)
+ private val browserApp = DesktopModeAppHelper(browserHelper)
+
+ @Rule
+ @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
+
+ @Before
+ fun setup() {
+ Assume.assumeTrue(Flags.enableDesktopWindowingMode() && tapl.isTablet)
+ tapl.setEnableRotation(true)
+ tapl.setExpectedRotation(rotation.value)
+ tapl.enableTransientTaskbar(false)
+ ChangeDisplayOrientationRule.setRotation(rotation)
+ testApp.enterDesktopMode(wmHelper, device)
+ tapl.showTaskbarIfHidden()
+ browserApp.launchViaIntent(wmHelper)
+ browserApp.minimizeDesktopApp(wmHelper, device)
+ }
+
+ @Test
+ open fun unminimizeApp() {
+ tapl.launchedAppState.taskbar
+ .getAppIcon(browserHelper.appName)
+ .launch(browserHelper.packageName)
+ }
+
+ @After
+ fun teardown() {
+ testApp.exit(wmHelper)
+ browserApp.exit(wmHelper)
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
index a6f8150ffc55..e51fa45c3010 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
@@ -27,6 +27,7 @@ import android.tools.flicker.legacy.LegacyFlickerTest
import android.tools.flicker.legacy.LegacyFlickerTestFactory
import android.tools.helpers.WindowUtils
import android.tools.traces.component.ComponentNameMatcher
+import android.view.WindowManagerGlobal
import androidx.test.filters.FlakyTest
import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.FixedOrientationAppHelper
@@ -38,13 +39,12 @@ import com.android.wm.shell.flicker.pip.common.PipTransition
import com.android.wm.shell.flicker.pip.common.PipTransition.BroadcastActionTrigger.Companion.ORIENTATION_LANDSCAPE
import com.android.wm.shell.flicker.pip.common.PipTransition.BroadcastActionTrigger.Companion.ORIENTATION_PORTRAIT
import org.junit.Assume.assumeFalse
-import org.junit.Assume.assumeTrue
import org.junit.FixMethodOrder
-import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized
+import java.lang.AssertionError
/**
* Test entering pip while changing orientation (from app in landscape to pip window in portrait)
@@ -75,7 +75,15 @@ import org.junit.runners.Parameterized
open class EnterPipToOtherOrientation(flicker: LegacyFlickerTest) : PipTransition(flicker) {
override val pipApp: PipAppHelper = PipAppHelper(instrumentation)
internal val testApp = FixedOrientationAppHelper(instrumentation)
- internal val startingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_90)
+ internal val ignoreOrientationRequest = WindowManagerGlobal.getWindowManagerService()
+ ?.getIgnoreOrientationRequest(WindowUtils.defaultDisplayId)
+ ?: throw AssertionError("WMS must not be null.")
+ internal val startingBounds = if (ignoreOrientationRequest) {
+ // If the device chooses to ignore orientation request, use the current display bounds.
+ WindowUtils.getDisplayBounds(Rotation.ROTATION_0)
+ } else {
+ WindowUtils.getDisplayBounds(Rotation.ROTATION_90)
+ }
private val endingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_0)
override val thisTransition: FlickerBuilder.() -> Unit = {
@@ -167,20 +175,14 @@ open class EnterPipToOtherOrientation(flicker: LegacyFlickerTest) : PipTransitio
@Presubmit
@Test
open fun pipAppLayerCoversFullScreenOnStart() {
- assumeFalse(tapl.isTablet)
- flicker.assertLayersStart { visibleRegion(pipApp).coversExactly(startingBounds) }
- }
-
- /**
- * Checks that the visible region of [pipApp] covers the full display area at the start of the
- * transition
- */
- @Ignore("TODO(b/356277166): enable the tablet test")
- @Test
- open fun pipAppLayerPlusLetterboxCoversFullScreenOnStartTablet() {
- assumeTrue(tapl.isTablet)
flicker.assertLayersStart {
- visibleRegion(pipApp.or(ComponentNameMatcher.LETTERBOX)).coversExactly(startingBounds)
+ visibleRegion(
+ if (ignoreOrientationRequest) {
+ pipApp.or(ComponentNameMatcher.LETTERBOX)
+ } else {
+ pipApp
+ }
+ ).coversExactly(startingBounds)
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfEnterPipToOtherOrientation.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfEnterPipToOtherOrientation.kt
index d65f158e00d6..676c9a4c7d8f 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfEnterPipToOtherOrientation.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfEnterPipToOtherOrientation.kt
@@ -26,10 +26,7 @@ import com.android.server.wm.flicker.helpers.BottomHalfPipAppHelper
import com.android.server.wm.flicker.helpers.PipAppHelper
import com.android.wm.shell.Flags
import com.android.wm.shell.flicker.pip.EnterPipToOtherOrientation
-import org.junit.Assume.assumeFalse
-import org.junit.Assume.assumeTrue
import org.junit.FixMethodOrder
-import org.junit.Ignore
import org.junit.Test
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized
@@ -71,19 +68,14 @@ class BottomHalfEnterPipToOtherOrientation(flicker: LegacyFlickerTest) :
@Test
override fun pipAppLayerCoversFullScreenOnStart() {
// Test app and pip app should covers the entire screen on start.
- assumeFalse(tapl.isTablet)
flicker.assertLayersStart {
- visibleRegion(pipApp.or(testApp)).coversExactly(startingBounds)
- }
- }
-
- @Ignore("TODO(b/356277166): enable the tablet test")
- @Test
- override fun pipAppLayerPlusLetterboxCoversFullScreenOnStartTablet() {
- // Test app and pip app should covers the entire screen on start.
- assumeTrue(tapl.isTablet)
- flicker.assertLayersStart {
- visibleRegion(pipApp.or(ComponentNameMatcher.LETTERBOX)).coversExactly(startingBounds)
+ visibleRegion(
+ if (ignoreOrientationRequest) {
+ pipApp.or(testApp).or(ComponentNameMatcher.LETTERBOX)
+ } else {
+ pipApp.or(testApp)
+ }
+ ).coversExactly(startingBounds)
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt
index eb6f1d75e6ca..bddc06204a52 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt
@@ -35,12 +35,14 @@ import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.DisplayLayout
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.EnterReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ExitReason
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.FocusReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.InputMethod
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.MinimizeReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.NO_SESSION_ID
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.TaskSizeUpdate
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.TaskUpdate
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.UNSET_FOCUS_REASON
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.UNSET_MINIMIZE_REASON
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.UNSET_UNMINIMIZE_REASON
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.UnminimizeReason
@@ -188,6 +190,7 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
UNSET_MINIMIZE_REASON,
UNSET_UNMINIMIZE_REASON,
TASK_COUNT,
+ UNSET_FOCUS_REASON,
)
verify {
EventLogTags.writeWmShellDesktopModeTaskUpdate(
@@ -202,6 +205,7 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
eq(UNSET_MINIMIZE_REASON),
eq(UNSET_UNMINIMIZE_REASON),
eq(TASK_COUNT),
+ eq(UNSET_FOCUS_REASON),
)
}
verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
@@ -233,6 +237,7 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
UNSET_MINIMIZE_REASON,
UNSET_UNMINIMIZE_REASON,
TASK_COUNT,
+ UNSET_FOCUS_REASON,
)
verify {
EventLogTags.writeWmShellDesktopModeTaskUpdate(
@@ -247,6 +252,7 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
eq(UNSET_MINIMIZE_REASON),
eq(UNSET_UNMINIMIZE_REASON),
eq(TASK_COUNT),
+ eq(UNSET_FOCUS_REASON),
)
}
verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
@@ -278,6 +284,7 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
UNSET_MINIMIZE_REASON,
UNSET_UNMINIMIZE_REASON,
TASK_COUNT,
+ UNSET_FOCUS_REASON,
)
verify {
EventLogTags.writeWmShellDesktopModeTaskUpdate(
@@ -295,6 +302,7 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
eq(UNSET_MINIMIZE_REASON),
eq(UNSET_UNMINIMIZE_REASON),
eq(TASK_COUNT),
+ eq(UNSET_FOCUS_REASON),
)
}
verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
@@ -320,6 +328,7 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
MinimizeReason.TASK_LIMIT.reason,
UNSET_UNMINIMIZE_REASON,
TASK_COUNT,
+ UNSET_FOCUS_REASON,
)
verify {
EventLogTags.writeWmShellDesktopModeTaskUpdate(
@@ -337,6 +346,7 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
eq(MinimizeReason.TASK_LIMIT.reason),
eq(UNSET_UNMINIMIZE_REASON),
eq(TASK_COUNT),
+ eq(UNSET_FOCUS_REASON),
)
}
verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
@@ -362,6 +372,7 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
UNSET_MINIMIZE_REASON,
UnminimizeReason.TASKBAR_TAP.reason,
TASK_COUNT,
+ UNSET_FOCUS_REASON,
)
verify {
EventLogTags.writeWmShellDesktopModeTaskUpdate(
@@ -379,6 +390,51 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
eq(UNSET_MINIMIZE_REASON),
eq(UnminimizeReason.TASKBAR_TAP.reason),
eq(TASK_COUNT),
+ eq(UNSET_FOCUS_REASON),
+ )
+ }
+ verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
+ }
+
+ @Test
+ fun logTaskInfoChanged_logsTaskUpdateWithFocusReason() {
+ val sessionId = startDesktopModeSession()
+
+ desktopModeEventLogger.logTaskInfoChanged(
+ createTaskUpdate(focusChangesReason = FocusReason.UNKNOWN)
+ )
+
+ verifyOnlyOneTaskUpdateLogging(
+ FrameworkStatsLog.DESKTOP_MODE_SESSION_TASK_UPDATE__TASK_EVENT__TASK_INFO_CHANGED,
+ TASK_UPDATE.instanceId,
+ TASK_UPDATE.uid,
+ TASK_UPDATE.taskHeight,
+ TASK_UPDATE.taskWidth,
+ TASK_UPDATE.taskX,
+ TASK_UPDATE.taskY,
+ sessionId,
+ UNSET_MINIMIZE_REASON,
+ UNSET_UNMINIMIZE_REASON,
+ TASK_COUNT,
+ FocusReason.UNKNOWN.reason,
+ )
+ verify {
+ EventLogTags.writeWmShellDesktopModeTaskUpdate(
+ eq(
+ FrameworkStatsLog
+ .DESKTOP_MODE_SESSION_TASK_UPDATE__TASK_EVENT__TASK_INFO_CHANGED
+ ),
+ eq(TASK_UPDATE.instanceId),
+ eq(TASK_UPDATE.uid),
+ eq(TASK_UPDATE.taskHeight),
+ eq(TASK_UPDATE.taskWidth),
+ eq(TASK_UPDATE.taskX),
+ eq(TASK_UPDATE.taskY),
+ eq(sessionId),
+ eq(UNSET_MINIMIZE_REASON),
+ eq(UNSET_UNMINIMIZE_REASON),
+ eq(TASK_COUNT),
+ eq(FocusReason.UNKNOWN.reason),
)
}
verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
@@ -497,6 +553,8 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
eq(UNSET_UNMINIMIZE_REASON),
/* visible_task_count */
eq(0),
+ /* focus_reason */
+ eq(UNSET_FOCUS_REASON),
)
}
}
@@ -536,6 +594,7 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
anyInt(),
anyInt(),
anyInt(),
+ anyInt(),
)
},
never(),
@@ -597,6 +656,7 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
minimizeReason: Int,
unminimizeReason: Int,
visibleTaskCount: Int,
+ focusChangedReason: Int,
) {
verify({
FrameworkStatsLog.write(
@@ -612,6 +672,7 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
eq(minimizeReason),
eq(unminimizeReason),
eq(visibleTaskCount),
+ eq(focusChangedReason),
)
})
verify({
@@ -628,6 +689,7 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
anyInt(),
anyInt(),
anyInt(),
+ anyInt(),
)
})
}
@@ -710,6 +772,7 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
private fun createTaskUpdate(
minimizeReason: MinimizeReason? = null,
unminimizeReason: UnminimizeReason? = null,
+ focusChangesReason: FocusReason? = null,
) =
TaskUpdate(
TASK_ID,
@@ -721,6 +784,7 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
minimizeReason,
unminimizeReason,
TASK_COUNT,
+ focusChangesReason,
)
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt
index 2e9d6d95eebb..b7d25b5255f8 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt
@@ -38,6 +38,7 @@ import android.view.WindowManager.TRANSIT_WAKE
import android.window.IWindowContainerToken
import android.window.TransitionInfo
import android.window.TransitionInfo.Change
+import android.window.TransitionInfo.FLAG_MOVED_TO_TOP
import android.window.WindowContainerToken
import androidx.test.filters.SmallTest
import com.android.dx.mockito.inline.extended.ExtendedMockito
@@ -47,6 +48,7 @@ import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.EnterReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ExitReason
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.FocusReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.MinimizeReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.TaskUpdate
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.UnminimizeReason
@@ -175,7 +177,7 @@ class DesktopModeLoggerTransitionObserverTest : ShellTestCase() {
verifyTaskAddedAndEnterLogging(
EnterReason.APP_FREEFORM_INTENT,
- DEFAULT_TASK_UPDATE.copy(visibleTaskCount = 1),
+ DEFAULT_TASK_UPDATE.copy(visibleTaskCount = 1, focusReason = FocusReason.UNKNOWN),
)
}
@@ -635,7 +637,15 @@ class DesktopModeLoggerTransitionObserverTest : ShellTestCase() {
callOnTransitionReady(transitionInfo)
verify(desktopModeEventLogger, times(1))
- .logTaskAdded(eq(DEFAULT_TASK_UPDATE.copy(instanceId = 2, visibleTaskCount = 2)))
+ .logTaskAdded(
+ eq(
+ DEFAULT_TASK_UPDATE.copy(
+ instanceId = 2,
+ visibleTaskCount = 2,
+ focusReason = FocusReason.UNKNOWN,
+ )
+ )
+ )
verify(desktopModeEventLogger, never()).logSessionEnter(any())
}
@@ -695,6 +705,34 @@ class DesktopModeLoggerTransitionObserverTest : ShellTestCase() {
}
@Test
+ fun sessionAlreadyStarted_taskFocusChanged_logsTaskUpdate() {
+ val taskInfo1 = createTaskInfo(WINDOWING_MODE_FREEFORM, id = 1)
+ val taskInfo2 = createTaskInfo(WINDOWING_MODE_FREEFORM, id = 2)
+ transitionObserver.addTaskInfosToCachedMap(taskInfo1)
+ transitionObserver.addTaskInfosToCachedMap(taskInfo2)
+ transitionObserver.isSessionActive = true
+ transitionObserver.setFocusedTaskForTesting(taskInfo1)
+
+ val task2FocusedChange = createChange(TRANSIT_CHANGE, taskInfo2)
+ task2FocusedChange.flags = FLAG_MOVED_TO_TOP
+ val transitionInfo =
+ TransitionInfoBuilder(TRANSIT_CHANGE, 0).addChange(task2FocusedChange).build()
+ callOnTransitionReady(transitionInfo)
+
+ verify(desktopModeEventLogger, times(1))
+ .logTaskInfoChanged(
+ eq(
+ DEFAULT_TASK_UPDATE.copy(
+ instanceId = 2,
+ visibleTaskCount = 2,
+ focusReason = FocusReason.UNKNOWN,
+ )
+ )
+ )
+ verifyZeroInteractions(desktopModeEventLogger)
+ }
+
+ @Test
fun sessionAlreadyStarted_multipleTasksUpdated_logsTaskUpdateForCorrectTask() {
// add 2 existing freeform task
val taskInfo1 = createTaskInfo(WINDOWING_MODE_FREEFORM)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
index 6d18e3696f84..b11715b669f4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
@@ -16,12 +16,16 @@
package com.android.wm.shell.pip.phone;
+import static com.android.wm.shell.Flags.FLAG_ENABLE_PIP2;
+
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.graphics.Rect;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.Size;
@@ -45,6 +49,7 @@ import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.sysui.ShellInit;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -63,6 +68,8 @@ import java.util.Optional;
@SmallTest
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class PipTouchHandlerTest extends ShellTestCase {
+ @Rule
+ public SetFlagsRule setFlagsRule = new SetFlagsRule();
private static final int INSET = 10;
private static final int PIP_LENGTH = 100;
@@ -150,6 +157,7 @@ public class PipTouchHandlerTest extends ShellTestCase {
}
@Test
+ @DisableFlags(FLAG_ENABLE_PIP2)
public void instantiate_addInitCallback() {
verify(mShellInit, times(1)).addInitCallback(any(), any());
}
diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
index 73728bcd1ff7..7bd4b3f771ab 100644
--- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
@@ -240,6 +240,11 @@ public class MainSwitchBar extends LinearLayout implements OnCheckedChangeListen
}
}
+ /** Removes all [OnCheckedChangeListener]s. */
+ public void removeAllOnSwitchChangeListeners() {
+ mSwitchChangeListeners.clear();
+ }
+
/**
* Remove a listener for switch changes
*/
diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
index 83858d9c9c54..d883fb0594e6 100644
--- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
@@ -17,12 +17,13 @@
package com.android.settingslib.widget;
import android.content.Context;
-import android.content.res.TypedArray;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.preference.PreferenceViewHolder;
import androidx.preference.TwoStatePreference;
@@ -34,124 +35,67 @@ import java.util.List;
/**
* MainSwitchPreference is a Preference with a customized Switch.
* This component is used as the main switch of the page
- * to enable or disable the prefereces on the page.
+ * to enable or disable the preferences on the page.
*/
-public class MainSwitchPreference extends TwoStatePreference
- implements OnCheckedChangeListener, GroupSectionDividerMixin {
+public class MainSwitchPreference extends TwoStatePreference implements OnCheckedChangeListener,
+ GroupSectionDividerMixin {
private final List<OnCheckedChangeListener> mSwitchChangeListeners = new ArrayList<>();
- private MainSwitchBar mMainSwitchBar;
-
- public MainSwitchPreference(Context context) {
- super(context);
- init(context, null);
+ public MainSwitchPreference(@NonNull Context context) {
+ this(context, null);
}
- public MainSwitchPreference(Context context, AttributeSet attrs) {
- super(context, attrs);
- init(context, attrs);
+ public MainSwitchPreference(@NonNull Context context, @Nullable AttributeSet attrs) {
+ this(context, attrs, 0);
}
- public MainSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- init(context, attrs);
+ public MainSwitchPreference(@NonNull Context context, @Nullable AttributeSet attrs,
+ int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
}
- public MainSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
+ public MainSwitchPreference(@NonNull Context context, @Nullable AttributeSet attrs,
+ int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- init(context, attrs);
+ boolean isExpressive = SettingsThemeHelper.isExpressiveTheme(context);
+ int resId = isExpressive ? R.layout.settingslib_expressive_main_switch_layout
+ : R.layout.settingslib_main_switch_layout;
+ setLayoutResource(resId);
}
@Override
- public void onBindViewHolder(PreferenceViewHolder holder) {
+ public void onBindViewHolder(@NonNull PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
holder.setDividerAllowedAbove(false);
holder.setDividerAllowedBelow(false);
- mMainSwitchBar = (MainSwitchBar) holder.findViewById(R.id.settingslib_main_switch_bar);
+ MainSwitchBar mainSwitchBar = holder.itemView.requireViewById(
+ R.id.settingslib_main_switch_bar);
+ mainSwitchBar.setTitle(getTitle());
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
+ mainSwitchBar.setSummary(getSummary());
+ }
+ mainSwitchBar.setIconSpaceReserved(isIconSpaceReserved());
// To support onPreferenceChange callback, it needs to call callChangeListener() when
// MainSwitchBar is clicked.
- mMainSwitchBar.setOnClickListener((view) -> callChangeListener(isChecked()));
- setIconSpaceReserved(isIconSpaceReserved());
- updateStatus(isChecked());
- registerListenerToSwitchBar();
- }
+ mainSwitchBar.setOnClickListener(view -> callChangeListener(isChecked()));
- private void init(Context context, AttributeSet attrs) {
- boolean isExpressive = SettingsThemeHelper.isExpressiveTheme(context);
- int resId = isExpressive
- ? R.layout.settingslib_expressive_main_switch_layout
- : R.layout.settingslib_main_switch_layout;
- setLayoutResource(resId);
- mSwitchChangeListeners.add(this);
- if (attrs != null) {
- final TypedArray a = context.obtainStyledAttributes(attrs,
- androidx.preference.R.styleable.Preference, 0 /*defStyleAttr*/,
- 0 /*defStyleRes*/);
- final CharSequence title = a.getText(
- androidx.preference.R.styleable.Preference_android_title);
- setTitle(title);
-
- CharSequence summary = a.getText(
- androidx.preference.R.styleable.Preference_android_summary);
- setSummary(summary);
-
- final boolean bIconSpaceReserved = a.getBoolean(
- androidx.preference.R.styleable.Preference_android_iconSpaceReserved, true);
- setIconSpaceReserved(bIconSpaceReserved);
- a.recycle();
- }
- }
+ // Remove all listeners to 1. avoid triggering listener when update UI 2. prevent potential
+ // listener leaking when the view holder is reused by RecyclerView
+ mainSwitchBar.removeAllOnSwitchChangeListeners();
+ mainSwitchBar.setChecked(isChecked());
+ mainSwitchBar.addOnSwitchChangeListener(this);
- @Override
- public void setChecked(boolean checked) {
- super.setChecked(checked);
- if (mMainSwitchBar != null && mMainSwitchBar.isChecked() != checked) {
- mMainSwitchBar.setChecked(checked);
- }
- }
-
- @Override
- public void setTitle(CharSequence title) {
- super.setTitle(title);
- if (mMainSwitchBar != null) {
- mMainSwitchBar.setTitle(title);
- }
- }
-
- @Override
- public void setSummary(CharSequence summary) {
- super.setSummary(summary);
- if (mMainSwitchBar != null
- && Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
- mMainSwitchBar.setSummary(summary);
- }
- }
-
- @Override
- public void setIconSpaceReserved(boolean iconSpaceReserved) {
- super.setIconSpaceReserved(iconSpaceReserved);
- if (mMainSwitchBar != null) {
- mMainSwitchBar.setIconSpaceReserved(iconSpaceReserved);
- }
+ mainSwitchBar.show();
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
super.setChecked(isChecked);
- }
-
- /**
- * Update the switch status of preference
- */
- public void updateStatus(boolean checked) {
- setChecked(checked);
- if (mMainSwitchBar != null) {
- mMainSwitchBar.setTitle(getTitle());
- mMainSwitchBar.show();
+ for (OnCheckedChangeListener listener : mSwitchChangeListeners) {
+ listener.onCheckedChanged(buttonView, isChecked);
}
}
@@ -162,10 +106,6 @@ public class MainSwitchPreference extends TwoStatePreference
if (!mSwitchChangeListeners.contains(listener)) {
mSwitchChangeListeners.add(listener);
}
-
- if (mMainSwitchBar != null) {
- mMainSwitchBar.addOnSwitchChangeListener(listener);
- }
}
/**
@@ -173,14 +113,5 @@ public class MainSwitchPreference extends TwoStatePreference
*/
public void removeOnSwitchChangeListener(OnCheckedChangeListener listener) {
mSwitchChangeListeners.remove(listener);
- if (mMainSwitchBar != null) {
- mMainSwitchBar.removeOnSwitchChangeListener(listener);
- }
- }
-
- private void registerListenerToSwitchBar() {
- for (OnCheckedChangeListener listener : mSwitchChangeListeners) {
- mMainSwitchBar.addOnSwitchChangeListener(listener);
- }
}
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/satellite/SatelliteDialogUtilsTest.kt b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/satellite/SatelliteDialogUtilsTest.kt
index 2078b363f434..1deb62510daf 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/satellite/SatelliteDialogUtilsTest.kt
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/satellite/SatelliteDialogUtilsTest.kt
@@ -67,7 +67,7 @@ class SatelliteDialogUtilsTest {
@Test
@RequiresFlagsEnabled(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
- fun mayStartSatelliteWarningDialog_satelliteIsOn_showWarningDialog() = runBlocking {
+ fun mayStartSatelliteWarningDialog_satelliteIsOn_showWarningDialog(): Unit = runBlocking {
`when`(satelliteManager.registerForModemStateChanged(any(), any()))
.thenAnswer { invocation ->
val callback = invocation
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java
index c2e81bd7d54c..a47b4d5c354f 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java
@@ -23,6 +23,7 @@ import android.view.View;
import android.widget.TextView;
import androidx.preference.PreferenceViewHolder;
+import androidx.test.core.app.ApplicationProvider;
import com.android.settingslib.widget.mainswitch.R;
@@ -30,19 +31,17 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class MainSwitchPreferenceTest {
- private Context mContext;
+ private final Context mContext = ApplicationProvider.getApplicationContext();
private View mRootView;
private PreferenceViewHolder mHolder;
private MainSwitchPreference mPreference;
@Before
public void setUp() {
- mContext = RuntimeEnvironment.application;
mRootView = View.inflate(mContext, R.layout.settingslib_main_switch_layout,
null /* parent */);
mHolder = PreferenceViewHolder.createInstanceForTests(mRootView);
@@ -50,23 +49,22 @@ public class MainSwitchPreferenceTest {
}
@Test
- public void setTitle_shouldUpdateTitle() {
+ public void onBindViewHolder_title() {
final String defaultOnText = "Test title";
- mPreference.onBindViewHolder(mHolder);
mPreference.setTitle(defaultOnText);
- mPreference.updateStatus(true /* checked */);
+ mPreference.onBindViewHolder(mHolder);
- assertThat(((TextView) mRootView.findViewById(R.id.switch_text)).getText())
- .isEqualTo(defaultOnText);
+ assertThat(mRootView.<TextView>requireViewById(
+ R.id.switch_text).getText().toString()).isEqualTo(defaultOnText);
}
@Test
- public void updateStatus_shouldMatchTheStatus() {
+ public void onBindViewHolder_checked() {
+ mPreference.setChecked(true);
mPreference.onBindViewHolder(mHolder);
- mPreference.updateStatus(true);
- assertThat(mPreference.isChecked()).isTrue();
+ assertThat(mRootView.<MainSwitchBar>requireViewById(
+ R.id.settingslib_main_switch_bar).isChecked()).isTrue();
}
-
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index c1c3e04d46fd..14b2dfe414a4 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -214,6 +214,17 @@ public class SettingsBackupAgent extends BackupAgentHelper {
"failed_to_restore_softap_config";
private static final String ERROR_FAILED_TO_RESTORE_WIFI_CONFIG =
"failed_to_restore_wifi_config";
+ private static final String ERROR_FAILED_TO_RESTORE_SIM_SPECIFIC_SETTINGS =
+ "failed_to_restore_sim_specific_settings";
+ private static final String ERROR_FAILED_TO_CONVERT_NETWORK_POLICIES =
+ "failed_to_convert_network_policies";
+ private static final String ERROR_UNKNOWN_BACKUP_SERIALIZATION_VERSION =
+ "unknown_backup_serialization_version";
+ private static final String INTERRUPTED_EXCEPTION = "interrupted_exception";
+ private static final String ERROR_FAILED_TO_RETRIEVE_WIFI_SETTINGS_BACKUP_DATA =
+ "failed_to_retrieve_wifi_settings_backup_data";
+ private static final String ERROR_FAILED_TO_RESTORE_WIFI_SETTINGS_BACKUP_DATA =
+ "failed_to_restore_wifi_settings_backup_data";
// Name of the temporary file we use during full backup/restore. This is
@@ -1436,6 +1447,7 @@ public class SettingsBackupAgent extends BackupAgentHelper {
try {
out.writeInt(NETWORK_POLICIES_BACKUP_VERSION);
out.writeInt(policies.length);
+ int numberOfPoliciesBackedUp = 0;
for (NetworkPolicy policy : policies) {
// We purposefully only backup policies that the user has
// defined; any inferred policies might include
@@ -1445,13 +1457,25 @@ public class SettingsBackupAgent extends BackupAgentHelper {
out.writeByte(BackupUtils.NOT_NULL);
out.writeInt(marshaledPolicy.length);
out.write(marshaledPolicy);
+ if (areAgentMetricsEnabled) {
+ numberOfPoliciesBackedUp++;
+ }
} else {
out.writeByte(BackupUtils.NULL);
}
}
+ if (areAgentMetricsEnabled) {
+ numberOfSettingsPerKey.put(KEY_NETWORK_POLICIES, numberOfPoliciesBackedUp);
+ }
} catch (IOException ioe) {
Log.e(TAG, "Failed to convert NetworkPolicies to byte array " + ioe.getMessage());
baos.reset();
+ if (areAgentMetricsEnabled) {
+ mBackupRestoreEventLogger.logItemsBackupFailed(
+ KEY_NETWORK_POLICIES,
+ policies.length,
+ ERROR_FAILED_TO_CONVERT_NETWORK_POLICIES);
+ }
}
}
return baos.toByteArray();
@@ -1502,6 +1526,12 @@ public class SettingsBackupAgent extends BackupAgentHelper {
try {
int version = in.readInt();
if (version < 1 || version > NETWORK_POLICIES_BACKUP_VERSION) {
+ if (areAgentMetricsEnabled) {
+ mBackupRestoreEventLogger.logItemsRestoreFailed(
+ KEY_NETWORK_POLICIES,
+ /* count= */ 1,
+ ERROR_UNKNOWN_BACKUP_SERIALIZATION_VERSION);
+ }
throw new BackupUtils.BadVersionException(
"Unknown Backup Serialization Version");
}
@@ -1518,10 +1548,20 @@ public class SettingsBackupAgent extends BackupAgentHelper {
}
// Only set the policies if there was no error in the restore operation
networkPolicyManager.setNetworkPolicies(policies);
+ if (areAgentMetricsEnabled) {
+ mBackupRestoreEventLogger
+ .logItemsRestored(KEY_NETWORK_POLICIES, policies.length);
+ }
} catch (NullPointerException | IOException | BackupUtils.BadVersionException
| DateTimeException e) {
// NPE can be thrown when trying to instantiate a NetworkPolicy
Log.e(TAG, "Failed to convert byte array to NetworkPolicies " + e.getMessage());
+ if (areAgentMetricsEnabled) {
+ mBackupRestoreEventLogger.logItemsRestoreFailed(
+ KEY_NETWORK_POLICIES,
+ /* count= */ 1,
+ ERROR_FAILED_TO_CONVERT_NETWORK_POLICIES);
+ }
}
}
}
@@ -1592,7 +1632,8 @@ public class SettingsBackupAgent extends BackupAgentHelper {
return true;
}
- private byte[] getSimSpecificSettingsData() {
+ @VisibleForTesting
+ byte[] getSimSpecificSettingsData() {
byte[] simSpecificData = new byte[0];
PackageManager packageManager = getBaseContext().getPackageManager();
if (packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
@@ -1600,17 +1641,36 @@ public class SettingsBackupAgent extends BackupAgentHelper {
simSpecificData = subManager.getAllSimSpecificSettingsForBackup();
Log.i(TAG, "sim specific data of length + " + simSpecificData.length
+ " successfully retrieved");
+ if (areAgentMetricsEnabled) {
+ // We're unable to determine how many settings this includes, so we'll just log 1.
+ numberOfSettingsPerKey.put(KEY_SIM_SPECIFIC_SETTINGS_2, 1);
+ }
}
return simSpecificData;
}
- private void restoreSimSpecificSettings(byte[] data) {
+ @VisibleForTesting
+ void restoreSimSpecificSettings(byte[] data) {
PackageManager packageManager = getBaseContext().getPackageManager();
boolean hasTelephony = packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
if (hasTelephony) {
SubscriptionManager subManager = SubscriptionManager.from(getBaseContext());
- subManager.restoreAllSimSpecificSettingsFromBackup(data);
+ if (areAgentMetricsEnabled) {
+ try {
+ subManager.restoreAllSimSpecificSettingsFromBackup(data);
+ mBackupRestoreEventLogger
+ .logItemsRestored(KEY_SIM_SPECIFIC_SETTINGS_2, /* count= */ 1);
+ } catch (Exception e) {
+ mBackupRestoreEventLogger
+ .logItemsRestoreFailed(
+ KEY_SIM_SPECIFIC_SETTINGS_2,
+ /* count= */ 1,
+ ERROR_FAILED_TO_RESTORE_SIM_SPECIFIC_SETTINGS);
+ }
+ } else {
+ subManager.restoreAllSimSpecificSettingsFromBackup(data);
+ }
}
}
@@ -1637,20 +1697,49 @@ public class SettingsBackupAgent extends BackupAgentHelper {
});
// cts requires B&R with 10 seconds
if (latch.await(10, TimeUnit.SECONDS) && backupWifiData.value != null) {
+ if (areAgentMetricsEnabled) {
+ numberOfSettingsPerKey.put(KEY_WIFI_SETTINGS_BACKUP_DATA, 1);
+ }
return backupWifiData.value;
}
} catch (InterruptedException ie) {
Log.e(TAG, "fail to retrieveWifiBackupData, " + ie);
+ if (areAgentMetricsEnabled) {
+ mBackupRestoreEventLogger.logItemsBackupFailed(
+ KEY_WIFI_SETTINGS_BACKUP_DATA,
+ /* count= */ 1,
+ INTERRUPTED_EXCEPTION);
+ }
}
Log.e(TAG, "fail to retrieveWifiBackupData");
+ if (areAgentMetricsEnabled) {
+ mBackupRestoreEventLogger.logItemsBackupFailed(
+ KEY_WIFI_SETTINGS_BACKUP_DATA,
+ /* count= */ 1,
+ ERROR_FAILED_TO_RETRIEVE_WIFI_SETTINGS_BACKUP_DATA);
+ }
return new byte[0];
}
- private void restoreWifiData(byte[] data) {
+ @VisibleForTesting
+ void restoreWifiData(byte[] data) {
if (DEBUG_BACKUP) {
Log.v(TAG, "Applying restored all wifi data");
}
- mWifiManager.restoreWifiBackupData(data);
+ if (areAgentMetricsEnabled) {
+ try {
+ mWifiManager.restoreWifiBackupData(data);
+ mBackupRestoreEventLogger.logItemsRestored(
+ KEY_WIFI_SETTINGS_BACKUP_DATA, /* count= */ 1);
+ } catch (Exception e) {
+ mBackupRestoreEventLogger.logItemsRestoreFailed(
+ KEY_WIFI_SETTINGS_BACKUP_DATA,
+ /* count= */ 1,
+ ERROR_FAILED_TO_RESTORE_WIFI_SETTINGS_BACKUP_DATA);
+ }
+ } else {
+ mWifiManager.restoreWifiBackupData(data);
+ }
}
private void updateWindowManagerIfNeeded(Integer previousDensity) {
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
index 6e5b602c02c5..48c360b635ea 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
@@ -18,6 +18,8 @@ package com.android.providers.settings;
import static com.android.providers.settings.SettingsBackupRestoreKeys.KEY_WIFI_NEW_CONFIG;
import static com.android.providers.settings.SettingsBackupRestoreKeys.KEY_SOFTAP_CONFIG;
+import static com.android.providers.settings.SettingsBackupRestoreKeys.KEY_SIM_SPECIFIC_SETTINGS_2;
+import static com.android.providers.settings.SettingsBackupRestoreKeys.KEY_WIFI_SETTINGS_BACKUP_DATA;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
@@ -59,6 +61,7 @@ import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import android.provider.settings.validators.SettingsValidators;
import android.provider.settings.validators.Validator;
+import android.telephony.SubscriptionManager;
import android.test.mock.MockContentProvider;
import android.test.mock.MockContentResolver;
@@ -136,6 +139,7 @@ public class SettingsBackupAgentTest extends BaseSettingsProviderTest {
@Mock private BackupDataInput mBackupDataInput;
@Mock private BackupDataOutput mBackupDataOutput;
@Mock private static WifiManager mWifiManager;
+ @Mock private static SubscriptionManager mSubscriptionManager;
private TestFriendlySettingsBackupAgent mAgentUnderTest;
private Context mContext;
@@ -906,6 +910,110 @@ public class SettingsBackupAgentTest extends BaseSettingsProviderTest {
assertNull(getLoggingResultForDatatype(KEY_WIFI_NEW_CONFIG, mAgentUnderTest));
}
+ @Test
+ @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void
+ getSimSpecificSettingsData_agentMetricsAreEnabled_numberOfSettingsInKeyAreRecorded() {
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.BACKUP);
+ when(mSubscriptionManager.getAllSimSpecificSettingsForBackup()).thenReturn(new byte[0]);
+
+ mAgentUnderTest.getSimSpecificSettingsData();
+
+ assertEquals(mAgentUnderTest.getNumberOfSettingsPerKey(KEY_SIM_SPECIFIC_SETTINGS_2), 1);
+ }
+
+ @Test
+ @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void
+ restoreSimSpecificSettings_agentMetricsAreEnabled_restoreIsSuccessful_successMetricsAreLogged() {
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+ doNothing().when(mSubscriptionManager).restoreAllSimSpecificSettingsFromBackup(any());
+
+ mAgentUnderTest.restoreSimSpecificSettings(new byte[0]);
+
+ DataTypeResult loggingResult =
+ getLoggingResultForDatatype(KEY_SIM_SPECIFIC_SETTINGS_2, mAgentUnderTest);
+ assertNotNull(loggingResult);
+ assertEquals(loggingResult.getSuccessCount(), 1);
+ }
+
+ @Test
+ @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void
+ restoreSimSpecificSettings_agentMetricsAreEnabled_restoreIsNotSuccessful_failureMetricsAreLogged() {
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+ doThrow(new RuntimeException())
+ .when(mSubscriptionManager)
+ .restoreAllSimSpecificSettingsFromBackup(any());
+
+ mAgentUnderTest.restoreSimSpecificSettings(new byte[0]);
+
+ DataTypeResult loggingResult =
+ getLoggingResultForDatatype(KEY_SIM_SPECIFIC_SETTINGS_2, mAgentUnderTest);
+ assertNotNull(loggingResult);
+ assertEquals(loggingResult.getFailCount(), 1);
+ }
+
+ @Test
+ @DisableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void
+ restoreSimSpecificSettings_agentMetricsAreNotEnabled_metricsAreNotLogged() {
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+ doNothing().when(mSubscriptionManager).restoreAllSimSpecificSettingsFromBackup(any());
+
+ mAgentUnderTest.restoreSimSpecificSettings(new byte[0]);
+
+ assertNull(getLoggingResultForDatatype(KEY_SIM_SPECIFIC_SETTINGS_2, mAgentUnderTest));
+ }
+
+ @Test
+ @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void
+ restoreWifiData_agentMetricsAreEnabled_restoreIsSuccessful_successMetricsAreLogged() {
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+ doNothing().when(mWifiManager).restoreWifiBackupData(any());
+
+ mAgentUnderTest.restoreWifiData(new byte[0]);
+
+ DataTypeResult loggingResult =
+ getLoggingResultForDatatype(KEY_WIFI_SETTINGS_BACKUP_DATA, mAgentUnderTest);
+ assertNotNull(loggingResult);
+ assertEquals(loggingResult.getSuccessCount(), 1);
+ }
+
+ @Test
+ @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void
+ restoreWifiData_agentMetricsAreEnabled_restoreIsNotSuccessful_failureMetricsAreLogged() {
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+ doThrow(new RuntimeException()).when(mWifiManager).restoreWifiBackupData(any());
+
+ mAgentUnderTest.restoreWifiData(new byte[0]);
+
+ DataTypeResult loggingResult =
+ getLoggingResultForDatatype(KEY_WIFI_SETTINGS_BACKUP_DATA, mAgentUnderTest);
+ assertNotNull(loggingResult);
+ assertEquals(loggingResult.getFailCount(), 1);
+ }
+
+ @Test
+ @DisableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void restoreWifiData_agentMetricsAreDisabled_metricsAreNotLogged() {
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+ doNothing().when(mWifiManager).restoreWifiBackupData(any());
+
+ mAgentUnderTest.restoreWifiData(new byte[0]);
+
+ assertNull(getLoggingResultForDatatype(KEY_WIFI_SETTINGS_BACKUP_DATA, mAgentUnderTest));
+ }
+
private byte[] generateBackupData(Map<String, String> keyValueData) {
int totalBytes = 0;
for (String key : keyValueData.keySet()) {
@@ -1106,10 +1214,14 @@ public class SettingsBackupAgentTest extends BaseSettingsProviderTest {
@Override
public Object getSystemService(String name) {
- if (name.equals(Context.WIFI_SERVICE)) {
- return mWifiManager;
+ switch (name) {
+ case Context.WIFI_SERVICE:
+ return mWifiManager;
+ case Context.TELEPHONY_SUBSCRIPTION_SERVICE:
+ return mSubscriptionManager;
+ default:
+ return super.getSystemService(name);
}
- return super.getSystemService(name);
}
}
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index f753316cb67a..d1a0d582d4d7 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -1946,4 +1946,14 @@ flag {
namespace: "systemui"
description: "Show a rich ongoing notification on the always-on display (depends on ui_rich_ongoing)"
bug: "369151941"
+}
+
+flag {
+ name: "stabilize_heads_up_group_v2"
+ namespace: "systemui"
+ description: "Stabilize heads up groups in VisualStabilityCoordinator"
+ bug: "357753857"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
} \ No newline at end of file
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaContentPicker.kt b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaContentPicker.kt
index 215a43382b06..6e9e8efea894 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaContentPicker.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaContentPicker.kt
@@ -41,8 +41,8 @@ object MediaContentPicker : StaticElementContentPicker {
override fun contentDuringTransition(
element: ElementKey,
transition: TransitionState.Transition,
- fromContentZIndex: Float,
- toContentZIndex: Float,
+ fromContentZIndex: Long,
+ toContentZIndex: Long,
): ContentKey {
return when {
transition.isTransitioningBetween(Scenes.Lockscreen, Scenes.Shade) -> {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToNotificationsShadeTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToNotificationsShadeTransition.kt
index 019639da48c5..b4c60037b426 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToNotificationsShadeTransition.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToNotificationsShadeTransition.kt
@@ -17,8 +17,11 @@
package com.android.systemui.scene.ui.composable.transitions
import androidx.compose.animation.core.tween
+import com.android.compose.animation.scene.ContentKey
import com.android.compose.animation.scene.Edge
import com.android.compose.animation.scene.TransitionBuilder
+import com.android.compose.animation.scene.UserActionDistance
+import com.android.compose.animation.scene.UserActionDistanceScope
import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys
import com.android.systemui.notifications.ui.composable.Notifications
import com.android.systemui.notifications.ui.composable.NotificationsShade
@@ -28,6 +31,10 @@ import kotlin.time.Duration.Companion.milliseconds
fun TransitionBuilder.toNotificationsShadeTransition(durationScale: Double = 1.0) {
spec = tween(durationMillis = (DefaultDuration * durationScale).inWholeMilliseconds.toInt())
+ distance = UserActionDistance { _, shadeContentKey, _ ->
+ calculateShadePanelTargetPositionY(shadeContentKey)
+ }
+
// Ensure the clock isn't clipped by the shade outline during the transition from lockscreen.
sharedElement(
ClockElementKeys.smallClockElementKey,
@@ -43,4 +50,12 @@ fun TransitionBuilder.toNotificationsShadeTransition(durationScale: Double = 1.0
fractionRange(start = .5f) { fade(Notifications.Elements.NotificationScrim) }
}
+/** Returns the Y position of the bottom of the shade container panel within [shadeOverlayKey]. */
+fun UserActionDistanceScope.calculateShadePanelTargetPositionY(shadeOverlayKey: ContentKey): Float {
+ val marginTop = OverlayShade.Elements.Panel.targetOffset(shadeOverlayKey)?.y ?: 0f
+ val panelHeight =
+ OverlayShade.Elements.Panel.targetSize(shadeOverlayKey)?.height?.toFloat() ?: 0f
+ return marginTop + panelHeight
+}
+
private val DefaultDuration = 300.milliseconds
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToQuickSettingsShadeTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToQuickSettingsShadeTransition.kt
index faccf14767b5..c9fbb4da9ffb 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToQuickSettingsShadeTransition.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToQuickSettingsShadeTransition.kt
@@ -25,9 +25,8 @@ import kotlin.time.Duration.Companion.milliseconds
fun TransitionBuilder.toQuickSettingsShadeTransition(durationScale: Double = 1.0) {
spec = tween(durationMillis = (DefaultDuration * durationScale).inWholeMilliseconds.toInt())
- distance = UserActionDistance { fromContent, _, _ ->
- val fromContentSize = checkNotNull(fromContent.targetSize())
- fromContentSize.height.toFloat() * 2 / 3f
+ distance = UserActionDistance { _, shadeContentKey, _ ->
+ calculateShadePanelTargetPositionY(shadeContentKey)
}
translate(OverlayShade.Elements.Panel, Edge.Top)
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
index 916d85a80e77..ab3f6396e5c0 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
@@ -92,6 +92,10 @@ internal class DraggableHandler(
else -> null
} ?: return NoOpDragController
+ if (result is UserActionResult.ShowOverlay) {
+ layoutImpl.hideOverlays(result.hideCurrentOverlays)
+ }
+
val swipeAnimation = createSwipeAnimation(swipes, result)
return updateDragController(swipes, swipeAnimation)
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
index 8865a079733a..a5dba0f64583 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
@@ -60,7 +60,6 @@ import com.android.compose.animation.scene.transformation.PropertyTransformation
import com.android.compose.animation.scene.transformation.TransformationWithRange
import com.android.compose.modifiers.thenIf
import com.android.compose.ui.graphics.drawInContainer
-import com.android.compose.ui.util.IntIndexedMap
import com.android.compose.ui.util.lerp
import kotlin.math.roundToInt
import kotlinx.coroutines.launch
@@ -74,14 +73,6 @@ internal class Element(val key: ElementKey) {
val stateByContent = SnapshotStateMap<ContentKey, State>()
/**
- * A sorted map of nesting depth (key) to content key (value). For shared elements it is used to
- * determine which content this element should be rendered by. The nesting depth refers to the
- * number of STLs nested within each other, starting at 0 for the parent STL and increasing by
- * one for each nested [NestedSceneTransitionLayout].
- */
- val renderAuthority = IntIndexedMap<ContentKey>()
-
- /**
* The last transition that was used when computing the state (size, position and alpha) of this
* element in any content, or `null` if it was last laid out when idle.
*/
@@ -285,7 +276,6 @@ internal class ElementNode(
val element =
layoutImpl.elements[key] ?: Element(key).also { layoutImpl.elements[key] = it }
_element = element
- addToRenderAuthority(element)
if (!element.stateByContent.contains(content.key)) {
val contents = buildList {
layoutImpl.ancestors.fastForEach { add(it.inContent) }
@@ -318,22 +308,9 @@ internal class ElementNode(
removeNodeFromContentState()
maybePruneMaps(layoutImpl, element, stateInContent)
- removeFromRenderAuthority()
_element = null
}
- private fun addToRenderAuthority(element: Element) {
- val nestingDepth = layoutImpl.ancestors.size
- element.renderAuthority[nestingDepth] = content.key
- }
-
- private fun removeFromRenderAuthority() {
- val nestingDepth = layoutImpl.ancestors.size
- if (element.renderAuthority[nestingDepth] == content.key) {
- element.renderAuthority.remove(nestingDepth)
- }
- }
-
private fun removeNodeFromContentState() {
stateInContent.nodes.remove(this)
}
@@ -677,12 +654,8 @@ internal inline fun elementState(
// Check if any ancestor runs a transition that has a transformation for the element
states.fastForEachReversed { state ->
if (
- state is TransitionState.Transition &&
- (state.transformationSpec.hasTransformation(
- elementKey,
- state.fromContent,
- ) ||
- state.transformationSpec.hasTransformation(elementKey, state.toContent))
+ isSharedElement(state, isInContent) ||
+ hasTransformationForElement(state, elementKey)
) {
return state
}
@@ -710,6 +683,21 @@ internal inline fun elementState(
return null
}
+private inline fun isSharedElement(
+ state: TransitionState,
+ isInContent: (ContentKey) -> Boolean,
+): Boolean {
+ return state is TransitionState.Transition &&
+ isInContent(state.fromContent) &&
+ isInContent(state.toContent)
+}
+
+private fun hasTransformationForElement(state: TransitionState, elementKey: ElementKey): Boolean {
+ return state is TransitionState.Transition &&
+ (state.transformationSpec.hasTransformation(elementKey, state.fromContent) ||
+ state.transformationSpec.hasTransformation(elementKey, state.toContent))
+}
+
internal inline fun elementContentWhenIdle(
layoutImpl: SceneTransitionLayoutImpl,
currentState: TransitionState,
@@ -964,13 +952,12 @@ private fun shouldPlaceElement(
val transition =
when (elementState) {
is TransitionState.Idle -> {
- return element.shouldBeRenderedBy(content) &&
- content ==
- elementContentWhenIdle(
- layoutImpl,
- elementState,
- isInContent = { it in element.stateByContent },
- )
+ return content ==
+ elementContentWhenIdle(
+ layoutImpl,
+ elementState,
+ isInContent = { it in element.stateByContent },
+ )
}
is TransitionState.Transition -> elementState
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt
index c10a48567b22..f4af5f055935 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt
@@ -212,8 +212,8 @@ private fun shouldComposeMoveableElement(
scenePicker.contentDuringTransition(
element = elementKey,
transition = transition,
- fromContentZIndex = layoutImpl.content(transition.fromContent).zIndex,
- toContentZIndex = layoutImpl.content(transition.toContent).zIndex,
+ fromContentZIndex = layoutImpl.content(transition.fromContent).globalZIndex,
+ toContentZIndex = layoutImpl.content(transition.toContent).globalZIndex,
)
return pickedScene == content
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 621166e1823a..96d68ff03acd 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
@@ -44,6 +44,10 @@ internal fun PredictiveBackHandler(
return@PredictiveBackHandler
}
+ if (result is ShowOverlay) {
+ layoutImpl.hideOverlays(result.hideCurrentOverlays)
+ }
+
val animation =
createSwipeAnimation(
layoutImpl,
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
index 431a376d8eaf..184c2a28727b 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
@@ -62,7 +62,7 @@ fun SceneTransitionLayout(
swipeSourceDetector: SwipeSourceDetector = DefaultEdgeDetector,
swipeDetector: SwipeDetector = DefaultSwipeDetector,
@FloatRange(from = 0.0, to = 0.5) transitionInterceptionThreshold: Float = 0.05f,
- builder: SceneTransitionLayoutScope.() -> Unit,
+ builder: SceneTransitionLayoutScope<ContentScope>.() -> Unit,
) {
SceneTransitionLayoutForTesting(
state,
@@ -75,7 +75,7 @@ fun SceneTransitionLayout(
)
}
-interface SceneTransitionLayoutScope {
+interface SceneTransitionLayoutScope<out CS : ContentScope> {
/**
* Add a scene to this layout, identified by [key].
*
@@ -88,7 +88,7 @@ interface SceneTransitionLayoutScope {
fun scene(
key: SceneKey,
userActions: Map<UserAction, UserActionResult> = emptyMap(),
- content: @Composable ContentScope.() -> Unit,
+ content: @Composable CS.() -> Unit,
)
/**
@@ -118,7 +118,7 @@ interface SceneTransitionLayoutScope {
mapOf(Back to UserActionResult.HideOverlay(key)),
alignment: Alignment = Alignment.Center,
isModal: Boolean = true,
- content: @Composable ContentScope.() -> Unit,
+ content: @Composable CS.() -> Unit,
)
}
@@ -253,18 +253,6 @@ interface BaseContentScope : ElementStateScope {
fun Modifier.disableSwipesWhenScrolling(
bounds: NestedScrollableBound = NestedScrollableBound.Any
): Modifier
-
- /**
- * A [NestedSceneTransitionLayout] will share its elements with its ancestor STLs therefore
- * enabling sharedElement transitions between them.
- */
- // TODO(b/380070506): Add more parameters when default params are supported in Kotlin 2.0.21
- @Composable
- fun NestedSceneTransitionLayout(
- state: SceneTransitionLayoutState,
- modifier: Modifier,
- builder: SceneTransitionLayoutScope.() -> Unit,
- )
}
@Stable
@@ -337,6 +325,29 @@ interface ContentScope : BaseContentScope {
type: SharedValueType<T, *>,
canOverflow: Boolean,
): AnimatedState<T>
+
+ /**
+ * A [NestedSceneTransitionLayout] will share its elements with its ancestor STLs therefore
+ * enabling sharedElement transitions between them.
+ */
+ // TODO(b/380070506): Add more parameters when default params are supported in Kotlin 2.0.21
+ @Composable
+ fun NestedSceneTransitionLayout(
+ state: SceneTransitionLayoutState,
+ modifier: Modifier,
+ builder: SceneTransitionLayoutScope<ContentScope>.() -> Unit,
+ )
+}
+
+internal interface InternalContentScope : ContentScope {
+
+ @Composable
+ fun NestedSceneTransitionLayoutForTesting(
+ state: SceneTransitionLayoutState,
+ modifier: Modifier,
+ onLayoutImpl: ((SceneTransitionLayoutImpl) -> Unit)?,
+ builder: SceneTransitionLayoutScope<InternalContentScope>.() -> Unit,
+ )
}
/**
@@ -607,8 +618,24 @@ sealed class UserActionResult(
val overlay: OverlayKey,
override val transitionKey: TransitionKey? = null,
override val requiresFullDistanceSwipe: Boolean = false,
+
+ /** Specify which overlays (if any) should be hidden when this user action is started. */
+ val hideCurrentOverlays: HideCurrentOverlays = HideCurrentOverlays.None,
) : UserActionResult(transitionKey, requiresFullDistanceSwipe) {
override fun toContent(currentScene: SceneKey): ContentKey = overlay
+
+ sealed class HideCurrentOverlays {
+ /** Hide none of the current overlays. */
+ object None : HideCurrentOverlays()
+
+ /** Hide all current overlays. */
+ object All : HideCurrentOverlays()
+
+ /** Hide [overlays], for those in that set that are currently shown. */
+ class Some(val overlays: Set<OverlayKey>) : HideCurrentOverlays() {
+ constructor(vararg overlays: OverlayKey) : this(overlays.toSet())
+ }
+ }
}
/** A [UserActionResult] that hides [overlay]. */
@@ -714,7 +741,7 @@ internal fun SceneTransitionLayoutForTesting(
sharedElementMap: MutableMap<ElementKey, Element> = remember { mutableMapOf() },
ancestors: List<Ancestor> = remember { emptyList() },
lookaheadScope: LookaheadScope? = null,
- builder: SceneTransitionLayoutScope.() -> Unit,
+ builder: SceneTransitionLayoutScope<InternalContentScope>.() -> Unit,
) {
val density = LocalDensity.current
val directionChangeSlop = LocalViewConfiguration.current.touchSlop
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
index 38ad0a80fd00..16fd5b1e78e6 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
@@ -45,9 +45,12 @@ import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
+import androidx.compose.ui.util.fastAny
+import androidx.compose.ui.util.fastFirstOrNull
import androidx.compose.ui.util.fastForEach
import androidx.compose.ui.util.fastForEachReversed
import androidx.compose.ui.zIndex
+import com.android.compose.animation.scene.UserActionResult.ShowOverlay.HideCurrentOverlays
import com.android.compose.animation.scene.content.Content
import com.android.compose.animation.scene.content.Overlay
import com.android.compose.animation.scene.content.Scene
@@ -78,7 +81,7 @@ internal class SceneTransitionLayoutImpl(
internal var swipeSourceDetector: SwipeSourceDetector,
internal var swipeDetector: SwipeDetector,
internal var transitionInterceptionThreshold: Float,
- builder: SceneTransitionLayoutScope.() -> Unit,
+ builder: SceneTransitionLayoutScope<InternalContentScope>.() -> Unit,
/**
* The scope that should be used by *animations started by this layout only*, i.e. animations
@@ -221,19 +224,30 @@ internal class SceneTransitionLayoutImpl(
state.checkThread()
}
- internal fun scene(key: SceneKey): Scene {
- return scenes[key] ?: error("Scene $key is not configured")
+ private fun sceneOrNull(key: SceneKey): Scene? {
+ return scenes[key]
+ ?: ancestors
+ .fastFirstOrNull { it.layoutImpl.scenes[key] != null }
+ ?.layoutImpl
+ ?.scenes
+ ?.get(key)
}
- internal fun contentOrNull(key: ContentKey): Content? {
- return when (key) {
- is SceneKey -> scenes[key]
- is OverlayKey -> overlays[key]
- }
+ private fun overlayOrNull(key: OverlayKey): Overlay? {
+ return overlays[key]
+ ?: ancestors
+ .fastFirstOrNull { it.layoutImpl.overlays[key] != null }
+ ?.layoutImpl
+ ?.overlays
+ ?.get(key)
+ }
+
+ internal fun scene(key: SceneKey): Scene {
+ return sceneOrNull(key) ?: error("Scene $key is not configured")
}
internal fun overlay(key: OverlayKey): Overlay {
- return overlays[key] ?: error("Overlay $key is not configured")
+ return overlayOrNull(key) ?: error("Overlay $key is not configured")
}
internal fun content(key: ContentKey): Content {
@@ -243,6 +257,10 @@ internal class SceneTransitionLayoutImpl(
}
}
+ internal fun isAncestorContent(content: ContentKey): Boolean {
+ return ancestors.fastAny { it.inContent == content }
+ }
+
internal fun contentForUserActions(): Content {
return findOverlayWithHighestZIndex() ?: scene(state.transitionState.currentScene)
}
@@ -266,7 +284,7 @@ internal class SceneTransitionLayoutImpl(
}
internal fun updateContents(
- builder: SceneTransitionLayoutScope.() -> Unit,
+ builder: SceneTransitionLayoutScope<InternalContentScope>.() -> Unit,
layoutDirection: LayoutDirection,
) {
// Keep a reference of the current contents. After processing [builder], the contents that
@@ -275,15 +293,17 @@ internal class SceneTransitionLayoutImpl(
val overlaysToRemove =
if (_overlays == null) mutableSetOf() else overlays.keys.toMutableSet()
+ val parentZIndex =
+ if (ancestors.isEmpty()) 0L else content(ancestors.last().inContent).globalZIndex
// The incrementing zIndex of each scene.
- var zIndex = 0f
+ var zIndex = 0
var overlaysDefined = false
- object : SceneTransitionLayoutScope {
+ object : SceneTransitionLayoutScope<InternalContentScope> {
override fun scene(
key: SceneKey,
userActions: Map<UserAction, UserActionResult>,
- content: @Composable ContentScope.() -> Unit,
+ content: @Composable InternalContentScope.() -> Unit,
) {
require(!overlaysDefined) { "all scenes must be defined before overlays" }
@@ -291,11 +311,14 @@ internal class SceneTransitionLayoutImpl(
val resolvedUserActions = resolveUserActions(key, userActions, layoutDirection)
val scene = scenes[key]
+ val globalZIndex =
+ Content.calculateGlobalZIndex(parentZIndex, ++zIndex, ancestors.size)
if (scene != null) {
// Update an existing scene.
scene.content = content
scene.userActions = resolvedUserActions
- scene.zIndex = zIndex
+ scene.zIndex = zIndex.toFloat()
+ scene.globalZIndex = globalZIndex
} else {
// New scene.
scenes[key] =
@@ -304,11 +327,10 @@ internal class SceneTransitionLayoutImpl(
this@SceneTransitionLayoutImpl,
content,
resolvedUserActions,
- zIndex,
+ zIndex.toFloat(),
+ globalZIndex,
)
}
-
- zIndex++
}
override fun overlay(
@@ -316,17 +338,20 @@ internal class SceneTransitionLayoutImpl(
userActions: Map<UserAction, UserActionResult>,
alignment: Alignment,
isModal: Boolean,
- content: @Composable (ContentScope.() -> Unit),
+ content: @Composable (InternalContentScope.() -> Unit),
) {
overlaysDefined = true
overlaysToRemove.remove(key)
val overlay = overlays[key]
val resolvedUserActions = resolveUserActions(key, userActions, layoutDirection)
+ val globalZIndex =
+ Content.calculateGlobalZIndex(parentZIndex, ++zIndex, ancestors.size)
if (overlay != null) {
// Update an existing overlay.
overlay.content = content
- overlay.zIndex = zIndex
+ overlay.zIndex = zIndex.toFloat()
+ overlay.globalZIndex = globalZIndex
overlay.userActions = resolvedUserActions
overlay.alignment = alignment
overlay.isModal = isModal
@@ -338,13 +363,12 @@ internal class SceneTransitionLayoutImpl(
this@SceneTransitionLayoutImpl,
content,
resolvedUserActions,
- zIndex,
+ zIndex.toFloat(),
+ globalZIndex,
alignment,
isModal,
)
}
-
- zIndex++
}
}
.builder()
@@ -537,13 +561,27 @@ internal class SceneTransitionLayoutImpl(
.sortedBy { it.zIndex }
}
+ internal fun hideOverlays(hide: HideCurrentOverlays) {
+ fun maybeHide(overlay: OverlayKey) {
+ if (state.canHideOverlay(overlay)) {
+ state.hideOverlay(overlay, animationScope = this.animationScope)
+ }
+ }
+
+ when (hide) {
+ HideCurrentOverlays.None -> {}
+ HideCurrentOverlays.All -> HashSet(state.currentOverlays).forEach { maybeHide(it) }
+ is HideCurrentOverlays.Some -> hide.overlays.forEach { maybeHide(it) }
+ }
+ }
+
@VisibleForTesting
internal fun setContentsAndLayoutTargetSizeForTest(size: IntSize) {
lastSize = size
(scenes.values + overlays.values).forEach { it.targetSize = size }
}
- internal fun overlaysOrNullForTest(): Map<OverlayKey, Overlay>? = _overlays
+ @VisibleForTesting internal fun overlaysOrNullForTest(): Map<OverlayKey, Overlay>? = _overlays
}
private data class LayoutElement(private val layoutImpl: SceneTransitionLayoutImpl) :
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SharedElement.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SharedElement.kt
index ed3a5cac8184..ee3944893ced 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SharedElement.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SharedElement.kt
@@ -20,52 +20,22 @@ import com.android.compose.animation.scene.content.state.TransitionState
import com.android.compose.animation.scene.transformation.SharedElementTransformation
import com.android.compose.animation.scene.transformation.TransformationWithRange
-/**
- * Whether this element should be rendered by the given [content]. This method returns true only for
- * exactly one content at any given time.
- */
-internal fun Element.shouldBeRenderedBy(content: ContentKey): Boolean {
- // The current strategy is that always the content with the lowest nestingDepth has authority.
- // This content is supposed to render the shared element because this is also the level at which
- // the transition is running. If the [renderAuthority.size] is 1 it means that that this element
- // is currently composed only in one nesting level, which means that the render authority
- // is determined by "classic" shared element code.
- return renderAuthority.size > 0 &&
- (renderAuthority.size == 1 || renderAuthority.first() == content)
-}
-
-/**
- * Whether this element is currently composed in multiple [SceneTransitionLayout]s.
- *
- * Note: Shared elements across [NestedSceneTransitionLayout]s side-by-side are not supported.
- */
-internal fun Element.isPresentInMultipleStls(): Boolean {
- return renderAuthority.size > 1
-}
-
internal fun shouldPlaceSharedElement(
layoutImpl: SceneTransitionLayoutImpl,
content: ContentKey,
elementKey: ElementKey,
transition: TransitionState.Transition,
): Boolean {
- val element = layoutImpl.elements.getValue(elementKey)
- if (element.isPresentInMultipleStls()) {
- // If the element is present in multiple STLs we require the highest STL to render it and
- // we don't want contentPicker to potentially return false for the highest STL.
- return element.shouldBeRenderedBy(content)
- }
-
- val scenePicker = elementKey.contentPicker
- val pickedScene =
- scenePicker.contentDuringTransition(
+ val contentPicker = elementKey.contentPicker
+ val pickedContent =
+ contentPicker.contentDuringTransition(
element = elementKey,
transition = transition,
- fromContentZIndex = layoutImpl.content(transition.fromContent).zIndex,
- toContentZIndex = layoutImpl.content(transition.toContent).zIndex,
+ fromContentZIndex = layoutImpl.content(transition.fromContent).globalZIndex,
+ toContentZIndex = layoutImpl.content(transition.toContent).globalZIndex,
)
- return pickedScene == content
+ return pickedContent == content || layoutImpl.isAncestorContent(pickedContent)
}
internal fun isSharedElementEnabled(
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 a29c1bbe0a0c..badb8a80b982 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
@@ -210,8 +210,8 @@ interface ElementContentPicker {
fun contentDuringTransition(
element: ElementKey,
transition: TransitionState.Transition,
- fromContentZIndex: Float,
- toContentZIndex: Float,
+ fromContentZIndex: Long,
+ toContentZIndex: Long,
): ContentKey
/**
@@ -279,8 +279,8 @@ object HighestZIndexContentPicker : ElementContentPicker {
override fun contentDuringTransition(
element: ElementKey,
transition: TransitionState.Transition,
- fromContentZIndex: Float,
- toContentZIndex: Float,
+ fromContentZIndex: Long,
+ toContentZIndex: Long,
): ContentKey {
return if (fromContentZIndex > toContentZIndex) {
transition.fromContent
@@ -300,8 +300,8 @@ object HighestZIndexContentPicker : ElementContentPicker {
override fun contentDuringTransition(
element: ElementKey,
transition: TransitionState.Transition,
- fromContentZIndex: Float,
- toContentZIndex: Float,
+ fromContentZIndex: Long,
+ toContentZIndex: Long,
): ContentKey {
return HighestZIndexContentPicker.contentDuringTransition(
element,
@@ -321,8 +321,8 @@ object LowestZIndexContentPicker : ElementContentPicker {
override fun contentDuringTransition(
element: ElementKey,
transition: TransitionState.Transition,
- fromContentZIndex: Float,
- toContentZIndex: Float,
+ fromContentZIndex: Long,
+ toContentZIndex: Long,
): ContentKey {
return if (fromContentZIndex < toContentZIndex) {
transition.fromContent
@@ -342,8 +342,8 @@ object LowestZIndexContentPicker : ElementContentPicker {
override fun contentDuringTransition(
element: ElementKey,
transition: TransitionState.Transition,
- fromContentZIndex: Float,
- toContentZIndex: Float,
+ fromContentZIndex: Long,
+ toContentZIndex: Long,
): ContentKey {
return LowestZIndexContentPicker.contentDuringTransition(
element,
@@ -375,8 +375,8 @@ class MovableElementContentPicker(override val contents: Set<ContentKey>) :
override fun contentDuringTransition(
element: ElementKey,
transition: TransitionState.Transition,
- fromContentZIndex: Float,
- toContentZIndex: Float,
+ fromContentZIndex: Long,
+ toContentZIndex: Long,
): ContentKey {
return when {
transition.toContent in contents -> transition.toContent
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/UserActionDistanceScopeImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/UserActionDistanceScopeImpl.kt
index 8457481b3e14..fffc7f988acf 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/UserActionDistanceScopeImpl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/UserActionDistanceScopeImpl.kt
@@ -36,7 +36,7 @@ internal class ElementStateScopeImpl(private val layoutImpl: SceneTransitionLayo
}
override fun ContentKey.targetSize(): IntSize? {
- return layoutImpl.contentOrNull(this)?.targetSize.takeIf { it != IntSize.Zero }
+ return layoutImpl.content(this).targetSize.takeIf { it != IntSize.Zero }
}
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt
index 6ccd498f7a04..86201a9c0879 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt
@@ -27,6 +27,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
+import androidx.compose.runtime.mutableLongStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -45,6 +46,7 @@ import com.android.compose.animation.scene.ElementContentScope
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.ElementScope
import com.android.compose.animation.scene.ElementStateScope
+import com.android.compose.animation.scene.InternalContentScope
import com.android.compose.animation.scene.MovableElement
import com.android.compose.animation.scene.MovableElementContentScope
import com.android.compose.animation.scene.MovableElementKey
@@ -68,24 +70,78 @@ import com.android.compose.gesture.nestedScrollController
import com.android.compose.modifiers.thenIf
import com.android.compose.ui.graphics.ContainerState
import com.android.compose.ui.graphics.container
+import kotlin.math.pow
/** A content defined in a [SceneTransitionLayout], i.e. a scene or an overlay. */
@Stable
internal sealed class Content(
open val key: ContentKey,
val layoutImpl: SceneTransitionLayoutImpl,
- content: @Composable ContentScope.() -> Unit,
+ content: @Composable InternalContentScope.() -> Unit,
actions: Map<UserAction.Resolved, UserActionResult>,
zIndex: Float,
+ globalZIndex: Long,
) {
private val nestedScrollControlState = NestedScrollControlState()
internal val scope = ContentScopeImpl(layoutImpl, content = this, nestedScrollControlState)
val containerState = ContainerState()
var content by mutableStateOf(content)
- var zIndex by mutableFloatStateOf(zIndex)
var targetSize by mutableStateOf(IntSize.Zero)
var userActions by mutableStateOf(actions)
+ var zIndex by mutableFloatStateOf(zIndex)
+
+ /**
+ * The globalZIndex is a zIndex that indicates the z order of each content across any nested
+ * STLs. This is done by dividing the number range of a Long into chunks of three digits. As
+ * Long.MAX_VALUE is a bit larger than 1e18 we start the first level at 1e15 to give at least
+ * 1000 contents space. The first level of nesting depth will occupy the 3 highest digits and
+ * with each level we continue into the next three. Therefore the parent z order will have
+ * priority and their children have room to order themselves within the "less significant bits".
+ *
+ * As an example, imagine the following tree of nested scenes:
+ * ```
+ * / \
+ * A01 A02 -- nestingDepth 0
+ * / \ |
+ * B01 B02 C01 -- nestingDepth 1
+ * |
+ * D01 -- nestingDepth 2
+ * ```
+ *
+ * The zIndex values would be:
+ * ```
+ * A01: 1e15 (1_000_000_000_000_000)
+ * A02: 2e15 (2_000_000_000_000_000)
+ * B01: 1.001e15 (1_001_000_000_000_000)
+ * B02: 1.002e15 (1_002_000_000_000_000)
+ * C01: 2.001e15 (2_001_000_000_000_000)
+ * D01: 1.002001e15 (1_002_001_000_000_000)
+ * ```
+ *
+ * Therefore the order of zIndexes will correctly be: A01, B01, B02, D01, A02, C01, which
+ * corresponds to a Pre-order traversal of the tree.
+ *
+ * Since composition of the tree does not happen all at once we can't do a Pre-order traversal
+ * right away without allocating resources to build and manage the tree structure through all
+ * updates. Using this method we have stable zIndexes at time of composition of each content
+ * independently with the only drawback that contents per each STL are limited to 999 and
+ * nesting depth is limited to 6 (18 / 3).
+ */
+ var globalZIndex by mutableLongStateOf(globalZIndex)
+
+ companion object {
+ fun calculateGlobalZIndex(
+ parentGlobalZIndex: Long,
+ localZIndex: Int,
+ nestingDepth: Int,
+ ): Long {
+ require(nestingDepth in 0..5) { "NestingDepth of STLs can be at most 5." }
+ require(localZIndex in 1..999) { "A scene can have at most 999 contents." }
+ val offsetForDepth = 10.0.pow((5 - nestingDepth) * 3).toLong()
+ return parentGlobalZIndex + offsetForDepth * localZIndex
+ }
+ }
@SuppressLint("NotConstructor")
@Composable
@@ -118,7 +174,7 @@ internal class ContentScopeImpl(
private val layoutImpl: SceneTransitionLayoutImpl,
private val content: Content,
private val nestedScrollControlState: NestedScrollControlState,
-) : ContentScope, ElementStateScope by layoutImpl.elementStateScope {
+) : InternalContentScope, ElementStateScope by layoutImpl.elementStateScope {
override val contentKey: ContentKey
get() = content.key
@@ -208,7 +264,17 @@ internal class ContentScopeImpl(
override fun NestedSceneTransitionLayout(
state: SceneTransitionLayoutState,
modifier: Modifier,
- builder: SceneTransitionLayoutScope.() -> Unit,
+ builder: SceneTransitionLayoutScope<ContentScope>.() -> Unit,
+ ) {
+ NestedSceneTransitionLayoutForTesting(state, modifier, null, builder)
+ }
+
+ @Composable
+ override fun NestedSceneTransitionLayoutForTesting(
+ state: SceneTransitionLayoutState,
+ modifier: Modifier,
+ onLayoutImpl: ((SceneTransitionLayoutImpl) -> Unit)?,
+ builder: SceneTransitionLayoutScope<InternalContentScope>.() -> Unit,
) {
val ancestors =
remember(layoutImpl, contentKey, layoutImpl.ancestors) {
@@ -217,7 +283,7 @@ internal class ContentScopeImpl(
SceneTransitionLayoutForTesting(
state,
modifier,
- onLayoutImpl = null,
+ onLayoutImpl = onLayoutImpl,
builder = builder,
sharedElementMap = layoutImpl.elements,
ancestors = ancestors,
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Overlay.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Overlay.kt
index d4de559cef43..300de3f36b1f 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Overlay.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Overlay.kt
@@ -22,7 +22,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
-import com.android.compose.animation.scene.ContentScope
+import com.android.compose.animation.scene.InternalContentScope
import com.android.compose.animation.scene.OverlayKey
import com.android.compose.animation.scene.SceneTransitionLayoutImpl
import com.android.compose.animation.scene.UserAction
@@ -33,12 +33,13 @@ import com.android.compose.animation.scene.UserActionResult
internal class Overlay(
override val key: OverlayKey,
layoutImpl: SceneTransitionLayoutImpl,
- content: @Composable ContentScope.() -> Unit,
+ content: @Composable InternalContentScope.() -> Unit,
actions: Map<UserAction.Resolved, UserActionResult>,
zIndex: Float,
+ globalZIndex: Long,
alignment: Alignment,
isModal: Boolean,
-) : Content(key, layoutImpl, content, actions, zIndex) {
+) : Content(key, layoutImpl, content, actions, zIndex, globalZIndex) {
var alignment by mutableStateOf(alignment)
var isModal by mutableStateOf(isModal)
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Scene.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Scene.kt
index 4a7a94d6e177..275341c7268b 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Scene.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Scene.kt
@@ -18,7 +18,7 @@ package com.android.compose.animation.scene.content
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
-import com.android.compose.animation.scene.ContentScope
+import com.android.compose.animation.scene.InternalContentScope
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.SceneTransitionLayoutImpl
import com.android.compose.animation.scene.UserAction
@@ -29,10 +29,11 @@ import com.android.compose.animation.scene.UserActionResult
internal class Scene(
override val key: SceneKey,
layoutImpl: SceneTransitionLayoutImpl,
- content: @Composable ContentScope.() -> Unit,
+ content: @Composable InternalContentScope.() -> Unit,
actions: Map<UserAction.Resolved, UserActionResult>,
zIndex: Float,
-) : Content(key, layoutImpl, content, actions, zIndex) {
+ globalZIndex: Long,
+) : Content(key, layoutImpl, content, actions, zIndex, globalZIndex) {
override fun toString(): String {
return "Scene(key=$key)"
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/ui/util/IntIndexedMap.kt b/packages/SystemUI/compose/scene/src/com/android/compose/ui/util/IntIndexedMap.kt
deleted file mode 100644
index 1b5341b8048a..000000000000
--- a/packages/SystemUI/compose/scene/src/com/android/compose/ui/util/IntIndexedMap.kt
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.compose.ui.util
-
-/**
- * This is a custom implementation that resembles a SortedMap<Int, T> but is based on a simple
- * ArrayList to avoid the allocation overhead and boxing.
- *
- * It can only hold positive keys and 0 and it is only efficient for small keys (0 - ~100), but
- * therefore provides fast operations for small keys.
- */
-internal class IntIndexedMap<T> {
- private val arrayList = ArrayList<T?>()
- private var _size = 0
- val size
- get() = _size
-
- /** Returns the value at [key] or null if the key is not present. */
- operator fun get(key: Int): T? {
- if (key < 0 || key >= arrayList.size) return null
- return arrayList[key]
- }
-
- /**
- * Sets the value at [key] to [value]. If [key] is larger than the current size of the map, this
- * operation may take up to O(key) time and space. Therefore this data structure is only
- * efficient for small [key] sizes.
- */
- operator fun set(key: Int, value: T?) {
- if (key < 0)
- throw UnsupportedOperationException("This map can only hold positive keys and 0.")
- if (key < arrayList.size) {
- if (arrayList[key] != null && value == null) _size--
- if (arrayList[key] == null && value != null) _size++
- arrayList[key] = value
- } else {
- if (value == null) return
- while (key > arrayList.size) {
- arrayList.add(null)
- }
- _size++
- arrayList.add(value)
- }
- }
-
- /** Remove value at [key] */
- fun remove(key: Int) {
- if (key >= arrayList.size) return
- this[key] = null
- }
-
- /** Get the [value] with the smallest [key] of the map. */
- fun first(): T {
- for (i in 0 until arrayList.size) {
- return arrayList[i] ?: continue
- }
- throw NoSuchElementException("The map is empty.")
- }
-}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
index 35ff0044f4d6..68e85db2c80b 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
@@ -36,6 +36,7 @@ import com.android.compose.animation.scene.TestScenes.SceneA
import com.android.compose.animation.scene.TestScenes.SceneB
import com.android.compose.animation.scene.TestScenes.SceneC
import com.android.compose.animation.scene.content.state.TransitionState
+import com.android.compose.animation.scene.content.state.TransitionState.Companion.DistanceUnspecified
import com.android.compose.animation.scene.content.state.TransitionState.Transition
import com.android.compose.animation.scene.subjects.assertThat
import com.android.compose.gesture.NestedDraggable
@@ -84,7 +85,7 @@ class DraggableHandlerTest {
layoutImpl.updateContents(scenesBuilder, layoutDirection)
}
- private val scenesBuilder: SceneTransitionLayoutScope.() -> Unit = {
+ private val scenesBuilder: SceneTransitionLayoutScope<ContentScope>.() -> Unit = {
scene(key = SceneA, userActions = mutableUserActionsA) { Text("SceneA") }
scene(key = SceneB, userActions = mutableUserActionsB) { Text("SceneB") }
scene(
@@ -785,6 +786,29 @@ class DraggableHandlerTest {
}
@Test
+ fun animateWhenDistanceUnspecified() = runGestureTest {
+ layoutState.transitions = transitions {
+ from(SceneA, to = SceneB) {
+ distance = UserActionDistance { _, _, _ -> DistanceUnspecified }
+ }
+ }
+
+ val controller = onDragStarted(overSlop = up(fractionOfScreen = 0.9f))
+
+ // The distance is not computed yet, so we don't know the "progress" value yet.
+ assertTransition(fromScene = SceneA, toScene = SceneB, progress = 0.0f)
+
+ controller.onDragStoppedAnimateNow(
+ // We are animating from SceneA to SceneA, when the distance is still unspecified.
+ velocity = velocityThreshold,
+ onAnimationStart = {
+ assertTransition(fromScene = SceneA, toScene = SceneB, progress = 0.0f)
+ },
+ )
+ assertIdle(SceneA)
+ }
+
+ @Test
fun showOverlay() = runGestureTest {
mutableUserActionsA = mapOf(Swipe.Down to UserActionResult.ShowOverlay(OverlayA))
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MovableElementContentPickerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MovableElementContentPickerTest.kt
index c8e7e6592e17..fba0aa88ef7a 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MovableElementContentPickerTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MovableElementContentPickerTest.kt
@@ -33,8 +33,8 @@ class MovableElementContentPickerTest {
picker.contentDuringTransition(
TestElements.Foo,
transition(from = TestScenes.SceneA, to = TestScenes.SceneB),
- fromContentZIndex = 0f,
- toContentZIndex = 1f,
+ fromContentZIndex = 0,
+ toContentZIndex = 1,
)
)
.isEqualTo(TestScenes.SceneB)
@@ -47,8 +47,8 @@ class MovableElementContentPickerTest {
picker.contentDuringTransition(
TestElements.Foo,
transition(from = TestScenes.SceneA, to = TestScenes.SceneB),
- fromContentZIndex = 0f,
- toContentZIndex = 1f,
+ fromContentZIndex = 0,
+ toContentZIndex = 1,
)
)
.isEqualTo(TestScenes.SceneA)
@@ -61,8 +61,8 @@ class MovableElementContentPickerTest {
picker.contentDuringTransition(
TestElements.Foo,
transition(from = TestScenes.SceneA, to = TestScenes.SceneB),
- fromContentZIndex = 0f,
- toContentZIndex = 1f,
+ fromContentZIndex = 0,
+ toContentZIndex = 1,
)
}
}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MovableElementTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MovableElementTest.kt
index 8d718c1418e0..e023936eb448 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MovableElementTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MovableElementTest.kt
@@ -166,14 +166,14 @@ class MovableElementTest {
override fun contentDuringTransition(
element: ElementKey,
transition: TransitionState.Transition,
- fromContentZIndex: Float,
- toContentZIndex: Float,
+ fromContentZIndex: Long,
+ toContentZIndex: Long,
): ContentKey {
transition as TransitionState.Transition.ChangeScene
assertThat(transition).hasFromScene(SceneA)
assertThat(transition).hasToScene(SceneB)
- assertThat(fromContentZIndex).isEqualTo(0)
- assertThat(toContentZIndex).isEqualTo(1)
+ assertThat(fromContentZIndex).isEqualTo(1_000_000_000_000_000)
+ assertThat(toContentZIndex).isEqualTo(2_000_000_000_000_000)
// Compose Foo in Scene A if progress < 0.65f, otherwise compose it
// in Scene B.
@@ -362,8 +362,8 @@ class MovableElementTest {
override fun contentDuringTransition(
element: ElementKey,
transition: TransitionState.Transition,
- fromContentZIndex: Float,
- toContentZIndex: Float,
+ fromContentZIndex: Long,
+ toContentZIndex: Long,
): ContentKey {
return SceneA
}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/OverlayTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/OverlayTest.kt
index 50bfbfe6d29c..b4b328b14a78 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/OverlayTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/OverlayTest.kt
@@ -33,6 +33,7 @@ import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.platform.LocalViewConfiguration
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.SemanticsMatcher
import androidx.compose.ui.test.assertIsDisplayed
@@ -50,7 +51,10 @@ import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.compose.animation.scene.TestOverlays.OverlayA
import com.android.compose.animation.scene.TestOverlays.OverlayB
+import com.android.compose.animation.scene.TestOverlays.OverlayC
+import com.android.compose.animation.scene.TestOverlays.OverlayD
import com.android.compose.animation.scene.TestScenes.SceneA
+import com.android.compose.animation.scene.UserActionResult.ShowOverlay
import com.android.compose.animation.scene.subjects.assertThat
import com.android.compose.test.assertSizeIsEqualTo
import com.android.compose.test.setContentAndCreateMainScope
@@ -821,4 +825,63 @@ class OverlayTest {
assertThat(state.transitionState).isIdle()
assertThat(state.transitionState).hasCurrentOverlays(/* empty */ )
}
+
+ @Test
+ fun showOverlay_hideAllOverlays() {
+ val state =
+ rule.runOnUiThread {
+ MutableSceneTransitionLayoutStateForTests(
+ SceneA,
+ initialOverlays = setOf(OverlayA, OverlayB, OverlayC),
+ // We don't allow overlay C to be hidden.
+ canHideOverlay = { it != OverlayC },
+ )
+ }
+
+ var touchSlop = 0f
+ rule.setContent {
+ touchSlop = LocalViewConfiguration.current.touchSlop
+ SceneTransitionLayout(state) {
+ scene(SceneA) { Box(Modifier.fillMaxSize()) }
+ overlay(OverlayA) { Box(Modifier.fillMaxSize()) }
+ overlay(OverlayB) { Box(Modifier.fillMaxSize()) }
+ overlay(
+ OverlayC,
+ mapOf(
+ Swipe.Down to
+ ShowOverlay(
+ OverlayD,
+ hideCurrentOverlays = ShowOverlay.HideCurrentOverlays.All,
+ )
+ ),
+ ) {
+ Box(Modifier.fillMaxSize())
+ }
+ overlay(OverlayD) { Box(Modifier.fillMaxSize()) }
+ }
+ }
+
+ assertThat(state.transitionState).hasCurrentOverlays(OverlayA, OverlayB, OverlayC)
+
+ rule.onRoot().performTouchInput {
+ down(center)
+ moveBy(Offset(0f, touchSlop))
+ }
+
+ // We closed all overlay, but C can not be hidden.
+ val transition = assertThat(state.transitionState).isShowOrHideOverlayTransition()
+ assertThat(transition).hasCurrentScene(SceneA)
+ assertThat(transition).hasCurrentOverlays(OverlayC)
+ assertThat(transition).hasProgress(0f)
+ assertThat(transition).hasOverlay(OverlayD)
+
+ rule.onRoot().performTouchInput { moveBy(Offset(0f, bottom / 2f)) }
+ assertThat(transition).hasProgress(0.5f)
+
+ rule.onRoot().performTouchInput { up() }
+ rule.waitForIdle()
+ assertThat(state.transitionState).isIdle()
+ assertThat(state.transitionState).hasCurrentScene(SceneA)
+ assertThat(state.transitionState).hasCurrentOverlays(OverlayC, OverlayD)
+ }
}
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 9f15ebd69657..2bf235846b32 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
@@ -32,9 +32,11 @@ import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.compose.animation.scene.TestOverlays.OverlayA
import com.android.compose.animation.scene.TestOverlays.OverlayB
+import com.android.compose.animation.scene.TestOverlays.OverlayC
import com.android.compose.animation.scene.TestScenes.SceneA
import com.android.compose.animation.scene.TestScenes.SceneB
import com.android.compose.animation.scene.TestScenes.SceneC
+import com.android.compose.animation.scene.UserActionResult.ShowOverlay
import com.android.compose.animation.scene.subjects.assertThat
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineScope
@@ -273,6 +275,57 @@ class PredictiveBackHandlerTest {
rule.onNode(hasTestTag(OverlayB.testTag)).assertDoesNotExist()
}
+ @Test
+ fun showOverlay_hideSomeOverlays() {
+ val state =
+ rule.runOnUiThread {
+ MutableSceneTransitionLayoutStateForTests(
+ SceneA,
+ initialOverlays = setOf(OverlayA, OverlayB),
+ )
+ }
+
+ rule.setContent {
+ SceneTransitionLayout(state) {
+ scene(SceneA) { Box(Modifier.fillMaxSize()) }
+ overlay(OverlayA) { Box(Modifier.fillMaxSize()) }
+ overlay(
+ OverlayB,
+ mapOf(
+ Back to
+ ShowOverlay(
+ OverlayC,
+ hideCurrentOverlays = ShowOverlay.HideCurrentOverlays.Some(OverlayA),
+ )
+ ),
+ ) {
+ Box(Modifier.fillMaxSize())
+ }
+ overlay(OverlayC) { Box(Modifier.fillMaxSize()) }
+ }
+ }
+
+ assertThat(state.transitionState).hasCurrentOverlays(OverlayA, OverlayB)
+
+ val dispatcher = rule.activity.onBackPressedDispatcher
+ rule.runOnUiThread { dispatcher.dispatchOnBackStarted(backEvent()) }
+
+ val transition = assertThat(state.transitionState).isShowOrHideOverlayTransition()
+ assertThat(transition).hasCurrentScene(SceneA)
+ assertThat(transition).hasCurrentOverlays(OverlayB)
+ assertThat(transition).hasProgress(0f)
+ assertThat(transition).hasOverlay(OverlayC)
+
+ rule.runOnUiThread { dispatcher.dispatchOnBackProgressed(backEvent(progress = 0.5f)) }
+ assertThat(transition).hasProgress(0.5f)
+
+ rule.runOnUiThread { dispatcher.onBackPressed() }
+ rule.waitForIdle()
+ assertThat(state.transitionState).isIdle()
+ assertThat(state.transitionState).hasCurrentScene(SceneA)
+ assertThat(state.transitionState).hasCurrentOverlays(OverlayB, OverlayC)
+ }
+
private fun backEvent(progress: Float = 0f): BackEventCompat {
return BackEventCompat(
touchX = 0f,
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt
index 8db7dbca2474..0bd51cd9822d 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt
@@ -129,22 +129,22 @@ abstract class BaseTransitionSubject<T : TransitionState.Transition>(
check("currentOverlays").that(actual.currentOverlays).containsExactlyElementsIn(overlays)
}
- fun hasProgress(progress: Float, tolerance: Float = 0f) {
+ fun hasProgress(progress: Float, tolerance: Float = 0.01f) {
check("progress").that(actual.progress).isWithin(tolerance).of(progress)
}
- fun hasProgressVelocity(progressVelocity: Float, tolerance: Float = 0f) {
+ fun hasProgressVelocity(progressVelocity: Float, tolerance: Float = 0.01f) {
check("progressVelocity")
.that(actual.progressVelocity)
.isWithin(tolerance)
.of(progressVelocity)
}
- fun hasPreviewProgress(progress: Float, tolerance: Float = 0f) {
+ fun hasPreviewProgress(progress: Float, tolerance: Float = 0.01f) {
check("previewProgress").that(actual.previewProgress).isWithin(tolerance).of(progress)
}
- fun hasPreviewProgressVelocity(progressVelocity: Float, tolerance: Float = 0f) {
+ fun hasPreviewProgressVelocity(progressVelocity: Float, tolerance: Float = 0.01f) {
check("previewProgressVelocity")
.that(actual.previewProgressVelocity)
.isWithin(tolerance)
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedSceneTransitionLayoutTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedSceneTransitionLayoutTest.kt
new file mode 100644
index 000000000000..0042f5018957
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedSceneTransitionLayoutTest.kt
@@ -0,0 +1,76 @@
+/*
+ * 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.compose.animation.scene.transformation
+
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.compose.animation.scene.MutableSceneTransitionLayoutStateForTests
+import com.android.compose.animation.scene.SceneTransitionLayoutForTesting
+import com.android.compose.animation.scene.SceneTransitionLayoutImpl
+import com.android.compose.animation.scene.TestScenes
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class NestedSceneTransitionLayoutTest {
+ @get:Rule val rule = createComposeRule()
+
+ @Test
+ fun nestedStls_testZIndex() {
+ var nullableLayoutImpl: SceneTransitionLayoutImpl? = null
+
+ rule.setContent {
+ SceneTransitionLayoutForTesting(
+ state = MutableSceneTransitionLayoutStateForTests(TestScenes.SceneA)
+ ) {
+ scene(TestScenes.SceneA) {
+ NestedSceneTransitionLayoutForTesting(
+ MutableSceneTransitionLayoutStateForTests(TestScenes.SceneD),
+ Modifier,
+ onLayoutImpl = null,
+ ) {
+ scene(TestScenes.SceneC) {}
+ scene(TestScenes.SceneD) {
+ NestedSceneTransitionLayoutForTesting(
+ MutableSceneTransitionLayoutStateForTests(TestScenes.SceneE),
+ Modifier,
+ onLayoutImpl = { nullableLayoutImpl = it },
+ ) {
+ scene(TestScenes.SceneE) {}
+ }
+ }
+ }
+ }
+ scene(TestScenes.SceneB) {}
+ }
+
+ assertThat(nullableLayoutImpl?.content(TestScenes.SceneA)?.globalZIndex)
+ .isEqualTo(1_000_000_000_000_000)
+ assertThat(nullableLayoutImpl?.content(TestScenes.SceneB)?.globalZIndex)
+ .isEqualTo(2_000_000_000_000_000)
+ assertThat(nullableLayoutImpl?.content(TestScenes.SceneC)?.globalZIndex)
+ .isEqualTo(1_001_000_000_000_000)
+ assertThat(nullableLayoutImpl?.content(TestScenes.SceneD)?.globalZIndex)
+ .isEqualTo(1_002_000_000_000_000)
+ assertThat(nullableLayoutImpl?.content(TestScenes.SceneE)?.globalZIndex)
+ .isEqualTo(1_002_001_000_000_000)
+ }
+ }
+}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedSharedElementTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedSharedElementTest.kt
index 83dd6d3eec28..f44ae90746d5 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedSharedElementTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedSharedElementTest.kt
@@ -38,6 +38,7 @@ import com.android.compose.animation.scene.AutoTransitionTestAssertionScope
import com.android.compose.animation.scene.ContentScope
import com.android.compose.animation.scene.Default4FrameLinearTransition
import com.android.compose.animation.scene.Edge
+import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.MutableSceneTransitionLayoutState
import com.android.compose.animation.scene.MutableSceneTransitionLayoutStateForTests
import com.android.compose.animation.scene.SceneKey
@@ -77,11 +78,14 @@ class NestedSharedElementTest {
)
@Composable
- private fun ContentScope.SharedElement(element: SharedElement) {
+ private fun ContentScope.SharedElement(
+ element: SharedElement,
+ key: ElementKey = TestElements.Foo,
+ ) {
Box(Modifier.fillMaxSize()) {
Box(
Modifier.offset(element.x, element.y)
- .element(TestElements.Foo)
+ .element(key)
.size(element.width, element.height)
.background(element.color)
.alpha(element.alpha)
@@ -165,9 +169,9 @@ class NestedSharedElementTest {
) {
before { onElement(TestElements.Foo).assertElementVariant(elementVariant1) }
atAllFrames(4) {
- onElement(TestElements.Foo, TestScenes.SceneB).assertIsNotDisplayed()
+ onElement(TestElements.Foo, TestScenes.SceneA).assertIsNotDisplayed()
- onElement(TestElements.Foo, TestScenes.SceneA)
+ onElement(TestElements.Foo, TestScenes.SceneB)
.assertBetweenElementVariants(elementVariant1, elementVariant2, this)
}
after { onElement(TestElements.Foo).assertElementVariant(elementVariant2) }
@@ -175,6 +179,29 @@ class NestedSharedElementTest {
}
@Test
+ fun fromParentSTLtoNestedSTL_contentPickerLowestZOrder() {
+ rule.testTransition(
+ fromSceneContent = { SharedElement(elementVariant1, TestElements.LowZIndex) },
+ toSceneContent = {
+ NestedSceneTransitionLayout(nestedState, modifier = Modifier) {
+ scene(Scenes.NestedSceneA) {
+ SharedElement(elementVariant2, TestElements.LowZIndex)
+ }
+ }
+ },
+ ) {
+ before { onElement(TestElements.LowZIndex).assertElementVariant(elementVariant1) }
+ atAllFrames(4) {
+ onElement(TestElements.LowZIndex, TestScenes.SceneB).assertIsNotDisplayed()
+
+ onElement(TestElements.LowZIndex, TestScenes.SceneA)
+ .assertBetweenElementVariants(elementVariant1, elementVariant2, this)
+ }
+ after { onElement(TestElements.LowZIndex).assertElementVariant(elementVariant2) }
+ }
+ }
+
+ @Test
fun nestedSharedElementTransition_fromParentSTLtoNestedNestedSTL() {
rule.testTransition(
fromSceneContent = contentWithSharedElement,
@@ -182,9 +209,9 @@ class NestedSharedElementTest {
) {
before { onElement(TestElements.Foo).assertElementVariant(elementVariant1) }
atAllFrames(4) {
- onElement(TestElements.Foo, TestScenes.SceneB).assertIsNotDisplayed()
+ onElement(TestElements.Foo, TestScenes.SceneA).assertIsNotDisplayed()
- onElement(TestElements.Foo, TestScenes.SceneA)
+ onElement(TestElements.Foo, TestScenes.SceneB)
.assertBetweenElementVariants(elementVariant1, elementVariant4, this)
}
after { onElement(TestElements.Foo).assertElementVariant(elementVariant4) }
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/ui/util/IntIndexMapTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/ui/util/IntIndexMapTest.kt
deleted file mode 100644
index d7a9b9007be0..000000000000
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/ui/util/IntIndexMapTest.kt
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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.compose.ui.util
-
-import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-
-class IntIndexMapTest {
-
- @Test
- fun testSetGetFirstAndSize() {
- val map = IntIndexedMap<String>()
-
- // Write first element at 10
- map[10] = "1"
- assertThat(map[10]).isEqualTo("1")
- assertThat(map.size).isEqualTo(1)
- assertThat(map.first()).isEqualTo("1")
-
- // Write same element to same index
- map[10] = "1"
- assertThat(map[10]).isEqualTo("1")
- assertThat(map.size).isEqualTo(1)
-
- // Writing into larger index
- map[12] = "2"
- assertThat(map[12]).isEqualTo("2")
- assertThat(map.size).isEqualTo(2)
- assertThat(map.first()).isEqualTo("1")
-
- // Overwriting existing index
- map[10] = "3"
- assertThat(map[10]).isEqualTo("3")
- assertThat(map.size).isEqualTo(2)
- assertThat(map.first()).isEqualTo("3")
-
- // Writing into smaller index
- map[0] = "4"
- assertThat(map[0]).isEqualTo("4")
- assert(map.size == 3)
- assertThat(map.first()).isEqualTo("4")
-
- // Writing null into non-null index
- map[0] = null
- assertThat(map[0]).isEqualTo(null)
- assertThat(map.size).isEqualTo(2)
- assertThat(map.first()).isEqualTo("3")
-
- // Writing null into smaller null index
- map[1] = null
- assertThat(map[1]).isEqualTo(null)
- assertThat(map.size).isEqualTo(2)
-
- // Writing null into larger null index
- map[15] = null
- assertThat(map[15]).isEqualTo(null)
- assertThat(map.size).isEqualTo(2)
-
- // Remove existing element
- map.remove(12)
- assertThat(map[12]).isEqualTo(null)
- assertThat(map.size).isEqualTo(1)
-
- // Remove non-existing element
- map.remove(17)
- assertThat(map[17]).isEqualTo(null)
- assertThat(map.size).isEqualTo(1)
-
- // Remove all elements
- assertThat(map.first()).isEqualTo("3")
- map.remove(10)
- map.remove(10)
- map.remove(0)
- assertThat(map.size).isEqualTo(0)
- assertThat(map[10]).isEqualTo(null)
- assertThat(map.size).isEqualTo(0)
- }
-}
diff --git a/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestValues.kt b/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestValues.kt
index 95ef2ce821e1..c6af0d4846e0 100644
--- a/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestValues.kt
+++ b/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestValues.kt
@@ -27,18 +27,22 @@ object TestScenes {
val SceneB = SceneKey("SceneB")
val SceneC = SceneKey("SceneC")
val SceneD = SceneKey("SceneD")
+ val SceneE = SceneKey("SceneE")
}
/** Overlay keys that can be reused by tests. */
object TestOverlays {
val OverlayA = OverlayKey("OverlayA")
val OverlayB = OverlayKey("OverlayB")
+ val OverlayC = OverlayKey("OverlayC")
+ val OverlayD = OverlayKey("OverlayD")
}
/** Element keys that can be reused by tests. */
object TestElements {
val Foo = ElementKey("Foo")
val Bar = ElementKey("Bar")
+ val LowZIndex = ElementKey("LowZIndex", contentPicker = LowestZIndexContentPicker)
}
/** Value keys that can be reused by tests. */
diff --git a/packages/SystemUI/res/raw/trackpad_switch_apps_edu.json b/packages/SystemUI/res/raw/trackpad_switch_apps_edu.json
new file mode 100644
index 000000000000..1d1d34628a5e
--- /dev/null
+++ b/packages/SystemUI/res/raw/trackpad_switch_apps_edu.json
@@ -0,0 +1 @@
+{"v":"5.12.1","fr":60,"ip":37,"op":538,"w":554,"h":564,"nm":"Trackpad-JSON_Quickswitch-EDU","ddd":0,"assets":[{"id":"comp_0","nm":"Trackpad-Quickswitch_toLeft","fr":60,"layers":[{"ddd":0,"ind":2,"ty":4,"nm":".tertiaryFixedDim","cl":"tertiaryFixedDim","parent":8,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":37,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":47,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":249,"s":[100]},{"t":255,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"k":[{"s":[4,0,0],"t":121,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[3.984,0,0],"t":122,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[3.922,0,0],"t":123,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[3.823,0,0],"t":124,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[3.685,0,0],"t":125,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[3.507,0,0],"t":126,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[3.294,0,0],"t":127,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[3.046,0,0],"t":128,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[2.768,0,0],"t":129,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[2.463,0,0],"t":130,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[2.136,0,0],"t":131,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[1.788,0,0],"t":132,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[1.424,0,0],"t":133,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[1.047,0,0],"t":134,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[0.662,0,0],"t":135,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-0.115,0,0],"t":137,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-0.5,0,0],"t":138,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-1.798,0,0],"t":139,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-3.075,0,0],"t":140,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-4.319,0,0],"t":141,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-5.521,0,0],"t":142,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-6.674,0,0],"t":143,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-7.774,0,0],"t":144,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-8.825,0,0],"t":145,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-9.819,0,0],"t":146,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-10.761,0,0],"t":147,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-11.65,0,0],"t":148,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-12.489,0,0],"t":149,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-13.282,0,0],"t":150,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-14.028,0,0],"t":151,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-14.732,0,0],"t":152,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-15.397,0,0],"t":153,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-16.023,0,0],"t":154,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-16.614,0,0],"t":155,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-17.171,0,0],"t":156,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-17.7,0,0],"t":157,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-18.199,0,0],"t":158,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-18.672,0,0],"t":159,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-19.119,0,0],"t":160,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-19.543,0,0],"t":161,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-19.945,0,0],"t":162,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-20.325,0,0],"t":163,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-20.684,0,0],"t":164,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-21.025,0,0],"t":165,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-21.349,0,0],"t":166,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-21.655,0,0],"t":167,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-21.945,0,0],"t":168,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-22.221,0,0],"t":169,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-22.481,0,0],"t":170,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-22.728,0,0],"t":171,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-22.962,0,0],"t":172,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-23.184,0,0],"t":173,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-23.393,0,0],"t":174,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-23.592,0,0],"t":175,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-23.779,0,0],"t":176,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-23.956,0,0],"t":177,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-24.124,0,0],"t":178,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-24.283,0,0],"t":179,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-24.433,0,0],"t":180,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-24.574,0,0],"t":181,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-24.706,0,0],"t":182,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-24.831,0,0],"t":183,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-24.947,0,0],"t":184,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-25.055,0,0],"t":185,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-25.158,0,0],"t":186,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-25.253,0,0],"t":187,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-25.341,0,0],"t":188,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-25.423,0,0],"t":189,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-25.497,0,0],"t":190,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-25.566,0,0],"t":191,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-25.631,0,0],"t":192,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-25.688,0,0],"t":193,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-25.741,0,0],"t":194,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-25.788,0,0],"t":195,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-25.83,0,0],"t":196,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-25.867,0,0],"t":197,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-25.899,0,0],"t":198,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-25.927,0,0],"t":199,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-25.951,0,0],"t":200,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-25.97,0,0],"t":201,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-25.996,0,0],"t":203,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"a":{"a":0,"k":[20.5,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ef":[{"ty":5,"nm":"Super Slider","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":1,"k":[{"i":{"x":[0.64],"y":[0.48]},"o":{"x":[0.36],"y":[0]},"t":121,"s":[0]},{"i":{"x":[0.31],"y":[1]},"o":{"x":[0.15],"y":[0.514]},"t":138,"s":[15]},{"t":205,"s":[100]}],"ix":1}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":62,"s":[36,36]},{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":72,"s":[28,28]},{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":247,"s":[28,28]},{"t":257,"s":[36,36]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.56,"y":1},"o":{"x":0.44,"y":0},"t":62,"s":[82,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.56,"y":0.56},"o":{"x":0.426,"y":0.426},"t":72,"s":[68.5,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.657,"y":1},"o":{"x":0.42,"y":0},"t":247,"s":[68.5,0],"to":[0,0],"ti":[0,0]},{"t":257,"s":[82,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":"4F","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":62,"s":[36,36]},{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.446,0.446],"y":[0,0]},"t":72,"s":[28,28]},{"i":{"x":[0.656,0.656],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":247,"s":[28,28]},{"t":257,"s":[36,36]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.56,"y":1},"o":{"x":0.44,"y":0},"t":62,"s":[41,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.56,"y":0.56},"o":{"x":0.426,"y":0.426},"t":72,"s":[36.5,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.657,"y":1},"o":{"x":0.42,"y":0},"t":247,"s":[36.5,0],"to":[0,0],"ti":[0,0]},{"t":257,"s":[41,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":"3F","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":62,"s":[36,36]},{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.446,0.446],"y":[0,0]},"t":72,"s":[28,28]},{"i":{"x":[0.656,0.656],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":247,"s":[28,28]},{"t":257,"s":[36,36]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.56,"y":1},"o":{"x":0.44,"y":0},"t":62,"s":[-41,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.56,"y":0.56},"o":{"x":0.426,"y":0.426},"t":72,"s":[-27.5,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.657,"y":1},"o":{"x":0.42,"y":0},"t":247,"s":[-27.5,0],"to":[0,0],"ti":[0,0]},{"t":257,"s":[-41,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":"1F","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":62,"s":[36,36]},{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.446,0.446],"y":[0,0]},"t":72,"s":[28,28]},{"i":{"x":[0.656,0.656],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":247,"s":[28,28]},{"t":257,"s":[36,36]}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.56,"y":1},"o":{"x":0.44,"y":0},"t":62,"s":[0,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.56,"y":0.56},"o":{"x":0.44,"y":0.44},"t":72,"s":[4.5,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.56,"y":1},"o":{"x":0.44,"y":0},"t":247,"s":[4.5,0],"to":[0,0],"ti":[0,0]},{"t":257,"s":[0,0]}],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"2F","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":37,"op":345,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":3,"nm":"qs:scale","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"k":[{"s":[277,197.5,0],"t":37,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[277,197.5,0],"t":287,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"k":[{"s":[99.903,99.903,100],"t":127,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.828,99.828,100],"t":128,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.731,99.731,100],"t":129,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.615,99.615,100],"t":130,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.479,99.479,100],"t":131,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.327,99.327,100],"t":132,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.16,99.16,100],"t":133,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[98.979,98.979,100],"t":134,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[98.789,98.789,100],"t":135,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[98.591,98.591,100],"t":136,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[98.388,98.388,100],"t":137,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[98.183,98.183,100],"t":138,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[97.978,97.978,100],"t":139,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[97.774,97.774,100],"t":140,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[97.574,97.574,100],"t":141,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[96.729,96.729,100],"t":142,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[95.95,95.95,100],"t":143,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[95.256,95.256,100],"t":144,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[94.657,94.657,100],"t":145,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[94.158,94.158,100],"t":146,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[93.758,93.758,100],"t":147,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[93.452,93.452,100],"t":148,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[93.233,93.233,100],"t":149,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[93.091,93.091,100],"t":150,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[93.085,93.085,100],"t":249,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[93.929,93.929,100],"t":250,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[95.014,95.014,100],"t":251,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[95.985,95.985,100],"t":252,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[96.803,96.803,100],"t":253,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[97.48,97.48,100],"t":254,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[98.039,98.039,100],"t":255,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[98.498,98.498,100],"t":256,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[98.874,98.874,100],"t":257,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.179,99.179,100],"t":258,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.424,99.424,100],"t":259,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.617,99.617,100],"t":260,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.765,99.765,100],"t":261,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.872,99.872,100],"t":262,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.946,99.946,100],"t":263,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}}],"l":2}},"ao":0,"ef":[{"ty":5,"nm":"Void","np":19,"mn":"Pseudo/250958","ix":1,"en":1,"ef":[{"ty":0,"nm":"Width","mn":"Pseudo/250958-0001","ix":1,"v":{"a":0,"k":100,"ix":1}},{"ty":0,"nm":"Height","mn":"Pseudo/250958-0002","ix":2,"v":{"a":0,"k":100,"ix":2}},{"ty":0,"nm":"Offset X","mn":"Pseudo/250958-0003","ix":3,"v":{"a":0,"k":0,"ix":3}},{"ty":0,"nm":"Offset Y","mn":"Pseudo/250958-0004","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Roundness","mn":"Pseudo/250958-0005","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":6,"nm":"About","mn":"Pseudo/250958-0006","ix":6,"v":0},{"ty":6,"nm":"Plague of null layers.","mn":"Pseudo/250958-0007","ix":7,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0008","ix":8,"v":0},{"ty":6,"nm":"Following projects","mn":"Pseudo/250958-0009","ix":9,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0010","ix":10,"v":0},{"ty":6,"nm":"through time.","mn":"Pseudo/250958-0011","ix":11,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0012","ix":12,"v":0},{"ty":6,"nm":"Be free of the past.","mn":"Pseudo/250958-0013","ix":13,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0014","ix":14,"v":0},{"ty":6,"nm":"Copyright 2023 Battle Axe Inc","mn":"Pseudo/250958-0015","ix":15,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0016","ix":16,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0017","ix":17,"v":0}]}],"ip":0,"op":457,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"screenMatte_app1","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[277,197.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[503.5,314.5],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"frame","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":457,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"QS_App1","parent":3,"tt":1,"tp":4,"refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"k":[{"s":[528.828,0,0],"t":125,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[528.311,0,0],"t":126,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[527.45,0,0],"t":127,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[526.244,0,0],"t":128,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[524.703,0,0],"t":129,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[522.835,0,0],"t":130,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[520.666,0,0],"t":131,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[518.221,0,0],"t":132,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[515.526,0,0],"t":133,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[512.606,0,0],"t":134,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[509.523,0,0],"t":135,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[506.294,0,0],"t":136,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[502.963,0,0],"t":137,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[499.562,0,0],"t":138,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[496.143,0,0],"t":139,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[492.715,0,0],"t":140,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[489.322,0,0],"t":141,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[474.472,0,0],"t":142,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[459.809,0,0],"t":143,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[445.483,0,0],"t":144,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[431.585,0,0],"t":145,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[418.223,0,0],"t":146,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[405.443,0,0],"t":147,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[393.278,0,0],"t":148,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[381.743,0,0],"t":149,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[370.824,0,0],"t":150,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[360.508,0,0],"t":151,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[350.778,0,0],"t":152,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[341.601,0,0],"t":153,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[332.958,0,0],"t":154,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[324.805,0,0],"t":155,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[317.115,0,0],"t":156,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[309.865,0,0],"t":157,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[303.02,0,0],"t":158,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[296.562,0,0],"t":159,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[290.467,0,0],"t":160,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[284.707,0,0],"t":161,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[279.267,0,0],"t":162,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[274.119,0,0],"t":163,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[269.247,0,0],"t":164,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[264.65,0,0],"t":165,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[260.286,0,0],"t":166,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[256.163,0,0],"t":167,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252.263,0,0],"t":168,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[248.57,0,0],"t":169,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[245.075,0,0],"t":170,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[241.76,0,0],"t":171,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[238.635,0,0],"t":172,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[235.673,0,0],"t":173,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[232.866,0,0],"t":174,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[230.223,0,0],"t":175,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[227.717,0,0],"t":176,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[225.358,0,0],"t":177,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[223.127,0,0],"t":178,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[221.026,0,0],"t":179,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[219.045,0,0],"t":180,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[217.185,0,0],"t":181,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[215.428,0,0],"t":182,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[213.792,0,0],"t":183,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[212.25,0,0],"t":184,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[210.812,0,0],"t":185,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[209.468,0,0],"t":186,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[208.211,0,0],"t":187,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[207.048,0,0],"t":188,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[205.972,0,0],"t":189,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[204.981,0,0],"t":190,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[204.068,0,0],"t":191,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[203.233,0,0],"t":192,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[202.466,0,0],"t":193,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[201.777,0,0],"t":194,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[201.157,0,0],"t":195,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[200.606,0,0],"t":196,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[200.124,0,0],"t":197,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[199.702,0,0],"t":198,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[199.34,0,0],"t":199,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[199.039,0,0],"t":200,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[198.798,0,0],"t":201,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[198.608,0,0],"t":202,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[198.479,0,0],"t":203,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[198.376,0,0],"t":247,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[191.108,0,0],"t":248,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[158.789,0,0],"t":249,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[117.772,0,0],"t":250,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[88.925,0,0],"t":251,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[68.502,0,0],"t":252,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[53.185,0,0],"t":253,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[41.287,0,0],"t":254,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[31.832,0,0],"t":255,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[24.24,0,0],"t":256,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[18.107,0,0],"t":257,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[13.165,0,0],"t":258,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[9.231,0,0],"t":259,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[6.132,0,0],"t":260,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[3.764,0,0],"t":261,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[2.041,0,0],"t":262,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[0.869,0,0],"t":263,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[0.207,0,0],"t":264,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[0,0,0],"t":265,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"a":{"k":[{"s":[252,157.593,0],"t":127,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.664,0],"t":128,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.755,0],"t":129,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.864,0],"t":130,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.989,0],"t":131,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.128,0],"t":132,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.278,0],"t":133,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.438,0],"t":134,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.604,0],"t":135,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.774,0],"t":136,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.945,0],"t":137,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,159.115,0],"t":138,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,159.281,0],"t":139,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,159.444,0],"t":140,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,159.601,0],"t":141,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,160.236,0],"t":142,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,160.781,0],"t":143,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,161.236,0],"t":144,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,161.606,0],"t":145,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,161.896,0],"t":146,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,162.117,0],"t":147,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,162.278,0],"t":148,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,162.389,0],"t":149,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,162.419,0],"t":249,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,161.659,0],"t":250,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,160.753,0],"t":251,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,160,0],"t":252,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,159.407,0],"t":253,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.947,0],"t":254,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.588,0],"t":255,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.309,0],"t":256,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.091,0],"t":257,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.921,0],"t":258,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.791,0],"t":259,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.69,0],"t":260,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.562,0],"t":262,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":504,"h":315,"ip":0,"op":457,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"screenMatte_app2","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"k":[{"s":[277,197.5,0],"t":37,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[277,197.5,0],"t":287,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"a":{"a":0,"k":[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":{"k":[{"s":[503.5,314.5],"t":37,"i":{"x":[1,1],"y":[1,1]},"o":{"x":[0,0],"y":[0,0]}},{"s":[503.5,314.5],"t":287,"i":{"x":[1,1],"y":[1,1]},"o":{"x":[0,0],"y":[0,0]}}]},"p":{"a":0,"k":[0,0],"ix":3},"r":{"k":[{"s":[28],"t":37,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"s":[28],"t":287,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}}]},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"k":[{"s":[0.208,0.302,0.184,1],"t":37,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"s":[0.208,0.302,0.184,1],"t":287,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}}]},"o":{"k":[{"s":[100],"t":37,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"s":[100],"t":287,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}}]},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"frame","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":457,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"QS_App2","parent":3,"tt":1,"tp":6,"refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"k":[{"s":[0,0,0],"t":124,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-0.172,0,0],"t":125,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-0.689,0,0],"t":126,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-1.55,0,0],"t":127,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-2.756,0,0],"t":128,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-4.297,0,0],"t":129,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-6.165,0,0],"t":130,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-8.334,0,0],"t":131,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-10.779,0,0],"t":132,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-13.474,0,0],"t":133,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-16.394,0,0],"t":134,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-19.477,0,0],"t":135,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-22.706,0,0],"t":136,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-26.037,0,0],"t":137,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-29.438,0,0],"t":138,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-32.857,0,0],"t":139,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-36.285,0,0],"t":140,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-39.678,0,0],"t":141,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-54.528,0,0],"t":142,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-69.191,0,0],"t":143,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-83.517,0,0],"t":144,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-97.415,0,0],"t":145,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-110.777,0,0],"t":146,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-123.557,0,0],"t":147,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-135.722,0,0],"t":148,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-147.257,0,0],"t":149,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-158.176,0,0],"t":150,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-168.492,0,0],"t":151,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-178.222,0,0],"t":152,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-187.399,0,0],"t":153,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-196.042,0,0],"t":154,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-204.195,0,0],"t":155,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-211.885,0,0],"t":156,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-219.135,0,0],"t":157,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-225.98,0,0],"t":158,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-232.438,0,0],"t":159,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-238.533,0,0],"t":160,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-244.293,0,0],"t":161,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-249.733,0,0],"t":162,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-254.881,0,0],"t":163,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-259.753,0,0],"t":164,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-264.35,0,0],"t":165,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-268.714,0,0],"t":166,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-272.837,0,0],"t":167,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-276.737,0,0],"t":168,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-280.43,0,0],"t":169,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-283.925,0,0],"t":170,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-287.24,0,0],"t":171,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-290.365,0,0],"t":172,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-293.327,0,0],"t":173,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-296.134,0,0],"t":174,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-298.777,0,0],"t":175,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-301.283,0,0],"t":176,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-303.642,0,0],"t":177,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-305.873,0,0],"t":178,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-307.974,0,0],"t":179,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-309.955,0,0],"t":180,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-311.815,0,0],"t":181,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-313.572,0,0],"t":182,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-315.208,0,0],"t":183,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-316.75,0,0],"t":184,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-318.188,0,0],"t":185,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-319.532,0,0],"t":186,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-320.789,0,0],"t":187,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-321.952,0,0],"t":188,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-323.028,0,0],"t":189,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-324.019,0,0],"t":190,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-324.932,0,0],"t":191,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-325.767,0,0],"t":192,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-326.534,0,0],"t":193,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-327.223,0,0],"t":194,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-327.843,0,0],"t":195,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-328.394,0,0],"t":196,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-328.876,0,0],"t":197,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-329.298,0,0],"t":198,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-329.66,0,0],"t":199,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-329.961,0,0],"t":200,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-330.202,0,0],"t":201,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-330.521,0,0],"t":203,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-330.624,0,0],"t":247,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-337.892,0,0],"t":248,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-370.211,0,0],"t":249,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-411.228,0,0],"t":250,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-440.075,0,0],"t":251,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-460.498,0,0],"t":252,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-475.815,0,0],"t":253,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-487.713,0,0],"t":254,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-497.168,0,0],"t":255,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-504.76,0,0],"t":256,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-510.893,0,0],"t":257,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-515.835,0,0],"t":258,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-519.769,0,0],"t":259,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-522.868,0,0],"t":260,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-525.236,0,0],"t":261,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-526.959,0,0],"t":262,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-528.131,0,0],"t":263,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-528.793,0,0],"t":264,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"a":{"k":[{"s":[252,157.593,0],"t":127,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.664,0],"t":128,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.755,0],"t":129,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.864,0],"t":130,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.989,0],"t":131,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.128,0],"t":132,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.278,0],"t":133,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.438,0],"t":134,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.604,0],"t":135,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.774,0],"t":136,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.945,0],"t":137,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,159.115,0],"t":138,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,159.281,0],"t":139,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,159.444,0],"t":140,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,159.601,0],"t":141,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,160.236,0],"t":142,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,160.781,0],"t":143,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,161.236,0],"t":144,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,161.606,0],"t":145,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,161.896,0],"t":146,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,162.117,0],"t":147,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,162.278,0],"t":148,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,162.389,0],"t":149,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,162.419,0],"t":249,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,161.659,0],"t":250,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,160.753,0],"t":251,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,160,0],"t":252,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,159.407,0],"t":253,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.947,0],"t":254,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.588,0],"t":255,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.309,0],"t":256,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.091,0],"t":257,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.921,0],"t":258,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.791,0],"t":259,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.69,0],"t":260,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.562,0],"t":262,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":504,"h":315,"ip":0,"op":457,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".onTertiaryFixedVariant","cl":"onTertiaryFixedVariant","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[277,459,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[200,128],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":18,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843137255,0.301960784314,0.18431372549,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Frame 1321317559","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":457,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".onTertiaryFixedVariant","cl":"onTertiaryFixedVariant","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[277,197.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[503.5,314.5],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":50,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"frame","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":457,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".tertiaryFixedDim","cl":"tertiaryFixedDim","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[277.5,197.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[504,315],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,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":"op","nm":"Stroke align: Outside","a":{"a":0,"k":7,"ix":1},"lj":1,"ml":{"a":0,"k":4,"ix":3},"ix":3,"mn":"ADBE Vector Filter - Offset","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"frame","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":457,"st":0,"ct":1,"bm":0}]},{"id":"comp_1","nm":"QS_App1","fr":60,"pfr":1,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".onTertiaryFixedVariant","cl":"onTertiaryFixedVariant","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[339.937,151.75,0],"ix":2,"l":2},"a":{"a":0,"k":[339.937,151.75,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":[[0,0],[1.021,-1.766],[0,0],[-2.043,0],[0,0],[1.022,1.767]],"o":[[-1.021,-1.766],[0,0],[-1.022,1.767],[0,0],[2.043,0],[0,0]],"v":[[2.297,-7.675],[-2.297,-7.675],[-9.64,5.025],[-7.343,9],[7.343,9],[9.64,5.025]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"rd","nm":"Round Corners 1","r":{"a":0,"k":9,"ix":1},"ix":2,"mn":"ADBE Vector Filter - RC","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Triangle","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[481.874,21],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Triangle","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[18,18],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":200,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[457.874,21],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"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","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[292,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":200,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Text field","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[334,279],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Text field","np":1,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[109,28],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Sent","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[425.5,208.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Sent","np":1,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[160,56],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":14,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Sent","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[400,158.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Sent","np":1,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[126,40],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":14,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Received","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[251,78.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Received","np":1,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"roundedMatte 2","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[252,157.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[504,315],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":0,"op":600,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".onTertiaryFixed","cl":"onTertiaryFixed","tt":1,"tp":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[334,157.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[340,315],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":16,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Message","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".onTertiaryFixedVariant","cl":"onTertiaryFixedVariant","parent":5,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[82,171.125,0],"ix":2,"l":2},"a":{"a":0,"k":[82,171.125,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":[{"ty":"rc","d":1,"s":{"a":0,"k":[64,8],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":39.375,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Line 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[80,177.125],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Line 4","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[92,8],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":39.375,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Line 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[94,165.125],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Line 3","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[20,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":39.375,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Avatar","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[34,171.125],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"circle 2","np":1,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".onTertiaryFixed","cl":"onTertiaryFixed","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[82.5,140.5,0],"ix":2,"l":2},"a":{"a":0,"k":[82,140.938,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":[{"ty":"rc","d":1,"s":{"a":0,"k":[132,22],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":39.375,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Search","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[82,31.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"header","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[64,8],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":200,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Line 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[80,257.375],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Line 6","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[92,8],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":200,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Line 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[94,245.375],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Line 5","np":1,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[20,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":200,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Avatar","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[34,251.375],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"circle 3","np":1,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[132,64],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Message","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[82,171],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"block","np":1,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[64,8],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":200,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Line 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[80,96.875],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Line 2","np":1,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[92,8],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":200,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Line 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[94,84.875],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Line 1","np":1,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[20,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":200,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Avatar","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[34,90.875],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"circle 1","np":1,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"roundedMatte","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[252,157.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[504,315],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":0,"op":600,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".onTertiaryFixedVariant","cl":"onTertiaryFixedVariant","tt":1,"tp":6,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[252,157.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[504,315],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"app only","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"ct":1,"bm":0}]},{"id":"comp_2","nm":"QS_App2","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".tertiaryFixedDim","cl":"tertiaryFixedDim","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[28,75.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,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],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[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],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-7,-0.65],[-7,8.5],[-2,8.5],[-2,2.5],[2,2.5],[2,8.5],[7,8.5],[7,-0.65],[9.8,1.5],[11,-0.1],[7,-3.15],[7,-7.5],[4,-7.5],[4,-5.45],[0,-8.5],[-11,-0.1],[-9.8,1.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":5,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,-0.533],[0,0],[-0.4,0.333],[-0.533,0],[-0.4,-0.35]],"o":[[0,0],[0,-0.533],[0.4,-0.35],[0.533,0],[0.4,0.333]],"v":[[2,-1.475],[-2,-1.475],[-1.4,-2.775],[0,-3.3],[1.4,-2.775]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":5,"nm":"Merge Paths 2","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":".tertiaryFixedDim","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"tertiaryFixedDim"}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".tertiaryFixedDim","cl":"tertiaryFixedDim","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[60,76,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,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],[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],[0,0],[0,0],[0,0]],"v":[[1.425,6.6],[-4.175,1],[8,1],[8,-1],[-4.175,-1],[1.425,-6.6],[0,-8],[-8,0],[0,8]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":".tertiaryFixedDim","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"tertiaryFixedDim"}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".tertiaryFixedDim","cl":"tertiaryFixedDim","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[92,76,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,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],[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],[0,0],[0,0],[0,0]],"v":[[-8,1],[4.175,1],[-1.425,6.6],[0,8],[8,0],[0,-8],[-1.425,-6.6],[4.175,-1],[-8,-1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":".tertiaryFixedDim","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"tertiaryFixedDim"}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".tertiaryFixedDim","cl":"tertiaryFixedDim","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[124,76,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[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.55,-1.55],[-2.233,0],[-1.433,1.117],[-0.467,1.767],[0,0],[1.033,-0.733],[1.283,0],[1.167,1.167],[0,1.667],[-1.167,1.167],[-1.667,0],[-0.917,-0.533],[-0.533,-0.933],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[1.05,0.467],[1.15,0],[1.55,-1.55],[0,-2.233]],"o":[[1.55,1.55],[1.833,0],[1.433,-1.117],[0,0],[-0.417,1.2],[-1.033,0.733],[-1.667,0],[-1.167,-1.167],[0,-1.667],[1.167,-1.167],[1.083,0],[0.933,0.533],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.75,-0.883],[-1.05,-0.483],[-2.233,0],[-1.55,1.55],[0,2.233]],"v":[[-5.675,5.675],[0,8],[4.9,6.325],[7.75,2],[5.65,2],[3.475,4.9],[0,6],[-4.25,4.25],[-6,0],[-4.25,-4.25],[0,-6],[3,-5.2],[5.2,-3],[1,-3],[1,-1],[8,-1],[8,-8],[6,-8],[6,-5.25],[3.3,-7.275],[0,-8],[-5.675,-5.675],[-8,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":".tertiaryFixedDim","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"tertiaryFixedDim"}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".onTertiaryFixedVariant","cl":"onTertiaryFixedVariant","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[320,76,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[336,24],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":360,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":".onTertiaryFixedVariant","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"onTertiaryFixedVariant"}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"appView Matte","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[252,157.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[504,315],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".onTertiaryFixed","cl":"onTertiaryFixed","tt":1,"tp":6,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[252,179.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,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,-4.418],[0,0],[0,0],[0,0],[4.418,0]],"o":[[-4.418,0],[0,0],[0,0],[0,0],[0,-4.418],[0,0]],"v":[[-244,-135.5],[-252,-127.5],[-252,135.5],[252,135.5],[252,-127.5],[244,-135.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":".onTertiaryFixed","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"onTertiaryFixed"}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".tertiaryFixedDim","cl":"tertiaryFixedDim","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[158,28,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,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],[0,0],[0,0],[0,0],[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],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-7,1],[-1,1],[-1,7],[1,7],[1,1],[7,1],[7,-1],[1,-1],[1,-7],[-1,-7],[-1,-1],[-7,-1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":".tertiaryFixedDim","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"tertiaryFixedDim"}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".tertiaryFixedDim","cl":"tertiaryFixedDim","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[32,28,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[18,18],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":39.375,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":".tertiaryFixedDim","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"tertiaryFixedDim"}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".tertiaryFixedDim","cl":"tertiaryFixedDim","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[124,28,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,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],[0,0],[0,0],[0,0],[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],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-7,5.6],[-5.6,7],[0,1.4],[5.6,7],[7,5.6],[1.4,0],[7,-5.6],[5.6,-7],[0,-1.4],[-5.6,-7],[-7,-5.6],[-1.4,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":".tertiaryFixedDim","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"tertiaryFixedDim"}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".onTertiaryFixed","cl":"onTertiaryFixed","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[78.5,28,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,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,-6.627],[0,0],[0,0],[0,0],[6.627,0]],"o":[[-6.627,0],[0,0],[0,0],[0,0],[0,-6.627],[0,0]],"v":[[-50.5,-16],[-62.5,-4],[-62.5,20],[62.5,20],[62.5,-4],[50.5,-16]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":".onTertiaryFixed","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"onTertiaryFixed"}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"background Matte","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[252,157.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[504,315],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".onTertiaryFixedVariant","cl":"onTertiaryFixedVariant","tt":1,"tp":12,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[252,157.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[504,315],"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.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":".onTertiaryFixedVariant","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"onTertiaryFixedVariant"}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0}]},{"id":"comp_3","nm":"Trackpad-Quickswitch_toRight","fr":60,"layers":[{"ddd":0,"ind":2,"ty":4,"nm":".tertiaryFixedDim","cl":"tertiaryFixedDim","parent":8,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":37,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":47,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":249,"s":[100]},{"t":255,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"k":[{"s":[4,0,0],"t":121,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[4.014,0,0],"t":122,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[4.067,0,0],"t":123,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[4.152,0,0],"t":124,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[4.27,0,0],"t":125,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[4.423,0,0],"t":126,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[4.606,0,0],"t":127,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[4.819,0,0],"t":128,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[5.06,0,0],"t":129,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[5.327,0,0],"t":130,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[5.613,0,0],"t":131,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[5.916,0,0],"t":132,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[6.233,0,0],"t":133,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[6.56,0,0],"t":134,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[6.893,0,0],"t":135,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[7.566,0,0],"t":137,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[7.9,0,0],"t":138,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[9.025,0,0],"t":139,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[10.133,0,0],"t":140,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[11.21,0,0],"t":141,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[12.251,0,0],"t":142,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[13.25,0,0],"t":143,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[14.205,0,0],"t":144,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[15.115,0,0],"t":145,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[15.977,0,0],"t":146,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[16.793,0,0],"t":147,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[17.564,0,0],"t":148,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[18.291,0,0],"t":149,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[18.978,0,0],"t":150,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[19.624,0,0],"t":151,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[20.235,0,0],"t":152,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[20.81,0,0],"t":153,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[21.353,0,0],"t":154,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[21.865,0,0],"t":155,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[22.349,0,0],"t":156,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[22.807,0,0],"t":157,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[23.24,0,0],"t":158,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[23.65,0,0],"t":159,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[24.038,0,0],"t":160,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[24.405,0,0],"t":161,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[24.753,0,0],"t":162,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[25.082,0,0],"t":163,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[25.393,0,0],"t":164,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[25.689,0,0],"t":165,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[25.969,0,0],"t":166,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[26.235,0,0],"t":167,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[26.486,0,0],"t":168,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[26.725,0,0],"t":169,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[26.951,0,0],"t":170,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[27.164,0,0],"t":171,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[27.367,0,0],"t":172,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[27.56,0,0],"t":173,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[27.741,0,0],"t":174,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[27.913,0,0],"t":175,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[28.074,0,0],"t":176,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[28.227,0,0],"t":177,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[28.372,0,0],"t":178,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[28.508,0,0],"t":179,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[28.636,0,0],"t":180,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[28.758,0,0],"t":181,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[28.871,0,0],"t":182,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[28.979,0,0],"t":183,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[29.079,0,0],"t":184,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[29.173,0,0],"t":185,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[29.263,0,0],"t":186,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[29.346,0,0],"t":187,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[29.422,0,0],"t":188,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[29.494,0,0],"t":189,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[29.56,0,0],"t":190,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[29.62,0,0],"t":191,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[29.677,0,0],"t":192,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[29.727,0,0],"t":193,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[29.774,0,0],"t":194,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[29.815,0,0],"t":195,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[29.852,0,0],"t":196,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[29.884,0,0],"t":197,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[29.912,0,0],"t":198,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[29.937,0,0],"t":199,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[29.958,0,0],"t":200,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[29.988,0,0],"t":202,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"a":{"a":0,"k":[20.5,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ef":[{"ty":5,"nm":"Super Slider","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":1,"k":[{"i":{"x":[0.64],"y":[0.48]},"o":{"x":[0.36],"y":[0]},"t":121,"s":[0]},{"i":{"x":[0.31],"y":[1]},"o":{"x":[0.15],"y":[0.514]},"t":138,"s":[15]},{"t":205,"s":[100]}],"ix":1}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":62,"s":[36,36]},{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":72,"s":[28,28]},{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":247,"s":[28,28]},{"t":257,"s":[36,36]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.56,"y":1},"o":{"x":0.44,"y":0},"t":62,"s":[82,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.56,"y":0.56},"o":{"x":0.426,"y":0.426},"t":72,"s":[68.5,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.657,"y":1},"o":{"x":0.42,"y":0},"t":247,"s":[68.5,0],"to":[0,0],"ti":[0,0]},{"t":257,"s":[82,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":"4F","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":62,"s":[36,36]},{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.446,0.446],"y":[0,0]},"t":72,"s":[28,28]},{"i":{"x":[0.656,0.656],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":247,"s":[28,28]},{"t":257,"s":[36,36]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.56,"y":1},"o":{"x":0.44,"y":0},"t":62,"s":[41,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.56,"y":0.56},"o":{"x":0.426,"y":0.426},"t":72,"s":[36.5,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.657,"y":1},"o":{"x":0.42,"y":0},"t":247,"s":[36.5,0],"to":[0,0],"ti":[0,0]},{"t":257,"s":[41,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":"3F","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":62,"s":[36,36]},{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.446,0.446],"y":[0,0]},"t":72,"s":[28,28]},{"i":{"x":[0.656,0.656],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":247,"s":[28,28]},{"t":257,"s":[36,36]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.56,"y":1},"o":{"x":0.44,"y":0},"t":62,"s":[-41,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.56,"y":0.56},"o":{"x":0.426,"y":0.426},"t":72,"s":[-27.5,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.657,"y":1},"o":{"x":0.42,"y":0},"t":247,"s":[-27.5,0],"to":[0,0],"ti":[0,0]},{"t":257,"s":[-41,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":"1F","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":62,"s":[36,36]},{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.446,0.446],"y":[0,0]},"t":72,"s":[28,28]},{"i":{"x":[0.656,0.656],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":247,"s":[28,28]},{"t":257,"s":[36,36]}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.56,"y":1},"o":{"x":0.44,"y":0},"t":62,"s":[0,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.56,"y":0.56},"o":{"x":0.44,"y":0.44},"t":72,"s":[4.5,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.56,"y":1},"o":{"x":0.44,"y":0},"t":247,"s":[4.5,0],"to":[0,0],"ti":[0,0]},{"t":257,"s":[0,0]}],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"2F","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":37,"op":345,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":3,"nm":"qs:scale","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"k":[{"s":[277,197.5,0],"t":37,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[277,197.5,0],"t":286,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"k":[{"s":[99.903,99.903,100],"t":127,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.828,99.828,100],"t":128,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.731,99.731,100],"t":129,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.615,99.615,100],"t":130,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.479,99.479,100],"t":131,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.327,99.327,100],"t":132,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.16,99.16,100],"t":133,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[98.979,98.979,100],"t":134,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[98.789,98.789,100],"t":135,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[98.591,98.591,100],"t":136,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[98.388,98.388,100],"t":137,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[98.183,98.183,100],"t":138,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[97.978,97.978,100],"t":139,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[97.774,97.774,100],"t":140,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[97.574,97.574,100],"t":141,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[96.729,96.729,100],"t":142,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[95.95,95.95,100],"t":143,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[95.256,95.256,100],"t":144,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[94.657,94.657,100],"t":145,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[94.158,94.158,100],"t":146,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[93.758,93.758,100],"t":147,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[93.452,93.452,100],"t":148,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[93.233,93.233,100],"t":149,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[93.091,93.091,100],"t":150,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[93.085,93.085,100],"t":249,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[93.929,93.929,100],"t":250,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[95.014,95.014,100],"t":251,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[95.985,95.985,100],"t":252,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[96.803,96.803,100],"t":253,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[97.48,97.48,100],"t":254,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[98.039,98.039,100],"t":255,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[98.498,98.498,100],"t":256,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[98.874,98.874,100],"t":257,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.179,99.179,100],"t":258,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.424,99.424,100],"t":259,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.617,99.617,100],"t":260,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.765,99.765,100],"t":261,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.872,99.872,100],"t":262,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.946,99.946,100],"t":263,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}}],"l":2}},"ao":0,"ef":[{"ty":5,"nm":"Void","np":19,"mn":"Pseudo/250958","ix":1,"en":1,"ef":[{"ty":0,"nm":"Width","mn":"Pseudo/250958-0001","ix":1,"v":{"a":0,"k":100,"ix":1}},{"ty":0,"nm":"Height","mn":"Pseudo/250958-0002","ix":2,"v":{"a":0,"k":100,"ix":2}},{"ty":0,"nm":"Offset X","mn":"Pseudo/250958-0003","ix":3,"v":{"a":0,"k":0,"ix":3}},{"ty":0,"nm":"Offset Y","mn":"Pseudo/250958-0004","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Roundness","mn":"Pseudo/250958-0005","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":6,"nm":"About","mn":"Pseudo/250958-0006","ix":6,"v":0},{"ty":6,"nm":"Plague of null layers.","mn":"Pseudo/250958-0007","ix":7,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0008","ix":8,"v":0},{"ty":6,"nm":"Following projects","mn":"Pseudo/250958-0009","ix":9,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0010","ix":10,"v":0},{"ty":6,"nm":"through time.","mn":"Pseudo/250958-0011","ix":11,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0012","ix":12,"v":0},{"ty":6,"nm":"Be free of the past.","mn":"Pseudo/250958-0013","ix":13,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0014","ix":14,"v":0},{"ty":6,"nm":"Copyright 2023 Battle Axe Inc","mn":"Pseudo/250958-0015","ix":15,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0016","ix":16,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0017","ix":17,"v":0}]}],"ip":0,"op":457,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"screenMatte_app1","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[277,197.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[503.5,314.5],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"frame","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":457,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"QS_App1","parent":3,"tt":1,"tp":4,"refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"k":[{"s":[0,0,0],"t":124,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[0.172,0,0],"t":125,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[0.689,0,0],"t":126,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[1.55,0,0],"t":127,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[2.756,0,0],"t":128,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[4.297,0,0],"t":129,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[6.165,0,0],"t":130,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[8.334,0,0],"t":131,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[10.779,0,0],"t":132,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[13.474,0,0],"t":133,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[16.394,0,0],"t":134,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[19.477,0,0],"t":135,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[22.706,0,0],"t":136,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[26.037,0,0],"t":137,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[29.438,0,0],"t":138,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[32.857,0,0],"t":139,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[36.285,0,0],"t":140,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[39.678,0,0],"t":141,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[54.528,0,0],"t":142,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[69.191,0,0],"t":143,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[83.517,0,0],"t":144,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[97.415,0,0],"t":145,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[110.777,0,0],"t":146,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[123.557,0,0],"t":147,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[135.722,0,0],"t":148,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[147.257,0,0],"t":149,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[158.176,0,0],"t":150,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[168.492,0,0],"t":151,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[178.222,0,0],"t":152,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[187.399,0,0],"t":153,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[196.042,0,0],"t":154,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[204.195,0,0],"t":155,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[211.885,0,0],"t":156,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[219.135,0,0],"t":157,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[225.98,0,0],"t":158,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[232.438,0,0],"t":159,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[238.533,0,0],"t":160,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[244.293,0,0],"t":161,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[249.733,0,0],"t":162,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[254.881,0,0],"t":163,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[259.753,0,0],"t":164,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[264.35,0,0],"t":165,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[268.714,0,0],"t":166,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[272.837,0,0],"t":167,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[276.737,0,0],"t":168,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[280.43,0,0],"t":169,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[283.925,0,0],"t":170,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[287.24,0,0],"t":171,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[290.365,0,0],"t":172,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[293.327,0,0],"t":173,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[296.134,0,0],"t":174,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[298.777,0,0],"t":175,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[301.283,0,0],"t":176,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[303.642,0,0],"t":177,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[305.873,0,0],"t":178,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[307.974,0,0],"t":179,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[309.955,0,0],"t":180,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[311.815,0,0],"t":181,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[313.572,0,0],"t":182,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[315.208,0,0],"t":183,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[316.75,0,0],"t":184,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[318.188,0,0],"t":185,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[319.532,0,0],"t":186,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[320.789,0,0],"t":187,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[321.952,0,0],"t":188,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[323.028,0,0],"t":189,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[324.019,0,0],"t":190,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[324.932,0,0],"t":191,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[325.767,0,0],"t":192,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[326.534,0,0],"t":193,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[327.223,0,0],"t":194,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[327.843,0,0],"t":195,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[328.394,0,0],"t":196,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[328.876,0,0],"t":197,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[329.298,0,0],"t":198,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[329.66,0,0],"t":199,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[329.961,0,0],"t":200,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[330.202,0,0],"t":201,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[330.521,0,0],"t":203,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[330.624,0,0],"t":247,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[337.892,0,0],"t":248,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[370.211,0,0],"t":249,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[411.228,0,0],"t":250,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[440.075,0,0],"t":251,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[460.498,0,0],"t":252,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[475.815,0,0],"t":253,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[487.713,0,0],"t":254,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[497.168,0,0],"t":255,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[504.76,0,0],"t":256,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[510.893,0,0],"t":257,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[515.835,0,0],"t":258,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[519.769,0,0],"t":259,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[522.868,0,0],"t":260,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[525.236,0,0],"t":261,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[526.959,0,0],"t":262,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[528.131,0,0],"t":263,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[528.793,0,0],"t":264,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"a":{"k":[{"s":[252,157.593,0],"t":127,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.664,0],"t":128,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.755,0],"t":129,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.864,0],"t":130,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.989,0],"t":131,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.128,0],"t":132,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.278,0],"t":133,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.438,0],"t":134,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.604,0],"t":135,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.774,0],"t":136,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.945,0],"t":137,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,159.115,0],"t":138,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,159.281,0],"t":139,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,159.444,0],"t":140,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,159.601,0],"t":141,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,160.236,0],"t":142,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,160.781,0],"t":143,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,161.236,0],"t":144,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,161.606,0],"t":145,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,161.896,0],"t":146,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,162.117,0],"t":147,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,162.278,0],"t":148,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,162.389,0],"t":149,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,162.419,0],"t":249,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,161.659,0],"t":250,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,160.753,0],"t":251,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,160,0],"t":252,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,159.407,0],"t":253,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.947,0],"t":254,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.588,0],"t":255,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.309,0],"t":256,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.091,0],"t":257,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.921,0],"t":258,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.791,0],"t":259,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.69,0],"t":260,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.562,0],"t":262,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":504,"h":315,"ip":0,"op":457,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"screenMatte_app2","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"k":[{"s":[277,197.5,0],"t":37,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[277,197.5,0],"t":286,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"a":{"a":0,"k":[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":{"k":[{"s":[503.5,314.5],"t":37,"i":{"x":[1,1],"y":[1,1]},"o":{"x":[0,0],"y":[0,0]}},{"s":[503.5,314.5],"t":286,"i":{"x":[1,1],"y":[1,1]},"o":{"x":[0,0],"y":[0,0]}}]},"p":{"a":0,"k":[0,0],"ix":3},"r":{"k":[{"s":[28],"t":37,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"s":[28],"t":286,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}}]},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"k":[{"s":[0.208,0.302,0.184,1],"t":37,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"s":[0.208,0.302,0.184,1],"t":286,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}}]},"o":{"k":[{"s":[100],"t":37,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"s":[100],"t":286,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}}]},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"frame","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":457,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"QS_App2","parent":3,"tt":1,"tp":6,"refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"k":[{"s":[-528.828,0,0],"t":125,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-528.311,0,0],"t":126,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-527.45,0,0],"t":127,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-526.244,0,0],"t":128,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-524.703,0,0],"t":129,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-522.835,0,0],"t":130,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-520.666,0,0],"t":131,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-518.221,0,0],"t":132,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-515.526,0,0],"t":133,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-512.606,0,0],"t":134,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-509.523,0,0],"t":135,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-506.294,0,0],"t":136,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-502.963,0,0],"t":137,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-499.562,0,0],"t":138,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-496.143,0,0],"t":139,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-492.715,0,0],"t":140,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-489.322,0,0],"t":141,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-474.472,0,0],"t":142,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-459.809,0,0],"t":143,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-445.483,0,0],"t":144,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-431.585,0,0],"t":145,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-418.223,0,0],"t":146,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-405.443,0,0],"t":147,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-393.278,0,0],"t":148,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-381.743,0,0],"t":149,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-370.824,0,0],"t":150,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-360.508,0,0],"t":151,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-350.778,0,0],"t":152,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-341.601,0,0],"t":153,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-332.958,0,0],"t":154,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-324.805,0,0],"t":155,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-317.115,0,0],"t":156,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-309.865,0,0],"t":157,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-303.02,0,0],"t":158,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-296.562,0,0],"t":159,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-290.467,0,0],"t":160,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-284.707,0,0],"t":161,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-279.267,0,0],"t":162,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-274.119,0,0],"t":163,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-269.247,0,0],"t":164,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-264.65,0,0],"t":165,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-260.286,0,0],"t":166,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-256.163,0,0],"t":167,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-252.263,0,0],"t":168,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-248.57,0,0],"t":169,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-245.075,0,0],"t":170,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-241.76,0,0],"t":171,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-238.635,0,0],"t":172,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-235.673,0,0],"t":173,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-232.866,0,0],"t":174,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-230.223,0,0],"t":175,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-227.717,0,0],"t":176,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-225.358,0,0],"t":177,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-223.127,0,0],"t":178,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-221.026,0,0],"t":179,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-219.045,0,0],"t":180,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-217.185,0,0],"t":181,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-215.428,0,0],"t":182,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-213.792,0,0],"t":183,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-212.25,0,0],"t":184,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-210.812,0,0],"t":185,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-209.468,0,0],"t":186,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-208.211,0,0],"t":187,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-207.048,0,0],"t":188,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-205.972,0,0],"t":189,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-204.981,0,0],"t":190,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-204.068,0,0],"t":191,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-203.233,0,0],"t":192,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-202.466,0,0],"t":193,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-201.777,0,0],"t":194,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-201.157,0,0],"t":195,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-200.606,0,0],"t":196,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-200.124,0,0],"t":197,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-199.702,0,0],"t":198,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-199.34,0,0],"t":199,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-199.039,0,0],"t":200,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-198.798,0,0],"t":201,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-198.608,0,0],"t":202,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-198.479,0,0],"t":203,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-198.376,0,0],"t":247,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-191.108,0,0],"t":248,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-158.789,0,0],"t":249,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-117.772,0,0],"t":250,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-88.925,0,0],"t":251,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-68.502,0,0],"t":252,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-53.185,0,0],"t":253,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-41.287,0,0],"t":254,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-31.832,0,0],"t":255,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-24.24,0,0],"t":256,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-18.107,0,0],"t":257,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-13.165,0,0],"t":258,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-9.231,0,0],"t":259,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-6.132,0,0],"t":260,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-3.764,0,0],"t":261,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-2.041,0,0],"t":262,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-0.869,0,0],"t":263,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-0.207,0,0],"t":264,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[0,0,0],"t":265,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"a":{"k":[{"s":[252,157.593,0],"t":127,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.664,0],"t":128,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.755,0],"t":129,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.864,0],"t":130,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.989,0],"t":131,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.128,0],"t":132,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.278,0],"t":133,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.438,0],"t":134,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.604,0],"t":135,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.774,0],"t":136,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.945,0],"t":137,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,159.115,0],"t":138,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,159.281,0],"t":139,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,159.444,0],"t":140,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,159.601,0],"t":141,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,160.236,0],"t":142,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,160.781,0],"t":143,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,161.236,0],"t":144,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,161.606,0],"t":145,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,161.896,0],"t":146,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,162.117,0],"t":147,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,162.278,0],"t":148,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,162.389,0],"t":149,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,162.419,0],"t":249,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,161.659,0],"t":250,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,160.753,0],"t":251,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,160,0],"t":252,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,159.407,0],"t":253,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.947,0],"t":254,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.588,0],"t":255,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.309,0],"t":256,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.091,0],"t":257,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.921,0],"t":258,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.791,0],"t":259,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.69,0],"t":260,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.562,0],"t":262,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":504,"h":315,"ip":0,"op":457,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".onTertiaryFixedVariant","cl":"onTertiaryFixedVariant","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[277,459,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[200,128],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":18,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843137255,0.301960784314,0.18431372549,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Frame 1321317559","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":457,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".onTertiaryFixedVariant","cl":"onTertiaryFixedVariant","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[277,197.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[503.5,314.5],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":50,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"frame","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":457,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".tertiaryFixedDim","cl":"tertiaryFixedDim","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[277.5,197.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[504,315],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,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":"op","nm":"Stroke align: Outside","a":{"a":0,"k":7,"ix":1},"lj":1,"ml":{"a":0,"k":4,"ix":3},"ix":3,"mn":"ADBE Vector Filter - Offset","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"frame","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":457,"st":0,"ct":1,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Trackpad-Quickswitch_toLeft","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[277,282,0],"ix":2,"l":2},"a":{"a":0,"k":[277,282,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":554,"h":564,"ip":287,"op":707,"st":250,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"Trackpad-Quickswitch_toRight","refId":"comp_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[277,282,0],"ix":2,"l":2},"a":{"a":0,"k":[277,282,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":554,"h":564,"ip":0,"op":287,"st":0,"bm":0}],"markers":[{"tm":37,"cm":"","dr":500},{"tm":121,"cm":"gesture to R","dr":84},{"tm":205,"cm":"end of gesture","dr":0},{"tm":247,"cm":"release","dr":0},{"tm":371,"cm":"gesture to L","dr":84},{"tm":455,"cm":"end of L gesture","dr":0},{"tm":497,"cm":"release","dr":0}],"props":{}} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/trackpad_switch_apps_success.json b/packages/SystemUI/res/raw/trackpad_switch_apps_success.json
new file mode 100644
index 000000000000..33925ed9d25e
--- /dev/null
+++ b/packages/SystemUI/res/raw/trackpad_switch_apps_success.json
@@ -0,0 +1 @@
+{"v":"5.12.1","fr":60,"ip":0,"op":78,"w":554,"h":564,"nm":"Trackpad-JSON_Quickswitch-Success","ddd":0,"assets":[{"id":"comp_0","nm":"TrackpadBack_Success_Checkmark","fr":60,"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Check Rotate","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.12],"y":[1]},"o":{"x":[0.44],"y":[0]},"t":2,"s":[-16]},{"t":20,"s":[6]}],"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[95.049,95.049,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":228,"st":-72,"bm":0},{"ddd":0,"ind":2,"ty":3,"nm":"Bounce","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.12],"y":[1]},"o":{"x":[0.44],"y":[0]},"t":12,"s":[0]},{"t":36,"s":[-6]}],"ix":10},"p":{"a":0,"k":[81,127,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.263,0.263,0.833],"y":[1.126,1.126,1]},"o":{"x":[0.05,0.05,0.05],"y":[0.958,0.958,0]},"t":1,"s":[80,80,100]},{"i":{"x":[0.1,0.1,0.1],"y":[1,1,1]},"o":{"x":[0.45,0.45,0.167],"y":[0.325,0.325,0]},"t":20,"s":[105,105,100]},{"t":36,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".tertiaryFixedDim","cl":"tertiaryFixedDim","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-0.289,"ix":10},"p":{"a":0,"k":[14.364,-33.591,0],"ix":2,"l":2},"a":{"a":0,"k":[-0.125,0,0],"ix":1,"l":2},"s":{"a":0,"k":[104.744,104.744,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-1.401,-0.007],[-10.033,11.235]],"o":[[5.954,7.288],[1.401,0.007],[0,0]],"v":[[-28.591,4.149],[-10.73,26.013],[31.482,-21.255]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - 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.4],"y":[0]},"t":3,"s":[0]},{"i":{"x":[0.22],"y":[1]},"o":{"x":[0.001],"y":[0.149]},"t":10,"s":[29]},{"t":27,"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},{"ty":"st","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":11,"ix":5},"lc":2,"lj":2,"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}],"ip":5,"op":44,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".onTertiaryFixedVariant","cl":"onTertiaryFixedVariant","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[95,95,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.275,0.275,0.21],"y":[1.102,1.102,1]},"o":{"x":[0.037,0.037,0.05],"y":[0.476,0.476,0]},"t":0,"s":[0,0,100]},{"i":{"x":[0.1,0.1,0.1],"y":[1,1,1]},"o":{"x":[0.252,0.252,0.47],"y":[0.159,0.159,0]},"t":16,"s":[120,120,100]},{"t":28,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.1,0.1],"y":[1,1]},"o":{"x":[0.32,0.32],"y":[0.11,0.11]},"t":16,"s":[148,148]},{"t":28,"s":[136,136]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":88,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"k":[{"s":[0.208,0.302,0.184,1],"t":0,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"s":[0.208,0.302,0.184,1],"t":43,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}}]},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Checkbox - Widget","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"ct":1,"bm":0}]},{"id":"comp_1","nm":"Trackpad-Quickswitch_toRight","fr":60,"layers":[{"ddd":0,"ind":2,"ty":4,"nm":".tertiaryFixedDim","cl":"tertiaryFixedDim","parent":8,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":37,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":47,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":249,"s":[100]},{"t":255,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"k":[{"s":[30,0,0],"t":247,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[30,0,0],"t":282,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"a":{"a":0,"k":[20.5,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ef":[{"ty":5,"nm":"Super Slider","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":1,"k":[{"i":{"x":[0.64],"y":[0.48]},"o":{"x":[0.36],"y":[0]},"t":121,"s":[0]},{"i":{"x":[0.31],"y":[1]},"o":{"x":[0.15],"y":[0.514]},"t":138,"s":[15]},{"t":205,"s":[100]}],"ix":1}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":62,"s":[36,36]},{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":72,"s":[28,28]},{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":247,"s":[28,28]},{"t":257,"s":[36,36]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.56,"y":1},"o":{"x":0.44,"y":0},"t":62,"s":[82,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.56,"y":0.56},"o":{"x":0.426,"y":0.426},"t":72,"s":[68.5,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.657,"y":1},"o":{"x":0.42,"y":0},"t":247,"s":[68.5,0],"to":[0,0],"ti":[0,0]},{"t":257,"s":[82,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":"4F","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":62,"s":[36,36]},{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.446,0.446],"y":[0,0]},"t":72,"s":[28,28]},{"i":{"x":[0.656,0.656],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":247,"s":[28,28]},{"t":257,"s":[36,36]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.56,"y":1},"o":{"x":0.44,"y":0},"t":62,"s":[41,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.56,"y":0.56},"o":{"x":0.426,"y":0.426},"t":72,"s":[36.5,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.657,"y":1},"o":{"x":0.42,"y":0},"t":247,"s":[36.5,0],"to":[0,0],"ti":[0,0]},{"t":257,"s":[41,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":"3F","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":62,"s":[36,36]},{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.446,0.446],"y":[0,0]},"t":72,"s":[28,28]},{"i":{"x":[0.656,0.656],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":247,"s":[28,28]},{"t":257,"s":[36,36]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.56,"y":1},"o":{"x":0.44,"y":0},"t":62,"s":[-41,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.56,"y":0.56},"o":{"x":0.426,"y":0.426},"t":72,"s":[-27.5,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.657,"y":1},"o":{"x":0.42,"y":0},"t":247,"s":[-27.5,0],"to":[0,0],"ti":[0,0]},{"t":257,"s":[-41,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":"1F","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":62,"s":[36,36]},{"i":{"x":[0.56,0.56],"y":[1,1]},"o":{"x":[0.446,0.446],"y":[0,0]},"t":72,"s":[28,28]},{"i":{"x":[0.656,0.656],"y":[1,1]},"o":{"x":[0.44,0.44],"y":[0,0]},"t":247,"s":[28,28]},{"t":257,"s":[36,36]}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.56,"y":1},"o":{"x":0.44,"y":0},"t":62,"s":[0,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.56,"y":0.56},"o":{"x":0.44,"y":0.44},"t":72,"s":[4.5,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.56,"y":1},"o":{"x":0.44,"y":0},"t":247,"s":[4.5,0],"to":[0,0],"ti":[0,0]},{"t":257,"s":[0,0]}],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"2F","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":37,"op":345,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":3,"nm":"qs:scale","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"k":[{"s":[277,197.5,0],"t":247,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[277,197.5,0],"t":282,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"k":[{"s":[93.085,93.085,100],"t":249,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[93.929,93.929,100],"t":250,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[95.014,95.014,100],"t":251,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[95.985,95.985,100],"t":252,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[96.803,96.803,100],"t":253,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[97.48,97.48,100],"t":254,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[98.039,98.039,100],"t":255,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[98.498,98.498,100],"t":256,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[98.874,98.874,100],"t":257,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.179,99.179,100],"t":258,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.424,99.424,100],"t":259,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.617,99.617,100],"t":260,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.765,99.765,100],"t":261,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.872,99.872,100],"t":262,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}},{"s":[99.946,99.946,100],"t":263,"i":{"x":[1,1,1],"y":[1,1,1]},"o":{"x":[0,0,0],"y":[0,0,0]}}],"l":2}},"ao":0,"ef":[{"ty":5,"nm":"Void","np":19,"mn":"Pseudo/250958","ix":1,"en":1,"ef":[{"ty":0,"nm":"Width","mn":"Pseudo/250958-0001","ix":1,"v":{"a":0,"k":100,"ix":1}},{"ty":0,"nm":"Height","mn":"Pseudo/250958-0002","ix":2,"v":{"a":0,"k":100,"ix":2}},{"ty":0,"nm":"Offset X","mn":"Pseudo/250958-0003","ix":3,"v":{"a":0,"k":0,"ix":3}},{"ty":0,"nm":"Offset Y","mn":"Pseudo/250958-0004","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Roundness","mn":"Pseudo/250958-0005","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":6,"nm":"About","mn":"Pseudo/250958-0006","ix":6,"v":0},{"ty":6,"nm":"Plague of null layers.","mn":"Pseudo/250958-0007","ix":7,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0008","ix":8,"v":0},{"ty":6,"nm":"Following projects","mn":"Pseudo/250958-0009","ix":9,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0010","ix":10,"v":0},{"ty":6,"nm":"through time.","mn":"Pseudo/250958-0011","ix":11,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0012","ix":12,"v":0},{"ty":6,"nm":"Be free of the past.","mn":"Pseudo/250958-0013","ix":13,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0014","ix":14,"v":0},{"ty":6,"nm":"Copyright 2023 Battle Axe Inc","mn":"Pseudo/250958-0015","ix":15,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0016","ix":16,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0017","ix":17,"v":0}]}],"ip":0,"op":457,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"screenMatte_app1","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[277,197.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[503.5,314.5],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"frame","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":457,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"QS_App1","parent":3,"tt":1,"tp":4,"refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"k":[{"s":[330.624,0,0],"t":247,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[337.892,0,0],"t":248,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[370.211,0,0],"t":249,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[411.228,0,0],"t":250,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[440.075,0,0],"t":251,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[460.498,0,0],"t":252,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[475.815,0,0],"t":253,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[487.713,0,0],"t":254,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[497.168,0,0],"t":255,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[504.76,0,0],"t":256,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[510.893,0,0],"t":257,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[515.835,0,0],"t":258,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[519.769,0,0],"t":259,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[522.868,0,0],"t":260,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[525.236,0,0],"t":261,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[526.959,0,0],"t":262,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[528.131,0,0],"t":263,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[528.793,0,0],"t":264,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"a":{"k":[{"s":[252,162.419,0],"t":249,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,161.659,0],"t":250,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,160.753,0],"t":251,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,160,0],"t":252,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,159.407,0],"t":253,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.947,0],"t":254,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.588,0],"t":255,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.309,0],"t":256,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.091,0],"t":257,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.921,0],"t":258,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.791,0],"t":259,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.69,0],"t":260,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.562,0],"t":262,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":504,"h":315,"ip":0,"op":457,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"screenMatte_app2","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"k":[{"s":[277,197.5,0],"t":247,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[277,197.5,0],"t":282,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"a":{"a":0,"k":[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":{"k":[{"s":[503.5,314.5],"t":247,"i":{"x":[1,1],"y":[1,1]},"o":{"x":[0,0],"y":[0,0]}},{"s":[503.5,314.5],"t":282,"i":{"x":[1,1],"y":[1,1]},"o":{"x":[0,0],"y":[0,0]}}]},"p":{"a":0,"k":[0,0],"ix":3},"r":{"k":[{"s":[28],"t":247,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"s":[28],"t":282,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}}]},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"k":[{"s":[0.208,0.302,0.184,1],"t":247,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"s":[0.208,0.302,0.184,1],"t":282,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}}]},"o":{"k":[{"s":[100],"t":247,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"s":[100],"t":282,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}}]},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"frame","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":457,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"QS_App2","parent":3,"tt":1,"tp":6,"refId":"comp_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"k":[{"s":[-198.376,0,0],"t":247,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-191.108,0,0],"t":248,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-158.789,0,0],"t":249,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-117.772,0,0],"t":250,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-88.925,0,0],"t":251,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-68.502,0,0],"t":252,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-53.185,0,0],"t":253,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-41.287,0,0],"t":254,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-31.832,0,0],"t":255,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-24.24,0,0],"t":256,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-18.107,0,0],"t":257,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-13.165,0,0],"t":258,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-9.231,0,0],"t":259,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-6.132,0,0],"t":260,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-3.764,0,0],"t":261,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-2.041,0,0],"t":262,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-0.869,0,0],"t":263,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-0.207,0,0],"t":264,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[0,0,0],"t":265,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"a":{"k":[{"s":[252,162.419,0],"t":249,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,161.659,0],"t":250,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,160.753,0],"t":251,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,160,0],"t":252,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,159.407,0],"t":253,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.947,0],"t":254,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.588,0],"t":255,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.309,0],"t":256,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,158.091,0],"t":257,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.921,0],"t":258,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.791,0],"t":259,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.69,0],"t":260,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[252,157.562,0],"t":262,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":504,"h":315,"ip":0,"op":457,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".onTertiaryFixedVariant","cl":"onTertiaryFixedVariant","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[277,459,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[200,128],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":18,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843137255,0.301960784314,0.18431372549,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Frame 1321317559","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":457,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".onTertiaryFixedVariant","cl":"onTertiaryFixedVariant","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[277,197.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[503.5,314.5],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":50,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"frame","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":457,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".tertiaryFixedDim","cl":"tertiaryFixedDim","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[277.5,197.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[504,315],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,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":"op","nm":"Stroke align: Outside","a":{"a":0,"k":7,"ix":1},"lj":1,"ml":{"a":0,"k":4,"ix":3},"ix":3,"mn":"ADBE Vector Filter - Offset","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"frame","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":457,"st":0,"ct":1,"bm":0}]},{"id":"comp_2","nm":"QS_App1","fr":60,"pfr":1,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".onTertiaryFixedVariant","cl":"onTertiaryFixedVariant","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[339.937,151.75,0],"ix":2,"l":2},"a":{"a":0,"k":[339.937,151.75,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":[[0,0],[1.021,-1.766],[0,0],[-2.043,0],[0,0],[1.022,1.767]],"o":[[-1.021,-1.766],[0,0],[-1.022,1.767],[0,0],[2.043,0],[0,0]],"v":[[2.297,-7.675],[-2.297,-7.675],[-9.64,5.025],[-7.343,9],[7.343,9],[9.64,5.025]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"rd","nm":"Round Corners 1","r":{"a":0,"k":9,"ix":1},"ix":2,"mn":"ADBE Vector Filter - RC","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Triangle","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[481.874,21],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Triangle","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[18,18],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":200,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[457.874,21],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"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","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[292,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":200,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Text field","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[334,279],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Text field","np":1,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[109,28],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Sent","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[425.5,208.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Sent","np":1,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[160,56],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":14,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Sent","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[400,158.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Sent","np":1,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[126,40],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":14,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Received","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[251,78.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Received","np":1,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"roundedMatte 2","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[252,157.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[504,315],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":0,"op":600,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".onTertiaryFixed","cl":"onTertiaryFixed","tt":1,"tp":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[334,157.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[340,315],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":16,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Message","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".onTertiaryFixedVariant","cl":"onTertiaryFixedVariant","parent":5,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[82,171.125,0],"ix":2,"l":2},"a":{"a":0,"k":[82,171.125,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":[{"ty":"rc","d":1,"s":{"a":0,"k":[64,8],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":39.375,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Line 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[80,177.125],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Line 4","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[92,8],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":39.375,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Line 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[94,165.125],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Line 3","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[20,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":39.375,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Avatar","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[34,171.125],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"circle 2","np":1,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".onTertiaryFixed","cl":"onTertiaryFixed","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[82.5,140.5,0],"ix":2,"l":2},"a":{"a":0,"k":[82,140.938,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":[{"ty":"rc","d":1,"s":{"a":0,"k":[132,22],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":39.375,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Search","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[82,31.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"header","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[64,8],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":200,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Line 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[80,257.375],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Line 6","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[92,8],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":200,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Line 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[94,245.375],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Line 5","np":1,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[20,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":200,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Avatar","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[34,251.375],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"circle 3","np":1,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[132,64],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Message","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[82,171],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"block","np":1,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[64,8],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":200,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Line 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[80,96.875],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Line 2","np":1,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[92,8],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":200,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Line 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[94,84.875],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Line 1","np":1,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[20,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":200,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Avatar","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[34,90.875],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"circle 1","np":1,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"roundedMatte","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[252,157.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[504,315],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":0,"op":600,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".onTertiaryFixedVariant","cl":"onTertiaryFixedVariant","tt":1,"tp":6,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[252,157.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[504,315],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"app only","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"ct":1,"bm":0}]},{"id":"comp_3","nm":"QS_App2","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".tertiaryFixedDim","cl":"tertiaryFixedDim","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[28,75.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,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],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[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],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-7,-0.65],[-7,8.5],[-2,8.5],[-2,2.5],[2,2.5],[2,8.5],[7,8.5],[7,-0.65],[9.8,1.5],[11,-0.1],[7,-3.15],[7,-7.5],[4,-7.5],[4,-5.45],[0,-8.5],[-11,-0.1],[-9.8,1.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":5,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,-0.533],[0,0],[-0.4,0.333],[-0.533,0],[-0.4,-0.35]],"o":[[0,0],[0,-0.533],[0.4,-0.35],[0.533,0],[0.4,0.333]],"v":[[2,-1.475],[-2,-1.475],[-1.4,-2.775],[0,-3.3],[1.4,-2.775]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":5,"nm":"Merge Paths 2","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":".tertiaryFixedDim","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"tertiaryFixedDim"}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".tertiaryFixedDim","cl":"tertiaryFixedDim","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[60,76,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,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],[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],[0,0],[0,0],[0,0]],"v":[[1.425,6.6],[-4.175,1],[8,1],[8,-1],[-4.175,-1],[1.425,-6.6],[0,-8],[-8,0],[0,8]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":".tertiaryFixedDim","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"tertiaryFixedDim"}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".tertiaryFixedDim","cl":"tertiaryFixedDim","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[92,76,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,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],[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],[0,0],[0,0],[0,0]],"v":[[-8,1],[4.175,1],[-1.425,6.6],[0,8],[8,0],[0,-8],[-1.425,-6.6],[4.175,-1],[-8,-1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":".tertiaryFixedDim","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"tertiaryFixedDim"}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".tertiaryFixedDim","cl":"tertiaryFixedDim","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[124,76,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[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.55,-1.55],[-2.233,0],[-1.433,1.117],[-0.467,1.767],[0,0],[1.033,-0.733],[1.283,0],[1.167,1.167],[0,1.667],[-1.167,1.167],[-1.667,0],[-0.917,-0.533],[-0.533,-0.933],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[1.05,0.467],[1.15,0],[1.55,-1.55],[0,-2.233]],"o":[[1.55,1.55],[1.833,0],[1.433,-1.117],[0,0],[-0.417,1.2],[-1.033,0.733],[-1.667,0],[-1.167,-1.167],[0,-1.667],[1.167,-1.167],[1.083,0],[0.933,0.533],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.75,-0.883],[-1.05,-0.483],[-2.233,0],[-1.55,1.55],[0,2.233]],"v":[[-5.675,5.675],[0,8],[4.9,6.325],[7.75,2],[5.65,2],[3.475,4.9],[0,6],[-4.25,4.25],[-6,0],[-4.25,-4.25],[0,-6],[3,-5.2],[5.2,-3],[1,-3],[1,-1],[8,-1],[8,-8],[6,-8],[6,-5.25],[3.3,-7.275],[0,-8],[-5.675,-5.675],[-8,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":".tertiaryFixedDim","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"tertiaryFixedDim"}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".onTertiaryFixedVariant","cl":"onTertiaryFixedVariant","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[320,76,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[336,24],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":360,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":".onTertiaryFixedVariant","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"onTertiaryFixedVariant"}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"appView Matte","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[252,157.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[504,315],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".onTertiaryFixed","cl":"onTertiaryFixed","tt":1,"tp":6,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[252,179.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,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,-4.418],[0,0],[0,0],[0,0],[4.418,0]],"o":[[-4.418,0],[0,0],[0,0],[0,0],[0,-4.418],[0,0]],"v":[[-244,-135.5],[-252,-127.5],[-252,135.5],[252,135.5],[252,-127.5],[244,-135.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":".onTertiaryFixed","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"onTertiaryFixed"}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".tertiaryFixedDim","cl":"tertiaryFixedDim","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[158,28,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,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],[0,0],[0,0],[0,0],[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],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-7,1],[-1,1],[-1,7],[1,7],[1,1],[7,1],[7,-1],[1,-1],[1,-7],[-1,-7],[-1,-1],[-7,-1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":".tertiaryFixedDim","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"tertiaryFixedDim"}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".tertiaryFixedDim","cl":"tertiaryFixedDim","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[32,28,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[18,18],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":39.375,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":".tertiaryFixedDim","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"tertiaryFixedDim"}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".tertiaryFixedDim","cl":"tertiaryFixedDim","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[124,28,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,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],[0,0],[0,0],[0,0],[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],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-7,5.6],[-5.6,7],[0,1.4],[5.6,7],[7,5.6],[1.4,0],[7,-5.6],[5.6,-7],[0,-1.4],[-5.6,-7],[-7,-5.6],[-1.4,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":".tertiaryFixedDim","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"tertiaryFixedDim"}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".onTertiaryFixed","cl":"onTertiaryFixed","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[78.5,28,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,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,-6.627],[0,0],[0,0],[0,0],[6.627,0]],"o":[[-6.627,0],[0,0],[0,0],[0,0],[0,-6.627],[0,0]],"v":[[-50.5,-16],[-62.5,-4],[-62.5,20],[62.5,20],[62.5,-4],[50.5,-16]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":".onTertiaryFixed","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"onTertiaryFixed"}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"background Matte","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[252,157.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[504,315],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".onTertiaryFixedVariant","cl":"onTertiaryFixedVariant","tt":1,"tp":12,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[252,157.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[504,315],"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.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":".onTertiaryFixedVariant","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"onTertiaryFixedVariant"}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"TrackpadBack_Success_Checkmark","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[277,198.5,0],"ix":2,"l":2},"a":{"a":0,"k":[95,95,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":190,"h":190,"ip":34,"op":78,"st":34,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".onTertiaryFixed","cl":"onTertiaryFixed","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":29,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":35,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":417,"s":[100]},{"t":420,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[277,197.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ef":[{"ty":5,"nm":"Global Position","np":4,"mn":"Pseudo/88900","ix":1,"en":1,"ef":[{"ty":10,"nm":"Master Parent","mn":"Pseudo/88900-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":3,"nm":"Global Position","mn":"Pseudo/88900-0002","ix":2,"v":{"k":[{"s":[277,197.5],"t":28,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[277,197.5],"t":77,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}]}}]}],"shapes":[{"ty":"rc","d":1,"s":{"a":0,"k":[504,315],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039215687662,0.1254902035,0.027450982481,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":28,"op":78,"st":28,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".onTertiaryFixedVariant","cl":"onTertiaryFixedVariant","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[277,459,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[200,128],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":18,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.207843139768,0.301960796118,0.184313729405,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"Frame 1321317559","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":91,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"matte","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[277,197.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"rc","d":1,"s":{"a":0,"k":[504,315],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,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":91,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"Trackpad-Quickswitch_toRight","tt":1,"tp":4,"refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[277,282,0],"ix":2,"l":2},"a":{"a":0,"k":[277,282,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":554,"h":564,"ip":0,"op":36,"st":-247,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".tertiaryFixedDim","cl":"tertiaryFixedDim","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[277,197.5,0],"ix":2,"l":2},"a":{"a":0,"k":[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":[504,315],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,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":"op","nm":"Stroke align: Outside","a":{"a":0,"k":7,"ix":1},"lj":1,"ml":{"a":0,"k":4,"ix":3},"ix":3,"mn":"ADBE Vector Filter - Offset","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039233685,0.811764717102,0.654901981354,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","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":"frame","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":91,"st":0,"ct":1,"bm":0}],"markers":[{"tm":121,"cm":"gesture to R","dr":84},{"tm":371,"cm":"gesture to L","dr":84}],"props":{}} \ No newline at end of file
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 752b71c2c4a0..c800b0374155 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -4000,13 +4000,13 @@
<!-- Touchpad switch apps gesture action name in tutorial [CHAR LIMIT=NONE] -->
<string name="touchpad_switch_apps_gesture_action_title">Switch apps</string>
<!-- Touchpad switch apps gesture guidance in gestures tutorial [CHAR LIMIT=NONE] -->
- <string name="touchpad_switch_apps_gesture_guidance">Swipe left or right using four fingers on your touchpad</string>
+ <string name="touchpad_switch_apps_gesture_guidance">Swipe left using four fingers on your touchpad</string>
<!-- Screen title after switch apps gesture was done successfully [CHAR LIMIT=NONE] -->
<string name="touchpad_switch_apps_gesture_success_title">Great job!</string>
<!-- Text shown to the user after they complete switch apps gesture tutorial [CHAR LIMIT=NONE] -->
<string name="touchpad_switch_apps_gesture_success_body">You completed the switch apps gesture.</string>
<!-- Text shown to the user after switch gesture was not done correctly [CHAR LIMIT=NONE] -->
- <string name="touchpad_switch_gesture_error_body">Swipe left or right using four fingers on your touchpad to switch apps</string>
+ <string name="touchpad_switch_gesture_error_body">Swipe left using four fingers on your touchpad to switch apps</string>
<!-- KEYBOARD TUTORIAL-->
<!-- Action key tutorial title [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
index 81a520661cfe..643f3bb917d1 100644
--- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
+++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
@@ -30,6 +30,7 @@ import android.os.Looper;
import android.os.Parcelable;
import android.os.Trace;
import android.util.ArrayMap;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -52,6 +53,8 @@ import javax.inject.Provider;
public class FragmentHostManager {
+ private static final String TAG = "FragmentHostManager";
+
private final Handler mHandler = new Handler(Looper.getMainLooper());
private final Context mContext;
private final HashMap<String, ArrayList<FragmentListener>> mListeners = new HashMap<>();
@@ -84,7 +87,7 @@ public class FragmentHostManager {
FragmentHostManager create(View rootView);
}
- private void createFragmentHost(Parcelable savedState) {
+ private void createFragmentHost(@Nullable Parcelable savedState) {
mFragments = FragmentController.createController(new HostCallbacks());
mFragments.attachHost(null);
mLifecycleCallbacks = new FragmentLifecycleCallbacks() {
@@ -115,12 +118,21 @@ public class FragmentHostManager {
mFragments.dispatchResume();
}
+ @Nullable
private Parcelable destroyFragmentHost() {
- mFragments.dispatchPause();
- Parcelable p = mFragments.saveAllState();
- mFragments.dispatchStop();
- mFragments.dispatchDestroy();
- mFragments.getFragmentManager().unregisterFragmentLifecycleCallbacks(mLifecycleCallbacks);
+ Parcelable p = null;
+ try {
+ mFragments.dispatchPause();
+ p = mFragments.saveAllState();
+ mFragments.dispatchStop();
+ mFragments.dispatchDestroy();
+ mFragments
+ .getFragmentManager()
+ .unregisterFragmentLifecycleCallbacks(mLifecycleCallbacks);
+ } catch (IllegalStateException e) {
+ Log.e(TAG, "Failed to destroy fragment host. This is expected to happen only in "
+ + "tests when displays are added and removed quickly");
+ }
return p;
}
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/ActionTutorialContent.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/ActionTutorialContent.kt
index 21afa40c441b..8cbcba2c3b1c 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/ActionTutorialContent.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/ActionTutorialContent.kt
@@ -43,7 +43,6 @@ import androidx.compose.runtime.saveable.mapSaver
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
-import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.stringResource
@@ -136,7 +135,7 @@ fun ActionTutorialContent(
val buttonAlpha by animateFloatAsState(if (actionState is Finished) 1f else 0f)
DoneButton(
onDoneButtonClicked = onDoneButtonClicked,
- modifier = Modifier.graphicsLayer { alpha = buttonAlpha },
+ modifier = Modifier.padding(horizontal = 60.dp).graphicsLayer { alpha = buttonAlpha },
enabled = actionState is Finished,
)
}
@@ -216,7 +215,7 @@ fun TutorialDescription(
Text(
text = stringResource(id = bodyTextId),
style = MaterialTheme.typography.bodyLarge,
- color = Color.White,
+ color = config.colors.bodyText,
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialScreenConfig.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialScreenConfig.kt
index 26259912741a..eda23a51a1ae 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialScreenConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialScreenConfig.kt
@@ -16,9 +16,12 @@
package com.android.systemui.inputdevice.tutorial.ui.composable
+import androidx.annotation.ColorInt
import androidx.annotation.RawRes
import androidx.annotation.StringRes
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.toArgb
+import androidx.core.graphics.ColorUtils
import com.airbnb.lottie.compose.LottieDynamicProperties
data class TutorialScreenConfig(
@@ -30,8 +33,23 @@ data class TutorialScreenConfig(
data class Colors(
val background: Color,
val title: Color,
+ val bodyText: Color,
val animationColors: LottieDynamicProperties,
- )
+ ) {
+ constructor(
+ background: Color,
+ title: Color,
+ animationColors: LottieDynamicProperties,
+ ) : this(background, title, textColorOnBackground(background.toArgb()), animationColors)
+
+ companion object {
+ private fun textColorOnBackground(@ColorInt background: Int): Color {
+ val whiteContrast = ColorUtils.calculateContrast(Color.White.toArgb(), background)
+ val blackContrast = ColorUtils.calculateContrast(Color.Black.toArgb(), background)
+ return if (whiteContrast >= blackContrast) Color.White else Color.Black
+ }
+ }
+ }
data class Strings(
@StringRes val titleResId: Int,
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt
index a16b4a6892b4..f1945e657d52 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt
@@ -17,6 +17,7 @@
package com.android.systemui.keyboard.shortcut.ui
import android.app.Dialog
+import android.content.res.Resources
import android.view.WindowManager.LayoutParams.PRIVATE_FLAG_ALLOW_ACTION_KEY_EVENTS
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
@@ -26,6 +27,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo
import com.android.systemui.keyboard.shortcut.ui.composable.ShortcutCustomizationDialog
import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiState
@@ -34,6 +36,8 @@ import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiSt
import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiState.ResetShortcutDialog
import com.android.systemui.keyboard.shortcut.ui.viewmodel.ShortcutCustomizationViewModel
import com.android.systemui.lifecycle.ExclusiveActivatable
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.phone.SystemUIDialogFactory
import com.android.systemui.statusbar.phone.create
import dagger.assisted.AssistedFactory
@@ -46,6 +50,7 @@ class ShortcutCustomizationDialogStarter
constructor(
viewModelFactory: ShortcutCustomizationViewModel.Factory,
private val dialogFactory: SystemUIDialogFactory,
+ @Main private val resources: Resources,
) : ExclusiveActivatable() {
private var dialog: Dialog? = null
@@ -97,14 +102,28 @@ constructor(
coroutineScope.launch { viewModel.resetAllCustomShortcuts() }
},
)
- dialog.setOnDismissListener { viewModel.onDialogDismissed() }
-
- // By default, apps cannot intercept action key. The system always handles it. This
- // flag is needed to enable customisation dialog window to intercept action key
- dialog.window?.addPrivateFlags(PRIVATE_FLAG_ALLOW_ACTION_KEY_EVENTS)
+ setDialogProperties(dialog, uiState)
}
}
+ private fun setDialogProperties(dialog: SystemUIDialog, uiState: ShortcutCustomizationUiState) {
+ dialog.setOnDismissListener { viewModel.onDialogDismissed() }
+ dialog.setTitle(
+ resources.getString(
+ when (uiState) {
+ is AddShortcutDialog ->
+ R.string.shortcut_customize_mode_add_shortcut_description
+ is DeleteShortcutDialog ->
+ R.string.shortcut_customize_mode_remove_shortcut_description
+ else -> R.string.shortcut_customize_mode_reset_shortcut_description
+ }
+ )
+ )
+ // By default, apps cannot intercept action key. The system always handles it. This
+ // flag is needed to enable customisation dialog window to intercept action key
+ dialog.window?.addPrivateFlags(PRIVATE_FLAG_ALLOW_ACTION_KEY_EVENTS)
+ }
+
@AssistedFactory
interface Factory {
fun create(): ShortcutCustomizationDialogStarter
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
index b42da5265d86..717437923e57 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
@@ -36,6 +36,7 @@ import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.debounce
@SysUISingleton
@@ -80,6 +81,7 @@ constructor(
/**
* Listen for the signal that we're waking up and figure what state we need to transition to.
*/
+ @OptIn(FlowPreview::class)
private fun listenForAodToAwake() {
// Use PowerInteractor's wakefulness, which is the earliest wake signal available. We
// have all of the information we need at this time to make a decision about where to
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
index 021cce6d1e23..4291181d8336 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
@@ -41,6 +41,7 @@ import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.debounce
@SysUISingleton
@@ -114,6 +115,7 @@ constructor(
}
}
+ @OptIn(FlowPreview::class)
@SuppressLint("MissingPermission")
private fun listenForDozingToAny() {
if (KeyguardWmStateRefactor.isEnabled) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
index a9992112f893..82b8ca2a890b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
@@ -125,6 +125,7 @@ constructor(
* the power button is pressed quickly, we may need to go directly from DREAMING to
* GLANCEABLE_HUB as the transition to DOZING has not occurred yet.
*/
+ @OptIn(FlowPreview::class)
@SuppressLint("MissingPermission")
private fun listenForDreamingToGlanceableHubFromPowerButton() {
if (!communalSettingsInteractor.isCommunalFlagEnabled()) return
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
index 8f7f2a0a8cbb..1f3c08ca9f7a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
@@ -56,6 +56,7 @@ import javax.inject.Inject
import javax.inject.Provider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -203,6 +204,7 @@ constructor(
* examining the value of this flow, to let other consumers have enough time to also see that
* same new value.
*/
+ @OptIn(FlowPreview::class)
val isAbleToDream: Flow<Boolean> =
dozeTransitionModel
.flatMapLatest { dozeTransitionModel ->
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
index cd62d5f3b6e1..3dc123a81bde 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
@@ -30,6 +30,7 @@ import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.SharedNotificationContainerViewModel
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.debounce
private val TAG = KeyguardTransitionAuditLogger::class.simpleName!!
@@ -52,6 +53,7 @@ constructor(
private val deviceEntryInteractor: DeviceEntryInteractor,
) {
+ @OptIn(FlowPreview::class)
fun start() {
scope.launch {
powerInteractor.detailedWakefulness.collect {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
index 70632b33f532..c748e28e60b4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
@@ -188,7 +188,11 @@ constructor(
finish.addListener(
object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
- animationWindowView.removeView(currentAnimatedView!!.view)
+ if (!::animationWindowView.isInitialized) {
+ return
+ }
+ val animatedView = currentAnimatedView ?: return
+ animationWindowView.removeView(animatedView.view)
}
}
)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/layout/StatusBarContentInsetsProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/layout/StatusBarContentInsetsProvider.kt
index f7a9094e0337..7358c513eaff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/layout/StatusBarContentInsetsProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/layout/StatusBarContentInsetsProvider.kt
@@ -53,6 +53,7 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import java.io.PrintWriter
import java.lang.Math.max
+import java.util.concurrent.CopyOnWriteArraySet
/**
* Encapsulates logic that can solve for the left/right insets required for the status bar contents.
@@ -163,7 +164,7 @@ constructor(
// Limit cache size as potentially we may connect large number of displays
// (e.g. network displays)
private val insetsCache = LruCache<CacheKey, Rect>(MAX_CACHE_SIZE)
- private val listeners = mutableSetOf<StatusBarContentInsetsChangedListener>()
+ private val listeners = CopyOnWriteArraySet<StatusBarContentInsetsChangedListener>()
private val isPrivacyDotEnabled: Boolean by
lazy(LazyThreadSafetyMode.PUBLICATION) {
context.resources.getBoolean(R.bool.config_enablePrivacyDot)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StabilizeHeadsUpGroup.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StabilizeHeadsUpGroup.kt
index 629cb831f17a..a0e44bfd7620 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StabilizeHeadsUpGroup.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StabilizeHeadsUpGroup.kt
@@ -24,7 +24,7 @@ import com.android.systemui.flags.RefactorFlagUtils
@Suppress("NOTHING_TO_INLINE")
object StabilizeHeadsUpGroup {
/** The aconfig flag name */
- const val FLAG_NAME: String = Flags.FLAG_STABILIZE_HEADS_UP_GROUP
+ const val FLAG_NAME: String = Flags.FLAG_STABILIZE_HEADS_UP_GROUP_V2
/** A token used for dependency declaration */
val token: FlagToken
@@ -33,7 +33,7 @@ object StabilizeHeadsUpGroup {
/** Is the refactor enabled */
@JvmStatic
inline val isEnabled
- get() = Flags.stabilizeHeadsUpGroup()
+ get() = Flags.stabilizeHeadsUpGroupV2()
/**
* 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/policy/domain/interactor/ZenModeInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt
index 5fa15b831299..a28d14fd908d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt
@@ -30,6 +30,7 @@ import com.android.settingslib.notification.modes.ZenIcon
import com.android.settingslib.notification.modes.ZenIconLoader
import com.android.settingslib.notification.modes.ZenMode
import com.android.settingslib.volume.shared.model.AudioStream
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.modes.shared.ModesUi
import com.android.systemui.shared.notifications.data.repository.NotificationSettingsRepository
@@ -57,6 +58,7 @@ import kotlinx.coroutines.flow.stateIn
* An interactor that performs business logic related to the status and configuration of Zen Mode
* (or Do Not Disturb/DND Mode).
*/
+ @SysUISingleton
class ZenModeInteractor
@Inject
constructor(
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/SwitchAppsGestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/SwitchAppsGestureTutorialScreen.kt
index 3bb0dd779613..e16007ea4384 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/SwitchAppsGestureTutorialScreen.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/SwitchAppsGestureTutorialScreen.kt
@@ -46,8 +46,8 @@ fun SwitchAppsGestureTutorialScreen(
titleErrorResId = R.string.gesture_error_title,
bodyErrorResId = R.string.touchpad_switch_gesture_error_body,
),
- // TODO: replace animation
- animations = TutorialScreenConfig.Animations(educationResId = R.raw.trackpad_back_edu),
+ animations =
+ TutorialScreenConfig.Animations(educationResId = R.raw.trackpad_switch_apps_edu),
)
GestureTutorialScreen(
screenConfig = screenConfig,
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/SwitchAppsGestureRecognizer.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/SwitchAppsGestureRecognizer.kt
index 470048bd3b20..cc382d0a6148 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/SwitchAppsGestureRecognizer.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/SwitchAppsGestureRecognizer.kt
@@ -16,9 +16,14 @@
package com.android.systemui.touchpad.tutorial.ui.gesture
+import android.util.MathUtils
import android.view.MotionEvent
+import com.android.systemui.touchpad.tutorial.ui.gesture.GestureDirection.LEFT
+import com.android.systemui.touchpad.tutorial.ui.gesture.GestureDirection.RIGHT
+import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.InProgress
+import kotlin.math.abs
-// TODO: javadoc
+/** Recognizes Quickswitch gesture i.e. using four fingers on touchpad, swiping right. */
class SwitchAppsGestureRecognizer(private val gestureDistanceThresholdPx: Int) : GestureRecognizer {
private val distanceTracker = DistanceTracker()
@@ -32,8 +37,26 @@ class SwitchAppsGestureRecognizer(private val gestureDistanceThresholdPx: Int) :
gestureStateChangedCallback = {}
}
- // TODO: recognizer logic
override fun accept(event: MotionEvent) {
if (!isMultifingerTouchpadSwipe(event)) return
+ if (!isFourFingerTouchpadSwipe(event)) {
+ if (event.actionMasked == MotionEvent.ACTION_UP) {
+ gestureStateChangedCallback(GestureState.Error)
+ }
+ return
+ }
+ val gestureState = distanceTracker.processEvent(event)
+ updateGestureState(
+ gestureStateChangedCallback,
+ gestureState,
+ isFinished = { it.deltaX >= gestureDistanceThresholdPx },
+ progress = ::getProgress,
+ )
+ }
+
+ private fun getProgress(it: Moving): InProgress {
+ val direction = if (it.deltaX > 0) RIGHT else LEFT
+ val value = MathUtils.saturate(abs(it.deltaX / gestureDistanceThresholdPx))
+ return InProgress(value, direction)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt
index 0a139125afa2..93aed891478c 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt
@@ -166,7 +166,7 @@ fun TouchpadTutorialScreen(
SwitchAppsGestureTutorialScreen(
switchAppsGestureScreenViewModel,
easterEggGestureViewModel,
- onDoneButtonClicked = { vm.goTo(SWITCH_APPS_GESTURE) },
+ onDoneButtonClicked = { vm.goTo(TUTORIAL_SELECTION) },
onBack = { vm.goTo(TUTORIAL_SELECTION) },
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/SwitchAppsGestureScreenViewModel.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/SwitchAppsGestureScreenViewModel.kt
index 6593db49745d..e53ddd206da3 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/SwitchAppsGestureScreenViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/SwitchAppsGestureScreenViewModel.kt
@@ -26,15 +26,14 @@ import kotlinx.coroutines.flow.map
class SwitchAppsGestureScreenViewModel(private val gestureRecognizer: GestureRecognizerAdapter) :
TouchpadTutorialScreenViewModel {
- // TODO: replace with correct markers and resource
override val tutorialState: Flow<TutorialActionState> =
gestureRecognizer.gestureState
.map {
it to
TutorialAnimationProperties(
- progressStartMarker = "drag with gesture",
- progressEndMarker = "onPause",
- successAnimation = R.raw.trackpad_recent_apps_success,
+ progressStartMarker = "gesture to R",
+ progressEndMarker = "end of gesture",
+ successAnimation = R.raw.trackpad_switch_apps_success,
)
}
.mapToTutorialState()
diff --git a/packages/SystemUI/tests/utils/src/com/android/app/WallpaperManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/app/WallpaperManagerKosmos.kt
index 2850ab7b1e41..f893aba240fc 100644
--- a/packages/SystemUI/tests/utils/src/com/android/app/WallpaperManagerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/app/WallpaperManagerKosmos.kt
@@ -19,9 +19,7 @@ import android.app.WallpaperManager
import android.content.applicationContext
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@OptIn(ExperimentalCoroutinesApi::class)
val Kosmos.wallpaperManager: WallpaperManager by Fixture {
WallpaperManager.getInstance(applicationContext)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysUITestModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/SysUITestModule.kt
index c9458125e762..dfcda222e54f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/SysUITestModule.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysUITestModule.kt
@@ -51,7 +51,6 @@ import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
@@ -148,7 +147,6 @@ interface SysUITestComponent<out T> {
val underTest: T
}
-@OptIn(ExperimentalCoroutinesApi::class)
fun <T : SysUITestComponent<*>> T.runTest(block: suspend T.() -> Unit): Unit =
testScope.runTest {
// Access underTest immediately to force Dagger to instantiate it prior to the test running
@@ -157,7 +155,6 @@ fun <T : SysUITestComponent<*>> T.runTest(block: suspend T.() -> Unit): Unit =
block()
}
-@OptIn(ExperimentalCoroutinesApi::class)
fun SysUITestComponent<*>.runCurrent() = testScope.runCurrent()
fun <T> SysUITestComponent<*>.collectLastValue(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt
index a7917a0866bb..3c264b9d6a81 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt
@@ -28,7 +28,6 @@ import com.android.systemui.dagger.SysUISingleton
import dagger.Binds
import dagger.Module
import dagger.Provides
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
@@ -260,7 +259,6 @@ class FakeAuthenticationRepository(private val currentTime: () -> Long) : Authen
}
}
-@OptIn(ExperimentalCoroutinesApi::class)
@Module(includes = [FakeAuthenticationRepositoryModule.Bindings::class])
object FakeAuthenticationRepositoryModule {
@Provides
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderKosmos.kt
index 79d58a1d4e40..e3bd6fa27d4c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderKosmos.kt
@@ -27,9 +27,7 @@ import com.android.systemui.keyguard.ui.viewmodel.sideFpsProgressBarViewModel
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.kosmos.applicationCoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@OptIn(ExperimentalCoroutinesApi::class)
val Kosmos.sideFpsOverlayViewBinder by Fixture {
SideFpsOverlayViewBinder(
applicationScope = applicationCoroutineScope,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelKosmos.kt
index e2386a6a42b4..220bb90303b8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelKosmos.kt
@@ -23,9 +23,7 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.statusbar.phone.systemUIDialogManager
import com.android.systemui.util.mockito.mock
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.deviceEntryUdfpsTouchOverlayViewModel by Fixture {
DeviceEntryUdfpsTouchOverlayViewModel(
deviceEntryIconViewModel = deviceEntryIconViewModel,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelKosmos.kt
index de038559fc38..e79c089361af 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelKosmos.kt
@@ -22,9 +22,7 @@ import com.android.systemui.biometrics.domain.interactor.sideFpsSensorInteractor
import com.android.systemui.keyguard.domain.interactor.deviceEntrySideFpsOverlayInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@OptIn(ExperimentalCoroutinesApi::class)
val Kosmos.sideFpsOverlayViewModel by Fixture {
SideFpsOverlayViewModel(
applicationContext = applicationContext,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelKosmos.kt
index 5c5969d359c3..7de71ff44bb1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelKosmos.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.bouncer.ui.viewmodel
import android.content.applicationContext
@@ -30,7 +28,6 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.user.ui.viewmodel.userSwitcherViewModel
import com.android.systemui.util.time.systemClock
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.bouncerMessageViewModel by Fixture {
BouncerMessageViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt
index 72541540226c..3bfd95816cf0 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.bouncer.ui.viewmodel
import android.app.admin.devicePolicyManager
@@ -34,7 +32,6 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.user.domain.interactor.selectedUserInteractor
import com.android.systemui.user.ui.viewmodel.userSwitcherViewModel
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.StateFlow
val Kosmos.bouncerUserActionsViewModel by Fixture {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalSceneRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalSceneRepository.kt
index 82454817ecbb..b3c1411243c1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalSceneRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalSceneRepository.kt
@@ -5,7 +5,6 @@ import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.TransitionKey
import com.android.systemui.communal.shared.model.CommunalScenes
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
@@ -16,7 +15,6 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
/** Fake implementation of [CommunalSceneRepository]. */
-@OptIn(ExperimentalCoroutinesApi::class)
class FakeCommunalSceneRepository(
private val applicationScope: CoroutineScope,
override val currentScene: MutableStateFlow<SceneKey> =
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModelKosmos.kt
index 1ae8449d8b4d..7b0c09cd80a6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModelKosmos.kt
@@ -26,9 +26,7 @@ import com.android.systemui.keyguard.ui.viewmodel.glanceableHubToLockscreenTrans
import com.android.systemui.keyguard.ui.viewmodel.lockscreenToGlanceableHubTransitionViewModel
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@OptIn(ExperimentalCoroutinesApi::class)
val Kosmos.communalTransitionViewModel by
Kosmos.Fixture {
CommunalTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/coroutines/TestCoroutineSchedulerUtils.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/coroutines/TestCoroutineSchedulerUtils.kt
index 84e2a5c7d4c2..2fb73264b3d4 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/coroutines/TestCoroutineSchedulerUtils.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/coroutines/TestCoroutineSchedulerUtils.kt
@@ -13,12 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.coroutines
import kotlin.time.Duration
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestCoroutineScheduler
/**
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/ui/viewmodel/UdfpsAccessibilityOverlayViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/ui/viewmodel/UdfpsAccessibilityOverlayViewModelKosmos.kt
index cdeade1876a7..2a46437ed33e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/ui/viewmodel/UdfpsAccessibilityOverlayViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/ui/viewmodel/UdfpsAccessibilityOverlayViewModelKosmos.kt
@@ -22,9 +22,7 @@ import com.android.systemui.deviceentry.ui.viewmodel.DeviceEntryUdfpsAccessibili
import com.android.systemui.keyguard.ui.viewmodel.deviceEntryForegroundIconViewModel
import com.android.systemui.keyguard.ui.viewmodel.deviceEntryIconViewModel
import com.android.systemui.kosmos.Kosmos
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.deviceEntryUdfpsAccessibilityOverlayViewModel by
Kosmos.Fixture {
DeviceEntryUdfpsAccessibilityOverlayViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/AuthRippleInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/AuthRippleInteractorKosmos.kt
index 3070cf4c06ad..015d4ddcd54e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/AuthRippleInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/AuthRippleInteractorKosmos.kt
@@ -17,9 +17,7 @@
package com.android.systemui.deviceentry.domain.interactor
import com.android.systemui.kosmos.Kosmos
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@OptIn(ExperimentalCoroutinesApi::class)
val Kosmos.authRippleInteractor by
Kosmos.Fixture {
AuthRippleInteractor(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorKosmos.kt
index 77d39f066e08..6b6488122b68 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorKosmos.kt
@@ -20,9 +20,7 @@ import android.content.res.mainResources
import com.android.systemui.biometrics.domain.interactor.fingerprintPropertyInteractor
import com.android.systemui.keyguard.domain.interactor.devicePostureInteractor
import com.android.systemui.kosmos.Kosmos
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.biometricMessageInteractor by
Kosmos.Fixture {
BiometricMessageInteractor(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricAuthInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricAuthInteractorKosmos.kt
index 1bd105620813..281782ad726a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricAuthInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricAuthInteractorKosmos.kt
@@ -14,13 +14,10 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.deviceentry.domain.interactor
import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
import com.android.systemui.kosmos.Kosmos
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.deviceEntryBiometricAuthInteractor by
Kosmos.Fixture {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricSettingsInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricSettingsInteractorKosmos.kt
index 4fcf43a2a055..44755897f88e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricSettingsInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricSettingsInteractorKosmos.kt
@@ -18,9 +18,7 @@ package com.android.systemui.deviceentry.domain.interactor
import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
import com.android.systemui.kosmos.Kosmos
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.deviceEntryBiometricSettingsInteractor by
Kosmos.Fixture {
DeviceEntryBiometricSettingsInteractor(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricsAllowedInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricsAllowedInteractorKosmos.kt
index 4357289b227e..3c08e5c55349 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricsAllowedInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricsAllowedInteractorKosmos.kt
@@ -14,13 +14,10 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.deviceentry.domain.interactor
import com.android.systemui.biometrics.data.repository.facePropertyRepository
import com.android.systemui.kosmos.Kosmos
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.deviceEntryBiometricsAllowedInteractor by
Kosmos.Fixture {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorKosmos.kt
index 3dfe0eea500f..33f8f40677af 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorKosmos.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.deviceentry.domain.interactor
import android.content.applicationContext
@@ -36,7 +34,6 @@ import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.user.data.repository.userRepository
import com.android.systemui.util.mockito.mock
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.faceAuthLogger by Kosmos.Fixture { mock<FaceAuthenticationLogger>() }
val Kosmos.deviceEntryFaceAuthInteractor by
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthStatusInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthStatusInteractorKosmos.kt
index 66d3709d14dc..4a489ab2773c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthStatusInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthStatusInteractorKosmos.kt
@@ -14,15 +14,12 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.deviceentry.domain.interactor
import android.content.res.mainResources
import com.android.systemui.keyguard.data.repository.deviceEntryFaceAuthRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.deviceEntryFaceAuthStatusInteractor by
Kosmos.Fixture {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFingerprintAuthInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFingerprintAuthInteractorKosmos.kt
index ebed922c423e..4d767e57e631 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFingerprintAuthInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFingerprintAuthInteractorKosmos.kt
@@ -14,14 +14,11 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.deviceentry.domain.interactor
import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
import com.android.systemui.keyguard.data.repository.deviceEntryFingerprintAuthRepository
import com.android.systemui.kosmos.Kosmos
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.deviceEntryFingerprintAuthInteractor by
Kosmos.Fixture {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorKosmos.kt
index 490b89bf6b13..6f570a86b19e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorKosmos.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.deviceentry.domain.interactor
import com.android.keyguard.logging.biometricUnlockLogger
@@ -27,9 +25,7 @@ import com.android.systemui.keyguard.domain.interactor.keyguardBypassInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.util.time.systemClock
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@OptIn(ExperimentalCoroutinesApi::class)
val Kosmos.deviceEntryHapticsInteractor by
Kosmos.Fixture {
DeviceEntryHapticsInteractor(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorKosmos.kt
index 096022ce1507..1d3fd300da06 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorKosmos.kt
@@ -24,9 +24,7 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.scene.domain.interactor.sceneBackInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.deviceEntryInteractor by
Kosmos.Fixture {
DeviceEntryInteractor(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntrySourceInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntrySourceInteractorKosmos.kt
index f91a044ad802..845d481cbbb7 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntrySourceInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntrySourceInteractorKosmos.kt
@@ -27,9 +27,7 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.statusbar.phone.dozeScrimController
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.deviceEntrySourceInteractor by
Kosmos.Fixture {
DeviceEntrySourceInteractor(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractorKosmos.kt
index 81123d09b43a..44d3c33c95fb 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractorKosmos.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.deviceentry.domain.interactor
import com.android.systemui.biometrics.domain.interactor.fingerprintPropertyInteractor
@@ -23,7 +21,6 @@ import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
import com.android.systemui.keyguard.data.repository.deviceEntryFingerprintAuthRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.deviceEntryUdfpsInteractor by Fixture {
DeviceEntryUdfpsInteractor(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/FaceHelpMessageDeferralInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/FaceHelpMessageDeferralInteractorKosmos.kt
index 724e943c9f55..79a9c57169a3 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/FaceHelpMessageDeferralInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/FaceHelpMessageDeferralInteractorKosmos.kt
@@ -19,9 +19,7 @@ package com.android.systemui.deviceentry.domain.interactor
import com.android.systemui.biometrics.domain.faceHelpMessageDeferralFactory
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.faceHelpMessageDeferralInteractor by
Kosmos.Fixture {
FaceHelpMessageDeferralInteractor(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/OccludingAppDeviceEntryInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/OccludingAppDeviceEntryInteractorKosmos.kt
index 3680e651246b..3d5c99cf180a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/OccludingAppDeviceEntryInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/OccludingAppDeviceEntryInteractorKosmos.kt
@@ -27,9 +27,7 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.plugins.activityStarter
import com.android.systemui.power.domain.interactor.powerInteractor
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.occludingAppDeviceEntryInteractor by
Kosmos.Fixture {
OccludingAppDeviceEntryInteractor(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/ui/binder/LiftToRunFaceAuthBinderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/ui/binder/LiftToRunFaceAuthBinderKosmos.kt
index 2fead91b430a..199a4a4d932c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/ui/binder/LiftToRunFaceAuthBinderKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/ui/binder/LiftToRunFaceAuthBinderKosmos.kt
@@ -26,9 +26,7 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.util.sensors.asyncSensorManager
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.liftToRunFaceAuthBinder by
Kosmos.Fixture {
LiftToRunFaceAuthBinder(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
index 3df3ee983ecf..60a6f3d904d4 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
@@ -211,6 +211,7 @@ val Kosmos.shortcutCustomizationDialogStarterFactory by
return ShortcutCustomizationDialogStarter(
shortcutCustomizationViewModelFactory,
systemUIDialogFactory,
+ mainResources,
)
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorKosmos.kt
index 40131c772de7..26ebe2e41a17 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorKosmos.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.domain.interactor
import android.content.applicationContext
@@ -24,7 +22,6 @@ import com.android.systemui.doze.util.burnInHelperWrapper
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.kosmos.applicationCoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
var Kosmos.burnInInteractor by Fixture {
BurnInInteractor(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/DevicePostureInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/DevicePostureInteractorKosmos.kt
index 75eb3c9ad7ad..b920dbf88e77 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/DevicePostureInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/DevicePostureInteractorKosmos.kt
@@ -18,9 +18,7 @@ package com.android.systemui.keyguard.domain.interactor
import com.android.systemui.keyguard.data.repository.devicePostureRepository
import com.android.systemui.kosmos.Kosmos
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.devicePostureInteractor by
Kosmos.Fixture {
DevicePostureInteractor(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorKosmos.kt
index ce317d43e988..7b0d208298d0 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorKosmos.kt
@@ -24,9 +24,7 @@ import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.fromAlternateBouncerTransitionInteractor by
Kosmos.Fixture {
FromAlternateBouncerTransitionInteractor(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorKosmos.kt
index e6c98cd83b5e..d995b868a162 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorKosmos.kt
@@ -27,9 +27,7 @@ import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@OptIn(ExperimentalCoroutinesApi::class)
var Kosmos.fromDreamingTransitionInteractor by
Kosmos.Fixture {
FromDreamingTransitionInteractor(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt
index 09f5fd79eeca..1d7671170d5b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt
@@ -25,9 +25,7 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.shade.domain.interactor.shadeInteractor
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.keyguardDismissActionInteractor by
Kosmos.Fixture {
KeyguardDismissActionInteractor(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorKosmos.kt
index 339210c07437..277c2ffa6e9a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorKosmos.kt
@@ -26,9 +26,7 @@ import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.user.domain.interactor.selectedUserInteractor
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.keyguardDismissInteractor by
Kosmos.Fixture {
KeyguardDismissInteractor(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardSmartspaceInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardSmartspaceInteractorKosmos.kt
index b5d5d641b0fe..87109b17ef0e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardSmartspaceInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardSmartspaceInteractorKosmos.kt
@@ -14,14 +14,11 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.domain.interactor
import com.android.systemui.keyguard.data.repository.keyguardSmartspaceRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
var Kosmos.keyguardSmartspaceInteractor by Fixture {
KeyguardSmartspaceInteractor(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowKosmos.kt
index 1a05d21cc30a..31fb36eb26db 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowKosmos.kt
@@ -14,15 +14,12 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui
import com.android.keyguard.logging.keyguardTransitionAnimationLogger
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.keyguardTransitionAnimationFlow by Fixture {
KeyguardTransitionAnimationFlow(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinderKosmos.kt
index 740d8919cbc0..697e7b9476ca 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinderKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinderKosmos.kt
@@ -38,9 +38,7 @@ import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.statusbar.gesture.TapGestureDetector
import com.android.systemui.util.mockito.mock
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@OptIn(ExperimentalCoroutinesApi::class)
val Kosmos.alternateBouncerViewBinder by
Kosmos.Fixture {
AlternateBouncerViewBinder(
@@ -52,7 +50,6 @@ val Kosmos.alternateBouncerViewBinder by
)
}
-@ExperimentalCoroutinesApi
private val Kosmos.alternateBouncerDependencies by
Kosmos.Fixture {
AlternateBouncerDependencies(
@@ -69,7 +66,6 @@ private val Kosmos.alternateBouncerDependencies by
)
}
-@ExperimentalCoroutinesApi
private val Kosmos.alternateBouncerUdfpsIconViewModel by
Kosmos.Fixture {
AlternateBouncerUdfpsIconViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerMessageAreaViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerMessageAreaViewModelKosmos.kt
index b7d9676040d0..938556e71cbb 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerMessageAreaViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerMessageAreaViewModelKosmos.kt
@@ -20,9 +20,7 @@ import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor
import com.android.systemui.deviceentry.domain.interactor.biometricMessageInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.util.time.systemClock
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.alternateBouncerMessageAreaViewModel by
Kosmos.Fixture {
AlternateBouncerMessageAreaViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToAodTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToAodTransitionViewModelKosmos.kt
index 3ed9392bab2a..7d729e38fdca 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToAodTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToAodTransitionViewModelKosmos.kt
@@ -14,15 +14,12 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.alternateBouncerToAodTransitionViewModel by Fixture {
AlternateBouncerToAodTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToDozingTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToDozingTransitionViewModelKosmos.kt
index c6f07068aad4..71cfb40c11d6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToDozingTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToDozingTransitionViewModelKosmos.kt
@@ -20,9 +20,7 @@ import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsIntera
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.alternateBouncerToDozingTransitionViewModel by Fixture {
AlternateBouncerToDozingTransitionViewModel(
deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToGoneTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToGoneTransitionViewModelKosmos.kt
index b943298f6b53..3ec0ee040269 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToGoneTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToGoneTransitionViewModelKosmos.kt
@@ -14,15 +14,12 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.statusbar.sysuiStatusBarStateController
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.alternateBouncerToGoneTransitionViewModel by Fixture {
AlternateBouncerToGoneTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToLockscreenTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToLockscreenTransitionViewModelKosmos.kt
index 6c644eee24ff..346580a91f9b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToLockscreenTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToLockscreenTransitionViewModelKosmos.kt
@@ -14,14 +14,11 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.alternateBouncerToLockscreenTransitionViewModel by Fixture {
AlternateBouncerToLockscreenTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToOccludedTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToOccludedTransitionViewModelKosmos.kt
index 71ad3c6689f7..87367b24fc7d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToOccludedTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToOccludedTransitionViewModelKosmos.kt
@@ -14,14 +14,11 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.alternateBouncerToOccludedTransitionViewModel by Fixture {
AlternateBouncerToOccludedTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModelKosmos.kt
index 79892442092c..7bf778deeab5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModelKosmos.kt
@@ -14,17 +14,13 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.blurConfig
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@OptIn(ExperimentalCoroutinesApi::class)
val Kosmos.alternateBouncerToPrimaryBouncerTransitionViewModel by Fixture {
AlternateBouncerToPrimaryBouncerTransitionViewModel(
animationFlow = keyguardTransitionAnimationFlow,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelKosmos.kt
index f1d87fe3abb7..3da27cb3c11d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelKosmos.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor
@@ -25,7 +23,6 @@ import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInterac
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.statusbar.phone.statusBarKeyguardViewManager
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.alternateBouncerViewModel by Fixture {
AlternateBouncerViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModelKosmos.kt
index 92cfbef987f6..335ab84a0851 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModelKosmos.kt
@@ -14,15 +14,12 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.alternateBouncerWindowViewModel by Fixture {
AlternateBouncerWindowViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelKosmos.kt
index c3c2c8c95aad..1471ddbcea61 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelKosmos.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.common.ui.domain.interactor.configurationInteractor
@@ -25,7 +23,6 @@ import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInterac
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.kosmos.applicationCoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
var Kosmos.aodBurnInViewModel by Fixture {
AodBurnInViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToGoneTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToGoneTransitionViewModelKosmos.kt
index b6f278c1b466..6aad53a5d067 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToGoneTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToGoneTransitionViewModelKosmos.kt
@@ -14,14 +14,11 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.aodToGoneTransitionViewModel by Fixture {
AodToGoneTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelKosmos.kt
index b8fcec648393..25a8d5d201be 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelKosmos.kt
@@ -14,15 +14,12 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.shade.domain.interactor.shadeInteractor
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.aodToLockscreenTransitionViewModel by Fixture {
AodToLockscreenTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModelKosmos.kt
index 8d066fc05996..3b33ee47bc41 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModelKosmos.kt
@@ -14,14 +14,11 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.aodToOccludedTransitionViewModel by Fixture {
AodToOccludedTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerViewModelKosmos.kt
index faa290be6129..ae411367fcfc 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerViewModelKosmos.kt
@@ -20,9 +20,7 @@ import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.blurConfig
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@OptIn(ExperimentalCoroutinesApi::class)
val Kosmos.aodToPrimaryBouncerTransitionViewModel by Fixture {
AodToPrimaryBouncerTransitionViewModel(
animationFlow = keyguardTransitionAnimationFlow,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlowsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlowsKosmos.kt
index 9774e4aa51a5..0b364eafb418 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlowsKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlowsKosmos.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.bouncer.domain.interactor.mockPrimaryBouncerInteractor
@@ -25,7 +23,6 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.statusbar.sysuiStatusBarStateController
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.bouncerToGoneFlows by Fixture {
BouncerToGoneFlows(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelKosmos.kt
index fc4f3a553d51..bd0045501ec8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelKosmos.kt
@@ -21,9 +21,7 @@ import com.android.systemui.common.ui.domain.interactor.configurationInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.deviceEntryBackgroundViewModel by Fixture {
DeviceEntryBackgroundViewModel(
context = applicationContext,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryFgIconViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryFgIconViewModelKosmos.kt
index 4f638d0e4a38..1a4bd338ade7 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryFgIconViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryFgIconViewModelKosmos.kt
@@ -23,9 +23,7 @@ import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsIntera
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.deviceEntryForegroundIconViewModel by Fixture {
DeviceEntryForegroundViewModel(
context = applicationContext,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelKosmos.kt
index 67fa857a1ecd..f8393d537f82 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelKosmos.kt
@@ -29,7 +29,6 @@ import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.kosmos.testScope
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.statusbar.phone.statusBarKeyguardViewManager
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.fakeDeviceEntryIconViewModelTransition by Fixture { FakeDeviceEntryIconTransition() }
@@ -37,7 +36,6 @@ val Kosmos.deviceEntryIconViewModelTransitionsMock by Fixture {
setOf<DeviceEntryIconTransition>(fakeDeviceEntryIconViewModelTransition)
}
-@ExperimentalCoroutinesApi
val Kosmos.deviceEntryIconViewModel by Fixture {
DeviceEntryIconViewModel(
transitions = deviceEntryIconViewModelTransitionsMock,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGlanceableHubTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGlanceableHubTransitionViewModelKosmos.kt
index ef10459b45cb..87c3dbf9487e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGlanceableHubTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGlanceableHubTransitionViewModelKosmos.kt
@@ -19,9 +19,7 @@ package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.dozingToGlanceableHubTransitionViewModel by Fixture {
DozingToGlanceableHubTransitionViewModel(animationFlow = keyguardTransitionAnimationFlow)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGoneTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGoneTransitionViewModelKosmos.kt
index 36ddc29b8914..7c066036b131 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGoneTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGoneTransitionViewModelKosmos.kt
@@ -19,9 +19,7 @@ package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.dozingToGoneTransitionViewModel by Fixture {
DozingToGoneTransitionViewModel(
animationFlow = keyguardTransitionAnimationFlow,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModelKosmos.kt
index de52d848e94b..46f9f8dcd962 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModelKosmos.kt
@@ -19,9 +19,7 @@ package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.dozingToLockscreenTransitionViewModel by Fixture {
DozingToLockscreenTransitionViewModel(
animationFlow = keyguardTransitionAnimationFlow,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToOccludedTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToOccludedTransitionViewModelKosmos.kt
index 8162520e5d88..25865ae8700f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToOccludedTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToOccludedTransitionViewModelKosmos.kt
@@ -18,9 +18,7 @@ package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.dozingToOccludedTransitionViewModel by
Kosmos.Fixture {
DozingToOccludedTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModelKosmos.kt
index d3ccb297fc9d..39f9530bcb17 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModelKosmos.kt
@@ -20,9 +20,7 @@ import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.blurConfig
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.dozingToPrimaryBouncerTransitionViewModel by Fixture {
DozingToPrimaryBouncerTransitionViewModel(
animationFlow = keyguardTransitionAnimationFlow,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToAodTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToAodTransitionViewModelKosmos.kt
index b5f0b897deba..ec1f906dc179 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToAodTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToAodTransitionViewModelKosmos.kt
@@ -14,15 +14,12 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
var Kosmos.dreamingToAodTransitionViewModel by Fixture {
DreamingToAodTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGoneTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGoneTransitionViewModelKosmos.kt
index f389142554b1..1e832bdf82dd 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGoneTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGoneTransitionViewModelKosmos.kt
@@ -18,9 +18,7 @@ package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.dreamingToGoneTransitionViewModel by
Kosmos.Fixture {
DreamingToGoneTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelKosmos.kt
index d06bab2f5345..1d0a210110ed 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelKosmos.kt
@@ -19,9 +19,7 @@ package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.dreamingToLockscreenTransitionViewModel by Fixture {
DreamingToLockscreenTransitionViewModel(
animationFlow = keyguardTransitionAnimationFlow,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModelKosmos.kt
index b1c21b8fa6cf..bb1098f14ea6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModelKosmos.kt
@@ -14,17 +14,13 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.common.ui.domain.interactor.configurationInteractor
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@OptIn(ExperimentalCoroutinesApi::class)
val Kosmos.glanceableHubToLockscreenTransitionViewModel by Fixture {
GlanceableHubToLockscreenTransitionViewModel(
configurationInteractor = configurationInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelKosmos.kt
index 8549a30c346e..2d24ef2fcfee 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelKosmos.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
@@ -23,7 +21,6 @@ import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.power.domain.interactor.powerInteractor
-import kotlinx.coroutines.ExperimentalCoroutinesApi
var Kosmos.goneToAodTransitionViewModel by Fixture {
GoneToAodTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDozingTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDozingTransitionViewModelKosmos.kt
index b19d4e87e68c..3f7348be8fe5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDozingTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDozingTransitionViewModelKosmos.kt
@@ -20,9 +20,7 @@ import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsIntera
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.goneToDozingTransitionViewModel by Fixture {
GoneToDozingTransitionViewModel(
deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelKosmos.kt
index b267a962a1ff..86ef95cbab4c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelKosmos.kt
@@ -14,14 +14,11 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.goneToDreamingTransitionViewModel by Fixture {
GoneToDreamingTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToLockscreenTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToLockscreenTransitionViewModelKosmos.kt
index 1b6fa064854d..4322a887928a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToLockscreenTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToLockscreenTransitionViewModelKosmos.kt
@@ -14,14 +14,11 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
var Kosmos.goneToLockscreenTransitionViewModel by Fixture {
GoneToLockscreenTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt
index 1c0f97d294df..40b8e0e62b03 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt
@@ -13,8 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.communal.domain.interactor.communalInteractor
@@ -31,7 +29,6 @@ import com.android.systemui.statusbar.notification.icon.ui.viewmodel.notificatio
import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationsKeyguardInteractor
import com.android.systemui.statusbar.phone.dozeParameters
import com.android.systemui.statusbar.phone.screenOffAnimationController
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.keyguardRootViewModel by Fixture {
KeyguardRootViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelKosmos.kt
index f45e33bf6865..5234b5bd17e2 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelKosmos.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
@@ -23,7 +21,6 @@ import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.power.domain.interactor.powerInteractor
-import kotlinx.coroutines.ExperimentalCoroutinesApi
var Kosmos.lockscreenToAodTransitionViewModel by Fixture {
LockscreenToAodTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModelKosmos.kt
index aa8e9a8c9a8c..bf1af3c47674 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModelKosmos.kt
@@ -20,9 +20,7 @@ import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsIntera
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.lockscreenToDozingTransitionViewModel by Fixture {
LockscreenToDozingTransitionViewModel(
deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelKosmos.kt
index 56d5ff6e30eb..1246b9455b4b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelKosmos.kt
@@ -14,14 +14,11 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.lockscreenToDreamingTransitionViewModel by Fixture {
LockscreenToDreamingTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModelKosmos.kt
index 471381f7a13f..0e961ccaf07b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModelKosmos.kt
@@ -14,17 +14,13 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.common.ui.domain.interactor.configurationInteractor
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.lockscreenToGlanceableHubTransitionViewModel by Fixture {
LockscreenToGlanceableHubTransitionViewModel(
configurationInteractor = configurationInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModelKosmos.kt
index 7a023ee29299..172b4f8db92b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModelKosmos.kt
@@ -20,9 +20,7 @@ import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.statusbar.sysuiStatusBarStateController
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.lockscreenToGoneTransitionViewModel by Fixture {
LockscreenToGoneTransitionViewModel(
animationFlow = keyguardTransitionAnimationFlow,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelKosmos.kt
index 9953d39e9a49..abd29cadb8f7 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelKosmos.kt
@@ -14,15 +14,12 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.common.ui.domain.interactor.configurationInteractor
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.lockscreenToOccludedTransitionViewModel by Fixture {
LockscreenToOccludedTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelKosmos.kt
index 68280d7622fd..b5c67b66ae5f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelKosmos.kt
@@ -14,15 +14,12 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.blurConfig
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.lockscreenToPrimaryBouncerTransitionViewModel by Fixture {
LockscreenToPrimaryBouncerTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAlternateBouncerTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAlternateBouncerTransitionViewModelKosmos.kt
index 2acd1b40af3e..39a545a8c451 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAlternateBouncerTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAlternateBouncerTransitionViewModelKosmos.kt
@@ -14,14 +14,11 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.occludedToAlternateBouncerTransitionViewModel by Fixture {
OccludedToAlternateBouncerTransitionViewModel(animationFlow = keyguardTransitionAnimationFlow)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModelKosmos.kt
index b7867b6cabde..dd6d9acaa33e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModelKosmos.kt
@@ -14,15 +14,12 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.occludedToAodTransitionViewModel by Fixture {
OccludedToAodTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToDozingTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToDozingTransitionViewModelKosmos.kt
index 4196e54a085d..4e8896ab11c1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToDozingTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToDozingTransitionViewModelKosmos.kt
@@ -14,15 +14,12 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.occludedToDozingTransitionViewModel by Fixture {
OccludedToDozingTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToGoneTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToGoneTransitionViewModelKosmos.kt
index 3b96912b53c6..70e9af1b1058 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToGoneTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToGoneTransitionViewModelKosmos.kt
@@ -14,14 +14,11 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
var Kosmos.occludedToGoneTransitionViewModel by Fixture {
OccludedToGoneTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelKosmos.kt
index f86e9b7216ce..5b1d8f126f84 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelKosmos.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.common.ui.domain.interactor.configurationInteractor
@@ -25,7 +23,6 @@ import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInterac
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
var Kosmos.occludedToLockscreenTransitionViewModel by Fixture {
OccludedToLockscreenTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModelKosmos.kt
index 5d62a0f4a0cf..579819f6d265 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModelKosmos.kt
@@ -14,14 +14,11 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.offToLockscreenTransitionViewModel by Fixture {
OffToLockscreenTransitionViewModel(animationFlow = keyguardTransitionAnimationFlow)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelKosmos.kt
index 043a49f5f640..73ef4328657a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelKosmos.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
@@ -23,7 +21,6 @@ import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.blurConfig
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.primaryBouncerToAodTransitionViewModel by Fixture {
PrimaryBouncerToAodTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModelKosmos.kt
index 59ea2c93089c..99297351bdaa 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModelKosmos.kt
@@ -21,9 +21,7 @@ import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.blurConfig
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@ExperimentalCoroutinesApi
val Kosmos.primaryBouncerToDozingTransitionViewModel by Fixture {
PrimaryBouncerToDozingTransitionViewModel(
deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelKosmos.kt
index b470ab12828b..acf0827b1614 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelKosmos.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.bouncer.domain.interactor.mockPrimaryBouncerInteractor
@@ -25,7 +23,6 @@ import com.android.systemui.keyguard.ui.transitions.blurConfig
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.statusbar.sysuiStatusBarStateController
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.primaryBouncerToGoneTransitionViewModel by Fixture {
PrimaryBouncerToGoneTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelKosmos.kt
index c3447753a86d..bd5a21195795 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelKosmos.kt
@@ -14,15 +14,12 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.blurConfig
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.primaryBouncerToLockscreenTransitionViewModel by Fixture {
PrimaryBouncerToLockscreenTransitionViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/SideFpsProgressBarViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/SideFpsProgressBarViewModelKosmos.kt
index 8da16fc4e855..e38c419a97f2 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/SideFpsProgressBarViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/SideFpsProgressBarViewModelKosmos.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.keyguard.ui.viewmodel
import android.content.applicationContext
@@ -29,7 +27,6 @@ import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.statusbar.phone.dozeServiceHost
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.sideFpsProgressBarViewModel by
Kosmos.Fixture {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt
index 439df543b9fb..a4c2cc275e44 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt
@@ -9,7 +9,6 @@ import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.settings.brightness.ui.BrightnessWarningToast
import com.android.systemui.util.mockito.mock
import kotlin.coroutines.CoroutineContext
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
@@ -73,7 +72,6 @@ fun <T> Kosmos.collectValues(flow: Flow<T>): FlowValue<List<T>> = testScope.coll
* If you want to assert on a [Flow] that is not a [StateFlow], please use
* [TestScope.collectLastValue], to make sure that the desired value is captured when emitted.
*/
-@OptIn(ExperimentalCoroutinesApi::class)
fun <T> TestScope.currentValue(stateFlow: StateFlow<T>): T {
val values = mutableListOf<T>()
val job = backgroundScope.launch { stateFlow.collect(values::add) }
@@ -90,7 +88,6 @@ fun <T> Kosmos.currentValue(fn: () -> T) = testScope.currentValue(fn)
* Retrieve the result of [fn] after running all pending tasks. Do not use to retrieve the value of
* a flow directly; for that, use either `currentValue(StateFlow)` or [collectLastValue]
*/
-@OptIn(ExperimentalCoroutinesApi::class)
fun <T> TestScope.currentValue(fn: () -> T): T {
runCurrent()
return fn()
@@ -102,7 +99,6 @@ fun <T> Kosmos.currentValue(stateFlow: StateFlow<T>): T {
}
/** Safely verify that a mock has been called after the test scope has caught up */
-@OptIn(ExperimentalCoroutinesApi::class)
fun <T> TestScope.verifyCurrent(mock: T): T {
runCurrent()
return verify(mock)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
index 39f1ad42797b..35e90f06ddde 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.kosmos
import android.content.applicationContext
@@ -92,7 +90,6 @@ import com.android.systemui.statusbar.policy.domain.interactor.deviceProvisionin
import com.android.systemui.statusbar.ui.viewmodel.keyguardStatusBarViewModel
import com.android.systemui.util.time.systemClock
import com.android.systemui.volume.domain.interactor.volumeDialogInteractor
-import kotlinx.coroutines.ExperimentalCoroutinesApi
/**
* Helper for using [Kosmos] from Java.
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/taskswitcher/TaskSwitcherKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/taskswitcher/TaskSwitcherKosmos.kt
index 5acadd7f192a..2ef3f4a70998 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/taskswitcher/TaskSwitcherKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/taskswitcher/TaskSwitcherKosmos.kt
@@ -23,7 +23,6 @@ import com.android.systemui.mediaprojection.data.repository.realMediaProjectionR
import com.android.systemui.mediaprojection.taskswitcher.data.repository.ActivityTaskManagerTasksRepository
import com.android.systemui.mediaprojection.taskswitcher.domain.interactor.TaskSwitchInteractor
import com.android.systemui.mediaprojection.taskswitcher.ui.viewmodel.TaskSwitcherNotificationViewModel
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.UnconfinedTestDispatcher
val Kosmos.fakeActivityTaskManager by Kosmos.Fixture { FakeActivityTaskManager() }
@@ -47,5 +46,4 @@ val Kosmos.taskSwitcherInteractor by
val Kosmos.taskSwitcherViewModel by
Kosmos.Fixture { TaskSwitcherNotificationViewModel(taskSwitcherInteractor, testDispatcher) }
-@OptIn(ExperimentalCoroutinesApi::class)
fun taskSwitcherKosmos() = Kosmos().apply { testDispatcher = UnconfinedTestDispatcher() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
index 49957f0b43cc..65e580cafcb5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
@@ -39,9 +39,7 @@ import com.android.systemui.shade.largeScreenHeaderHelper
import com.android.systemui.shade.transition.largeScreenShadeInterpolator
import com.android.systemui.statusbar.disableflags.domain.interactor.disableFlagsInteractor
import com.android.systemui.statusbar.sysuiStatusBarStateController
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@OptIn(ExperimentalCoroutinesApi::class)
val Kosmos.qsFragmentComposeViewModelFactory by
Kosmos.Fixture {
object : QSFragmentComposeViewModel.Factory {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/resolver/SceneResolverKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/resolver/SceneResolverKosmos.kt
index a4a63ec6ca21..9d18fbfccb36 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/resolver/SceneResolverKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/resolver/SceneResolverKosmos.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.scene.domain.resolver
import com.android.compose.animation.scene.SceneKey
@@ -25,7 +23,6 @@ import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.scene.shared.model.SceneFamilies
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.sceneFamilyResolvers: Map<SceneKey, SceneResolver>
get() = mapOf(SceneFamilies.Home to homeSceneFamilyResolver)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/ScrimStartableKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/ScrimStartableKosmos.kt
index b64c84075936..12b46536b2a2 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/ScrimStartableKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/ScrimStartableKosmos.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.scene.domain.startable
import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor
@@ -31,7 +29,6 @@ import com.android.systemui.settings.brightness.domain.interactor.brightnessMirr
import com.android.systemui.statusbar.phone.dozeServiceHost
import com.android.systemui.statusbar.phone.scrimController
import com.android.systemui.statusbar.phone.statusBarKeyguardViewManager
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.scrimStartable by Fixture {
ScrimStartable(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/StatusBarStartableKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/StatusBarStartableKosmos.kt
index ee69c30fe6b9..881d110dff25 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/StatusBarStartableKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/StatusBarStartableKosmos.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.scene.domain.startable
import android.content.applicationContext
@@ -33,7 +31,6 @@ import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.user.domain.interactor.selectedUserInteractor
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.statusBarStartable by Fixture {
StatusBarStartable(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeControllerKosmos.kt
index b9f0c9a70d3d..e2b2026550f1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeControllerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeControllerKosmos.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.shade
import com.android.systemui.assist.AssistManager
@@ -39,7 +37,6 @@ import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.statusbar.policy.deviceProvisionedController
import com.android.systemui.statusbar.window.StatusBarWindowControllerStore
import com.android.systemui.util.mockito.mock
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.shadeControllerSceneImpl by
Kosmos.Fixture {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeTestUtil.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeTestUtil.kt
index b3d89dbb834d..e143324baeae 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeTestUtil.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeTestUtil.kt
@@ -25,7 +25,6 @@ import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.data.repository.FakeShadeRepository
import com.android.systemui.shade.data.repository.ShadeRepository
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.TestScope
@@ -193,7 +192,6 @@ class ShadeTestUtilLegacyImpl(
}
/** Sets up shade state for tests when the scene container flag is enabled. */
-@OptIn(ExperimentalCoroutinesApi::class)
class ShadeTestUtilSceneImpl(
val testScope: TestScope,
val sceneInteractor: SceneInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorKosmos.kt
index 88bf9a5f2d5b..6593547f393d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorKosmos.kt
@@ -27,9 +27,7 @@ import com.android.systemui.statusbar.notificationLockscreenUserManager
import com.android.systemui.statusbar.policy.keyguardStateController
import com.android.systemui.statusbar.policy.sensitiveNotificationProtectionController
import com.android.systemui.user.domain.interactor.selectedUserInteractor
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@OptIn(ExperimentalCoroutinesApi::class)
var Kosmos.sensitiveContentCoordinator: SensitiveContentCoordinator by
Kosmos.Fixture {
SensitiveContentCoordinatorImpl(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorKosmos.kt
index 774782cc019c..dc7595f7f2e4 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorKosmos.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.statusbar.notification.icon.domain.interactor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
@@ -27,7 +25,6 @@ import com.android.systemui.statusbar.notification.data.repository.notifications
import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
import com.android.systemui.statusbar.notification.domain.interactor.headsUpNotificationIconInteractor
import com.android.wm.shell.bubbles.bubblesOptional
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.alwaysOnDisplayNotificationIconsInteractor by Fixture {
AlwaysOnDisplayNotificationIconsInteractor(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/AmbientStateKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/AmbientStateKosmos.kt
index 65f4ec1c437c..d65a4a0532e3 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/AmbientStateKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/AmbientStateKosmos.kt
@@ -23,9 +23,7 @@ import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.shade.transition.largeScreenShadeInterpolator
import com.android.systemui.statusbar.notification.headsup.mockAvalancheController
import com.android.systemui.statusbar.phone.statusBarKeyguardViewManager
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@OptIn(ExperimentalCoroutinesApi::class)
val Kosmos.ambientState by Fixture {
AmbientState(
/*context=*/ applicationContext,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorKosmos.kt
index b1e9d89dfd42..e250575ad3fc 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorKosmos.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.statusbar.notification.stack.domain.interactor
import android.content.applicationContext
@@ -25,7 +23,6 @@ import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.shade.largeScreenHeaderHelper
import com.android.systemui.statusbar.policy.splitShadeStateController
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.sharedNotificationContainerInteractor by
Kosmos.Fixture {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
index 8461da77796d..45c56ae0ab7a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
@@ -60,9 +60,7 @@ import com.android.systemui.statusbar.notification.stack.domain.interactor.notif
import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
import com.android.systemui.unfold.domain.interactor.unfoldTransitionInteractor
import com.android.systemui.window.ui.viewmodel.fakeBouncerTransitions
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@OptIn(ExperimentalCoroutinesApi::class)
val Kosmos.sharedNotificationContainerViewModel by Fixture {
SharedNotificationContainerViewModel(
interactor = sharedNotificationContainerInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/BiometricUnlockController.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/BiometricUnlockController.kt
index f377e28bb51a..c87a20e660a1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/BiometricUnlockController.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/BiometricUnlockController.kt
@@ -14,14 +14,11 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.statusbar.phone
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.util.mockito.mock
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.biometricUnlockController: BiometricUnlockController by Fixture {
mock<BiometricUnlockController>()
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/DozeServiceHostKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/DozeServiceHostKosmos.kt
index d0bf584d9a62..78140416cb40 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/DozeServiceHostKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/DozeServiceHostKosmos.kt
@@ -31,9 +31,7 @@ import com.android.systemui.statusbar.notificationShadeWindowController
import com.android.systemui.statusbar.policy.batteryController
import com.android.systemui.statusbar.policy.deviceProvisionedController
import com.android.systemui.statusbar.pulseExpansionHandler
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@OptIn(ExperimentalCoroutinesApi::class)
val Kosmos.dozeServiceHost: DozeServiceHost by
Kosmos.Fixture {
DozeServiceHost(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ManagedProfileControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ManagedProfileControllerKosmos.kt
index ef04b9d907f1..7c8ad12ccf0d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ManagedProfileControllerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ManagedProfileControllerKosmos.kt
@@ -14,14 +14,11 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.statusbar.phone
import android.testing.LeakCheck
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.utils.leaks.FakeManagedProfileController
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.fakeManagedProfileController by Fixture { FakeManagedProfileController(LeakCheck()) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerKosmos.kt
index ddce4c896c14..4e15ea2d9377 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerKosmos.kt
@@ -18,7 +18,5 @@ package com.android.systemui.statusbar.phone
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.util.mockito.mock
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@OptIn(ExperimentalCoroutinesApi::class)
var Kosmos.statusBarKeyguardViewManager by Kosmos.Fixture { mock<StatusBarKeyguardViewManager>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterKosmos.kt
index 7743a1c7e0cd..0d6ac4481742 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterKosmos.kt
@@ -47,9 +47,7 @@ import com.android.systemui.statusbar.notificationShadeWindowController
import com.android.systemui.statusbar.policy.keyguardStateController
import com.android.systemui.wmshell.bubblesManager
import java.util.Optional
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@OptIn(ExperimentalCoroutinesApi::class)
val Kosmos.statusBarNotificationActivityStarter by
Kosmos.Fixture {
StatusBarNotificationActivityStarter(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/coroutines/MainDispatcherRule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/util/coroutines/MainDispatcherRule.kt
index 577620347991..a0d9227cc048 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/util/coroutines/MainDispatcherRule.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/coroutines/MainDispatcherRule.kt
@@ -17,7 +17,6 @@
package com.android.systemui.util.coroutines
import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestDispatcher
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.setMain
@@ -28,7 +27,6 @@ import org.junit.runner.Description
* Overrides main dispatcher to passed testDispatcher. You probably want to use it when using
* viewModelScope which has hardcoded main dispatcher.
*/
-@OptIn(ExperimentalCoroutinesApi::class)
class MainDispatcherRule(val testDispatcher: TestDispatcher) : TestWatcher() {
override fun starting(description: Description) {
Dispatchers.setMain(testDispatcher)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/time/FakeSystemClockKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/util/time/FakeSystemClockKosmos.kt
index f3a8b14abab8..703d6ad83eac 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/util/time/FakeSystemClockKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/time/FakeSystemClockKosmos.kt
@@ -20,10 +20,8 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.currentTime
-@OptIn(ExperimentalCoroutinesApi::class)
val Kosmos.systemClock by
Kosmos.Fixture<SystemClock> {
mock {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 70c4c1311fc9..75c629b77700 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -21,8 +21,6 @@ import static android.view.MotionEvent.ACTION_SCROLL;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
-import static com.android.hardware.input.Flags.enableTalkbackAndMagnifierKeyGestures;
-
import android.accessibilityservice.AccessibilityTrace;
import android.annotation.MainThread;
import android.annotation.NonNull;
@@ -758,7 +756,7 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
addFirstEventHandler(Display.DEFAULT_DISPLAY, mMouseKeysInterceptor);
}
- if (enableTalkbackAndMagnifierKeyGestures() && isAnyMagnificationEnabled()) {
+ if (Flags.enableMagnificationKeyboardControl() && isAnyMagnificationEnabled()) {
mMagnificationKeyHandler = new MagnificationKeyHandler(
mAms.getMagnificationController());
addFirstEventHandler(Display.DEFAULT_DISPLAY, mMagnificationKeyHandler);
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationKeyHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationKeyHandler.java
index a65580c82124..f20755328479 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationKeyHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationKeyHandler.java
@@ -20,6 +20,7 @@ import android.view.Display;
import android.view.KeyEvent;
import com.android.server.accessibility.BaseEventStreamTransformation;
+import com.android.server.accessibility.Flags;
/*
* A class that listens to key presses used to control magnification.
@@ -79,7 +80,7 @@ public class MagnificationKeyHandler extends BaseEventStreamTransformation {
@Override
public void onKeyEvent(KeyEvent event, int policyFlags) {
- if (!com.android.hardware.input.Flags.enableTalkbackAndMagnifierKeyGestures()) {
+ if (!Flags.enableMagnificationKeyboardControl()) {
// Send to the rest of the handlers.
super.onKeyEvent(event, policyFlags);
return;
diff --git a/services/core/Android.bp b/services/core/Android.bp
index bb493370f9fc..420dcfe9cea6 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -143,6 +143,7 @@ java_library_static {
":platform-compat-overrides",
":display-device-config",
":display-layout-config",
+ ":display-topology",
":device-state-config",
"java/com/android/server/EventLogTags.logtags",
"java/com/android/server/am/EventLogTags.logtags",
diff --git a/services/core/java/com/android/server/display/DisplayTopologyStore.java b/services/core/java/com/android/server/display/DisplayTopologyStore.java
new file mode 100644
index 000000000000..2256c11feee8
--- /dev/null
+++ b/services/core/java/com/android/server/display/DisplayTopologyStore.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2025 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.display;
+
+import android.annotation.Nullable;
+import android.hardware.display.DisplayTopology;
+
+/**
+ * Allows to save and restore {@link DisplayTopology}.
+ * See implementation: {@link DisplayTopologyXmlStore}
+ */
+interface DisplayTopologyStore {
+ boolean saveTopology(DisplayTopology topology);
+
+ @Nullable
+ DisplayTopology restoreTopology(DisplayTopology topology);
+
+ void reloadTopologies(int userId);
+}
diff --git a/services/core/java/com/android/server/display/DisplayTopologyXmlStore.java b/services/core/java/com/android/server/display/DisplayTopologyXmlStore.java
new file mode 100644
index 000000000000..b7f31b75f6dc
--- /dev/null
+++ b/services/core/java/com/android/server/display/DisplayTopologyXmlStore.java
@@ -0,0 +1,582 @@
+/*
+ * 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.
+ */
+
+package com.android.server.display;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.INVALID_DISPLAY;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static java.util.Comparator.comparingInt;
+
+import android.annotation.Nullable;
+import android.hardware.display.DisplayTopology;
+import android.os.Environment;
+import android.util.AtomicFile;
+import android.util.AtomicFilePrintWriter;
+import android.util.Slog;
+import android.util.SparseArray;
+
+// automatically generated classes from display-topology.xsd
+import com.android.server.display.topology.Children;
+import com.android.server.display.topology.Display;
+import com.android.server.display.topology.DisplayTopologyState;
+import com.android.server.display.topology.Position;
+import com.android.server.display.topology.Topology;
+import com.android.server.display.topology.XmlParser;
+import com.android.server.display.topology.XmlWriter;
+import com.android.server.display.utils.DebugUtils;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.datatype.DatatypeConfigurationException;
+
+/**
+ * Saves and restores {@link DisplayTopology} to/from xml files with topologies for each
+ * {@link DisplayTopologyXmlStore#mUserId} user.
+ */
+class DisplayTopologyXmlStore implements DisplayTopologyStore {
+ private static final String TAG = "DisplayManager.DisplayTopologyXmlStore";
+ private static final String ETC_DIR = "etc";
+ private static final String DISPLAY_CONFIG_DIR = "displayconfig";
+
+ // To enable these logs, run:
+ // adb shell setprop persist.log.tag.DisplayManager.DisplayTopologyXmlStore DEBUG
+ // adb reboot
+ private static final boolean DEBUG = DebugUtils.isDebuggable(TAG);
+
+ private static final int PERSISTENT_TOPOLOGY_VERSION = 1;
+ /**
+ * {@link #restoreTopology} needs to reorder topologies to keep the most recently used
+ * topologies order close to 0. In case current topology displays change often, the persistence
+ * of the reordered topologies can become a performance issue. To avoid persistence for small
+ * changes in the order values lets use this constant, serving as the threshold when
+ * to trigger persistence during {@link #restoreTopology}.
+ */
+ private static final int MIN_REORDER_WHICH_TRIGGERS_PERSISTENCE = 10;
+ private static final int MAX_NUMBER_OF_TOPOLOGIES = 100;
+
+ static File getUserTopologyFile(int userId) {
+ return new File(Environment.getDataSystemCeDirectory(userId), "display_topology.xml");
+ }
+
+ private static File getVendorTopologyFile() {
+ return Environment.buildPath(Environment.getVendorDirectory(),
+ ETC_DIR, DISPLAY_CONFIG_DIR, "display_topology.xml");
+ }
+
+ private static File getProductTopologyFile() {
+ return Environment.buildPath(Environment.getProductDirectory(),
+ ETC_DIR, DISPLAY_CONFIG_DIR, "display_topology.xml");
+ }
+
+ private static List<Topology> readTopologiesFromInputStream(
+ @Nullable InputStream iStream)
+ throws DatatypeConfigurationException, XmlPullParserException, IOException {
+ if (null == iStream) {
+ if (DEBUG) {
+ Slog.d(TAG, "iStream is null");
+ }
+ return List.of();
+ }
+ // use parser automatically generated from display-topology.xsd
+ var topologyState = XmlParser.read(iStream);
+ if (topologyState.getVersion() > PERSISTENT_TOPOLOGY_VERSION) {
+ Slog.e(TAG, "Topology version=" + topologyState.getVersion()
+ + " is not supported by DisplayTopologyXmlStore version="
+ + PERSISTENT_TOPOLOGY_VERSION);
+ return List.of();
+ }
+ if (DEBUG) {
+ Slog.d(TAG, "readTopologiesFromInputStream: done");
+ }
+
+ var topologyList = topologyState.getTopology();
+ topologyList.sort(comparingInt(Topology::getOrder));
+ return topologyList;
+ }
+
+ private static int getOrderOrDefault(@Nullable Topology topology, int defaultOrder) {
+ return null != topology ? topology.getOrder() : defaultOrder;
+ }
+
+ private final Injector mInjector;
+ private int mUserId = -1;
+ private final List<Topology> mImmutableTopologies = new ArrayList<>();
+ private final Map<String, Topology> mTopologies = new HashMap<>();
+
+ DisplayTopologyXmlStore(Injector injector) {
+ mInjector = injector;
+ reloadImmutableTopologies();
+ }
+
+ /**
+ * Persists the topology into XML
+ * @param topology the topology to persist
+ * @return true if persisted successfully, false otherwise
+ */
+ @Override
+ public boolean saveTopology(DisplayTopology topology) {
+ String topologyId = getTopologyId(topology);
+ if (DEBUG) {
+ Slog.d(TAG, "saveTopology userId=" + mUserId + ", topologyId=" + topologyId);
+ }
+ if (null == topologyId) {
+ Slog.w(TAG, "saveTopology cancelled: topology id is null for " + topology);
+ return false;
+ }
+
+ Topology topologyToPersist = convertTopologyForPersistence(topology, topologyId);
+ if (null == topologyToPersist) {
+ Slog.w(TAG, "saveTopology cancelled: can't convert topology " + topology);
+ return false;
+ }
+
+ if (!prependTopology(topologyToPersist)) {
+ Slog.w(TAG, "saveTopology cancelled: can't prependTopology");
+ return false;
+ }
+ saveTopologiesToFile();
+ return true;
+ }
+
+ /**
+ * Searches for the topology's id in the store. If topology is found in the store,
+ * then uses the passed topology display width and height, and the persisted topology
+ * structure, position and offset.
+ * @param topology original topology which we would like to restore to a state which was
+ * previously persisted, keeping the current width and height.
+ * @return null if topology is not found, or the new restored topology otherwise.
+ */
+ @Nullable
+ @Override
+ public DisplayTopology restoreTopology(DisplayTopology topology) {
+ String topologyId = getTopologyId(topology);
+ if (DEBUG) {
+ Slog.d(TAG, "restoreTopology userId=" + mUserId + ", topologyId=" + topologyId);
+ }
+ if (null == topologyId) {
+ Slog.w(TAG, "restoreTopology cancelled: topology id is null for " + topology);
+ return null;
+ }
+
+ Topology restoredTopology = mTopologies.get(topologyId);
+ if (null == restoredTopology) {
+ // Topology is not found in persistent storage.
+ if (DEBUG) {
+ Slog.d(TAG, "restoreTopology userId=" + mUserId + ", topologyId=" + topologyId
+ + " is not found");
+ }
+ return null;
+ }
+
+ // Reorder and save to file for significant changes in topologies order.
+ if (restoredTopology.getOrder() >= MIN_REORDER_WHICH_TRIGGERS_PERSISTENCE) {
+ moveTopologyToHead(restoredTopology);
+ saveTopologiesToFile();
+ }
+ return convertPersistentTopologyToDisplayTopology(topology, restoredTopology.getDisplay(),
+ mInjector.getUniqueIdToDisplayIdMapping());
+ }
+
+ @Override
+ public void reloadTopologies(int userId) {
+ if (DEBUG) {
+ Slog.d(TAG, "reloadTopologies mUserId=" + mUserId + "->userId=" + userId);
+ }
+ if (mUserId != userId) {
+ mUserId = userId;
+ resetTopologies();
+ }
+ reloadTopologies();
+ }
+
+ private void resetTopologies() {
+ mTopologies.clear();
+ appendTopologies(mImmutableTopologies);
+ }
+
+ /**
+ * Increases all orders by 1 for those topologies currently below the order of the
+ * passed topology. Sets the order of the passed topology to 0.
+ */
+ private void moveTopologyToHead(Topology topology) {
+ if (topology.getOrder() == 0) {
+ return;
+ }
+ for (var t : mTopologies.values()) {
+ if (t.getOrder() < topology.getOrder()) {
+ t.setOrder(t.getOrder() + 1);
+ }
+ }
+ topology.setOrder(0);
+ }
+
+ private void reloadImmutableTopologies() {
+ mImmutableTopologies.clear();
+ try (InputStream iStream = mInjector.readProductTopologies()) {
+ mImmutableTopologies.addAll(readTopologiesFromInputStream(iStream));
+ } catch (IOException | XmlPullParserException | DatatypeConfigurationException e) {
+ Slog.e(TAG, "reloadImmutableTopologies for product topologies failed", e);
+ }
+ try (InputStream iStream = mInjector.readVendorTopologies()) {
+ mImmutableTopologies.addAll(readTopologiesFromInputStream(iStream));
+ } catch (IOException | XmlPullParserException | DatatypeConfigurationException e) {
+ Slog.e(TAG, "reloadImmutableTopologies for vendor topologies failed", e);
+ }
+ for (var topology : mImmutableTopologies) {
+ topology.setImmutable(true);
+ }
+ }
+
+ private void reloadTopologies() {
+ if (mUserId < 0) {
+ Slog.e(TAG, "Can't reload topologies for userId=" + mUserId);
+ return;
+ }
+ try (InputStream iStream = mInjector.readUserTopologies(mUserId)) {
+ appendTopologies(readTopologiesFromInputStream(iStream));
+ } catch (IOException | XmlPullParserException | DatatypeConfigurationException e) {
+ Slog.e(TAG, "reloadTopologies failed", e);
+ }
+ }
+
+ private void appendTopologies(List<Topology> topologyList) {
+ for (var topology : topologyList) {
+ appendTopology(topology);
+ }
+ }
+
+ private void appendTopology(Topology topology) {
+ Topology restoredTopology = mTopologies.get(topology.getId());
+ if (null != restoredTopology && restoredTopology.getImmutable()) {
+ Slog.w(TAG, "addTopology: can't override immutable topology "
+ + topology.getId());
+ return;
+ }
+
+ // If topology is not found, and we exceed the limit of topologies
+ // (so we can't add more topologies), then skip this topology
+ if (null == restoredTopology && mTopologies.size() >= MAX_NUMBER_OF_TOPOLOGIES) {
+ if (DEBUG) {
+ Slog.d(TAG, "appendTopology: MAX_NUMBER_OF_TOPOLOGIES is reached,"
+ + " can't append topology" + topology.getId());
+ }
+ return;
+ }
+ topology.setOrder(getOrderOrDefault(restoredTopology, mTopologies.size()));
+ mTopologies.put(topology.getId(), topology);
+ }
+
+ private boolean prependTopology(Topology topology) {
+ Topology restoredTopology = mTopologies.get(topology.getId());
+ if (null != restoredTopology && restoredTopology.getImmutable()) {
+ Slog.w(TAG, "prependTopology: can't override immutable topology "
+ + topology.getId());
+ return false;
+ }
+
+ // If topology is not found, and we exceed the limit of topologies
+ // remove the max order mutable topology.
+ if (null == restoredTopology && mTopologies.size() >= MAX_NUMBER_OF_TOPOLOGIES) {
+ Topology topologyToRemove = findMaxOrderMutableTopology();
+ if (topologyToRemove == null) {
+ Slog.w(TAG, "prependTopology: can't find a topology to remove to free up space");
+ return false;
+ }
+ mTopologies.remove(topologyToRemove.getId());
+ if (DEBUG) {
+ Slog.d(TAG, "prependTopology: remove topology " + topologyToRemove.getId());
+ }
+ }
+
+ topology.setOrder(Integer.MAX_VALUE);
+ moveTopologyToHead(topology);
+ mTopologies.put(topology.getId(), topology);
+ return true;
+ }
+
+ /**
+ * Higher order of the topology means lower priority.
+ */
+ @Nullable
+ private Topology findMaxOrderMutableTopology() {
+ Topology res = null;
+ for (var topology : mTopologies.values()) {
+ if (topology.getImmutable()) {
+ continue;
+ }
+ if (res == null || res.getOrder() < topology.getOrder()) {
+ res = topology;
+ }
+ }
+ return res;
+ }
+
+ private void saveTopologiesToFile() {
+ if (mUserId < 0) {
+ Slog.e(TAG, "Can't save topologies for userId=" + mUserId);
+ return;
+ }
+ if (mTopologies.isEmpty()) {
+ if (DEBUG) {
+ Slog.d(TAG, "No topologies to save for userId=" + mUserId);
+ }
+ return;
+ }
+ var topologyState = new DisplayTopologyState();
+ topologyState.setVersion(PERSISTENT_TOPOLOGY_VERSION);
+ for (var topology : mTopologies.values()) {
+ if (!topology.getImmutable()) {
+ topologyState.getTopology().add(topology);
+ }
+ }
+
+ try (var pw = mInjector.getTopologyFilePrintWriter(mUserId)) {
+ // use writer automatically generated from display-topology.xsd
+ XmlWriter.write(new XmlWriter(pw), topologyState);
+ pw.markSuccess();
+ if (DEBUG) Slog.d(TAG, "saveTopologiesToFile " + pw);
+ } catch (IOException e) {
+ Slog.e(TAG, "saveTopologiesToFile failed", e);
+ }
+ }
+
+ private DisplayTopology convertPersistentTopologyToDisplayTopology(
+ DisplayTopology currentDisplayTopology,
+ Display persistentDisplayTopology,
+ Map<String, Integer> uniqueIdToDisplayIdMapping) {
+ var rootNode = convertPersistentDisplayToTreeNode(persistentDisplayTopology,
+ currentDisplayTopology, uniqueIdToDisplayIdMapping);
+ int primaryDisplayId = findPrimaryDisplayId(persistentDisplayTopology,
+ uniqueIdToDisplayIdMapping);
+ if (primaryDisplayId == INVALID_DISPLAY) {
+ Slog.e(TAG, "Primary display id is not found in persistent topology");
+ primaryDisplayId = DEFAULT_DISPLAY;
+ }
+ return new DisplayTopology(rootNode, primaryDisplayId);
+ }
+
+ private DisplayTopology.TreeNode convertPersistentDisplayToTreeNode(
+ Display persistentDisplay,
+ DisplayTopology currentDisplayTopology,
+ Map<String, Integer> uniqueIdToDisplayIdMapping
+ ) {
+ Integer displayId = uniqueIdToDisplayIdMapping.get(persistentDisplay.getId());
+ if (null == displayId) {
+ throw new IllegalStateException("Can't map uniqueId="
+ + persistentDisplay.getId() + " to displayId");
+ }
+
+ var displayNode = DisplayTopology.findDisplay(displayId,
+ currentDisplayTopology.getRoot());
+ if (null == displayNode) {
+ throw new IllegalStateException("Can't find displayId="
+ + displayId + " in current topology");
+ }
+
+ List<DisplayTopology.TreeNode> children = new ArrayList<>();
+ for (var child : persistentDisplay.getChildren().getDisplay()) {
+ children.add(convertPersistentDisplayToTreeNode(child, currentDisplayTopology,
+ uniqueIdToDisplayIdMapping));
+ }
+
+ return new DisplayTopology.TreeNode(
+ displayId, displayNode.getWidth(), displayNode.getHeight(),
+ toDisplayTopologyPosition(persistentDisplay.getPosition()),
+ persistentDisplay.getOffset(), children);
+ }
+
+ private int findPrimaryDisplayId(Display persistentDisplay,
+ Map<String, Integer> uniqueIdToDisplayIdMapping) {
+ if (persistentDisplay.getPrimary()) {
+ var displayId = uniqueIdToDisplayIdMapping.get(persistentDisplay.getId());
+ if (null == displayId) {
+ throw new IllegalStateException("Can't map uniqueId="
+ + persistentDisplay.getId() + " to displayId");
+ }
+ return displayId;
+ }
+ for (var child : persistentDisplay.getChildren().getDisplay()) {
+ var displayId = findPrimaryDisplayId(child, uniqueIdToDisplayIdMapping);
+ if (displayId != INVALID_DISPLAY) {
+ return displayId;
+ }
+ }
+ return INVALID_DISPLAY;
+ }
+
+ @Nullable
+ private Topology convertTopologyForPersistence(DisplayTopology topology, String topologyId) {
+ var rootNode = convertTreeNodeForPersistence(topology.getRoot(),
+ topology.getPrimaryDisplayId(), mInjector.getDisplayIdToUniqueIdMapping());
+ if (null == rootNode) {
+ return null;
+ }
+
+ Topology persistentTopology = new Topology();
+ persistentTopology.setDisplay(rootNode);
+ persistentTopology.setId(topologyId);
+ return persistentTopology;
+ }
+
+ @Nullable
+ private Display convertTreeNodeForPersistence(
+ @Nullable DisplayTopology.TreeNode node,
+ int primaryDisplayId,
+ SparseArray<String> idsToUniqueIds) {
+ if (null == node) {
+ Slog.e(TAG, "Can't convertTreeNodeForPersistence, node == null");
+ return null;
+ }
+ var uniqueId = idsToUniqueIds.get(node.getDisplayId());
+ if (null == uniqueId) {
+ Slog.e(TAG, "Can't convertTreeNodeForPersistence,"
+ + " uniqueId is not found for " + node.getDisplayId());
+ return null;
+ }
+ Children children = new Children();
+ for (var child : node.getChildren()) {
+ var display = convertTreeNodeForPersistence(child, primaryDisplayId, idsToUniqueIds);
+ if (null == display) {
+ return null;
+ }
+ children.getDisplay().add(display);
+ }
+ var root = new Display();
+ root.setPosition(toPersistentPosition(node.getPosition()));
+ root.setId(uniqueId);
+ root.setOffset(node.getOffset());
+ root.setPrimary(node.getDisplayId() == primaryDisplayId);
+ root.setChildren(children);
+ return root;
+ }
+
+ private Position toPersistentPosition(@DisplayTopology.TreeNode.Position int pos) {
+ return switch (pos) {
+ case DisplayTopology.TreeNode.POSITION_LEFT -> Position.left;
+ case DisplayTopology.TreeNode.POSITION_TOP -> Position.top;
+ case DisplayTopology.TreeNode.POSITION_RIGHT -> Position.right;
+ case DisplayTopology.TreeNode.POSITION_BOTTOM -> Position.bottom;
+ default -> throw new IllegalArgumentException("Unknown position=" + pos);
+ };
+ }
+
+ @DisplayTopology.TreeNode.Position
+ private int toDisplayTopologyPosition(Position pos) {
+ return switch (pos) {
+ case left -> DisplayTopology.TreeNode.POSITION_LEFT;
+ case top -> DisplayTopology.TreeNode.POSITION_TOP;
+ case right -> DisplayTopology.TreeNode.POSITION_RIGHT;
+ case bottom -> DisplayTopology.TreeNode.POSITION_BOTTOM;
+ };
+ }
+
+ private List<String> getUniqueIds(@Nullable DisplayTopology.TreeNode node,
+ SparseArray<String> mapping, List<String> uniqueIds) {
+ if (null == node) {
+ return uniqueIds;
+ }
+ uniqueIds.add(mapping.get(node.getDisplayId()));
+ for (var child : node.getChildren()) {
+ getUniqueIds(child, mapping, uniqueIds);
+ }
+ return uniqueIds;
+ }
+
+ @Nullable
+ private String getTopologyId(DisplayTopology topology) {
+ SparseArray<String> mapping = mInjector.getDisplayIdToUniqueIdMapping();
+ return getTopologyId(getUniqueIds(topology.getRoot(), mapping, new ArrayList<>()));
+ }
+
+ @Nullable
+ private String getTopologyId(List<String> uniqueIds) {
+ if (uniqueIds.isEmpty() || uniqueIds.contains(null)) {
+ return null;
+ }
+ Collections.sort(uniqueIds);
+ return String.join("|", uniqueIds);
+ }
+
+ abstract static class Injector {
+ /**
+ * Necessary mapping for conversion of {@link DisplayTopology} which uses
+ * {@link android.view.DisplayInfo#displayId} to {@link DisplayTopologyState}
+ * which uses {@link android.view.DisplayInfo#uniqueId}
+ *
+ * @return mapping from {@link android.view.DisplayInfo#displayId}
+ * to {@link android.view.DisplayInfo#uniqueId}
+ */
+ public abstract SparseArray<String> getDisplayIdToUniqueIdMapping();
+
+ /**
+ * Necessary mapping for conversion opposite to {@link #getDisplayIdToUniqueIdMapping()}
+ *
+ * @return mapping from {@link android.view.DisplayInfo#uniqueId}
+ * to {@link android.view.DisplayInfo#displayId}
+ */
+ public abstract Map<String, Integer> getUniqueIdToDisplayIdMapping();
+
+ /**
+ * Reads vendor topologies, if configured.
+ * @return input stream with vendor-defined topologies, or null if not configured.
+ */
+ @Nullable
+ public InputStream readVendorTopologies() throws FileNotFoundException {
+ return getFileInputStream(getVendorTopologyFile());
+ }
+
+ /**
+ * Reads product topologies, if configured.
+ * @return input stream with product-defined topologies, or null if not configured.
+ */
+ @Nullable
+ public InputStream readProductTopologies() throws FileNotFoundException {
+ return getFileInputStream(getProductTopologyFile());
+ }
+
+ @Nullable
+ InputStream readUserTopologies(int userId) throws FileNotFoundException {
+ return getFileInputStream(getUserTopologyFile(userId));
+ }
+
+ AtomicFilePrintWriter getTopologyFilePrintWriter(int userId) throws IOException {
+ var atomicFile = new AtomicFile(getUserTopologyFile(userId),
+ /*commitTag=*/ "topology-state");
+ return new AtomicFilePrintWriter(atomicFile, UTF_8);
+ }
+
+ @Nullable
+ private FileInputStream getFileInputStream(File file) throws FileNotFoundException {
+ if (DEBUG) {
+ Slog.d(TAG, "File: " + file + " exists=" + file.exists());
+ }
+ return !file.exists() ? null : new FileInputStream(file);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/SnapshotPersistQueue.java b/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
index 5e1d7928e96d..eafc8be7bf77 100644
--- a/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
+++ b/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
@@ -319,7 +319,13 @@ class SnapshotPersistQueue {
@Override
void onQueuedLocked() {
// Remove duplicate request.
- mStoreQueueItems.remove(this);
+ mStoreQueueItems.removeIf(item -> {
+ if (item.equals(this) && item.mSnapshot != mSnapshot) {
+ item.mSnapshot.removeReference(TaskSnapshot.REFERENCE_PERSIST);
+ return true;
+ }
+ return false;
+ });
mStoreQueueItems.offer(this);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 8410f9f313be..5de0e9b6ed93 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4309,7 +4309,8 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- boolean getIgnoreOrientationRequest(int displayId) {
+ @Override
+ public boolean getIgnoreOrientationRequest(int displayId) {
synchronized (mGlobalLock) {
final DisplayContent display = mRoot.getDisplayContent(displayId);
if (display == null) {
diff --git a/services/core/jni/com_android_server_vibrator_VibratorController.cpp b/services/core/jni/com_android_server_vibrator_VibratorController.cpp
index 0ecc0a8a9524..abd4cd25cf68 100644
--- a/services/core/jni/com_android_server_vibrator_VibratorController.cpp
+++ b/services/core/jni/com_android_server_vibrator_VibratorController.cpp
@@ -435,8 +435,8 @@ static jlong vibratorPerformPwleV2Effect(JNIEnv* env, jclass /* clazz */, jlong
auto composePwleV2Fn = [&composite, &callback](vibrator::HalWrapper* hal) {
return hal->composePwleV2(composite, callback);
};
- auto result = wrapper->halCall<void>(composePwleV2Fn, "composePwleV2");
- return result.isOk();
+ auto result = wrapper->halCall<std::chrono::milliseconds>(composePwleV2Fn, "composePwleV2");
+ return result.isOk() ? result.value().count() : (result.isUnsupported() ? 0 : -1);
}
static void vibratorAlwaysOnEnable(JNIEnv* env, jclass /* clazz */, jlong ptr, jlong id,
diff --git a/services/core/xsd/Android.bp b/services/core/xsd/Android.bp
index 6a50d3834355..8b7bdf5cece2 100644
--- a/services/core/xsd/Android.bp
+++ b/services/core/xsd/Android.bp
@@ -30,6 +30,14 @@ xsd_config {
}
xsd_config {
+ name: "display-topology",
+ srcs: ["display-topology/display-topology.xsd"],
+ api_dir: "display-topology/schema",
+ package_name: "com.android.server.display.topology",
+ gen_writer: true,
+}
+
+xsd_config {
name: "display-device-config",
srcs: ["display-device-config/display-device-config.xsd"],
api_dir: "display-device-config/schema",
diff --git a/services/core/xsd/display-topology/OWNERS b/services/core/xsd/display-topology/OWNERS
new file mode 100644
index 000000000000..6ce1ee4d3de2
--- /dev/null
+++ b/services/core/xsd/display-topology/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/display/OWNERS
diff --git a/services/core/xsd/display-topology/display-topology.xsd b/services/core/xsd/display-topology/display-topology.xsd
new file mode 100644
index 000000000000..00f766fe018c
--- /dev/null
+++ b/services/core/xsd/display-topology/display-topology.xsd
@@ -0,0 +1,65 @@
+<?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.
+-->
+
+<!--
+ This defines the format of the XML file used to define how displays are arranged
+ in topologies.
+ It is parsed in com/android/server/display/PersistentTopologyStore.java
+ More information on display topology can be found in DisplayTopology.java
+-->
+<xs:schema version="2.0"
+ elementFormDefault="qualified"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:simpleType name="position">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="left"/>
+ <xs:enumeration value="top"/>
+ <xs:enumeration value="right"/>
+ <xs:enumeration value="bottom"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:complexType name="children">
+ <xs:sequence>
+ <xs:element type="display" name="display" maxOccurs="unbounded" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="display">
+ <xs:sequence>
+ <xs:element type="position" name="position" />
+ <xs:element type="xs:float" name="offset"/>
+ <xs:element type="children" name="children" />
+ </xs:sequence>
+ <xs:attribute type="xs:string" name="id" use="required"/>
+ <xs:attribute type="xs:boolean" name="primary"/>
+ </xs:complexType>
+ <xs:complexType name="topology">
+ <xs:sequence>
+ <xs:element type="display" name="display"/>
+ </xs:sequence>
+ <xs:attribute type="xs:string" name="id" use="required"/>
+ <xs:attribute type="xs:int" name="order" use="required"/>
+ <xs:attribute type="xs:boolean" name="immutable"/>
+ </xs:complexType>
+ <xs:element name="displayTopologyState">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element type="topology" name="topology" maxOccurs="1000" minOccurs="0"/>
+ </xs:sequence>
+ <xs:attribute type="xs:int" name="version" use="required"/>
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
diff --git a/services/core/xsd/display-topology/schema/current.txt b/services/core/xsd/display-topology/schema/current.txt
new file mode 100644
index 000000000000..eb59e9ec5f7b
--- /dev/null
+++ b/services/core/xsd/display-topology/schema/current.txt
@@ -0,0 +1,64 @@
+// Signature format: 2.0
+package com.android.server.display.topology {
+
+ public class Children {
+ ctor public Children();
+ method public java.util.List<com.android.server.display.topology.Display> getDisplay();
+ }
+
+ public class Display {
+ ctor public Display();
+ method public com.android.server.display.topology.Children getChildren();
+ method public String getId();
+ method public float getOffset();
+ method public com.android.server.display.topology.Position getPosition();
+ method public boolean getPrimary();
+ method public void setChildren(com.android.server.display.topology.Children);
+ method public void setId(String);
+ method public void setOffset(float);
+ method public void setPosition(com.android.server.display.topology.Position);
+ method public void setPrimary(boolean);
+ }
+
+ public class DisplayTopologyState {
+ ctor public DisplayTopologyState();
+ method public java.util.List<com.android.server.display.topology.Topology> getTopology();
+ method public int getVersion();
+ method public void setVersion(int);
+ }
+
+ public enum Position {
+ method public String getRawName();
+ enum_constant public static final com.android.server.display.topology.Position bottom;
+ enum_constant public static final com.android.server.display.topology.Position left;
+ enum_constant public static final com.android.server.display.topology.Position right;
+ enum_constant public static final com.android.server.display.topology.Position top;
+ }
+
+ public class Topology {
+ ctor public Topology();
+ method public com.android.server.display.topology.Display getDisplay();
+ method public String getId();
+ method public boolean getImmutable();
+ method public int getOrder();
+ method public void setDisplay(com.android.server.display.topology.Display);
+ method public void setId(String);
+ method public void setImmutable(boolean);
+ method public void setOrder(int);
+ }
+
+ public class XmlParser {
+ ctor public XmlParser();
+ method public static com.android.server.display.topology.DisplayTopologyState read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ }
+
+ public class XmlWriter implements java.io.Closeable {
+ ctor public XmlWriter(java.io.PrintWriter);
+ method public void close();
+ method public static void write(com.android.server.display.topology.XmlWriter, com.android.server.display.topology.DisplayTopologyState) throws java.io.IOException;
+ }
+
+}
+
diff --git a/services/core/xsd/display-topology/schema/last_current.txt b/services/core/xsd/display-topology/schema/last_current.txt
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/services/core/xsd/display-topology/schema/last_current.txt
diff --git a/services/core/xsd/display-topology/schema/last_removed.txt b/services/core/xsd/display-topology/schema/last_removed.txt
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/services/core/xsd/display-topology/schema/last_removed.txt
diff --git a/services/core/xsd/display-topology/schema/removed.txt b/services/core/xsd/display-topology/schema/removed.txt
new file mode 100644
index 000000000000..d802177e249b
--- /dev/null
+++ b/services/core/xsd/display-topology/schema/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayTopologyXmlStoreTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayTopologyXmlStoreTest.java
new file mode 100644
index 000000000000..48822821ba01
--- /dev/null
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayTopologyXmlStoreTest.java
@@ -0,0 +1,388 @@
+/*
+ * Copyright 2025 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.display;
+
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import android.graphics.PointF;
+import android.hardware.display.DisplayTopology;
+import android.util.AtomicFilePrintWriter;
+import android.util.SparseArray;
+
+import androidx.test.filters.SmallTest;
+
+import com.google.common.io.CharSource;
+import com.google.testing.junit.testparameterinjector.TestParameterInjector;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Tests for {@link DisplayTopologyXmlStore}
+ * Run: atest PersistentTopologyStoreTest
+ */
+@SmallTest
+@RunWith(TestParameterInjector.class)
+public class DisplayTopologyXmlStoreTest {
+ private static final String NO_TOPOLOGIES = """
+ <?xml version="1.0" encoding="utf-8"?>
+ <displayTopologyState version="1"/>
+ """;
+
+ private static final String SIMPLE_TOPOLOGY = """
+ <?xml version="1.0" encoding="utf-8"?>
+ <displayTopologyState version="1">
+ <topology id="uniqueid0|uniqueid1" order="0">
+ <display id="uniqueid0" primary="true">
+ <position>left</position>
+ <offset>0.0</offset>
+ <children>
+ <display id="uniqueid1" primary="false">
+ <position>top</position>
+ <offset>-560.0</offset>
+ <children>
+ </children>
+ </display>
+ </children>
+ </display>
+ </topology>
+ </displayTopologyState>
+ """;
+
+ private static final String IMMUTABLE_TOPOLOGY = """
+ <?xml version="1.0" encoding="utf-8"?>
+ <displayTopologyState version="1">
+ <topology id="uniqueid10|uniqueid11" order="0" immutable="true">
+ <display id="uniqueid10" primary="true">
+ <position>left</position>
+ <offset>0.0</offset>
+ <children>
+ <display id="uniqueid11" primary="false">
+ <position>top</position>
+ <offset>-560.0</offset>
+ <children>
+ </children>
+ </display>
+ </children>
+ </display>
+ </topology>
+ </displayTopologyState>
+ """;
+
+ private static final String MULTIPLE_TOPOLOGIES = """
+ <?xml version="1.0" encoding="utf-8"?>
+ <displayTopologyState version="1">
+ <topology id="uniqueid0|uniqueid1" order="0">
+ <display id="uniqueid0" primary="true">
+ <position>left</position>
+ <offset>0.0</offset>
+ <children>
+ <display id="uniqueid1" primary="false">
+ <position>top</position>
+ <offset>-560.0</offset>
+ <children>
+ </children>
+ </display>
+ </children>
+ </display>
+ </topology>
+ <topology id="uniqueid0|uniqueid1|uniqueid2|uniqueid3" order="0">
+ <display id="uniqueid1" primary="false">
+ <position>left</position>
+ <offset>0.0</offset>
+ <children>
+ <display id="uniqueid0" primary="false">
+ <position>top</position>
+ <offset>-50</offset>
+ <children>
+ </children>
+ </display>
+ <display id="uniqueid2" primary="true">
+ <position>right</position>
+ <offset>-100</offset>
+ <children>
+ <display id="uniqueid3" primary="false">
+ <position>bottom</position>
+ <offset>-300</offset>
+ <children>
+ </children>
+ </display>
+ </children>
+ </display>
+ </children>
+ </display>
+ </topology>
+ </displayTopologyState>
+ """;
+
+ private static InputStream asInputStream(String value) throws IOException {
+ return CharSource.wrap(value).asByteSource(UTF_8).openStream();
+ }
+
+ private static SparseArray<String> generateIdToUniqueId() {
+ var res = new SparseArray<String>();
+ for (int i = 0; i < 200; i++) {
+ res.put(i, "uniqueid" + i);
+ }
+ return res;
+ }
+
+ private static Map<String, Integer> generateUniqueIdToId() {
+ var res = new HashMap<String, Integer>();
+ for (int i = 0; i < 200; i++) {
+ res.put("uniqueid" + i, i);
+ }
+ return res;
+ }
+
+ private static DisplayTopology generateTopology(int displayId1, int displayId2) {
+ var topology = new DisplayTopology();
+ topology.addDisplay(displayId1, 800f, 600f);
+ topology.addDisplay(displayId2, 1920f, 1080f);
+ return topology;
+ }
+
+ @Mock
+ private DisplayTopologyXmlStore.Injector mInjector;
+ @Mock
+ private AtomicFilePrintWriter mPrintWriter0;
+ @Mock
+ private AtomicFilePrintWriter mPrintWriter1;
+
+ private DisplayTopology mTopology;
+
+ /** Setup tests. */
+ @Before
+ public void setup() throws IOException {
+ MockitoAnnotations.initMocks(this);
+ configureTopologyFile(/*userId=*/ 0, NO_TOPOLOGIES, mPrintWriter0);
+ configureTopologyFile(/*userId=*/ 1, SIMPLE_TOPOLOGY, mPrintWriter1);
+ configureTopologyFile(/*userId=*/ 2, MULTIPLE_TOPOLOGIES, mPrintWriter1);
+
+ when(mInjector.getDisplayIdToUniqueIdMapping()).thenReturn(generateIdToUniqueId());
+ when(mInjector.getUniqueIdToDisplayIdMapping()).thenReturn(generateUniqueIdToId());
+
+ mTopology = generateTopology(0, 1);
+ }
+
+ @Test
+ public void testSaveAndRestoreTopologyWithoutFileStreams() throws IOException {
+ final float initialOffset = -560f;
+ final float newOffset = -300f;
+
+ var store = new DisplayTopologyXmlStore(mInjector);
+ assertThat(store.saveTopology(mTopology)).isTrue();
+ assertThat(mTopology.getRoot().getChildren().getFirst().getOffset())
+ .isEqualTo(initialOffset);
+ assertThat(mTopology.getRoot().getWidth()).isEqualTo(800f);
+ assertThat(mTopology.getRoot().getHeight()).isEqualTo(600f);
+
+ // Change display size
+ assertThat(mTopology.updateDisplay(0, 640f, 480f)).isTrue();
+ assertThat(mTopology.getRoot().getWidth()).isEqualTo(640f);
+ assertThat(mTopology.getRoot().getHeight()).isEqualTo(480f);
+
+ // Move display#1.
+ mTopology.rearrange(Map.of(0, new PointF(0, 0),
+ 1, new PointF(newOffset, -1080f)));
+ assertThat(mTopology.getRoot().getChildren().getFirst().getOffset()).isEqualTo(newOffset);
+
+ // Restore the topology, should apply saved offset, while keeping the current display sizes
+ mTopology = store.restoreTopology(mTopology);
+
+ // Offset is taken from the persisted topology.
+ assertThat(mTopology.getRoot().getChildren().getFirst().getOffset())
+ .isEqualTo(initialOffset);
+
+ // Size is taken from the current topology
+ assertThat(mTopology.getRoot().getWidth()).isEqualTo(640f);
+ assertThat(mTopology.getRoot().getHeight()).isEqualTo(480f);
+
+ // reloadTopologies was never called so, no file operations should have been performed.
+ verify(mInjector, never()).readUserTopologies(anyInt());
+ verify(mInjector, never()).getTopologyFilePrintWriter(anyInt());
+ }
+
+ @Test
+ public void testSaveTopologyInPrintWriter() throws IOException {
+ var store = new DisplayTopologyXmlStore(mInjector);
+ store.reloadTopologies(/*userId=*/ 0);
+ assertThat(store.saveTopology(mTopology)).isTrue();
+ verify(mPrintWriter0).print(eq(SIMPLE_TOPOLOGY));
+ verify(mPrintWriter0).markSuccess();
+ verify(mPrintWriter0).close();
+ }
+
+ @Test
+ public void testRestoreTopology() {
+ var store = new DisplayTopologyXmlStore(mInjector);
+ store.reloadTopologies(/*userId=*/ 0);
+ var restoredTopology = store.restoreTopology(mTopology);
+
+ // Should return null because there was nothing persisted before.
+ assertThat(restoredTopology).isNull();
+
+ // Persist topology
+ assertThat(store.saveTopology(mTopology)).isTrue();
+
+ // Should return new instance (restored), but equal.
+ var restoredTopologyAfterSave = store.restoreTopology(mTopology);
+ assertThat(restoredTopologyAfterSave).isNotSameInstanceAs(mTopology);
+ assertThat(restoredTopologyAfterSave).isEqualTo(mTopology);
+ }
+
+ @Test
+ public void testChangeUser() {
+ var store = new DisplayTopologyXmlStore(mInjector);
+ // Move display#1.
+ mTopology.rearrange(Map.of(0, new PointF(0, 0),
+ 1, new PointF(-10f, -1080f)));
+ assertThat(mTopology.getRoot().getChildren().getFirst().getOffset()).isEqualTo(-10f);
+
+ store.reloadTopologies(/*userId=*/ 1);
+ // Should return new instance (restored), with new offset.
+ var restoredTopology = store.restoreTopology(mTopology);
+ assertThat(restoredTopology).isNotSameInstanceAs(mTopology);
+ assertThat(restoredTopology.getRoot().getChildren().getFirst().getOffset())
+ .isEqualTo(-560f);
+
+ // Change user.
+ store.reloadTopologies(/*userId=*/ 0);
+ // Should return null because the topology is not found for user 0.
+ assertThat(store.restoreTopology(mTopology)).isNull();
+ }
+
+ @Test
+ public void testMultipleUserTopologies() {
+ var store = new DisplayTopologyXmlStore(mInjector);
+ store.reloadTopologies(/*userId=*/ 2);
+
+ var topology4Displays = new DisplayTopology();
+ topology4Displays.addDisplay(0, 800f, 600f);
+ topology4Displays.addDisplay(1, 1920f, 1080f);
+ topology4Displays.addDisplay(2, 480f, 640f);
+ topology4Displays.addDisplay(3, 768f, 1024f);
+
+ var restored = store.restoreTopology(topology4Displays);
+ assertThat(restored).isNotNull();
+ assertThat(restored.getPrimaryDisplayId()).isEqualTo(2);
+ assertThat(restored.getRoot()).isNotNull();
+ assertThat(restored.getRoot().getDisplayId()).isEqualTo(1);
+ assertThat(restored.getRoot().getWidth()).isEqualTo(1920f);
+ assertThat(restored.getRoot().getHeight()).isEqualTo(1080f);
+ assertThat(restored.getRoot().getOffset()).isEqualTo(0);
+ assertThat(restored.getRoot().getChildren().size()).isEqualTo(2);
+ assertThat(restored.getRoot().getChildren().getFirst().getDisplayId()).isEqualTo(0);
+ assertThat(restored.getRoot().getChildren().getFirst().getWidth()).isEqualTo(800f);
+ assertThat(restored.getRoot().getChildren().getFirst().getHeight()).isEqualTo(600f);
+ assertThat(restored.getRoot().getChildren().getFirst().getOffset()).isEqualTo(-50);
+ assertThat(restored.getRoot().getChildren().getFirst().getChildren().size())
+ .isEqualTo(0);
+ assertThat(restored.getRoot().getChildren().getLast().getDisplayId()).isEqualTo(2);
+ assertThat(restored.getRoot().getChildren().getLast().getWidth()).isEqualTo(480f);
+ assertThat(restored.getRoot().getChildren().getLast().getHeight()).isEqualTo(640f);
+ assertThat(restored.getRoot().getChildren().getLast().getOffset()).isEqualTo(-100);
+ assertThat(restored.getRoot().getChildren().getLast().getChildren().size())
+ .isEqualTo(1);
+
+ assertThat(restored.getRoot().getChildren().getLast().getChildren().getFirst()
+ .getDisplayId()).isEqualTo(3);
+ assertThat(restored.getRoot().getChildren().getLast().getChildren().getFirst()
+ .getWidth()).isEqualTo(768f);
+ assertThat(restored.getRoot().getChildren().getLast().getChildren().getFirst()
+ .getHeight()).isEqualTo(1024f);
+ assertThat(restored.getRoot().getChildren().getLast().getChildren().getFirst()
+ .getOffset()).isEqualTo(-300);
+ }
+
+ @Test
+ public void testLimitNumberOfTopologies() {
+ var store = new DisplayTopologyXmlStore(mInjector);
+ store.reloadTopologies(/*userId=*/ 0);
+ for (int i = 0; i < 110; i++) {
+ assertThat(store.saveTopology(generateTopology(i, i + 1))).isTrue();
+ }
+
+ assertThat(store.restoreTopology(generateTopology(110, 111))).isNull();
+ assertThat(store.restoreTopology(generateTopology(109, 110))).isNotNull();
+ assertThat(store.restoreTopology(generateTopology(10, 11))).isNotNull();
+ assertThat(store.restoreTopology(generateTopology(9, 10))).isNull();
+ for (int i = 0; i < 100; i++) {
+ assertThat(store.restoreTopology(generateTopology(i + 10, i + 11))).isNotNull();
+ }
+ }
+
+ @Test
+ public void testVendorTopology() throws IOException {
+ configureVendorTopologyFile(IMMUTABLE_TOPOLOGY);
+ var store = new DisplayTopologyXmlStore(mInjector);
+ store.reloadTopologies(/*userId=*/ 0);
+ var restored = store.restoreTopology(generateTopology(10, 11));
+ assertThat(restored).isNotNull();
+ assertThat(store.saveTopology(restored)).isFalse();
+
+ var userTopology = generateTopology(0, 1);
+ assertThat(store.restoreTopology(userTopology)).isNull();
+ assertThat(store.saveTopology(userTopology)).isTrue();
+ }
+
+ @Test
+ public void testProductTopology() throws IOException {
+ configureProductTopologyFile(IMMUTABLE_TOPOLOGY);
+ var store = new DisplayTopologyXmlStore(mInjector);
+ store.reloadTopologies(/*userId=*/ 0);
+ var restored = store.restoreTopology(generateTopology(10, 11));
+ assertThat(restored).isNotNull();
+ assertThat(store.saveTopology(restored)).isFalse();
+
+ var userTopology = generateTopology(0, 1);
+ assertThat(store.restoreTopology(userTopology)).isNull();
+ assertThat(store.saveTopology(userTopology)).isTrue();
+ }
+
+ private void configureTopologyFile(int userId, String initialFileContent,
+ AtomicFilePrintWriter printWriter) throws IOException {
+ doReturn(asInputStream(initialFileContent)).when(mInjector).readUserTopologies(eq(userId));
+ doReturn(printWriter).when(mInjector).getTopologyFilePrintWriter(eq(userId));
+ }
+
+ private void configureVendorTopologyFile(String initialFileContent) throws IOException {
+ doReturn(asInputStream(initialFileContent)).when(mInjector).readVendorTopologies();
+ }
+
+ private void configureProductTopologyFile(String initialFileContent) throws IOException {
+ doReturn(asInputStream(initialFileContent)).when(mInjector).readProductTopologies();
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java
index fb31cfe762f2..ecc48bfc40e4 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java
@@ -20,13 +20,13 @@ import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
import static android.view.WindowManagerPolicyConstants.FLAG_PASS_TO_USER;
-import static com.android.hardware.input.Flags.FLAG_ENABLE_TALKBACK_AND_MAGNIFIER_KEY_GESTURES;
import static com.android.server.accessibility.AccessibilityInputFilter.FLAG_FEATURE_AUTOCLICK;
import static com.android.server.accessibility.AccessibilityInputFilter.FLAG_FEATURE_CONTROL_SCREEN_MAGNIFIER;
import static com.android.server.accessibility.AccessibilityInputFilter.FLAG_FEATURE_FILTER_KEY_EVENTS;
import static com.android.server.accessibility.AccessibilityInputFilter.FLAG_FEATURE_INJECT_MOTION_EVENTS;
import static com.android.server.accessibility.AccessibilityInputFilter.FLAG_FEATURE_TOUCH_EXPLORATION;
import static com.android.server.accessibility.AccessibilityInputFilter.FLAG_FEATURE_TRIGGERED_SCREEN_MAGNIFIER;
+import static com.android.server.accessibility.Flags.FLAG_ENABLE_MAGNIFICATION_KEYBOARD_CONTROL;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -191,7 +191,7 @@ public class AccessibilityInputFilterTest {
}
@Test
- @RequiresFlagsEnabled(FLAG_ENABLE_TALKBACK_AND_MAGNIFIER_KEY_GESTURES)
+ @RequiresFlagsEnabled(FLAG_ENABLE_MAGNIFICATION_KEYBOARD_CONTROL)
public void testEventHandler_shouldIncreaseAndHaveCorrectOrderAfterOnDisplayAdded() {
prepareLooper();
@@ -248,7 +248,7 @@ public class AccessibilityInputFilterTest {
}
@Test
- @RequiresFlagsEnabled(FLAG_ENABLE_TALKBACK_AND_MAGNIFIER_KEY_GESTURES)
+ @RequiresFlagsEnabled(FLAG_ENABLE_MAGNIFICATION_KEYBOARD_CONTROL)
public void testEventHandler_shouldHaveCorrectOrderForEventStreamTransformation() {
prepareLooper();
@@ -274,7 +274,7 @@ public class AccessibilityInputFilterTest {
}
@Test
- @RequiresFlagsDisabled(FLAG_ENABLE_TALKBACK_AND_MAGNIFIER_KEY_GESTURES)
+ @RequiresFlagsDisabled(FLAG_ENABLE_MAGNIFICATION_KEYBOARD_CONTROL)
public void testEventHandler_shouldHaveCorrectOrderForEventStreamTransformation_noMagKeys() {
prepareLooper();
@@ -455,7 +455,7 @@ public class AccessibilityInputFilterTest {
}
@Test
- @RequiresFlagsEnabled(FLAG_ENABLE_TALKBACK_AND_MAGNIFIER_KEY_GESTURES)
+ @RequiresFlagsEnabled(FLAG_ENABLE_MAGNIFICATION_KEYBOARD_CONTROL)
public void testEnabledFeatures_windowMagnificationMode_expectedMagnificationKeyHandler() {
prepareLooper();
doReturn(Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW).when(
@@ -468,7 +468,7 @@ public class AccessibilityInputFilterTest {
}
@Test
- @RequiresFlagsEnabled(FLAG_ENABLE_TALKBACK_AND_MAGNIFIER_KEY_GESTURES)
+ @RequiresFlagsEnabled(FLAG_ENABLE_MAGNIFICATION_KEYBOARD_CONTROL)
public void testEnabledFeatures_fullscreenMagnificationMode_expectedMagnificationKeyHandler() {
prepareLooper();
doReturn(Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN).when(
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationKeyHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationKeyHandlerTest.java
index d1ef33d8fb70..1c85086e2f42 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationKeyHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationKeyHandlerTest.java
@@ -16,7 +16,7 @@
package com.android.server.accessibility.magnification;
-import static com.android.hardware.input.Flags.FLAG_ENABLE_TALKBACK_AND_MAGNIFIER_KEY_GESTURES;
+import static com.android.server.accessibility.Flags.FLAG_ENABLE_MAGNIFICATION_KEYBOARD_CONTROL;
import static com.android.server.accessibility.magnification.MagnificationController.PAN_DIRECTION_DOWN;
import static com.android.server.accessibility.magnification.MagnificationController.PAN_DIRECTION_LEFT;
import static com.android.server.accessibility.magnification.MagnificationController.PAN_DIRECTION_RIGHT;
@@ -50,7 +50,7 @@ import org.mockito.MockitoAnnotations;
* Tests for {@link MagnificationKeyHandler}.
*/
@RunWith(AndroidJUnit4.class)
-@RequiresFlagsEnabled(FLAG_ENABLE_TALKBACK_AND_MAGNIFIER_KEY_GESTURES)
+@RequiresFlagsEnabled(FLAG_ENABLE_MAGNIFICATION_KEYBOARD_CONTROL)
public class MagnificationKeyHandlerTest {
@Rule
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
index 3b32701b5169..39206dcf21ef 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
@@ -1612,7 +1612,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
);
}
- public void disabled_testThrottling() {
+ public void testThrottling() {
final ShortcutInfo si1 = makeShortcut("shortcut1");
assertTrue(mManager.setDynamicShortcuts(list(si1)));
@@ -1685,7 +1685,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
assertEquals(START_TIME + INTERVAL * 9, mManager.getRateLimitResetTime());
}
- public void disabled_testThrottling_rewind() {
+ public void testThrottling_rewind() {
final ShortcutInfo si1 = makeShortcut("shortcut1");
assertTrue(mManager.setDynamicShortcuts(list(si1)));
@@ -1715,7 +1715,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
assertEquals(3, mManager.getRemainingCallCount());
}
- public void disabled_testThrottling_perPackage() {
+ public void testThrottling_perPackage() {
final ShortcutInfo si1 = makeShortcut("shortcut1");
assertTrue(mManager.setDynamicShortcuts(list(si1)));
@@ -1847,7 +1847,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
});
}
- public void disabled_testThrottling_foreground() throws Exception {
+ public void testThrottling_foreground() throws Exception {
prepareCrossProfileDataSet();
dumpsysOnLogcat("Before save & load");
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java
index 81ebf867fe2d..aad06c6d6c0e 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java
@@ -171,12 +171,11 @@ public class ShortcutManagerTest3 extends BaseShortcutManagerTest {
.haveRanksInOrder("ms1");
}
- public void disabled_testSetDynamicShortcuts_withManifestShortcuts() {
- runTestWithManifestShortcuts(() ->
- disabled_testAddDynamicShortcuts_noManifestShortcuts());
+ public void testSetDynamicShortcuts_withManifestShortcuts() {
+ runTestWithManifestShortcuts(() -> testSetDynamicShortcuts_noManifestShortcuts());
}
- public void disabled_testAddDynamicShortcuts_noManifestShortcuts() {
+ public void testAddDynamicShortcuts_noManifestShortcuts() {
mManager.addDynamicShortcuts(list(
shortcut("s1", A1)
));
@@ -265,8 +264,8 @@ public class ShortcutManagerTest3 extends BaseShortcutManagerTest {
.haveIds("s1", "s2", "s4", "s5", "s10");
}
- public void disabled_testAddDynamicShortcuts_withManifestShortcuts() {
- runTestWithManifestShortcuts(() -> disabled_testAddDynamicShortcuts_noManifestShortcuts());
+ public void testAddDynamicShortcuts_withManifestShortcuts() {
+ runTestWithManifestShortcuts(() -> testAddDynamicShortcuts_noManifestShortcuts());
}
public void testUpdateShortcuts_noManifestShortcuts() {
diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/BottomHalfPipAppHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/BottomHalfPipAppHelper.kt
index fe344c9b79f2..7b8b43af18da 100644
--- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/BottomHalfPipAppHelper.kt
+++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/BottomHalfPipAppHelper.kt
@@ -25,7 +25,7 @@ import com.android.server.wm.flicker.testapp.ActivityOptions.BottomHalfPip
class BottomHalfPipAppHelper(
instrumentation: Instrumentation,
private val useLaunchingActivity: Boolean = false,
- private val fillTaskOnCreate: Boolean = true,
+ private val fillTaskOnCreate: Boolean = false,
) : PipAppHelper(
instrumentation,
appName = BottomHalfPip.LABEL,
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/BottomHalfPipActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/BottomHalfPipActivity.java
index 3bbb94515f69..1f82d674cfa7 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/BottomHalfPipActivity.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/BottomHalfPipActivity.java
@@ -31,7 +31,7 @@ import androidx.annotation.NonNull;
public class BottomHalfPipActivity extends PipActivity {
- private boolean mUseBottomHalfLayout;
+ private boolean mUseBottomHalfLayout = true;
@Override
public void onCreate(Bundle savedInstanceState) {
diff --git a/tools/aapt/SdkConstants.h b/tools/aapt/SdkConstants.h
index ebb82ce1e2b7..af6063c37820 100644
--- a/tools/aapt/SdkConstants.h
+++ b/tools/aapt/SdkConstants.h
@@ -51,6 +51,7 @@ enum {
SDK_TIRAMISU = 33,
SDK_UPSIDE_DOWN_CAKE = 34,
SDK_VANILLA_ICE_CREAM = 35,
+ SDK_BAKLAVA = 36,
SDK_CUR_DEVELOPMENT = 10000,
};
diff --git a/tools/aapt2/SdkConstants.h b/tools/aapt2/SdkConstants.h
index f131cc6d7553..2a93c177e2ce 100644
--- a/tools/aapt2/SdkConstants.h
+++ b/tools/aapt2/SdkConstants.h
@@ -61,6 +61,7 @@ enum : ApiVersion {
SDK_TIRAMISU = 33,
SDK_UPSIDE_DOWN_CAKE = 34,
SDK_VANILLA_ICE_CREAM = 35,
+ SDK_BAKLAVA = 36,
SDK_CUR_DEVELOPMENT = 10000,
};
diff --git a/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
index af753e5963a3..b62843ca3ff4 100644
--- a/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
+++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
@@ -19,6 +19,7 @@ package com.google.android.lint
import com.android.tools.lint.client.api.IssueRegistry
import com.android.tools.lint.client.api.Vendor
import com.android.tools.lint.detector.api.CURRENT_API
+import com.google.android.lint.multiuser.PendingIntentGetActivityDetector
import com.google.android.lint.parcel.SaferParcelChecker
import com.google.auto.service.AutoService
@@ -40,6 +41,7 @@ class AndroidFrameworkIssueRegistry : IssueRegistry() {
PermissionMethodDetector.ISSUE_PERMISSION_METHOD_USAGE,
PermissionMethodDetector.ISSUE_CAN_BE_PERMISSION_METHOD,
FeatureAutomotiveDetector.ISSUE,
+ PendingIntentGetActivityDetector.ISSUE_PENDING_INTENT_GET_ACTIVITY,
)
override val api: Int
diff --git a/tools/lint/framework/checks/src/main/java/com/google/android/lint/multiuser/PendingIntentGetActivityDetector.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/multiuser/PendingIntentGetActivityDetector.kt
new file mode 100644
index 000000000000..b9f22ebfa8ec
--- /dev/null
+++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/multiuser/PendingIntentGetActivityDetector.kt
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2025 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.google.android.lint.multiuser
+
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.android.tools.lint.detector.api.SourceCodeScanner
+import com.intellij.psi.PsiMethod
+import java.util.EnumSet
+import org.jetbrains.uast.UCallExpression
+
+/**
+ * Detector for flagging potential multiuser issues in `PendingIntent.getActivity()` calls.
+ *
+ * This detector checks for calls to `PendingIntent#getActivity()` and
+ * reports a warning if such a call is found, suggesting that the
+ * default user 0 context might not be the right one.
+ */
+class PendingIntentGetActivityDetector : Detector(), SourceCodeScanner {
+
+ companion object {
+
+ val description = """Flags potential multiuser issue in PendingIntent.getActivity() calls."""
+
+ val EXPLANATION =
+ """
+ **Problem:**
+
+ Calling `PendingIntent.getActivity()` in the `system_server` often accidentally uses the user 0 context. Moreover, since there's no explicit user parameter in the `getActivity` method, it can be hard to tell which user the `PendingIntent` activity is associated with, making the code error-prone and less readable.
+
+ **Solution:**
+
+ Always use the user aware methods to refer the correct user context. You can achieve this by:
+
+ * **Using `PendingIntent.getActivityAsUser(...)`:** This API allows you to explicitly specify the user for the activity.
+
+ ```java
+ PendingIntent.getActivityAsUser(
+ mContext, /*requestCode=*/0, intent,
+ PendingIntent.FLAG_IMMUTABLE, /*options=*/null,
+ UserHandle.of(mUserId));
+ ```
+
+ **When to Ignore this Warning:**
+
+ You can safely ignore this warning if you are certain that:
+
+ * You've confirmed that the `PendingIntent` activity you're targeting is the correct one and is **rightly** associated with the context parameter passed into the `PendingIntent.getActivity` method.
+
+ **Note:** If you are unsure about the user context, it's best to err on the side of caution and explicitly specify the user using the method specified above.
+
+ **For any further questions, please reach out to go/multiuser-help.**
+ """.trimIndent()
+
+ val ISSUE_PENDING_INTENT_GET_ACTIVITY: Issue =
+ Issue.create(
+ id = "PendingIntent#getActivity",
+ briefDescription = description,
+ explanation = EXPLANATION,
+ category = Category.SECURITY,
+ priority = 8,
+ severity = Severity.WARNING,
+ implementation =
+ Implementation(
+ PendingIntentGetActivityDetector::class.java,
+ EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES),
+ ),
+ )
+ }
+
+ override fun getApplicableMethodNames() = listOf("getActivity")
+
+ override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
+ // Check if the method call is PendingIntent.getActivity
+ if (
+ context.evaluator.isMemberInClass(method, "android.app.PendingIntent") &&
+ method.name == "getActivity"
+ ) {
+ context.report(
+ ISSUE_PENDING_INTENT_GET_ACTIVITY,
+ node,
+ context.getLocation(node),
+ "Using `PendingIntent.getActivity(...)` might not be multiuser-aware. " +
+ "Consider using the user aware method `PendingIntent.getActivityAsUser(...)`.",
+ )
+ }
+ }
+}
diff --git a/tools/lint/framework/checks/src/test/java/com/google/android/lint/multiuser/PendingIntentGetActivityDetectorTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/multiuser/PendingIntentGetActivityDetectorTest.kt
new file mode 100644
index 000000000000..401055055232
--- /dev/null
+++ b/tools/lint/framework/checks/src/test/java/com/google/android/lint/multiuser/PendingIntentGetActivityDetectorTest.kt
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2025 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.google.android.lint.multiuser
+
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.checks.infrastructure.TestFile
+import com.android.tools.lint.checks.infrastructure.TestLintTask
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+
+@Suppress("UnstableApiUsage")
+class PendingIntentGetActivityDetectorTest : LintDetectorTest() {
+
+ override fun getDetector(): Detector = PendingIntentGetActivityDetector()
+
+ override fun getIssues(): List<Issue> =
+ listOf(PendingIntentGetActivityDetector.ISSUE_PENDING_INTENT_GET_ACTIVITY)
+
+ override fun lint(): TestLintTask = super.lint().allowMissingSdk(true)
+
+ fun testPendingIntentGetActivity() {
+ lint()
+ .files(
+ java(
+ """
+ package test.pkg;
+
+ import android.app.PendingIntent;
+ import android.content.Context;
+ import android.content.Intent;
+
+ public class TestClass {
+ private Context mContext;
+
+ public void testMethod(Intent intent) {
+ PendingIntent.getActivity(
+ mContext, /*requestCode=*/0, intent,
+ PendingIntent.FLAG_IMMUTABLE, /*options=*/null
+ );
+ }
+ }
+ """
+ )
+ .indented(),
+ *stubs,
+ )
+ .issues(PendingIntentGetActivityDetector.ISSUE_PENDING_INTENT_GET_ACTIVITY)
+ .run()
+ .expect(
+ """
+ src/test/pkg/TestClass.java:11: Warning: Using PendingIntent.getActivity(...) might not be multiuser-aware. Consider using the user aware method PendingIntent.getActivityAsUser(...). [PendingIntent#getActivity]
+ PendingIntent.getActivity(
+ ^
+ 0 errors, 1 warnings
+ """
+ )
+ }
+
+ fun testPendingIntentGetActivityAsUser() {
+ lint()
+ .files(
+ java(
+ """
+ package test.pkg;
+
+ import android.app.PendingIntent;
+ import android.content.Context;
+ import android.content.Intent;
+ import android.os.UserHandle;
+
+ public class TestClass {
+ private Context mContext;
+
+ public void testMethod(Intent intent) {
+ PendingIntent.getActivityAsUser(
+ mContext, /*requestCode=*/0, intent,
+ 0, /*options=*/null,
+ UserHandle.CURRENT
+ );
+ }
+ }
+ """
+ )
+ .indented(),
+ *stubs,
+ )
+ .issues(PendingIntentGetActivityDetector.ISSUE_PENDING_INTENT_GET_ACTIVITY)
+ .run()
+ .expectClean()
+ }
+
+ private val pendingIntentStub: TestFile =
+ java(
+ """
+ package android.app;
+
+ import android.content.Context;
+ import android.content.Intent;
+ import android.os.UserHandle;
+
+ public class PendingIntent {
+ public static boolean getActivity(Context context, int requestCode, Intent intent, int flags) {
+ return true;
+ }
+
+ public static boolean getActivityAsUser(
+ Context context,
+ int requestCode,
+ Intent intent,
+ int flags,
+ UserHandle userHandle
+ ) {
+ return true;
+ }
+ }
+ """
+ )
+
+ private val contxtStub: TestFile =
+ java(
+ """
+ package android.content;
+
+ import android.os.UserHandle;
+
+ public class Context {
+
+ public Context createContextAsUser(UserHandle userHandle, int flags) {
+ return this;
+ }
+ }
+
+ """
+ )
+
+ private val userHandleStub: TestFile =
+ java(
+ """
+ package android.os;
+
+ public class UserHandle {
+
+ }
+
+ """
+ )
+
+ private val intentStub: TestFile =
+ java(
+ """
+ package android.content;
+
+ public class Intent {
+
+ }
+ """
+ )
+
+ private val stubs = arrayOf(pendingIntentStub, contxtStub, userHandleStub, intentStub)
+}