summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ADPF_OWNERS5
-rw-r--r--core/api/test-current.txt2
-rw-r--r--core/java/android/os/CombinedMessageQueue/MessageQueue.java11
-rw-r--r--core/java/android/os/UserManager.java3
-rw-r--r--core/java/android/view/textclassifier/intent/OWNERS1
-rw-r--r--core/java/android/widget/RemoteViews.java2
-rw-r--r--core/java/android/window/flags/lse_desktop_experience.aconfig17
-rw-r--r--core/java/com/android/internal/accessibility/AccessibilityShortcutController.java9
-rw-r--r--core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java14
-rw-r--r--core/res/res/color-night/surface_effect_2_color.xml20
-rw-r--r--core/res/res/color-night/surface_effect_3_color.xml20
-rw-r--r--core/res/res/color/surface_effect_2_color.xml20
-rw-r--r--core/res/res/color/surface_effect_3_color.xml20
-rw-r--r--core/res/res/layout/notification_2025_template_header.xml26
-rw-r--r--core/res/res/layout/notification_template_header.xml24
-rw-r--r--core/res/res/values-night/colors.xml2
-rw-r--r--core/res/res/values/colors.xml2
-rw-r--r--core/res/res/values/strings.xml3
-rw-r--r--core/res/res/values/symbols.xml5
-rw-r--r--core/tests/coretests/src/android/widget/RemoteViewsTest.java17
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.java62
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/PipSurfaceTransactionHelper.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java128
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt17
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedTaskInfoTest.kt51
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java8
-rw-r--r--libs/hostgraphics/Fence.cpp2
-rw-r--r--packages/SettingsLib/ActionButtonsPreference/res/layout-v36/settingslib_expressive_action_buttons.xml (renamed from packages/SettingsLib/ActionButtonsPreference/res/layout-v35/settingslib_expressive_action_buttons.xml)0
-rw-r--r--packages/SettingsLib/ActionButtonsPreference/res/values-v36/styles_expressive.xml (renamed from packages/SettingsLib/ActionButtonsPreference/res/values-v35/styles_expressive.xml)0
-rw-r--r--packages/SettingsLib/BannerMessagePreference/res/drawable-v36/settingslib_expressive_card_background.xml (renamed from packages/SettingsLib/BannerMessagePreference/res/drawable-v35/settingslib_expressive_card_background.xml)0
-rw-r--r--packages/SettingsLib/BannerMessagePreference/res/drawable-v36/settingslib_resolved_banner_avd.xml (renamed from packages/SettingsLib/BannerMessagePreference/res/drawable-v35/settingslib_resolved_banner_avd.xml)0
-rw-r--r--packages/SettingsLib/BannerMessagePreference/res/layout-v36/settingslib_expressive_banner_message.xml (renamed from packages/SettingsLib/BannerMessagePreference/res/layout-v35/settingslib_expressive_banner_message.xml)0
-rw-r--r--packages/SettingsLib/BannerMessagePreference/res/values-v36/styles_expressive.xml (renamed from packages/SettingsLib/BannerMessagePreference/res/values-v35/styles_expressive.xml)0
-rw-r--r--packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_filled.xml (renamed from packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_filled.xml)0
-rw-r--r--packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_filled_extra.xml (renamed from packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_filled_extra.xml)0
-rw-r--r--packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_filled_large.xml (renamed from packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_filled_large.xml)0
-rw-r--r--packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_outline.xml (renamed from packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_outline.xml)0
-rw-r--r--packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_outline_extra.xml (renamed from packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_outline_extra.xml)0
-rw-r--r--packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_outline_large.xml (renamed from packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_outline_large.xml)0
-rw-r--r--packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_tonal.xml (renamed from packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_tonal.xml)0
-rw-r--r--packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_tonal_extra.xml (renamed from packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_tonal_extra.xml)0
-rw-r--r--packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_tonal_large.xml (renamed from packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_tonal_large.xml)0
-rw-r--r--packages/SettingsLib/CollapsingToolbarBaseActivity/res/drawable-v36/settingslib_expressive_icon_back.xml (renamed from packages/SettingsLib/CollapsingToolbarBaseActivity/res/drawable-v35/settingslib_expressive_icon_back.xml)0
-rw-r--r--packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v36/settingslib_expressive_collapsing_toolbar_base_layout.xml (renamed from packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v35/settingslib_expressive_collapsing_toolbar_base_layout.xml)0
-rw-r--r--packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v36/settingslib_expressive_collapsing_toolbar_content_layout.xml (renamed from packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v35/settingslib_expressive_collapsing_toolbar_content_layout.xml)0
-rw-r--r--packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-night-v36/themes.xml (renamed from packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-night-v35/themes.xml)0
-rw-r--r--packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v36/styles.xml (renamed from packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/styles.xml)0
-rw-r--r--packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v36/styles_expressive.xml (renamed from packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/styles_expressive.xml)0
-rw-r--r--packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v36/themes.xml (renamed from packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/themes.xml)0
-rw-r--r--packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v36/themes_expressive.xml (renamed from packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/themes_expressive.xml)0
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/color-night-v36/settingslib_main_switch_text_color.xml (renamed from packages/SettingsLib/MainSwitchPreference/res/color-night-v35/settingslib_main_switch_text_color.xml)0
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/color-v36/settingslib_main_switch_text_color.xml (renamed from packages/SettingsLib/MainSwitchPreference/res/color-v35/settingslib_main_switch_text_color.xml)0
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/drawable-v36/settingslib_expressive_switch_bar_bg.xml (renamed from packages/SettingsLib/MainSwitchPreference/res/drawable-v35/settingslib_expressive_switch_bar_bg.xml)0
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/layout-v36/settingslib_expressive_main_switch_bar.xml (renamed from packages/SettingsLib/MainSwitchPreference/res/layout-v35/settingslib_expressive_main_switch_bar.xml)0
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/layout-v36/settingslib_expressive_main_switch_layout.xml (renamed from packages/SettingsLib/MainSwitchPreference/res/layout-v35/settingslib_expressive_main_switch_layout.xml)0
-rw-r--r--packages/SettingsLib/ProfileSelector/res/color-night-v36/settingslib_tabs_indicator_color.xml (renamed from packages/SettingsLib/ProfileSelector/res/color-night-v35/settingslib_tabs_indicator_color.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/color-night-v36/settingslib_switch_track_outline_color.xml (renamed from packages/SettingsLib/SettingsTheme/res/color-night-v35/settingslib_switch_track_outline_color.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/color-v36/settingslib_expressive_color_main_switch_track.xml (renamed from packages/SettingsLib/SettingsTheme/res/color-v35/settingslib_expressive_color_main_switch_track.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/color-v36/settingslib_preference_bg_color.xml (renamed from packages/SettingsLib/SettingsTheme/res/color-v35/settingslib_preference_bg_color.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/color-v36/settingslib_switch_track_outline_color.xml (renamed from packages/SettingsLib/SettingsTheme/res/color-v35/settingslib_switch_track_outline_color.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/color-v36/settingslib_text_color_primary.xml (renamed from packages/SettingsLib/SettingsTheme/res/color-v35/settingslib_text_color_primary.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/color-v36/settingslib_text_color_secondary.xml (renamed from packages/SettingsLib/SettingsTheme/res/color-v35/settingslib_text_color_secondary.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_arrow_drop_down.xml (renamed from packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_arrow_drop_down.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_list_divider.xml (renamed from packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_list_divider.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_progress_horizontal.xml (renamed from packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_progress_horizontal.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background.xml (renamed from packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom.xml (renamed from packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_bottom.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom_highlighted.xml (renamed from packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_bottom_highlighted.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom_selected.xml (renamed from packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_bottom_selected.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center.xml (renamed from packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_center.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center_highlighted.xml (renamed from packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_center_highlighted.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center_selected.xml (renamed from packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_center_selected.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_highlighted.xml (renamed from packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_highlighted.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_selected.xml (renamed from packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_selected.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top.xml (renamed from packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_top.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top_highlighted.xml (renamed from packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_top_highlighted.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top_selected.xml (renamed from packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_top_selected.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_spinner_background.xml (renamed from packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_spinner_background.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_spinner_dropdown_background.xml (renamed from packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_spinner_dropdown_background.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/layout-v36/settingslib_expressive_preference.xml (renamed from packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_preference.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/layout-v36/settingslib_expressive_preference_icon_frame.xml (renamed from packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_preference_icon_frame.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/layout-v36/settingslib_expressive_preference_switch.xml (renamed from packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_preference_switch.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/layout-v36/settingslib_expressive_two_target_divider.xml (renamed from packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_two_target_divider.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-night-v36/colors.xml (renamed from packages/SettingsLib/SettingsTheme/res/values-night-v35/colors.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-v36/colors.xml (renamed from packages/SettingsLib/SettingsTheme/res/values-v35/colors.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-v36/dimens.xml (renamed from packages/SettingsLib/SettingsTheme/res/values-v35/dimens.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-v36/styles_expressive.xml (renamed from packages/SettingsLib/SettingsTheme/res/values-v35/styles_expressive.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-v36/styles_preference_expressive.xml (renamed from packages/SettingsLib/SettingsTheme/res/values-v35/styles_preference_expressive.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-v36/themes.xml (renamed from packages/SettingsLib/SettingsTheme/res/values-v35/themes.xml)4
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-v36/themes_expressive.xml (renamed from packages/SettingsLib/SettingsTheme/res/values-v35/themes_expressive.xml)0
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-v36/themes_preference_expressive.xml (renamed from packages/SettingsLib/SettingsTheme/res/values-v35/themes_preference_expressive.xml)0
-rw-r--r--packages/SettingsLib/TwoTargetPreference/res/layout-v36/settingslib_expressive_preference_two_target.xml (renamed from packages/SettingsLib/TwoTargetPreference/res/layout-v35/settingslib_expressive_preference_two_target.xml)0
-rw-r--r--packages/SystemUI/aconfig/systemui.aconfig10
-rw-r--r--packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/BouncerOverlayModule.kt (renamed from packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/BouncerSceneModule.kt)11
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt42
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerOverlay.kt (renamed from packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt)32
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerOverlayLayout.kt (renamed from packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerSceneLayout.kt)30
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationLockscreenScrim.kt5
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt3
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerInterruptionHandler.kt8
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt29
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromBouncerToGoneTransition.kt4
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/ObservableTransitionState.kt61
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt18
-rw-r--r--packages/SystemUI/lint.xml5
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt86
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerActionButtonInteractorTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerOverlayLayoutTest.kt (renamed from packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerSceneLayoutTest.kt)18
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerPredictiveBackTest.kt38
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerOverlayContentViewModelTest.kt (renamed from packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModelTest.kt)6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModelTest.kt7
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt42
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt34
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt40
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalUserActionsViewModelTest.kt9
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt5
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt83
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt8
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt24
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntrySourceInteractorTest.kt35
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt5
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt9
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModelTest.kt22
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt12
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt21
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt11
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt44
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt60
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt52
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractorTest.kt16
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelTest.kt14
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt41
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/media/dialog/MediaOutputAdapterLegacyTest.java17
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModelTest.kt14
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/CastTileTest.java10
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModelTest.kt14
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt240
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneBackInteractorTest.kt35
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt84
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt187
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/ScrimStartableTest.kt101
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/StatusBarStartableTest.kt21
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/shared/model/SceneDataSourceDelegatorTest.kt14
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/view/SceneJankMonitorTest.kt13
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerHapticsViewModelTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractorImplTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/NotificationShadeWindowModelTest.kt13
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt26
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt18
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt1
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt3
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt17
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/KeyguardBypassInteractorTest.kt8
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt8
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt3
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java2
-rw-r--r--packages/SystemUI/res/anim/volume_dialog_ringer_close.xml22
-rw-r--r--packages/SystemUI/res/anim/volume_dialog_ringer_open.xml22
-rw-r--r--packages/SystemUI/res/layout/media_output_list_group_divider.xml4
-rw-r--r--packages/SystemUI/res/layout/media_output_list_item_advanced.xml37
-rw-r--r--packages/SystemUI/res/values-land-television/dimens.xml2
-rw-r--r--packages/SystemUI/res/values/strings.xml6
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/ComposeBouncerViewBinder.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/composable/BouncerContainer.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerOverlayContentViewModel.kt (renamed from packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModel.kt)6
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModel.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/common/shared/colors/SurfaceEffectColors.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalUserActionsViewModel.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt66
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntrySourceInteractor.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/TouchpadTutorialScreensProvider.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/ActionTutorialContent.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialScreenConfig.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModel.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBypassInteractor.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt2
-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/KeyguardOcclusionInteractor.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt128
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt37
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/shared/model/Edge.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerTransitionViewModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModel.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/util/MediaUiEventLogger.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapterLegacy.java55
-rw-r--r--packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModel.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt53
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModel.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt89
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractor.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt123
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/startable/ScrimStartable.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/startable/StatusBarStartable.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/shared/model/Overlays.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/shared/model/Scenes.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneJankMonitor.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/NotificationShadeWindowModel.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt55
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/domain/interactor/StatusBarKeyguardViewManagerInteractor.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/ui/compose/MediaControlPopup.kt56
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopup.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopupChipsContainer.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/ConnectedDisplaysStatusBarNotificationIconViewStore.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java37
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java37
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaContainerView.kt33
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/composable/BouncerContentTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt33
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java13
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt16
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryUtil.kt66
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/model/FakeSceneDataSource.kt13
-rw-r--r--services/core/java/com/android/server/om/OverlayManagerSettings.java1
-rw-r--r--services/core/java/com/android/server/pm/DeletePackageHelper.java21
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerInternalBase.java2
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java48
-rw-r--r--services/tests/mockingservicestests/res/xml/expectedUserWakeupList_1.xml20
-rw-r--r--services/tests/mockingservicestests/res/xml/expectedUserWakeupList_2.xml19
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/UserWakeupStoreTest.java56
-rw-r--r--services/tests/servicestests/src/com/android/server/om/OverlayManagerSettingsTests.java46
-rw-r--r--services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java727
284 files changed, 3232 insertions, 1873 deletions
diff --git a/ADPF_OWNERS b/ADPF_OWNERS
index bcdc33825a13..c7ff4640b185 100644
--- a/ADPF_OWNERS
+++ b/ADPF_OWNERS
@@ -1,4 +1,5 @@
-sumir@google.com
+adyabr@google.com
chingtangyu@google.com
-xwxw@google.com
mattbuckley@google.com
+sumir@google.com
+xwxw@google.com \ No newline at end of file
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 4222c7c64672..514a58244aa2 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -2586,7 +2586,7 @@ package android.os {
}
public class UserManager {
- method @FlaggedApi("android.os.allow_private_profile") @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}, conditional=true) public boolean canAddPrivateProfile();
+ method @FlaggedApi("android.os.allow_private_profile") @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean canAddPrivateProfile();
method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.content.pm.UserInfo createProfileForUser(@Nullable String, @NonNull String, int, int, @Nullable String[]);
method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.content.pm.UserInfo createRestrictedProfile(@Nullable String);
method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.content.pm.UserInfo createUser(@Nullable String, @NonNull String, int);
diff --git a/core/java/android/os/CombinedMessageQueue/MessageQueue.java b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
index 3c03bb5626c8..74972346bf2e 100644
--- a/core/java/android/os/CombinedMessageQueue/MessageQueue.java
+++ b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
@@ -130,7 +130,7 @@ public final class MessageQueue {
MessageQueue(boolean quitAllowed) {
initIsProcessAllowedToUseConcurrent();
- mUseConcurrent = sIsProcessAllowedToUseConcurrent && !isInstrumenting();
+ mUseConcurrent = sIsProcessAllowedToUseConcurrent;
mQuitAllowed = quitAllowed;
mPtr = nativeInit();
mThread = Thread.currentThread();
@@ -202,15 +202,6 @@ public final class MessageQueue {
return;
}
- private static boolean isInstrumenting() {
- final ActivityThread activityThread = ActivityThread.currentActivityThread();
- if (activityThread == null) {
- return false;
- }
- final Instrumentation instrumentation = activityThread.getInstrumentation();
- return instrumentation != null && instrumentation.isInstrumenting();
- }
-
@Override
protected void finalize() throws Throwable {
try {
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 33bf4a29ecc6..767019d97758 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -3324,8 +3324,7 @@ public class UserManager {
@FlaggedApi(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE)
@RequiresPermission(anyOf = {
Manifest.permission.MANAGE_USERS,
- Manifest.permission.CREATE_USERS},
- conditional = true)
+ Manifest.permission.CREATE_USERS})
@UserHandleAware
public boolean canAddPrivateProfile() {
if (!android.multiuser.Flags.enablePrivateSpaceFeatures()) return false;
diff --git a/core/java/android/view/textclassifier/intent/OWNERS b/core/java/android/view/textclassifier/intent/OWNERS
index 3465fe62784f..dc18514ce949 100644
--- a/core/java/android/view/textclassifier/intent/OWNERS
+++ b/core/java/android/view/textclassifier/intent/OWNERS
@@ -1,6 +1,5 @@
# Bug component: 709498
-mns@google.com
toki@google.com
svetoslavganov@android.com
svetoslavganov@google.com
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 0a5c14e3a08b..222a7b38c966 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -9216,6 +9216,7 @@ public class RemoteViews implements Parcelable, Filter {
public static RemoteResponse fromFillInIntent(@NonNull Intent fillIntent) {
RemoteResponse response = new RemoteResponse();
response.mFillIntent = fillIntent;
+ fillIntent.collectExtraIntentKeys();
return response;
}
@@ -9224,6 +9225,7 @@ public class RemoteViews implements Parcelable, Filter {
RemoteResponse response = new RemoteResponse();
response.mPendingIntent = pendingIntent;
response.mFillIntent = intent;
+ intent.collectExtraIntentKeys();
return response;
}
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index f77a36676b3d..2e36e9a205bf 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -206,6 +206,13 @@ flag {
}
flag {
+ name: "enable_camera_compat_for_desktop_windowing_opt_out_api"
+ namespace: "lse_desktop_experience"
+ description: "Introduces a developer API to opt-out of Camera Compat treatment for fixed-orientation apps in desktop windowing mode"
+ bug: "397165621"
+}
+
+flag {
name: "enable_task_stack_observer_in_shell"
namespace: "lse_desktop_experience"
description: "Introduces a new observer in shell to track the task stack."
@@ -794,4 +801,14 @@ flag {
namespace: "lse_desktop_experience"
description: "Enable Desktop Mode on Projected Mode devices but constrained to the external display."
bug: "384568161"
+}
+
+flag {
+ name: "enable_persisting_density_scale_for_connected_displays"
+ namespace: "lse_desktop_experience"
+ description: "Enables persisting density scale on resolution change for connected displays."
+ bug: "392855657"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
} \ No newline at end of file
diff --git a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
index a27eeb8fdd63..1281a78d4fa2 100644
--- a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
+++ b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
@@ -97,6 +97,8 @@ public class AccessibilityShortcutController {
new ComponentName("com.android.server.accessibility", "ReduceBrightColors");
public static final ComponentName FONT_SIZE_COMPONENT_NAME =
new ComponentName("com.android.server.accessibility", "FontSize");
+ public static final ComponentName AUTOCLICK_COMPONENT_NAME =
+ new ComponentName("com.android.server.accessibility", "Autoclick");
// The component name for the sub setting of Accessibility button in Accessibility settings
public static final ComponentName ACCESSIBILITY_BUTTON_COMPONENT_NAME =
@@ -163,7 +165,7 @@ public class AccessibilityShortcutController {
getFrameworkShortcutFeaturesMap() {
if (sFrameworkShortcutFeaturesMap == null) {
- Map<ComponentName, FrameworkFeatureInfo> featuresMap = new ArrayMap<>(4);
+ Map<ComponentName, FrameworkFeatureInfo> featuresMap = new ArrayMap<>(8);
featuresMap.put(COLOR_INVERSION_COMPONENT_NAME,
new ToggleableFrameworkFeatureInfo(
Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED,
@@ -174,6 +176,11 @@ public class AccessibilityShortcutController {
Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
"1" /* Value to enable */, "0" /* Value to disable */,
R.string.color_correction_feature_name));
+ featuresMap.put(AUTOCLICK_COMPONENT_NAME,
+ new ToggleableFrameworkFeatureInfo(
+ Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED,
+ "1" /* Value to enable */, "0" /* Value to disable */,
+ R.string.autoclick_feature_name));
if (SUPPORT_ONE_HANDED_MODE) {
featuresMap.put(ONE_HANDED_COMPONENT_NAME,
new ToggleableFrameworkFeatureInfo(
diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java
index b187eb42366f..6498c53a63e2 100644
--- a/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java
+++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java
@@ -17,6 +17,7 @@
package com.android.internal.accessibility.dialog;
import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME;
+import static com.android.internal.accessibility.AccessibilityShortcutController.AUTOCLICK_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.COLOR_INVERSION_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
@@ -214,6 +215,19 @@ public final class AccessibilityTargetHelper {
Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
targets.add(colorInversion);
+ // TODO(b/394683600): Update Icon with the autoclick asset.
+ final ToggleAllowListingFeatureTarget autoclick =
+ new ToggleAllowListingFeatureTarget(context,
+ shortcutType,
+ isShortcutContained(context, shortcutType,
+ AUTOCLICK_COMPONENT_NAME.flattenToString()),
+ AUTOCLICK_COMPONENT_NAME.flattenToString(),
+ uid,
+ context.getString(R.string.autoclick_feature_name),
+ context.getDrawable(R.drawable.ic_accessibility_generic),
+ Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED);
+ targets.add(autoclick);
+
if (SUPPORT_ONE_HANDED_MODE) {
final ToggleAllowListingFeatureTarget oneHandedMode =
new ToggleAllowListingFeatureTarget(context,
diff --git a/core/res/res/color-night/surface_effect_2_color.xml b/core/res/res/color-night/surface_effect_2_color.xml
new file mode 100644
index 000000000000..6485017bec98
--- /dev/null
+++ b/core/res/res/color-night/surface_effect_2_color.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ 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.
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="@android:color/system_accent1_100"
+ android:alpha="0.15"/>
+</selector>
diff --git a/core/res/res/color-night/surface_effect_3_color.xml b/core/res/res/color-night/surface_effect_3_color.xml
new file mode 100644
index 000000000000..a7a7f8d89549
--- /dev/null
+++ b/core/res/res/color-night/surface_effect_3_color.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ 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.
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="@android:color/system_accent1_100"
+ android:alpha="0.10"/>
+</selector>
diff --git a/core/res/res/color/surface_effect_2_color.xml b/core/res/res/color/surface_effect_2_color.xml
new file mode 100644
index 000000000000..91c84095ec12
--- /dev/null
+++ b/core/res/res/color/surface_effect_2_color.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ 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.
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="@android:color/system_accent1_0"
+ android:alpha="0.32"/>
+</selector>
diff --git a/core/res/res/color/surface_effect_3_color.xml b/core/res/res/color/surface_effect_3_color.xml
new file mode 100644
index 000000000000..d766a32aff8b
--- /dev/null
+++ b/core/res/res/color/surface_effect_3_color.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ 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.
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="@android:color/system_accent1_600"
+ android:alpha="0.15"/>
+</selector>
diff --git a/core/res/res/layout/notification_2025_template_header.xml b/core/res/res/layout/notification_2025_template_header.xml
index 5aae67802af9..72b3798e0780 100644
--- a/core/res/res/layout/notification_2025_template_header.xml
+++ b/core/res/res/layout/notification_2025_template_header.xml
@@ -59,7 +59,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
- android:layout_toStartOf="@id/expand_button_container"
+ android:layout_toStartOf="@id/expand_button"
android:layout_alignWithParentIfMissing="true"
android:layout_marginVertical="@dimen/notification_2025_margin"
android:clipChildren="false"
@@ -81,30 +81,12 @@
android:focusable="false"
/>
-
- <LinearLayout
- android:id="@+id/expand_button_container"
+ <include layout="@layout/notification_2025_expand_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentEnd="true"
- android:orientation="vertical"
- >
- <FrameLayout
- android:id="@+id/expand_button_spacer"
- android:layout_width="@dimen/notification_2025_expand_button_pill_width"
- android:layout_height="@dimen/notification_2025_expand_button_pill_height"
- android:layout_centerVertical="true"
- android:layout_alignParentEnd="true"
- android:layout_margin="@dimen/notification_2025_margin"
- android:visibility="gone" />
-
- <include layout="@layout/notification_2025_expand_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="top|end"
- android:layout_alignParentEnd="true" />
+ android:layout_gravity="top|end"
+ android:layout_alignParentEnd="true" />
- </LinearLayout>
<include layout="@layout/notification_close_button"
android:id="@+id/close_button"
android:layout_width="@dimen/notification_close_button_size"
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index b7fd737a4e39..57959361bd48 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -62,7 +62,7 @@
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
- android:layout_toStartOf="@id/expand_button_container"
+ android:layout_toStartOf="@id/expand_button"
android:layout_alignWithParentIfMissing="true"
android:clipChildren="false"
android:gravity="center_vertical"
@@ -83,28 +83,12 @@
android:focusable="false"
/>
- <LinearLayout
- android:id="@+id/expand_button_container"
+ <include layout="@layout/notification_expand_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentEnd="true"
- android:orientation="vertical"
- >
- <FrameLayout
- android:id="@+id/expand_button_spacer"
- android:layout_width="@dimen/notification_expand_button_pill_height"
- android:layout_height="@dimen/notification_header_height"
- android:layout_centerVertical="true"
- android:layout_alignParentEnd="true"
- android:layout_marginHorizontal="16dp"
- android:visibility="gone" />
+ android:layout_centerVertical="true"
+ android:layout_alignParentEnd="true" />
- <include layout="@layout/notification_expand_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_alignParentEnd="true" />
- </LinearLayout>
<include layout="@layout/notification_close_button"
android:id="@+id/close_button"
android:layout_width="@dimen/notification_close_button_size"
diff --git a/core/res/res/values-night/colors.xml b/core/res/res/values-night/colors.xml
index 7b9b2d666292..e19ee23a8bd2 100644
--- a/core/res/res/values-night/colors.xml
+++ b/core/res/res/values-night/colors.xml
@@ -50,6 +50,8 @@
<!-- Color for various surfaces related to system-wide blur -->
<color name="surface_effect_0">@color/surface_effect_0_color</color>
<color name="surface_effect_1">@color/surface_effect_1_color</color>
+ <color name="surface_effect_2">@color/surface_effect_2_color</color>
+ <color name="surface_effect_3">@color/surface_effect_3_color</color>
<!-- Color for side fps toast dark theme-->
<color name="side_fps_toast_background">#2E3132</color>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 864daf9d2072..4e93c44e44bd 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -585,6 +585,8 @@
<!-- Color for various surfaces related to system-wide blur -->
<color name="surface_effect_0">@color/surface_effect_0_color</color>
<color name="surface_effect_1">@color/surface_effect_1_color</color>
+ <color name="surface_effect_2">@color/surface_effect_2_color</color>
+ <color name="surface_effect_3">@color/surface_effect_3_color</color>
<!-- Color for system bars -->
<color name="navigation_bar_compatible">@android:color/black</color>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 7a93ca1e9ac6..6a83bae15e76 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -5009,6 +5009,9 @@
<!-- Title of hearing aids feature, shown in the warning dialog about the accessibility shortcut. [CHAR LIMIT=none] -->
<string name="hearing_aids_feature_name">Hearing devices</string>
+ <!-- Title of autoclick feature, shown in the warning dialog about the accessibility shortcut. [CHAR LIMIT=none] -->
+ <string name="autoclick_feature_name">Autoclick</string>
+
<!-- Text of hearing device disconnected state. [CHAR LIMIT=20] -->
<string name="hearing_device_status_disconnected">Disconnected</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b013ffd41ecb..ed553c00d652 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -535,6 +535,8 @@
<java-symbol type="color" name="surface_effect_0" />
<java-symbol type="color" name="surface_effect_1" />
+ <java-symbol type="color" name="surface_effect_2" />
+ <java-symbol type="color" name="surface_effect_3" />
<java-symbol type="color" name="tab_indicator_text_v4" />
<java-symbol type="dimen" name="accessibility_touch_slop" />
@@ -3235,8 +3237,6 @@
<java-symbol type="id" name="header_text" />
<java-symbol type="id" name="header_text_secondary" />
<java-symbol type="id" name="expand_button" />
- <java-symbol type="id" name="expand_button_spacer" />
- <java-symbol type="id" name="expand_button_container" />
<java-symbol type="id" name="expand_button_pill" />
<java-symbol type="id" name="expand_button_pill_colorized_layer" />
<java-symbol type="id" name="expand_button_number" />
@@ -3791,6 +3791,7 @@
<java-symbol type="string" name="accessibility_shortcut_disabling_service" />
<java-symbol type="string" name="color_inversion_feature_name" />
<java-symbol type="string" name="color_correction_feature_name" />
+ <java-symbol type="string" name="autoclick_feature_name"/>
<java-symbol type="string" name="reduce_bright_colors_feature_name" />
<java-symbol type="string" name="config_defaultAccessibilityService" />
<java-symbol type="string" name="config_defaultSelectToSpeakService" />
diff --git a/core/tests/coretests/src/android/widget/RemoteViewsTest.java b/core/tests/coretests/src/android/widget/RemoteViewsTest.java
index 8b0d3158e9e7..9110898e18c9 100644
--- a/core/tests/coretests/src/android/widget/RemoteViewsTest.java
+++ b/core/tests/coretests/src/android/widget/RemoteViewsTest.java
@@ -22,6 +22,7 @@ import static com.android.internal.R.id.pending_intent_tag;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
@@ -1065,6 +1066,22 @@ public class RemoteViewsTest {
assertEquals(b1Memory + b2Memory, rv.estimateTotalBitmapMemoryUsage());
}
+ @Test
+ public void remoteResponse_FillInIntentNestedIntentKeysCollected() {
+ Intent fillInIntent = new Intent();
+ fillInIntent.putExtra("extraIntent", new Intent());
+ RemoteViews.RemoteResponse.fromFillInIntent(fillInIntent);
+ assertNotEquals(0, fillInIntent.getExtendedFlags()
+ & Intent.EXTENDED_FLAG_NESTED_INTENT_KEYS_COLLECTED);
+
+ fillInIntent = new Intent();
+ fillInIntent.putExtra("extraIntent", new Intent());
+ RemoteViews rv = new RemoteViews(mPackage, R.layout.remote_views_test);
+ rv.setOnClickFillInIntent(R.id.view, fillInIntent);
+ assertNotEquals(0, fillInIntent.getExtendedFlags()
+ & Intent.EXTENDED_FLAG_NESTED_INTENT_KEYS_COLLECTED);
+ }
+
private static LayoutInflater.Factory2 createLayoutInflaterFactory(String viewTypeToReplace,
View replacementView) {
return new LayoutInflater.Factory2() {
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.java
index 0a1e3b9495a0..25b9f8ccc6ae 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.java
@@ -47,20 +47,26 @@ public class GroupedTaskInfo implements Parcelable {
public static final int TYPE_FULLSCREEN = 1;
public static final int TYPE_SPLIT = 2;
- public static final int TYPE_FREEFORM = 3;
+ public static final int TYPE_DESK = 3;
public static final int TYPE_MIXED = 4;
@IntDef(prefix = {"TYPE_"}, value = {
TYPE_FULLSCREEN,
TYPE_SPLIT,
- TYPE_FREEFORM,
+ TYPE_DESK,
TYPE_MIXED
})
public @interface GroupType {}
/**
+ * The ID of the desk that this `GroupedTaskInfo` represents (when the type is `TYPE_DESK`). The
+ * value is -1 if this is not a desk.
+ */
+ private final int mDeskId;
+
+ /**
* The type of this particular task info, can be one of TYPE_FULLSCREEN, TYPE_SPLIT or
- * TYPE_FREEFORM.
+ * TYPE_DESK.
*/
@GroupType
protected final int mType;
@@ -69,7 +75,7 @@ public class GroupedTaskInfo implements Parcelable {
* The list of tasks associated with this single recent task info.
* TYPE_FULLSCREEN: Contains the stack of tasks associated with a single "task" in overview
* TYPE_SPLIT: Contains the two split roots of each side
- * TYPE_FREEFORM: Contains the set of tasks currently in freeform mode
+ * TYPE_DESK: Contains the set of tasks currently in freeform mode contained in desk.
*/
@Nullable
protected final List<TaskInfo> mTasks;
@@ -83,7 +89,7 @@ public class GroupedTaskInfo implements Parcelable {
protected final SplitBounds mSplitBounds;
/**
- * Only set for TYPE_FREEFORM.
+ * Only set for TYPE_DESK.
*
* TODO(b/348332802): move isMinimized inside each Task object instead once we have a
* replacement for RecentTaskInfo
@@ -103,8 +109,8 @@ public class GroupedTaskInfo implements Parcelable {
* Create new for a stack of fullscreen tasks
*/
public static GroupedTaskInfo forFullscreenTasks(@NonNull TaskInfo task) {
- return new GroupedTaskInfo(List.of(task), null, TYPE_FULLSCREEN,
- null /* minimizedFreeformTasks */);
+ return new GroupedTaskInfo(/* deskId = */ -1, List.of(task), null, TYPE_FULLSCREEN,
+ /* minimizedFreeformTaskIds = */ null);
}
/**
@@ -112,18 +118,19 @@ public class GroupedTaskInfo implements Parcelable {
*/
public static GroupedTaskInfo forSplitTasks(@NonNull TaskInfo task1,
@NonNull TaskInfo task2, @NonNull SplitBounds splitBounds) {
- return new GroupedTaskInfo(List.of(task1, task2), splitBounds, TYPE_SPLIT,
- null /* minimizedFreeformTasks */);
+ return new GroupedTaskInfo(/* deskId = */ -1, List.of(task1, task2), splitBounds,
+ TYPE_SPLIT, /* minimizedFreeformTaskIds = */ null);
}
/**
- * Create new for a group of freeform tasks
+ * Create new for a group of freeform tasks that belong to a single desk.
*/
- public static GroupedTaskInfo forFreeformTasks(
- @NonNull List<TaskInfo> tasks,
- @NonNull Set<Integer> minimizedFreeformTasks) {
- return new GroupedTaskInfo(tasks, null /* splitBounds */, TYPE_FREEFORM,
- minimizedFreeformTasks.stream().mapToInt(i -> i).toArray());
+ public static GroupedTaskInfo forDeskTasks(
+ int deskId,
+ @NonNull List<TaskInfo> tasks,
+ @NonNull Set<Integer> minimizedFreeformTaskIds) {
+ return new GroupedTaskInfo(deskId, tasks, /* splitBounds = */ null, TYPE_DESK,
+ minimizedFreeformTaskIds.stream().mapToInt(i -> i).toArray());
}
/**
@@ -141,10 +148,12 @@ public class GroupedTaskInfo implements Parcelable {
}
private GroupedTaskInfo(
+ int deskId,
@NonNull List<TaskInfo> tasks,
@Nullable SplitBounds splitBounds,
@GroupType int type,
@Nullable int[] minimizedFreeformTaskIds) {
+ mDeskId = deskId;
mTasks = tasks;
mGroupedTasks = null;
mSplitBounds = splitBounds;
@@ -154,6 +163,7 @@ public class GroupedTaskInfo implements Parcelable {
}
private GroupedTaskInfo(@NonNull List<GroupedTaskInfo> groupedTasks) {
+ mDeskId = -1;
mTasks = null;
mGroupedTasks = groupedTasks;
mSplitBounds = null;
@@ -174,6 +184,7 @@ public class GroupedTaskInfo implements Parcelable {
}
protected GroupedTaskInfo(@NonNull Parcel parcel) {
+ mDeskId = parcel.readInt();
mTasks = new ArrayList();
final int numTasks = parcel.readInt();
for (int i = 0; i < numTasks; i++) {
@@ -274,6 +285,16 @@ public class GroupedTaskInfo implements Parcelable {
}
/**
+ * Returns the ID of the desk represented by `this` if the type is `TYPE_DESK`, or -1 otherwise.
+ */
+ public int getDeskId() {
+ if (mType == TYPE_MIXED) {
+ throw new IllegalStateException("No desk ID for a mixed task");
+ }
+ return mDeskId;
+ }
+
+ /**
* Get type of this recents entry. One of {@link GroupType}.
* Note: This is deprecated, callers should use `isBaseType()` and not make assumptions about
* specific group types
@@ -285,7 +306,7 @@ public class GroupedTaskInfo implements Parcelable {
}
/**
- * Returns the set of minimized task ids, only valid for TYPE_FREEFORM.
+ * Returns the set of minimized task ids, only valid for TYPE_DESK.
*/
@Nullable
public int[] getMinimizedTaskIds() {
@@ -301,7 +322,8 @@ public class GroupedTaskInfo implements Parcelable {
return false;
}
GroupedTaskInfo other = (GroupedTaskInfo) obj;
- return mType == other.mType
+ return mDeskId == other.mDeskId
+ && mType == other.mType
&& Objects.equals(mTasks, other.mTasks)
&& Objects.equals(mGroupedTasks, other.mGroupedTasks)
&& Objects.equals(mSplitBounds, other.mSplitBounds)
@@ -310,7 +332,7 @@ public class GroupedTaskInfo implements Parcelable {
@Override
public int hashCode() {
- return Objects.hash(mType, mTasks, mGroupedTasks, mSplitBounds,
+ return Objects.hash(mDeskId, mType, mTasks, mGroupedTasks, mSplitBounds,
Arrays.hashCode(mMinimizedTaskIds));
}
@@ -322,6 +344,7 @@ public class GroupedTaskInfo implements Parcelable {
.map(GroupedTaskInfo::toString)
.collect(Collectors.joining(",\n\t", "[\n\t", "\n]")));
} else {
+ taskString.append("Desk ID= ").append(mDeskId).append(", ");
taskString.append("Tasks=" + mTasks.stream()
.map(taskInfo -> getTaskInfoDumpString(taskInfo))
.collect(Collectors.joining(", ", "[", "]")));
@@ -353,6 +376,7 @@ public class GroupedTaskInfo implements Parcelable {
@Override
public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeInt(mDeskId);
// We don't use the parcel list methods because we want to only write the TaskInfo state
// and not the subclasses (Recents/RunningTaskInfo) whose fields are all deprecated
final int tasksSize = mTasks != null ? mTasks.size() : 0;
@@ -375,7 +399,7 @@ public class GroupedTaskInfo implements Parcelable {
return switch (type) {
case TYPE_FULLSCREEN -> "FULLSCREEN";
case TYPE_SPLIT -> "SPLIT";
- case TYPE_FREEFORM -> "FREEFORM";
+ case TYPE_DESK -> "DESK";
case TYPE_MIXED -> "MIXED";
default -> "UNKNOWN";
};
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
index 7c6cf4a8b37f..926e0f287869 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
@@ -217,6 +217,9 @@ class DesktopRepository(
fun getDeskIds(displayId: Int): Set<Int> =
desktopData.desksSequence(displayId).map { desk -> desk.deskId }.toSet()
+ /** Returns all the ids of all desks in all displays. */
+ fun getAllDeskIds(): Set<Int> = desktopData.desksSequence().map { desk -> desk.deskId }.toSet()
+
/** Returns the id of the default desk in the given display. */
fun getDefaultDeskId(displayId: Int): Int? = getDefaultDesk(displayId)?.deskId
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index ca870d2b6988..87d967427d88 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -1745,6 +1745,9 @@ class DesktopTasksController(
launchWindowingMode = WINDOWING_MODE_FULLSCREEN
pendingIntentBackgroundActivityStartMode =
ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS
+ if (Flags.enablePerDisplayDesktopWallpaperActivity()) {
+ launchDisplayId = displayId
+ }
}
val pendingIntent =
PendingIntent.getActivityAsUser(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/PipSurfaceTransactionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/PipSurfaceTransactionHelper.java
index c4d065f158a4..e0cae81920ad 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/PipSurfaceTransactionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/PipSurfaceTransactionHelper.java
@@ -134,6 +134,18 @@ public class PipSurfaceTransactionHelper {
}
/**
+ * Operates the round corner radius on a given transaction and leash, scaled by bounds
+ * @return same {@link PipSurfaceTransactionHelper} instance for method chaining
+ */
+ public PipSurfaceTransactionHelper round(SurfaceControl.Transaction tx, SurfaceControl leash,
+ Rect fromBounds, Rect toBounds) {
+ final float scale = (float) (Math.hypot(fromBounds.width(), fromBounds.height())
+ / Math.hypot(toBounds.width(), toBounds.height()));
+ tx.setCornerRadius(leash, mCornerRadius * scale);
+ return this;
+ }
+
+ /**
* Operates the shadow radius on a given transaction and leash
* @return same {@link PipSurfaceTransactionHelper} instance for method chaining
*/
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java
index 06e8349259b4..eb5fe88648b3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java
@@ -173,7 +173,7 @@ public class PipResizeAnimator extends ValueAnimator {
transformTensor.postRotate(degrees, targetBounds.centerX(), targetBounds.centerY());
tx.setMatrix(leash, transformTensor, mMatrixTmp)
- .setCornerRadius(leash, cornerRadius)
+ .setCornerRadius(leash, cornerRadius / scaleX)
.setShadowRadius(leash, shadowRadius);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
index df7a25af8376..7805ec34e105 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
@@ -55,6 +55,7 @@ public class PipScheduler {
private PipTransitionController mPipTransitionController;
private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory
mSurfaceControlTransactionFactory;
+ private final PipSurfaceTransactionHelper mPipSurfaceTransactionHelper;
@Nullable private Runnable mUpdateMovementBoundsRunnable;
@@ -75,6 +76,7 @@ public class PipScheduler {
mSurfaceControlTransactionFactory =
new PipSurfaceTransactionHelper.VsyncSurfaceControlTransactionFactory();
+ mPipSurfaceTransactionHelper = new PipSurfaceTransactionHelper(mContext);
mPipAlphaAnimatorSupplier = PipAlphaAnimator::new;
}
@@ -214,6 +216,8 @@ public class PipScheduler {
transformTensor.postTranslate(toBounds.left, toBounds.top);
transformTensor.postRotate(degrees, toBounds.centerX(), toBounds.centerY());
+ mPipSurfaceTransactionHelper.round(tx, leash, mPipBoundsState.getBounds(), toBounds);
+
tx.setMatrix(leash, transformTensor, mMatrixTmp);
tx.apply();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
index 97b3e5a2da87..0cfab11dbc64 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
@@ -50,6 +50,7 @@ import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.IBinder;
+import android.os.SystemProperties;
import android.view.SurfaceControl;
import android.view.WindowManager;
import android.window.TransitionInfo;
@@ -105,7 +106,10 @@ public class PipTransition extends PipTransitionController implements
* The fixed start delay in ms when fading out the content overlay from bounds animation.
* The fadeout animation is guaranteed to start after the client has drawn under the new config.
*/
- private static final int CONTENT_OVERLAY_FADE_OUT_DELAY_MS = 500;
+ private static final int EXTRA_CONTENT_OVERLAY_FADE_OUT_DELAY_MS =
+ SystemProperties.getInt(
+ "persist.wm.debug.extra_content_overlay_fade_out_delay_ms", 400);
+ private static final int CONTENT_OVERLAY_FADE_OUT_DURATION_MS = 500;
//
// Dependencies
@@ -551,7 +555,8 @@ public class PipTransition extends PipTransitionController implements
@NonNull Runnable onAnimationEnd) {
PipAlphaAnimator animator = new PipAlphaAnimator(mContext, overlayLeash,
null /* startTx */, null /* finishTx */, PipAlphaAnimator.FADE_OUT);
- animator.setDuration(CONTENT_OVERLAY_FADE_OUT_DELAY_MS);
+ animator.setDuration(CONTENT_OVERLAY_FADE_OUT_DURATION_MS);
+ animator.setStartDelay(EXTRA_CONTENT_OVERLAY_FADE_OUT_DELAY_MS);
animator.setAnimationEndCallback(onAnimationEnd);
animator.start();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
index 2fa09664b73f..bb5b5cec1b4a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
@@ -44,6 +44,7 @@ import android.os.Bundle;
import android.os.RemoteException;
import android.util.Slog;
import android.util.SparseIntArray;
+import android.window.DesktopExperienceFlags;
import android.window.DesktopModeFlags;
import android.window.WindowContainerToken;
@@ -92,6 +93,11 @@ public class RecentTasksController implements TaskStackListenerCallback,
TaskStackTransitionObserver.TaskStackTransitionObserverListener, UserChangeListener {
private static final String TAG = RecentTasksController.class.getSimpleName();
+ // When the multiple desktops feature is disabled, all freeform tasks are lumped together into
+ // a single `GroupedTaskInfo` whose type is `TYPE_DESK`, and its `mDeskId` doesn't matter, so
+ // we pick the below arbitrary value.
+ private static final int INVALID_DESK_ID = -1;
+
private final Context mContext;
private final ShellController mShellController;
private final ShellCommandHandler mShellCommandHandler;
@@ -128,6 +134,7 @@ public class RecentTasksController implements TaskStackListenerCallback,
// Temporary vars used in `generateList()`
private final Map<Integer, TaskInfo> mTmpRemaining = new HashMap<>();
+ private final Map<Integer, Desk> mTmpDesks = new HashMap<>();
/**
* Creates {@link RecentTasksController}, returns {@code null} if the feature is not
@@ -529,6 +536,78 @@ public class RecentTasksController implements TaskStackListenerCallback,
}
/**
+ * Represents a desk whose ID is `mDeskId` and contains the tasks in `mDeskTasks`. Some of these
+ * tasks are minimized and their IDs are contained in the `mMinimizedDeskTasks` set.
+ */
+ private static class Desk {
+ final int mDeskId;
+ boolean mHasVisibleTasks = false;
+ final ArrayList<TaskInfo> mDeskTasks = new ArrayList<>();
+ final Set<Integer> mMinimizedDeskTasks = new HashSet<>();
+
+ Desk(int deskId) {
+ mDeskId = deskId;
+ }
+
+ void addTask(TaskInfo taskInfo, boolean isMinimized, boolean isVisible) {
+ mDeskTasks.add(taskInfo);
+ if (isMinimized) {
+ mMinimizedDeskTasks.add(taskInfo.taskId);
+ }
+ mHasVisibleTasks |= isVisible;
+ }
+
+ boolean hasTasks() {
+ return !mDeskTasks.isEmpty();
+ }
+
+ GroupedTaskInfo createDeskTaskInfo() {
+ return GroupedTaskInfo.forDeskTasks(mDeskId, mDeskTasks, mMinimizedDeskTasks);
+ }
+ }
+
+ /**
+ * Clears the `mTmpDesks` map, and re-initializes it with the current state of desks from all
+ * displays, without adding any desk tasks. This is a preparation step so that tasks can be
+ * added to these desks in `generateList()`.
+ *
+ * This is needed since with the `ENABLE_MULTIPLE_DESKTOPS_BACKEND` flag, we want to include
+ * desk even if they're empty (i.e. have no tasks).
+ *
+ * @param multipleDesktopsEnabled whether the multiple desktops backend feature is enabled.
+ */
+ private void initializeDesksMap(boolean multipleDesktopsEnabled) {
+ mTmpDesks.clear();
+
+ if (DesktopModeStatus.canEnterDesktopMode(mContext)
+ && mDesktopUserRepositories.isPresent()) {
+ if (multipleDesktopsEnabled) {
+ for (var deskId : mDesktopUserRepositories.get().getCurrent().getAllDeskIds()) {
+ getOrCreateDesk(deskId);
+ }
+ } else {
+ // When the multiple desks feature is disabled, we lump all freeform windows in a
+ // single `GroupedTaskInfo` regardless of their display. The `deskId` in this case
+ // doesn't matter and can be any arbitrary value.
+ getOrCreateDesk(/* deskId = */ INVALID_DESK_ID);
+ }
+ }
+ }
+
+ /**
+ * Returns the `Desk` whose ID is `deskId` from the `mTmpDesks` map if it exists, or it creates
+ * one and adds it to the map and then returns it.
+ */
+ private Desk getOrCreateDesk(int deskId) {
+ var desk = mTmpDesks.get(deskId);
+ if (desk == null) {
+ desk = new Desk(deskId);
+ mTmpDesks.put(deskId, desk);
+ }
+ return desk;
+ }
+
+ /**
* Generates a list of GroupedTaskInfos for the given raw list of tasks (either recents or
* running tasks).
*
@@ -555,6 +634,14 @@ public class RecentTasksController implements TaskStackListenerCallback,
ProtoLog.v(WM_SHELL_TASK_OBSERVER, "RecentTasksController.generateList(%s)", reason);
}
+ final boolean multipleDesktopsEnabled =
+ DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue();
+ initializeDesksMap(multipleDesktopsEnabled);
+
+ // When the multiple desktops feature is enabled, we include all desks even if they're
+ // empty.
+ final boolean shouldIncludeEmptyDesktops = multipleDesktopsEnabled;
+
// Make a mapping of task id -> task info for the remaining tasks to be processed, this
// mapping is used to keep track of split tasks that may exist later in the task list that
// should be ignored because they've already been grouped
@@ -566,11 +653,7 @@ public class RecentTasksController implements TaskStackListenerCallback,
ArrayList<GroupedTaskInfo> groupedTasks = new ArrayList<>(tasks.size());
ArrayList<GroupedTaskInfo> visibleGroupedTasks = new ArrayList<>();
- // Phase 1: Extract the desktop and visible fullscreen/split tasks. We make new collections
- // here as the GroupedTaskInfo can store them without copying
- ArrayList<TaskInfo> desktopTasks = new ArrayList<>();
- Set<Integer> minimizedDesktopTasks = new HashSet<>();
- boolean desktopTasksVisible = false;
+ // Phase 1: Extract the desktops and visible fullscreen/split tasks.
for (int i = 0; i < tasks.size(); i++) {
final TaskInfo taskInfo = tasks.get(i);
final int taskId = taskInfo.taskId;
@@ -600,11 +683,15 @@ public class RecentTasksController implements TaskStackListenerCallback,
taskInfo.positionInParent = new Point(taskInfo.lastNonFullscreenBounds.left,
taskInfo.lastNonFullscreenBounds.top);
}
- desktopTasks.add(taskInfo);
- if (mDesktopUserRepositories.get().getCurrent().isMinimizedTask(taskId)) {
- minimizedDesktopTasks.add(taskId);
- }
- desktopTasksVisible |= mVisibleTasksMap.containsKey(taskId);
+ // Lump all freeform tasks together as if they were all in a single desk whose ID is
+ // `INVALID_DESK_ID` when the multiple desktops feature is disabled.
+ final int deskId = multipleDesktopsEnabled
+ ? mDesktopUserRepositories.get().getCurrent().getDeskIdForTask(taskId)
+ : INVALID_DESK_ID;
+ final Desk desk = getOrCreateDesk(deskId);
+ desk.addTask(taskInfo,
+ mDesktopUserRepositories.get().getCurrent().isMinimizedTask(taskId),
+ mVisibleTasksMap.containsKey(taskId));
mTmpRemaining.remove(taskId);
continue;
}
@@ -636,9 +723,10 @@ public class RecentTasksController implements TaskStackListenerCallback,
if (enableShellTopTaskTracking()) {
// Phase 2: If there were desktop tasks and they are visible, add them to the visible
// list as well (the actual order doesn't matter for Overview)
- if (!desktopTasks.isEmpty() && desktopTasksVisible) {
- visibleGroupedTasks.add(
- GroupedTaskInfo.forFreeformTasks(desktopTasks, minimizedDesktopTasks));
+ for (var desk : mTmpDesks.values()) {
+ if (desk.mHasVisibleTasks) {
+ visibleGroupedTasks.add(desk.createDeskTaskInfo());
+ }
}
if (!visibleGroupedTasks.isEmpty()) {
@@ -674,16 +762,18 @@ public class RecentTasksController implements TaskStackListenerCallback,
// Phase 5: If there were desktop tasks and they are not visible (ie. weren't added
// above), add them to the end of the final list (the actual order doesn't
// matter for Overview)
- if (!desktopTasks.isEmpty() && !desktopTasksVisible) {
- groupedTasks.add(
- GroupedTaskInfo.forFreeformTasks(desktopTasks, minimizedDesktopTasks));
+ for (var desk : mTmpDesks.values()) {
+ if (!desk.mHasVisibleTasks && (desk.hasTasks() || shouldIncludeEmptyDesktops)) {
+ groupedTasks.add(desk.createDeskTaskInfo());
+ }
}
dumpGroupedTasks(groupedTasks, "Phase 5");
} else {
// Add the desktop tasks at the end of the list
- if (!desktopTasks.isEmpty()) {
- groupedTasks.add(
- GroupedTaskInfo.forFreeformTasks(desktopTasks, minimizedDesktopTasks));
+ for (var desk : mTmpDesks.values()) {
+ if (desk.hasTasks() || shouldIncludeEmptyDesktops) {
+ groupedTasks.add(desk.createDeskTaskInfo());
+ }
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index 0b160c6844ae..9a73b022ebc3 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -2809,6 +2809,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
// Should launch home
wct.assertPendingIntentAt(0, launchHomeIntent(DEFAULT_DISPLAY))
+ wct.assertPendingIntentActivityOptionsLaunchDisplayIdAt(0, DEFAULT_DISPLAY)
}
@Test
@@ -3931,6 +3932,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
// Should launch home
assertNotNull(result, "Should handle request")
.assertPendingIntentAt(0, launchHomeIntent(DEFAULT_DISPLAY))
+ result!!.assertPendingIntentActivityOptionsLaunchDisplayIdAt(0, DEFAULT_DISPLAY)
}
@Test
@@ -3957,6 +3959,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
// Should launch home
assertNotNull(result, "Should handle request")
.assertPendingIntentAt(0, launchHomeIntent(DEFAULT_DISPLAY))
+ result!!.assertPendingIntentActivityOptionsLaunchDisplayIdAt(0, DEFAULT_DISPLAY)
}
@Test
@@ -4089,6 +4092,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
// Should launch home
assertNotNull(result, "Should handle request")
.assertPendingIntentAt(0, launchHomeIntent(DEFAULT_DISPLAY))
+ result!!.assertPendingIntentActivityOptionsLaunchDisplayIdAt(0, DEFAULT_DISPLAY)
}
@Test
@@ -4105,6 +4109,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
// Should launch home
assertNotNull(result, "Should handle request")
.assertPendingIntentAt(0, launchHomeIntent(SECOND_DISPLAY))
+ result!!.assertPendingIntentActivityOptionsLaunchDisplayIdAt(0, SECOND_DISPLAY)
}
@Test
@@ -6898,6 +6903,18 @@ private fun WindowContainerTransaction.assertPendingIntentAt(index: Int, intent:
assertThat(op.pendingIntent?.intent?.categories).isEqualTo(intent.categories)
}
+private fun WindowContainerTransaction.assertPendingIntentActivityOptionsLaunchDisplayIdAt(
+ index: Int,
+ displayId: Int,
+) {
+ assertIndexInBounds(index)
+ val op = hierarchyOps[index]
+ if (op.launchOptions != null) {
+ val options = ActivityOptions(op.launchOptions)
+ assertThat(options.launchDisplayId).isEqualTo(displayId)
+ }
+}
+
private fun WindowContainerTransaction.assertLaunchTask(taskId: Int, windowingMode: Int) {
val keyLaunchWindowingMode = "android.activity.windowingMode"
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedTaskInfoTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedTaskInfoTest.kt
index 32096645aea7..6ecebd76a951 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedTaskInfoTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedTaskInfoTest.kt
@@ -26,7 +26,7 @@ import android.window.WindowContainerToken
import androidx.test.filters.SmallTest
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.shared.GroupedTaskInfo
-import com.android.wm.shell.shared.GroupedTaskInfo.TYPE_FREEFORM
+import com.android.wm.shell.shared.GroupedTaskInfo.TYPE_DESK
import com.android.wm.shell.shared.GroupedTaskInfo.TYPE_FULLSCREEN
import com.android.wm.shell.shared.GroupedTaskInfo.TYPE_SPLIT
import com.android.wm.shell.shared.split.SplitBounds
@@ -87,14 +87,14 @@ class GroupedTaskInfoTest : ShellTestCase() {
}
@Test
- fun testFreeformTasks_hasCorrectType() {
- assertThat(freeformTasksGroupInfo(freeformTaskIds = arrayOf(1)).isBaseType(TYPE_FREEFORM))
+ fun testDeskTasks_hasCorrectType() {
+ assertThat(deskTasksGroupInfo(deskId = 0, freeformTaskIds = arrayOf(1)).isBaseType(TYPE_DESK))
.isTrue()
}
@Test
- fun testCreateFreeformTasks_hasCorrectNumberOfTasks() {
- val list = freeformTasksGroupInfo(freeformTaskIds = arrayOf(1, 2, 3)).taskInfoList
+ fun testCreateDeskTasks_hasCorrectNumberOfTasks() {
+ val list = deskTasksGroupInfo(deskId = 0, freeformTaskIds = arrayOf(1, 2, 3)).taskInfoList
assertThat(list).hasSize(3)
assertThat(list[0].taskId).isEqualTo(1)
assertThat(list[1].taskId).isEqualTo(2)
@@ -102,9 +102,9 @@ class GroupedTaskInfoTest : ShellTestCase() {
}
@Test
- fun testCreateFreeformTasks_nonExistentMinimizedTaskId_throwsException() {
+ fun testCreateDeskTasks_nonExistentMinimizedTaskId_throwsException() {
assertThrows(IllegalArgumentException::class.java) {
- freeformTasksGroupInfo(
+ deskTasksGroupInfo(deskId = 0,
freeformTaskIds = arrayOf(1, 2, 3),
minimizedTaskIds = arrayOf(1, 4)
)
@@ -122,8 +122,8 @@ class GroupedTaskInfoTest : ShellTestCase() {
}
@Test
- fun testMixedWithFreeformBase_hasCorrectType() {
- assertThat(mixedTaskGroupInfoWithFreeformBase().isBaseType(TYPE_FREEFORM)).isTrue()
+ fun testMixedWithDeskBase_hasCorrectType() {
+ assertThat(mixedTaskGroupInfoWithDeskBase().isBaseType(TYPE_DESK)).isTrue()
}
@Test
@@ -190,15 +190,16 @@ class GroupedTaskInfoTest : ShellTestCase() {
}
@Test
- fun testParcelling_freeformTasks() {
- val taskInfo = freeformTasksGroupInfo(freeformTaskIds = arrayOf(1, 2, 3))
+ fun testParcelling_DeskTasks() {
+ val taskInfo = deskTasksGroupInfo(deskId = 50, freeformTaskIds = arrayOf(1, 2, 3))
val parcel = Parcel.obtain()
taskInfo.writeToParcel(parcel, 0)
parcel.setDataPosition(0)
// Read the object back from the parcel
val taskInfoFromParcel: GroupedTaskInfo =
GroupedTaskInfo.CREATOR.createFromParcel(parcel)
- assertThat(taskInfoFromParcel.isBaseType(TYPE_FREEFORM)).isTrue()
+ assertThat(taskInfoFromParcel.deskId).isEqualTo(taskInfo.deskId)
+ assertThat(taskInfoFromParcel.isBaseType(TYPE_DESK)).isTrue()
assertThat(taskInfoFromParcel.taskInfoList).hasSize(3)
// Only compare task ids
val taskIdComparator = Correspondence.transforming<TaskInfo, Int>(
@@ -209,8 +210,8 @@ class GroupedTaskInfoTest : ShellTestCase() {
}
@Test
- fun testParcelling_freeformTasks_minimizedTasks() {
- val taskInfo = freeformTasksGroupInfo(
+ fun testParcelling_DeskTasks_minimizedTasks() {
+ val taskInfo = deskTasksGroupInfo(deskId = 0,
freeformTaskIds = arrayOf(1, 2, 3), minimizedTaskIds = arrayOf(2))
val parcel = Parcel.obtain()
@@ -220,14 +221,14 @@ class GroupedTaskInfoTest : ShellTestCase() {
// Read the object back from the parcel
val taskInfoFromParcel: GroupedTaskInfo =
GroupedTaskInfo.CREATOR.createFromParcel(parcel)
- assertThat(taskInfoFromParcel.isBaseType(TYPE_FREEFORM)).isTrue()
+ assertThat(taskInfoFromParcel.isBaseType(TYPE_DESK)).isTrue()
assertThat(taskInfoFromParcel.minimizedTaskIds).isEqualTo(arrayOf(2).toIntArray())
}
@Test
fun testParcelling_mixedTasks() {
val taskInfo = GroupedTaskInfo.forMixed(listOf(
- freeformTasksGroupInfo(freeformTaskIds = arrayOf(4, 5, 6),
+ deskTasksGroupInfo(deskId = 0, freeformTaskIds = arrayOf(4, 5, 6),
minimizedTaskIds = arrayOf(5)),
splitTasksGroupInfo(firstId = 2, secondId = 3),
singleTaskGroupInfo(id = 1)))
@@ -239,7 +240,7 @@ class GroupedTaskInfoTest : ShellTestCase() {
// Read the object back from the parcel
val taskInfoFromParcel: GroupedTaskInfo =
GroupedTaskInfo.CREATOR.createFromParcel(parcel)
- assertThat(taskInfoFromParcel.isBaseType(TYPE_FREEFORM)).isTrue()
+ assertThat(taskInfoFromParcel.isBaseType(TYPE_DESK)).isTrue()
assertThat(taskInfoFromParcel.baseGroupedTask.minimizedTaskIds).isEqualTo(
arrayOf(5).toIntArray())
for (i in 1..6) {
@@ -275,12 +276,14 @@ class GroupedTaskInfoTest : ShellTestCase() {
}
@Test
- fun testTaskProperties_freeformTasks() {
+ fun testTaskProperties_DeskTasks() {
val task1 = createTaskInfo(id = 1)
val task2 = createTaskInfo(id = 2)
- val taskInfo = GroupedTaskInfo.forFreeformTasks(listOf(task1, task2), setOf())
+ val taskInfo = GroupedTaskInfo.forDeskTasks(
+ /* deskId = */ 500, listOf(task1, task2), setOf())
+ assertThat(taskInfo.deskId).isEqualTo(500)
assertThat(taskInfo.getTaskById(1)).isEqualTo(task1)
assertThat(taskInfo.getTaskById(2)).isEqualTo(task2)
assertThat(taskInfo.containsTask(1)).isTrue()
@@ -325,11 +328,13 @@ class GroupedTaskInfoTest : ShellTestCase() {
return GroupedTaskInfo.forSplitTasks(task1, task2, splitBounds)
}
- private fun freeformTasksGroupInfo(
+ private fun deskTasksGroupInfo(
+ deskId: Int,
freeformTaskIds: Array<Int>,
minimizedTaskIds: Array<Int> = emptyArray()
): GroupedTaskInfo {
- return GroupedTaskInfo.forFreeformTasks(
+ return GroupedTaskInfo.forDeskTasks(
+ deskId,
freeformTaskIds.map { createTaskInfo(it) }.toList(),
minimizedTaskIds.toSet())
}
@@ -346,9 +351,9 @@ class GroupedTaskInfoTest : ShellTestCase() {
singleTaskGroupInfo(id = 1)))
}
- private fun mixedTaskGroupInfoWithFreeformBase(): GroupedTaskInfo {
+ private fun mixedTaskGroupInfoWithDeskBase(): GroupedTaskInfo {
return GroupedTaskInfo.forMixed(listOf(
- freeformTasksGroupInfo(freeformTaskIds = arrayOf(2, 3, 4)),
+ deskTasksGroupInfo(deskId = 0, freeformTaskIds = arrayOf(2, 3, 4)),
singleTaskGroupInfo(id = 1)))
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
index a546b3ea7d8f..bf65caec88c7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
@@ -24,7 +24,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PERSISTENCE;
-import static com.android.wm.shell.shared.GroupedTaskInfo.TYPE_FREEFORM;
+import static com.android.wm.shell.shared.GroupedTaskInfo.TYPE_DESK;
import static com.android.wm.shell.shared.GroupedTaskInfo.TYPE_FULLSCREEN;
import static com.android.wm.shell.shared.GroupedTaskInfo.TYPE_SPLIT;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_50_50;
@@ -349,7 +349,7 @@ public class RecentTasksControllerTest extends ShellTestCase {
GroupedTaskInfo freeformGroup = recentTasks.get(2);
// Check that groups have expected types
- assertTrue(freeformGroup.isBaseType(TYPE_FREEFORM));
+ assertTrue(freeformGroup.isBaseType(TYPE_DESK));
assertTrue(singleGroup1.isBaseType(TYPE_FULLSCREEN));
assertTrue(singleGroup2.isBaseType(TYPE_FULLSCREEN));
@@ -389,7 +389,7 @@ public class RecentTasksControllerTest extends ShellTestCase {
// Check that groups have expected types
assertTrue(splitGroup.isBaseType(TYPE_SPLIT));
- assertTrue(freeformGroup.isBaseType(TYPE_FREEFORM));
+ assertTrue(freeformGroup.isBaseType(TYPE_DESK));
assertTrue(singleGroup.isBaseType(TYPE_FULLSCREEN));
// Check freeform group entries
@@ -460,7 +460,7 @@ public class RecentTasksControllerTest extends ShellTestCase {
GroupedTaskInfo freeformGroup = recentTasks.get(2);
// Check that groups have expected types
- assertTrue(freeformGroup.isBaseType(TYPE_FREEFORM));
+ assertTrue(freeformGroup.isBaseType(TYPE_DESK));
assertTrue(singleGroup1.isBaseType(TYPE_FULLSCREEN));
assertTrue(singleGroup2.isBaseType(TYPE_FULLSCREEN));
diff --git a/libs/hostgraphics/Fence.cpp b/libs/hostgraphics/Fence.cpp
index 4383bf02a00e..938a9384768d 100644
--- a/libs/hostgraphics/Fence.cpp
+++ b/libs/hostgraphics/Fence.cpp
@@ -18,6 +18,6 @@
namespace android {
-const sp<Fence> Fence::NO_FENCE = sp<Fence>(new Fence);
+const sp<Fence> Fence::NO_FENCE = sp<Fence>::make();
} // namespace android
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/layout-v35/settingslib_expressive_action_buttons.xml b/packages/SettingsLib/ActionButtonsPreference/res/layout-v36/settingslib_expressive_action_buttons.xml
index 3e73ebd4880e..3e73ebd4880e 100644
--- a/packages/SettingsLib/ActionButtonsPreference/res/layout-v35/settingslib_expressive_action_buttons.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/res/layout-v36/settingslib_expressive_action_buttons.xml
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/values-v35/styles_expressive.xml b/packages/SettingsLib/ActionButtonsPreference/res/values-v36/styles_expressive.xml
index 267c9f65e104..267c9f65e104 100644
--- a/packages/SettingsLib/ActionButtonsPreference/res/values-v35/styles_expressive.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/res/values-v36/styles_expressive.xml
diff --git a/packages/SettingsLib/BannerMessagePreference/res/drawable-v35/settingslib_expressive_card_background.xml b/packages/SettingsLib/BannerMessagePreference/res/drawable-v36/settingslib_expressive_card_background.xml
index a677a66f86e7..a677a66f86e7 100644
--- a/packages/SettingsLib/BannerMessagePreference/res/drawable-v35/settingslib_expressive_card_background.xml
+++ b/packages/SettingsLib/BannerMessagePreference/res/drawable-v36/settingslib_expressive_card_background.xml
diff --git a/packages/SettingsLib/BannerMessagePreference/res/drawable-v35/settingslib_resolved_banner_avd.xml b/packages/SettingsLib/BannerMessagePreference/res/drawable-v36/settingslib_resolved_banner_avd.xml
index c999de7d99ea..c999de7d99ea 100644
--- a/packages/SettingsLib/BannerMessagePreference/res/drawable-v35/settingslib_resolved_banner_avd.xml
+++ b/packages/SettingsLib/BannerMessagePreference/res/drawable-v36/settingslib_resolved_banner_avd.xml
diff --git a/packages/SettingsLib/BannerMessagePreference/res/layout-v35/settingslib_expressive_banner_message.xml b/packages/SettingsLib/BannerMessagePreference/res/layout-v36/settingslib_expressive_banner_message.xml
index c448a2d434f8..c448a2d434f8 100644
--- a/packages/SettingsLib/BannerMessagePreference/res/layout-v35/settingslib_expressive_banner_message.xml
+++ b/packages/SettingsLib/BannerMessagePreference/res/layout-v36/settingslib_expressive_banner_message.xml
diff --git a/packages/SettingsLib/BannerMessagePreference/res/values-v35/styles_expressive.xml b/packages/SettingsLib/BannerMessagePreference/res/values-v36/styles_expressive.xml
index 09e07ccef683..09e07ccef683 100644
--- a/packages/SettingsLib/BannerMessagePreference/res/values-v35/styles_expressive.xml
+++ b/packages/SettingsLib/BannerMessagePreference/res/values-v36/styles_expressive.xml
diff --git a/packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_filled.xml b/packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_filled.xml
index ff22b2e7f86f..ff22b2e7f86f 100644
--- a/packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_filled.xml
+++ b/packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_filled.xml
diff --git a/packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_filled_extra.xml b/packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_filled_extra.xml
index d878ba0d310b..d878ba0d310b 100644
--- a/packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_filled_extra.xml
+++ b/packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_filled_extra.xml
diff --git a/packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_filled_large.xml b/packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_filled_large.xml
index 8f0a158c55eb..8f0a158c55eb 100644
--- a/packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_filled_large.xml
+++ b/packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_filled_large.xml
diff --git a/packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_outline.xml b/packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_outline.xml
index 0c8996063e9f..0c8996063e9f 100644
--- a/packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_outline.xml
+++ b/packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_outline.xml
diff --git a/packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_outline_extra.xml b/packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_outline_extra.xml
index 41d8490feeb3..41d8490feeb3 100644
--- a/packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_outline_extra.xml
+++ b/packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_outline_extra.xml
diff --git a/packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_outline_large.xml b/packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_outline_large.xml
index 958552064c98..958552064c98 100644
--- a/packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_outline_large.xml
+++ b/packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_outline_large.xml
diff --git a/packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_tonal.xml b/packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_tonal.xml
index 03ca1f0a1033..03ca1f0a1033 100644
--- a/packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_tonal.xml
+++ b/packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_tonal.xml
diff --git a/packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_tonal_extra.xml b/packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_tonal_extra.xml
index 030ee66fef3f..030ee66fef3f 100644
--- a/packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_tonal_extra.xml
+++ b/packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_tonal_extra.xml
diff --git a/packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_tonal_large.xml b/packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_tonal_large.xml
index 5c16723f7a63..5c16723f7a63 100644
--- a/packages/SettingsLib/ButtonPreference/res/layout-v35/settingslib_expressive_button_tonal_large.xml
+++ b/packages/SettingsLib/ButtonPreference/res/layout-v36/settingslib_expressive_button_tonal_large.xml
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/drawable-v35/settingslib_expressive_icon_back.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/drawable-v36/settingslib_expressive_icon_back.xml
index 9986a60250fe..9986a60250fe 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/drawable-v35/settingslib_expressive_icon_back.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/drawable-v36/settingslib_expressive_icon_back.xml
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v35/settingslib_expressive_collapsing_toolbar_base_layout.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v36/settingslib_expressive_collapsing_toolbar_base_layout.xml
index b881c57e2f53..b881c57e2f53 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v35/settingslib_expressive_collapsing_toolbar_base_layout.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v36/settingslib_expressive_collapsing_toolbar_base_layout.xml
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v35/settingslib_expressive_collapsing_toolbar_content_layout.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v36/settingslib_expressive_collapsing_toolbar_content_layout.xml
index 6221659388d1..6221659388d1 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v35/settingslib_expressive_collapsing_toolbar_content_layout.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v36/settingslib_expressive_collapsing_toolbar_content_layout.xml
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-night-v35/themes.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-night-v36/themes.xml
index fadcf7ba8699..fadcf7ba8699 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-night-v35/themes.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-night-v36/themes.xml
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/styles.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v36/styles.xml
index 0f71a788e8c6..0f71a788e8c6 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/styles.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v36/styles.xml
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/styles_expressive.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v36/styles_expressive.xml
index 37a78101cc4e..37a78101cc4e 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/styles_expressive.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v36/styles_expressive.xml
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/themes.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v36/themes.xml
index 7c9d1a47b7ef..7c9d1a47b7ef 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/themes.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v36/themes.xml
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/themes_expressive.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v36/themes_expressive.xml
index ca1904a15b2f..ca1904a15b2f 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/themes_expressive.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v36/themes_expressive.xml
diff --git a/packages/SettingsLib/MainSwitchPreference/res/color-night-v35/settingslib_main_switch_text_color.xml b/packages/SettingsLib/MainSwitchPreference/res/color-night-v36/settingslib_main_switch_text_color.xml
index ea15a67e93cd..ea15a67e93cd 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/color-night-v35/settingslib_main_switch_text_color.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/color-night-v36/settingslib_main_switch_text_color.xml
diff --git a/packages/SettingsLib/MainSwitchPreference/res/color-v35/settingslib_main_switch_text_color.xml b/packages/SettingsLib/MainSwitchPreference/res/color-v36/settingslib_main_switch_text_color.xml
index ea15a67e93cd..ea15a67e93cd 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/color-v35/settingslib_main_switch_text_color.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/color-v36/settingslib_main_switch_text_color.xml
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable-v35/settingslib_expressive_switch_bar_bg.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable-v36/settingslib_expressive_switch_bar_bg.xml
index 3999e762ea9e..3999e762ea9e 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable-v35/settingslib_expressive_switch_bar_bg.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable-v36/settingslib_expressive_switch_bar_bg.xml
diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout-v35/settingslib_expressive_main_switch_bar.xml b/packages/SettingsLib/MainSwitchPreference/res/layout-v36/settingslib_expressive_main_switch_bar.xml
index f75d9b23c49b..f75d9b23c49b 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/layout-v35/settingslib_expressive_main_switch_bar.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/layout-v36/settingslib_expressive_main_switch_bar.xml
diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout-v35/settingslib_expressive_main_switch_layout.xml b/packages/SettingsLib/MainSwitchPreference/res/layout-v36/settingslib_expressive_main_switch_layout.xml
index 94c6924a02f2..94c6924a02f2 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/layout-v35/settingslib_expressive_main_switch_layout.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/layout-v36/settingslib_expressive_main_switch_layout.xml
diff --git a/packages/SettingsLib/ProfileSelector/res/color-night-v35/settingslib_tabs_indicator_color.xml b/packages/SettingsLib/ProfileSelector/res/color-night-v36/settingslib_tabs_indicator_color.xml
index 5192a9a53572..5192a9a53572 100644
--- a/packages/SettingsLib/ProfileSelector/res/color-night-v35/settingslib_tabs_indicator_color.xml
+++ b/packages/SettingsLib/ProfileSelector/res/color-night-v36/settingslib_tabs_indicator_color.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/color-night-v35/settingslib_switch_track_outline_color.xml b/packages/SettingsLib/SettingsTheme/res/color-night-v36/settingslib_switch_track_outline_color.xml
index eedc364ff54b..eedc364ff54b 100644
--- a/packages/SettingsLib/SettingsTheme/res/color-night-v35/settingslib_switch_track_outline_color.xml
+++ b/packages/SettingsLib/SettingsTheme/res/color-night-v36/settingslib_switch_track_outline_color.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/color-v35/settingslib_expressive_color_main_switch_track.xml b/packages/SettingsLib/SettingsTheme/res/color-v36/settingslib_expressive_color_main_switch_track.xml
index a6885a4ac358..a6885a4ac358 100644
--- a/packages/SettingsLib/SettingsTheme/res/color-v35/settingslib_expressive_color_main_switch_track.xml
+++ b/packages/SettingsLib/SettingsTheme/res/color-v36/settingslib_expressive_color_main_switch_track.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/color-v35/settingslib_preference_bg_color.xml b/packages/SettingsLib/SettingsTheme/res/color-v36/settingslib_preference_bg_color.xml
index cece9665b729..cece9665b729 100644
--- a/packages/SettingsLib/SettingsTheme/res/color-v35/settingslib_preference_bg_color.xml
+++ b/packages/SettingsLib/SettingsTheme/res/color-v36/settingslib_preference_bg_color.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/color-v35/settingslib_switch_track_outline_color.xml b/packages/SettingsLib/SettingsTheme/res/color-v36/settingslib_switch_track_outline_color.xml
index eedc364ff54b..eedc364ff54b 100644
--- a/packages/SettingsLib/SettingsTheme/res/color-v35/settingslib_switch_track_outline_color.xml
+++ b/packages/SettingsLib/SettingsTheme/res/color-v36/settingslib_switch_track_outline_color.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/color-v35/settingslib_text_color_primary.xml b/packages/SettingsLib/SettingsTheme/res/color-v36/settingslib_text_color_primary.xml
index 230eb7d30aea..230eb7d30aea 100644
--- a/packages/SettingsLib/SettingsTheme/res/color-v35/settingslib_text_color_primary.xml
+++ b/packages/SettingsLib/SettingsTheme/res/color-v36/settingslib_text_color_primary.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/color-v35/settingslib_text_color_secondary.xml b/packages/SettingsLib/SettingsTheme/res/color-v36/settingslib_text_color_secondary.xml
index 5bd2a29ccf9a..5bd2a29ccf9a 100644
--- a/packages/SettingsLib/SettingsTheme/res/color-v35/settingslib_text_color_secondary.xml
+++ b/packages/SettingsLib/SettingsTheme/res/color-v36/settingslib_text_color_secondary.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_arrow_drop_down.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_arrow_drop_down.xml
index 875524775a3c..875524775a3c 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_arrow_drop_down.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_arrow_drop_down.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_list_divider.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_list_divider.xml
index c17f7ee8c61e..c17f7ee8c61e 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_list_divider.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_list_divider.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_progress_horizontal.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_progress_horizontal.xml
index 3cb34354de17..3cb34354de17 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_progress_horizontal.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_progress_horizontal.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background.xml
index 9aa0bc39c5d8..9aa0bc39c5d8 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_bottom.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom.xml
index 554cba565383..554cba565383 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_bottom.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_bottom_highlighted.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom_highlighted.xml
index c0c08699cc2a..c0c08699cc2a 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_bottom_highlighted.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom_highlighted.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_bottom_selected.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom_selected.xml
index 543b237373fb..543b237373fb 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_bottom_selected.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom_selected.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_center.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center.xml
index b89a0ddcdec5..b89a0ddcdec5 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_center.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_center_highlighted.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center_highlighted.xml
index 8099d9b3d7f7..8099d9b3d7f7 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_center_highlighted.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center_highlighted.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_center_selected.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center_selected.xml
index 6d2cd1a51620..6d2cd1a51620 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_center_selected.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center_selected.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_highlighted.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_highlighted.xml
index a119a4ae083f..a119a4ae083f 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_highlighted.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_highlighted.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_selected.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_selected.xml
index bcdbf1d19545..bcdbf1d19545 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_selected.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_selected.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_top.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top.xml
index 7955e4418ae9..7955e4418ae9 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_top.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_top_highlighted.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top_highlighted.xml
index 052eb01cab8d..052eb01cab8d 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_top_highlighted.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top_highlighted.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_top_selected.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top_selected.xml
index d4b658c384e6..d4b658c384e6 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_top_selected.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top_selected.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_spinner_background.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_spinner_background.xml
index 20ee38190b01..20ee38190b01 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_spinner_background.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_spinner_background.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_spinner_dropdown_background.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_spinner_dropdown_background.xml
index b287c3bb546f..b287c3bb546f 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_spinner_dropdown_background.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_spinner_dropdown_background.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_preference.xml b/packages/SettingsLib/SettingsTheme/res/layout-v36/settingslib_expressive_preference.xml
index 4ef747a99b49..4ef747a99b49 100644
--- a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_preference.xml
+++ b/packages/SettingsLib/SettingsTheme/res/layout-v36/settingslib_expressive_preference.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_preference_icon_frame.xml b/packages/SettingsLib/SettingsTheme/res/layout-v36/settingslib_expressive_preference_icon_frame.xml
index 19818e0b06da..19818e0b06da 100644
--- a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_preference_icon_frame.xml
+++ b/packages/SettingsLib/SettingsTheme/res/layout-v36/settingslib_expressive_preference_icon_frame.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_preference_switch.xml b/packages/SettingsLib/SettingsTheme/res/layout-v36/settingslib_expressive_preference_switch.xml
index 4abcd22d67cc..4abcd22d67cc 100644
--- a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_preference_switch.xml
+++ b/packages/SettingsLib/SettingsTheme/res/layout-v36/settingslib_expressive_preference_switch.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_two_target_divider.xml b/packages/SettingsLib/SettingsTheme/res/layout-v36/settingslib_expressive_two_target_divider.xml
index 9be9ec331984..9be9ec331984 100644
--- a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_two_target_divider.xml
+++ b/packages/SettingsLib/SettingsTheme/res/layout-v36/settingslib_expressive_two_target_divider.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/values-night-v35/colors.xml b/packages/SettingsLib/SettingsTheme/res/values-night-v36/colors.xml
index e31e80176625..e31e80176625 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-night-v35/colors.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-night-v36/colors.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v35/colors.xml b/packages/SettingsLib/SettingsTheme/res/values-v36/colors.xml
index b1b37b12c572..b1b37b12c572 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-v35/colors.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-v36/colors.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v35/dimens.xml b/packages/SettingsLib/SettingsTheme/res/values-v36/dimens.xml
index 193ae618e803..193ae618e803 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-v35/dimens.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-v36/dimens.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v35/styles_expressive.xml b/packages/SettingsLib/SettingsTheme/res/values-v36/styles_expressive.xml
index 3af88c48e8ca..3af88c48e8ca 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-v35/styles_expressive.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-v36/styles_expressive.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v35/styles_preference_expressive.xml b/packages/SettingsLib/SettingsTheme/res/values-v36/styles_preference_expressive.xml
index cec8e45e2bfb..cec8e45e2bfb 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-v35/styles_preference_expressive.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-v36/styles_preference_expressive.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v35/themes.xml b/packages/SettingsLib/SettingsTheme/res/values-v36/themes.xml
index b6e80c784f10..1c45ff6ca6cf 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-v35/themes.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-v36/themes.xml
@@ -16,7 +16,7 @@
-->
<resources>
- <style name="Theme.SettingsBase_v35" parent="Theme.SettingsBase_v33" >
+ <style name="Theme.SettingsBase_v36" parent="Theme.SettingsBase_v33" >
<item name="android:colorAccent">@color/settingslib_materialColorPrimary</item>
<item name="android:colorBackground">@color/settingslib_materialColorSurfaceContainer</item>
<item name="android:textColorPrimary">@color/settingslib_materialColorOnSurface</item>
@@ -27,5 +27,5 @@
<item name="android:clipChildren">false</item>
</style>
- <style name="Theme.SettingsBase" parent="Theme.SettingsBase_v35" />
+ <style name="Theme.SettingsBase" parent="Theme.SettingsBase_v36" />
</resources> \ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v35/themes_expressive.xml b/packages/SettingsLib/SettingsTheme/res/values-v36/themes_expressive.xml
index 14f214a96435..14f214a96435 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-v35/themes_expressive.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-v36/themes_expressive.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v35/themes_preference_expressive.xml b/packages/SettingsLib/SettingsTheme/res/values-v36/themes_preference_expressive.xml
index 41fe2250f0ad..41fe2250f0ad 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-v35/themes_preference_expressive.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-v36/themes_preference_expressive.xml
diff --git a/packages/SettingsLib/TwoTargetPreference/res/layout-v35/settingslib_expressive_preference_two_target.xml b/packages/SettingsLib/TwoTargetPreference/res/layout-v36/settingslib_expressive_preference_two_target.xml
index 4347ef29037d..4347ef29037d 100644
--- a/packages/SettingsLib/TwoTargetPreference/res/layout-v35/settingslib_expressive_preference_two_target.xml
+++ b/packages/SettingsLib/TwoTargetPreference/res/layout-v36/settingslib_expressive_preference_two_target.xml
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index eb5b22f6c82c..f2c76ba25079 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -1939,6 +1939,16 @@ flag {
}
flag {
+ name: "notification_appear_nonlinear"
+ namespace: "systemui"
+ description: "Fix linear usage of notification appear"
+ bug: "397658189"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "disable_shade_trackpad_two_finger_swipe"
namespace: "systemui"
description: "Disables expansion of the shade via two finger swipe on a trackpad"
diff --git a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/BouncerSceneModule.kt b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/BouncerOverlayModule.kt
index 5b368df9d0ef..426942439391 100644
--- a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/BouncerSceneModule.kt
+++ b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/BouncerOverlayModule.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * 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.
@@ -16,14 +16,13 @@
package com.android.systemui.scene
-import com.android.systemui.bouncer.ui.composable.BouncerScene
-import com.android.systemui.scene.ui.composable.Scene
+import com.android.systemui.bouncer.ui.composable.BouncerOverlay
+import com.android.systemui.scene.ui.composable.Overlay
import dagger.Binds
import dagger.Module
import dagger.multibindings.IntoSet
@Module
-interface BouncerSceneModule {
-
- @Binds @IntoSet fun bouncerScene(scene: BouncerScene): Scene
+interface BouncerOverlayModule {
+ @Binds @IntoSet fun bouncer(overlay: BouncerOverlay): Overlay
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt
index 456edaf1012e..48e52d6c5fb2 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt
@@ -98,7 +98,7 @@ import com.android.systemui.bouncer.shared.model.BouncerActionButtonModel
import com.android.systemui.bouncer.ui.BouncerDialogFactory
import com.android.systemui.bouncer.ui.viewmodel.AuthMethodBouncerViewModel
import com.android.systemui.bouncer.ui.viewmodel.BouncerMessageViewModel
-import com.android.systemui.bouncer.ui.viewmodel.BouncerSceneContentViewModel
+import com.android.systemui.bouncer.ui.viewmodel.BouncerOverlayContentViewModel
import com.android.systemui.bouncer.ui.viewmodel.MessageViewModel
import com.android.systemui.bouncer.ui.viewmodel.PasswordBouncerViewModel
import com.android.systemui.bouncer.ui.viewmodel.PatternBouncerViewModel
@@ -118,7 +118,7 @@ import platform.test.motion.compose.values.motionTestValues
@Composable
fun BouncerContent(
- viewModel: BouncerSceneContentViewModel,
+ viewModel: BouncerOverlayContentViewModel,
dialogFactory: BouncerDialogFactory,
modifier: Modifier = Modifier,
) {
@@ -131,8 +131,8 @@ fun BouncerContent(
@Composable
@VisibleForTesting
fun BouncerContent(
- layout: BouncerSceneLayout,
- viewModel: BouncerSceneContentViewModel,
+ layout: BouncerOverlayLayout,
+ viewModel: BouncerOverlayContentViewModel,
dialogFactory: BouncerDialogFactory,
modifier: Modifier,
) {
@@ -147,11 +147,12 @@ fun BouncerContent(
modifier = modifier.imePadding().onKeyEvent(viewModel::onKeyEvent).scale(scale)
) {
when (layout) {
- BouncerSceneLayout.STANDARD_BOUNCER -> StandardLayout(viewModel = viewModel)
- BouncerSceneLayout.BESIDE_USER_SWITCHER ->
+ BouncerOverlayLayout.STANDARD_BOUNCER -> StandardLayout(viewModel = viewModel)
+ BouncerOverlayLayout.BESIDE_USER_SWITCHER ->
BesideUserSwitcherLayout(viewModel = viewModel)
- BouncerSceneLayout.BELOW_USER_SWITCHER -> BelowUserSwitcherLayout(viewModel = viewModel)
- BouncerSceneLayout.SPLIT_BOUNCER -> SplitLayout(viewModel = viewModel)
+ BouncerOverlayLayout.BELOW_USER_SWITCHER ->
+ BelowUserSwitcherLayout(viewModel = viewModel)
+ BouncerOverlayLayout.SPLIT_BOUNCER -> SplitLayout(viewModel = viewModel)
}
Dialog(bouncerViewModel = viewModel, dialogFactory = dialogFactory)
@@ -163,7 +164,10 @@ fun BouncerContent(
* authentication attempt, including all messaging UI (directives, reasoning, errors, etc.).
*/
@Composable
-private fun StandardLayout(viewModel: BouncerSceneContentViewModel, modifier: Modifier = Modifier) {
+private fun StandardLayout(
+ viewModel: BouncerOverlayContentViewModel,
+ modifier: Modifier = Modifier,
+) {
val isHeightExpanded =
LocalWindowSizeClass.current.heightSizeClass == WindowHeightSizeClass.Expanded
@@ -208,7 +212,7 @@ private fun StandardLayout(viewModel: BouncerSceneContentViewModel, modifier: Mo
* by double-tapping on the side.
*/
@Composable
-private fun SplitLayout(viewModel: BouncerSceneContentViewModel, modifier: Modifier = Modifier) {
+private fun SplitLayout(viewModel: BouncerOverlayContentViewModel, modifier: Modifier = Modifier) {
val authMethod by viewModel.authMethodViewModel.collectAsStateWithLifecycle()
Row(
@@ -297,7 +301,7 @@ private fun SplitLayout(viewModel: BouncerSceneContentViewModel, modifier: Modif
*/
@Composable
private fun BesideUserSwitcherLayout(
- viewModel: BouncerSceneContentViewModel,
+ viewModel: BouncerOverlayContentViewModel,
modifier: Modifier = Modifier,
) {
val isLeftToRight = LocalLayoutDirection.current == LayoutDirection.Ltr
@@ -452,7 +456,7 @@ private fun BesideUserSwitcherLayout(
/** Arranges the bouncer contents and user switcher contents one on top of the other, vertically. */
@Composable
private fun BelowUserSwitcherLayout(
- viewModel: BouncerSceneContentViewModel,
+ viewModel: BouncerOverlayContentViewModel,
modifier: Modifier = Modifier,
) {
Column(modifier = modifier.padding(vertical = 128.dp)) {
@@ -483,7 +487,7 @@ private fun BelowUserSwitcherLayout(
@Composable
private fun FoldAware(
- viewModel: BouncerSceneContentViewModel,
+ viewModel: BouncerOverlayContentViewModel,
aboveFold: @Composable BoxScope.() -> Unit,
belowFold: @Composable BoxScope.() -> Unit,
modifier: Modifier = Modifier,
@@ -606,7 +610,7 @@ private fun StatusMessage(viewModel: BouncerMessageViewModel, modifier: Modifier
* For example, this can be the PIN shapes or password text field.
*/
@Composable
-private fun OutputArea(viewModel: BouncerSceneContentViewModel, modifier: Modifier = Modifier) {
+private fun OutputArea(viewModel: BouncerOverlayContentViewModel, modifier: Modifier = Modifier) {
val authMethodViewModel: AuthMethodBouncerViewModel? by
viewModel.authMethodViewModel.collectAsStateWithLifecycle()
when (val nonNullViewModel = authMethodViewModel) {
@@ -631,7 +635,7 @@ private fun OutputArea(viewModel: BouncerSceneContentViewModel, modifier: Modifi
*/
@Composable
private fun InputArea(
- viewModel: BouncerSceneContentViewModel,
+ viewModel: BouncerOverlayContentViewModel,
pinButtonRowVerticalSpacing: Dp,
centerPatternDotsVertically: Boolean,
modifier: Modifier = Modifier,
@@ -659,7 +663,7 @@ private fun InputArea(
}
@Composable
-private fun ActionArea(viewModel: BouncerSceneContentViewModel, modifier: Modifier = Modifier) {
+private fun ActionArea(viewModel: BouncerOverlayContentViewModel, modifier: Modifier = Modifier) {
val actionButton: BouncerActionButtonModel? by
viewModel.actionButton.collectAsStateWithLifecycle()
val appearFadeInAnimatable = remember { Animatable(0f) }
@@ -723,7 +727,7 @@ private fun ActionArea(viewModel: BouncerSceneContentViewModel, modifier: Modifi
@Composable
private fun Dialog(
- bouncerViewModel: BouncerSceneContentViewModel,
+ bouncerViewModel: BouncerOverlayContentViewModel,
dialogFactory: BouncerDialogFactory,
) {
val dialogViewModel by bouncerViewModel.dialogViewModel.collectAsStateWithLifecycle()
@@ -751,7 +755,7 @@ private fun Dialog(
/** Renders the UI of the user switcher that's displayed on large screens next to the bouncer UI. */
@Composable
-private fun UserSwitcher(viewModel: BouncerSceneContentViewModel, modifier: Modifier = Modifier) {
+private fun UserSwitcher(viewModel: BouncerOverlayContentViewModel, modifier: Modifier = Modifier) {
val isUserSwitcherVisible by viewModel.isUserSwitcherVisible.collectAsStateWithLifecycle()
if (!isUserSwitcherVisible) {
// Take up the same space as the user switcher normally would, but with nothing inside it.
@@ -829,7 +833,7 @@ private fun UserSwitcher(viewModel: BouncerSceneContentViewModel, modifier: Modi
@Composable
private fun UserSwitcherDropdownMenu(
isExpanded: Boolean,
- items: List<BouncerSceneContentViewModel.UserSwitcherDropdownItemViewModel>,
+ items: List<BouncerOverlayContentViewModel.UserSwitcherDropdownItemViewModel>,
onDismissed: () -> Unit,
) {
val context = LocalContext.current
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerOverlay.kt
index fad8ae7e3ba2..48dee240a1df 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerOverlay.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -29,19 +29,19 @@ import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.bouncer.ui.BouncerDialogFactory
-import com.android.systemui.bouncer.ui.viewmodel.BouncerSceneContentViewModel
+import com.android.systemui.bouncer.ui.viewmodel.BouncerOverlayContentViewModel
import com.android.systemui.bouncer.ui.viewmodel.BouncerUserActionsViewModel
import com.android.systemui.compose.modifiers.sysuiResTag
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.rememberViewModel
-import com.android.systemui.scene.shared.model.Scenes
-import com.android.systemui.scene.ui.composable.Scene
+import com.android.systemui.scene.shared.model.Overlays
+import com.android.systemui.scene.ui.composable.Overlay
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
object Bouncer {
object Elements {
+ val Root = ElementKey("BouncerRoot")
val Background = ElementKey("BouncerBackground")
val Content = ElementKey("BouncerContent")
}
@@ -51,16 +51,16 @@ object Bouncer {
}
}
-/** The bouncer scene displays authentication challenges like PIN, password, or pattern. */
+/** The bouncer overlay displays authentication challenges like PIN, password, or pattern. */
@SysUISingleton
-class BouncerScene
+class BouncerOverlay
@Inject
constructor(
private val actionsViewModelFactory: BouncerUserActionsViewModel.Factory,
- private val contentViewModelFactory: BouncerSceneContentViewModel.Factory,
+ private val contentViewModelFactory: BouncerOverlayContentViewModel.Factory,
private val dialogFactory: BouncerDialogFactory,
-) : ExclusiveActivatable(), Scene {
- override val key = Scenes.Bouncer
+) : Overlay {
+ override val key = Overlays.Bouncer
private val actionsViewModel: BouncerUserActionsViewModel by lazy {
actionsViewModelFactory.create()
@@ -68,22 +68,22 @@ constructor(
override val userActions: Flow<Map<UserAction, UserActionResult>> = actionsViewModel.actions
- override suspend fun onActivated(): Nothing {
+ override suspend fun activate(): Nothing {
actionsViewModel.activate()
}
@Composable
override fun ContentScope.Content(modifier: Modifier) =
- BouncerScene(
- viewModel = rememberViewModel("BouncerScene") { contentViewModelFactory.create() },
+ BouncerOverlay(
+ viewModel = rememberViewModel("BouncerOverlay") { contentViewModelFactory.create() },
dialogFactory = dialogFactory,
- modifier = modifier,
+ modifier = modifier.element(Bouncer.Elements.Root),
)
}
@Composable
-private fun ContentScope.BouncerScene(
- viewModel: BouncerSceneContentViewModel,
+private fun ContentScope.BouncerOverlay(
+ viewModel: BouncerOverlayContentViewModel,
dialogFactory: BouncerDialogFactory,
modifier: Modifier = Modifier,
) {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerSceneLayout.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerOverlayLayout.kt
index 328fec591b41..8651859dd556 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerSceneLayout.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerOverlayLayout.kt
@@ -23,12 +23,12 @@ import androidx.compose.runtime.Composable
import com.android.compose.windowsizeclass.LocalWindowSizeClass
/**
- * Returns the [BouncerSceneLayout] that should be used by the bouncer scene. If
- * [isOneHandedModeSupported] is `false`, then [BouncerSceneLayout.BESIDE_USER_SWITCHER] is replaced
- * by [BouncerSceneLayout.STANDARD_BOUNCER].
+ * Returns the [BouncerOverlayLayout] that should be used by the bouncer scene. If
+ * [isOneHandedModeSupported] is `false`, then [BouncerOverlayLayout.BESIDE_USER_SWITCHER] is
+ * replaced by [BouncerOverlayLayout.STANDARD_BOUNCER].
*/
@Composable
-fun calculateLayout(isOneHandedModeSupported: Boolean): BouncerSceneLayout {
+fun calculateLayout(isOneHandedModeSupported: Boolean): BouncerOverlayLayout {
val windowSizeClass = LocalWindowSizeClass.current
return calculateLayoutInternal(
@@ -57,7 +57,7 @@ private fun WindowHeightSizeClass.toEnum(): SizeClass {
}
/** Enumerates all known adaptive layout configurations. */
-enum class BouncerSceneLayout {
+enum class BouncerOverlayLayout {
/** The default UI with the bouncer laid out normally. */
STANDARD_BOUNCER,
/** The bouncer is displayed vertically stacked with the user switcher. */
@@ -84,21 +84,21 @@ fun calculateLayoutInternal(
width: SizeClass,
height: SizeClass,
isOneHandedModeSupported: Boolean,
-): BouncerSceneLayout {
+): BouncerOverlayLayout {
return when (height) {
- SizeClass.COMPACT -> BouncerSceneLayout.SPLIT_BOUNCER
+ SizeClass.COMPACT -> BouncerOverlayLayout.SPLIT_BOUNCER
SizeClass.MEDIUM ->
when (width) {
- SizeClass.COMPACT -> BouncerSceneLayout.STANDARD_BOUNCER
- SizeClass.MEDIUM -> BouncerSceneLayout.STANDARD_BOUNCER
- SizeClass.EXPANDED -> BouncerSceneLayout.BESIDE_USER_SWITCHER
+ SizeClass.COMPACT -> BouncerOverlayLayout.STANDARD_BOUNCER
+ SizeClass.MEDIUM -> BouncerOverlayLayout.STANDARD_BOUNCER
+ SizeClass.EXPANDED -> BouncerOverlayLayout.BESIDE_USER_SWITCHER
}
SizeClass.EXPANDED ->
when (width) {
- SizeClass.COMPACT -> BouncerSceneLayout.STANDARD_BOUNCER
- SizeClass.MEDIUM -> BouncerSceneLayout.BELOW_USER_SWITCHER
- SizeClass.EXPANDED -> BouncerSceneLayout.BESIDE_USER_SWITCHER
+ SizeClass.COMPACT -> BouncerOverlayLayout.STANDARD_BOUNCER
+ SizeClass.MEDIUM -> BouncerOverlayLayout.BELOW_USER_SWITCHER
+ SizeClass.EXPANDED -> BouncerOverlayLayout.BESIDE_USER_SWITCHER
}
- }.takeIf { it != BouncerSceneLayout.BESIDE_USER_SWITCHER || isOneHandedModeSupported }
- ?: BouncerSceneLayout.STANDARD_BOUNCER
+ }.takeIf { it != BouncerOverlayLayout.BESIDE_USER_SWITCHER || isOneHandedModeSupported }
+ ?: BouncerOverlayLayout.STANDARD_BOUNCER
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationLockscreenScrim.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationLockscreenScrim.kt
index ef8911dae566..624c56099e25 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationLockscreenScrim.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationLockscreenScrim.kt
@@ -31,6 +31,7 @@ import androidx.compose.ui.graphics.graphicsLayer
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.animation.scene.ContentScope
import com.android.compose.animation.scene.content.state.TransitionState
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationLockscreenScrimViewModel
@@ -100,7 +101,7 @@ fun ContentScope.NotificationLockscreenScrim(
val isBouncerToLockscreen =
layoutState.currentTransition?.isTransitioning(
- from = Scenes.Bouncer,
+ from = Overlays.Bouncer,
to = Scenes.Lockscreen,
) ?: false
@@ -120,5 +121,5 @@ private fun shouldShowScrimFadeOut(
return shadeMode != ShadeMode.Dual &&
currentTransition.isInitiatedByUserInput &&
(currentTransition.isTransitioning(from = Scenes.Shade, to = Scenes.Lockscreen) ||
- currentTransition.isTransitioning(from = Scenes.Bouncer, to = Scenes.Lockscreen))
+ currentTransition.isTransitioning(from = Overlays.Bouncer, to = Scenes.Lockscreen))
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt
index b826187578e0..fe5c72f930fa 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt
@@ -135,7 +135,8 @@ private fun ContentScope.stateForQuickSettingsContent(
}
}
is TransitionState.Transition.OverlayTransition ->
- error("Bad transition for QuickSettings scene: overlays not supported")
+ // Currently, no overlays use this QS impl, so we should make sure it's closed.
+ QSSceneAdapter.State.CLOSED
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerInterruptionHandler.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerInterruptionHandler.kt
index 7e99847a7200..4ff7f4815e7c 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerInterruptionHandler.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerInterruptionHandler.kt
@@ -20,9 +20,11 @@ import com.android.compose.animation.scene.InterruptionHandler
import com.android.compose.animation.scene.InterruptionResult
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.content.state.TransitionState
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.ui.composable.transitions.TO_BOUNCER_FADE_FRACTION
+// TODO(b/394632609) update this class to handle Bouncer as an Overlay
object SceneContainerInterruptionHandler : InterruptionHandler {
override fun onInterruption(
interrupted: TransitionState.Transition.ChangeScene,
@@ -39,7 +41,7 @@ object SceneContainerInterruptionHandler : InterruptionHandler {
transition: TransitionState.Transition.ChangeScene,
targetScene: SceneKey,
): InterruptionResult? {
- if (targetScene != Scenes.Gone || !transition.isTransitioningFromOrTo(Scenes.Bouncer)) {
+ if (targetScene != Scenes.Gone || !transition.isTransitioningFromOrTo(Overlays.Bouncer)) {
return null
}
@@ -48,7 +50,7 @@ object SceneContainerInterruptionHandler : InterruptionHandler {
// usually the Lockscreen scene).
val otherScene: SceneKey
val animatesFromBouncer =
- if (transition.isTransitioning(to = Scenes.Bouncer)) {
+ if (transition.isTransitioning(to = Overlays.Bouncer)) {
otherScene = transition.fromScene
transition.progress >= TO_BOUNCER_FADE_FRACTION
} else {
@@ -58,7 +60,7 @@ object SceneContainerInterruptionHandler : InterruptionHandler {
return if (animatesFromBouncer) {
InterruptionResult(
- animateFrom = Scenes.Bouncer,
+ animateFrom = Scenes.Lockscreen,
// We don't want the content of the lockscreen to be shown during the Bouncer =>
// Launcher transition. We disable chaining of the transitions so that only the
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt
index 2ad9b7a10ad1..7fe19fe70a25 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt
@@ -1,5 +1,6 @@
package com.android.systemui.scene.ui.composable
+import com.android.compose.animation.scene.DefaultInterruptionHandler
import com.android.compose.animation.scene.SceneTransitions
import com.android.compose.animation.scene.TransitionKey
import com.android.compose.animation.scene.reveal.ContainerRevealHaptics
@@ -29,6 +30,7 @@ import com.android.systemui.scene.ui.composable.transitions.lockscreenToQuickSet
import com.android.systemui.scene.ui.composable.transitions.lockscreenToShadeTransition
import com.android.systemui.scene.ui.composable.transitions.lockscreenToSplitShadeTransition
import com.android.systemui.scene.ui.composable.transitions.shadeToQuickSettingsTransition
+import com.android.systemui.scene.ui.composable.transitions.toBouncerTransition
import com.android.systemui.scene.ui.composable.transitions.toNotificationsShadeTransition
import com.android.systemui.scene.ui.composable.transitions.toQuickSettingsShadeTransition
import com.android.systemui.shade.ui.composable.Shade
@@ -48,12 +50,10 @@ import com.android.systemui.shade.ui.composable.Shade
class SceneContainerTransitions : SceneContainerTransitionsBuilder {
override fun build(revealHaptics: ContainerRevealHaptics): SceneTransitions {
return transitions {
- interruptionHandler = SceneContainerInterruptionHandler
+ interruptionHandler = DefaultInterruptionHandler
// Scene transitions
- from(Scenes.Bouncer, to = Scenes.Gone) { bouncerToGoneTransition() }
- from(Scenes.Dream, to = Scenes.Bouncer) { dreamToBouncerTransition() }
from(Scenes.Dream, to = Scenes.Communal) { dreamToCommunalTransition() }
from(Scenes.Dream, to = Scenes.Gone) { dreamToGoneTransition() }
from(
@@ -102,15 +102,6 @@ class SceneContainerTransitions : SceneContainerTransitionsBuilder {
goneToQuickSettingsTransition(durationScale = 0.9)
}
- from(Scenes.Lockscreen, to = Scenes.Bouncer) { lockscreenToBouncerTransition() }
- from(
- Scenes.Lockscreen,
- to = Scenes.Bouncer,
- key = TransitionKey.PredictiveBack,
- reversePreview = { bouncerToLockscreenPreview() },
- ) {
- lockscreenToBouncerTransition()
- }
from(Scenes.Lockscreen, to = Scenes.Communal) { lockscreenToCommunalTransition() }
from(Scenes.Lockscreen, to = Scenes.Dream) { lockscreenToDreamTransition() }
from(
@@ -190,10 +181,22 @@ class SceneContainerTransitions : SceneContainerTransitionsBuilder {
) {
communalToShadeTransition()
}
- from(Scenes.Communal, to = Scenes.Bouncer) { communalToBouncerTransition() }
// Overlay transitions
+ to(Overlays.Bouncer) { toBouncerTransition() }
+ from(Overlays.Bouncer, to = Scenes.Gone) { bouncerToGoneTransition() }
+ from(Scenes.Dream, to = Overlays.Bouncer) { dreamToBouncerTransition() }
+ from(Scenes.Lockscreen, to = Overlays.Bouncer) { lockscreenToBouncerTransition() }
+ from(
+ Scenes.Lockscreen,
+ to = Overlays.Bouncer,
+ key = TransitionKey.PredictiveBack,
+ reversePreview = { bouncerToLockscreenPreview() },
+ ) {
+ lockscreenToBouncerTransition()
+ }
+ from(Scenes.Communal, to = Overlays.Bouncer) { communalToBouncerTransition() }
to(
Overlays.NotificationsShade,
cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, // NOTYPO
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromBouncerToGoneTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromBouncerToGoneTransition.kt
index 5eefe490ab5b..27cdf21f0697 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromBouncerToGoneTransition.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromBouncerToGoneTransition.kt
@@ -2,10 +2,10 @@ package com.android.systemui.scene.ui.composable.transitions
import androidx.compose.animation.core.tween
import com.android.compose.animation.scene.TransitionBuilder
-import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.bouncer.ui.composable.Bouncer
fun TransitionBuilder.bouncerToGoneTransition() {
spec = tween(durationMillis = 500)
- fade(Scenes.Bouncer.rootElementKey)
+ fade(Bouncer.Elements.Root)
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/ObservableTransitionState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/ObservableTransitionState.kt
index 5bf77ae9b23c..f7f0bf19dda6 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/ObservableTransitionState.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/ObservableTransitionState.kt
@@ -220,13 +220,70 @@ sealed interface ObservableTransitionState {
isInPreviewStage,
)
}
+
+ fun showOverlay(
+ overlay: OverlayKey,
+ fromScene: SceneKey,
+ currentOverlays: Flow<Set<OverlayKey>>,
+ progress: Flow<Float>,
+ isInitiatedByUserInput: Boolean,
+ isUserInputOngoing: Flow<Boolean>,
+ previewProgress: Flow<Float> = flowOf(0f),
+ isInPreviewStage: Flow<Boolean> = flowOf(false),
+ ): ShowOrHideOverlay {
+ return ShowOrHideOverlay(
+ overlay = overlay,
+ fromContent = fromScene,
+ toContent = overlay,
+ currentScene = fromScene,
+ currentOverlays = currentOverlays,
+ progress = progress,
+ isInitiatedByUserInput = isInitiatedByUserInput,
+ isUserInputOngoing = isUserInputOngoing,
+ previewProgress = previewProgress,
+ isInPreviewStage = isInPreviewStage,
+ )
+ }
+
+ fun hideOverlay(
+ overlay: OverlayKey,
+ toScene: SceneKey,
+ currentOverlays: Flow<Set<OverlayKey>>,
+ progress: Flow<Float>,
+ isInitiatedByUserInput: Boolean,
+ isUserInputOngoing: Flow<Boolean>,
+ previewProgress: Flow<Float> = flowOf(0f),
+ isInPreviewStage: Flow<Boolean> = flowOf(false),
+ ): ShowOrHideOverlay {
+ return ShowOrHideOverlay(
+ overlay = overlay,
+ fromContent = overlay,
+ toContent = toScene,
+ currentScene = toScene,
+ currentOverlays = currentOverlays,
+ progress = progress,
+ isInitiatedByUserInput = isInitiatedByUserInput,
+ isUserInputOngoing = isUserInputOngoing,
+ previewProgress = previewProgress,
+ isInPreviewStage = isInPreviewStage,
+ )
+ }
}
}
- fun isIdle(scene: SceneKey? = null): Boolean {
- return this is Idle && (scene == null || this.currentScene == scene)
+ fun isIdle(scene: SceneKey? = null, overlay: OverlayKey? = null): Boolean {
+ return this is Idle &&
+ (scene == null || this.currentScene == scene) &&
+ (overlay == null || overlay in this.currentOverlays)
}
+ fun isIdle(content: ContentKey?): Boolean =
+ when (content) {
+ is SceneKey -> isIdle(scene = content)
+ is OverlayKey -> isIdle(overlay = content)
+ null -> this is Idle
+ }
+
fun isTransitioning(from: ContentKey? = null, to: ContentKey? = null): Boolean {
return this is Transition &&
(from == null || this.fromContent == from) &&
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 72bb82bd41bb..f423bab5381f 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
@@ -447,7 +447,7 @@ sealed class UserAction {
}
infix fun to(overlay: OverlayKey): Pair<UserAction, UserActionResult> {
- return this to UserActionResult(toOverlay = overlay)
+ return this to UserActionResult.ShowOverlay(overlay)
}
/** Resolve this into a [Resolved] user action given [layoutDirection]. */
@@ -677,22 +677,6 @@ sealed class UserActionResult(
*/
requiresFullDistanceSwipe: Boolean = false,
): UserActionResult = ChangeScene(toScene, transitionKey, requiresFullDistanceSwipe)
-
- /** A [UserActionResult] that shows [toOverlay]. */
- operator fun invoke(
- /** The overlay we should be transitioning to during the [UserAction]. */
- toOverlay: OverlayKey,
-
- /** The key of the transition that should be used. */
- transitionKey: TransitionKey? = null,
-
- /**
- * If `true`, the swipe will be committed if only if the user swiped at least the swipe
- * distance, i.e. the transition progress was already equal to or bigger than 100% when
- * the user released their finger.
- */
- requiresFullDistanceSwipe: Boolean = false,
- ): UserActionResult = ShowOverlay(toOverlay, transitionKey, requiresFullDistanceSwipe)
}
}
diff --git a/packages/SystemUI/lint.xml b/packages/SystemUI/lint.xml
index 59a71099bb3f..bef2edd436e2 100644
--- a/packages/SystemUI/lint.xml
+++ b/packages/SystemUI/lint.xml
@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<lint>
+<!-- TODO(397519800): Remove hard coded once ASfP is capable of configuring this automatically -->
+<lint lintJars="../../../../out/soong/.intermediates/frameworks/base/packages/SystemUI/checks/SystemUILintChecker/linux_glibc_common/combined/SystemUILintChecker.jar">
<issue id="PrivateResource" severity="ignore" />
-</lint> \ No newline at end of file
+</lint>
diff --git a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
index 24b9e847d621..189d554415d0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
@@ -43,6 +43,7 @@ import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants
import com.android.systemui.classifier.FalsingA11yDelegate
import com.android.systemui.classifier.FalsingCollector
+import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
@@ -65,6 +66,7 @@ import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.FakeSceneDataSource
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.fakeSceneDataSource
import com.android.systemui.statusbar.policy.ConfigurationController
@@ -797,6 +799,9 @@ class KeyguardSecurityContainerControllerTest : SysuiTestCase() {
@EnableSceneContainer
fun dismissesKeyguard_whenSceneChangesToGone() =
kosmos.testScope.runTest {
+ // Collect sceneInteractor.currentOverlays so that show/hideOverlay receive updated
+ // overlay state during validation
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
// Upon init, we have never dismisses the keyguard.
underTest.onInit()
runCurrent()
@@ -807,19 +812,24 @@ class KeyguardSecurityContainerControllerTest : SysuiTestCase() {
// is not enough to trigger a dismissal of the keyguard.
underTest.onViewAttached()
fakeSceneDataSource.pause()
- sceneInteractor.changeScene(Scenes.Bouncer, "reason")
+ sceneInteractor.changeScene(Scenes.Lockscreen, "reason")
+ sceneInteractor.showOverlay(Overlays.Bouncer, "reason")
sceneTransitionStateFlow.value =
- ObservableTransitionState.Transition(
- Scenes.Lockscreen,
- Scenes.Bouncer,
- flowOf(Scenes.Bouncer),
- flowOf(.5f),
- false,
+ ObservableTransitionState.Transition.showOverlay(
+ overlay = Overlays.Bouncer,
+ fromScene = Scenes.Lockscreen,
+ currentOverlays = flowOf(setOf(Overlays.Bouncer)),
+ progress = flowOf(.5f),
+ isInitiatedByUserInput = false,
isUserInputOngoing = flowOf(false),
)
runCurrent()
- fakeSceneDataSource.unpause(expectedScene = Scenes.Bouncer)
- sceneTransitionStateFlow.value = ObservableTransitionState.Idle(Scenes.Bouncer)
+ fakeSceneDataSource.unpause(expectedOverlays = setOf(Overlays.Bouncer))
+ sceneTransitionStateFlow.value =
+ ObservableTransitionState.Idle(
+ currentScene = Scenes.Lockscreen,
+ currentOverlays = setOf(Overlays.Bouncer),
+ )
runCurrent()
verify(primaryBouncerInteractor, never())
.notifyKeyguardAuthenticatedPrimaryAuth(anyInt())
@@ -832,17 +842,18 @@ class KeyguardSecurityContainerControllerTest : SysuiTestCase() {
runCurrent()
fakeSceneDataSource.pause()
sceneInteractor.changeScene(Scenes.Gone, "reason")
+ sceneInteractor.hideOverlay(Overlays.Bouncer, "reason")
sceneTransitionStateFlow.value =
- ObservableTransitionState.Transition(
- Scenes.Bouncer,
- Scenes.Gone,
- flowOf(Scenes.Gone),
- flowOf(.5f),
- false,
+ ObservableTransitionState.Transition.hideOverlay(
+ overlay = Overlays.Bouncer,
+ toScene = Scenes.Gone,
+ currentOverlays = flowOf(emptySet()),
+ progress = flowOf(.5f),
+ isInitiatedByUserInput = false,
isUserInputOngoing = flowOf(false),
)
runCurrent()
- fakeSceneDataSource.unpause(expectedScene = Scenes.Gone)
+ fakeSceneDataSource.unpause(expectedScene = Scenes.Gone, expectedOverlays = emptySet())
sceneTransitionStateFlow.value = ObservableTransitionState.Idle(Scenes.Gone)
runCurrent()
verify(primaryBouncerInteractor).notifyKeyguardAuthenticatedPrimaryAuth(anyInt())
@@ -850,20 +861,30 @@ class KeyguardSecurityContainerControllerTest : SysuiTestCase() {
// While listening, moving back to the bouncer scene does not dismiss the keyguard
// again.
clearInvocations(primaryBouncerInteractor)
+
+ // switch to a different non-keyguard scene since showing overlay over Gone is
+ // prohibited
+ sceneInteractor.snapToScene(Scenes.Shade, "reason")
+ runCurrent()
+
fakeSceneDataSource.pause()
- sceneInteractor.changeScene(Scenes.Bouncer, "reason")
+ sceneInteractor.showOverlay(Overlays.Bouncer, "reason")
sceneTransitionStateFlow.value =
- ObservableTransitionState.Transition(
- Scenes.Gone,
- Scenes.Bouncer,
- flowOf(Scenes.Bouncer),
- flowOf(.5f),
- false,
+ ObservableTransitionState.Transition.showOverlay(
+ overlay = Overlays.Bouncer,
+ fromScene = Scenes.Shade,
+ currentOverlays = flowOf(setOf(Overlays.Bouncer)),
+ progress = flowOf(.5f),
+ isInitiatedByUserInput = false,
isUserInputOngoing = flowOf(false),
)
runCurrent()
- fakeSceneDataSource.unpause(expectedScene = Scenes.Bouncer)
- sceneTransitionStateFlow.value = ObservableTransitionState.Idle(Scenes.Bouncer)
+ fakeSceneDataSource.unpause(expectedOverlays = setOf(Overlays.Bouncer))
+ sceneTransitionStateFlow.value =
+ ObservableTransitionState.Idle(
+ currentScene = Scenes.Lockscreen,
+ currentOverlays = setOf(Overlays.Bouncer),
+ )
runCurrent()
verify(primaryBouncerInteractor, never())
.notifyKeyguardAuthenticatedPrimaryAuth(anyInt())
@@ -874,17 +895,18 @@ class KeyguardSecurityContainerControllerTest : SysuiTestCase() {
underTest.onViewDetached()
fakeSceneDataSource.pause()
sceneInteractor.changeScene(Scenes.Gone, "reason")
+ sceneInteractor.hideOverlay(Overlays.Bouncer, "reason")
sceneTransitionStateFlow.value =
- ObservableTransitionState.Transition(
- Scenes.Bouncer,
- Scenes.Gone,
- flowOf(Scenes.Gone),
- flowOf(.5f),
- false,
+ ObservableTransitionState.Transition.hideOverlay(
+ overlay = Overlays.Bouncer,
+ toScene = Scenes.Gone,
+ currentOverlays = flowOf(emptySet()),
+ progress = flowOf(.5f),
+ isInitiatedByUserInput = false,
isUserInputOngoing = flowOf(false),
)
runCurrent()
- fakeSceneDataSource.unpause(expectedScene = Scenes.Gone)
+ fakeSceneDataSource.unpause(expectedScene = Scenes.Gone, expectedOverlays = emptySet())
sceneTransitionStateFlow.value = ObservableTransitionState.Idle(Scenes.Gone)
runCurrent()
verify(primaryBouncerInteractor, never())
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerActionButtonInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerActionButtonInteractorTest.kt
index f376e932e70b..40295a242b2a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerActionButtonInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerActionButtonInteractorTest.kt
@@ -33,6 +33,7 @@ import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.fake
@@ -94,7 +95,8 @@ class BouncerActionButtonInteractorTest : SysuiTestCase() {
kosmos.telecomManager = telecomManager
- kosmos.sceneInteractor.changeScene(Scenes.Bouncer, "")
+ kosmos.sceneInteractor.changeScene(Scenes.Lockscreen, "")
+ kosmos.sceneInteractor.showOverlay(Overlays.Bouncer, "")
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerSceneLayoutTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerOverlayLayoutTest.kt
index b4b41787d833..2d0dd49242af 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerSceneLayoutTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerOverlayLayoutTest.kt
@@ -18,10 +18,10 @@ package com.android.systemui.bouncer.ui.composable
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.bouncer.ui.composable.BouncerSceneLayout.BELOW_USER_SWITCHER
-import com.android.systemui.bouncer.ui.composable.BouncerSceneLayout.BESIDE_USER_SWITCHER
-import com.android.systemui.bouncer.ui.composable.BouncerSceneLayout.SPLIT_BOUNCER
-import com.android.systemui.bouncer.ui.composable.BouncerSceneLayout.STANDARD_BOUNCER
+import com.android.systemui.bouncer.ui.composable.BouncerOverlayLayout.BELOW_USER_SWITCHER
+import com.android.systemui.bouncer.ui.composable.BouncerOverlayLayout.BESIDE_USER_SWITCHER
+import com.android.systemui.bouncer.ui.composable.BouncerOverlayLayout.SPLIT_BOUNCER
+import com.android.systemui.bouncer.ui.composable.BouncerOverlayLayout.STANDARD_BOUNCER
import com.google.common.truth.Truth.assertThat
import java.util.Locale
import org.junit.Test
@@ -32,7 +32,7 @@ import platform.test.runner.parameterized.Parameters
@SmallTest
@RunWith(ParameterizedAndroidJunit4::class)
-class BouncerSceneLayoutTest : SysuiTestCase() {
+class BouncerOverlayLayoutTest : SysuiTestCase() {
data object Phone :
Device(
@@ -186,7 +186,7 @@ class BouncerSceneLayoutTest : SysuiTestCase() {
data class TestCase(
val device: Device,
val held: Held,
- val expected: BouncerSceneLayout,
+ val expected: BouncerOverlayLayout,
val isOneHandedModeSupported: Boolean = true,
) {
override fun toString(): String {
@@ -203,10 +203,10 @@ class BouncerSceneLayoutTest : SysuiTestCase() {
}
data class Expected(
- val whenNaturallyHeld: BouncerSceneLayout,
- val whenUnnaturallyHeld: BouncerSceneLayout,
+ val whenNaturallyHeld: BouncerOverlayLayout,
+ val whenUnnaturallyHeld: BouncerOverlayLayout,
) {
- fun layout(heldNaturally: Boolean): BouncerSceneLayout {
+ fun layout(heldNaturally: Boolean): BouncerOverlayLayout {
return if (heldNaturally) {
whenNaturallyHeld
} else {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerPredictiveBackTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerPredictiveBackTest.kt
index dda460a6198f..0fe649c867f2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerPredictiveBackTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerPredictiveBackTest.kt
@@ -43,11 +43,10 @@ import com.android.compose.animation.scene.UserActionResult
import com.android.compose.animation.scene.isElement
import com.android.compose.theme.PlatformTheme
import com.android.systemui.SysuiTestCase
-import com.android.systemui.bouncer.domain.interactor.bouncerInteractor
import com.android.systemui.bouncer.ui.BouncerDialogFactory
-import com.android.systemui.bouncer.ui.viewmodel.BouncerSceneContentViewModel
+import com.android.systemui.bouncer.ui.viewmodel.BouncerOverlayContentViewModel
import com.android.systemui.bouncer.ui.viewmodel.BouncerUserActionsViewModel
-import com.android.systemui.bouncer.ui.viewmodel.bouncerSceneContentViewModel
+import com.android.systemui.bouncer.ui.viewmodel.bouncerOverlayContentViewModel
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
@@ -59,6 +58,7 @@ import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.domain.startable.sceneContainerStartable
import com.android.systemui.scene.sceneContainerViewModelFactory
import com.android.systemui.scene.sceneTransitionsBuilder
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.SceneContainerConfig
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.sceneDataSourceDelegator
@@ -103,10 +103,10 @@ class BouncerPredictiveBackTest : SysuiTestCase() {
motionTestRule.toolkit.composeContentTestRule as AndroidComposeTestRule<*, *>
private val sceneInteractor by lazy { kosmos.sceneInteractor }
- private val Kosmos.sceneKeys by Fixture { listOf(Scenes.Lockscreen, Scenes.Bouncer) }
- private val Kosmos.initialSceneKey by Fixture { Scenes.Bouncer }
+ private val Kosmos.sceneKeys by Fixture { listOf(Scenes.Lockscreen) }
+ private val Kosmos.initialSceneKey by Fixture { Scenes.Lockscreen }
private val Kosmos.sceneContainerConfig by Fixture {
- val navigationDistances = mapOf(Scenes.Lockscreen to 1, Scenes.Bouncer to 0)
+ val navigationDistances = mapOf(Scenes.Lockscreen to 1)
SceneContainerConfig(
sceneKeys,
initialSceneKey,
@@ -137,17 +137,17 @@ class BouncerPredictiveBackTest : SysuiTestCase() {
}
private val bouncerSceneActionsViewModelFactory =
object : BouncerUserActionsViewModel.Factory {
- override fun create() = BouncerUserActionsViewModel(kosmos.bouncerInteractor)
+ override fun create() = BouncerUserActionsViewModel()
}
- private lateinit var bouncerSceneContentViewModel: BouncerSceneContentViewModel
- private val bouncerSceneContentViewModelFactory =
- object : BouncerSceneContentViewModel.Factory {
- override fun create() = bouncerSceneContentViewModel
+ private lateinit var mBouncerOverlayContentViewModel: BouncerOverlayContentViewModel
+ private val mBouncerOverlayContentViewModelFactory =
+ object : BouncerOverlayContentViewModel.Factory {
+ override fun create() = mBouncerOverlayContentViewModel
}
private val bouncerScene =
- BouncerScene(
+ BouncerOverlay(
bouncerSceneActionsViewModelFactory,
- bouncerSceneContentViewModelFactory,
+ mBouncerOverlayContentViewModelFactory,
bouncerDialogFactory,
)
@@ -155,7 +155,7 @@ class BouncerPredictiveBackTest : SysuiTestCase() {
fun setUp() {
MockitoAnnotations.initMocks(this)
- bouncerSceneContentViewModel = kosmos.bouncerSceneContentViewModel
+ mBouncerOverlayContentViewModel = kosmos.bouncerOverlayContentViewModel
val startable = kosmos.sceneContainerStartable
startable.start()
@@ -175,14 +175,10 @@ class BouncerPredictiveBackTest : SysuiTestCase() {
rememberViewModel("BouncerPredictiveBackTest") {
sceneContainerViewModel
},
- sceneByKey =
- mapOf(
- Scenes.Lockscreen to FakeLockscreen(),
- Scenes.Bouncer to bouncerScene,
- ),
- initialSceneKey = Scenes.Bouncer,
+ sceneByKey = mapOf(Scenes.Lockscreen to FakeLockscreen()),
+ initialSceneKey = Scenes.Lockscreen,
transitionsBuilder = kosmos.sceneTransitionsBuilder,
- overlayByKey = emptyMap(),
+ overlayByKey = mapOf(Overlays.Bouncer to bouncerScene),
dataSourceDelegator = kosmos.sceneDataSourceDelegator,
qsSceneAdapter = { kosmos.fakeQsSceneAdapter },
sceneJankMonitorFactory = kosmos.sceneJankMonitorFactory,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerOverlayContentViewModelTest.kt
index eef8d9f40458..9cc09bd406e7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerOverlayContentViewModelTest.kt
@@ -61,17 +61,17 @@ import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
@EnableSceneContainer
-class BouncerSceneContentViewModelTest : SysuiTestCase() {
+class BouncerOverlayContentViewModelTest : SysuiTestCase() {
private val kosmos = testKosmos()
private val testScope = kosmos.testScope
- private lateinit var underTest: BouncerSceneContentViewModel
+ private lateinit var underTest: BouncerOverlayContentViewModel
@Before
fun setUp() {
kosmos.sceneContainerStartable.start()
- underTest = kosmos.bouncerSceneContentViewModel
+ underTest = kosmos.bouncerOverlayContentViewModel
underTest.activateIn(testScope)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModelTest.kt
index e12fabfd199d..fe2f51fd52cd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModelTest.kt
@@ -27,6 +27,7 @@ import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.kosmos.testScope
import com.android.systemui.lifecycle.activateIn
import com.android.systemui.scene.domain.startable.sceneContainerStartable
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.fakeSceneDataSource
import com.android.systemui.testKosmos
@@ -62,13 +63,13 @@ class BouncerUserActionsViewModelTest : SysuiTestCase() {
kosmos.fakeSceneDataSource.changeScene(Scenes.QuickSettings)
runCurrent()
- kosmos.fakeSceneDataSource.changeScene(Scenes.Bouncer)
+ kosmos.fakeSceneDataSource.showOverlay(Overlays.Bouncer)
runCurrent()
assertThat(actions)
.containsEntriesExactly(
- Back to UserActionResult(Scenes.QuickSettings),
- Swipe.Down to UserActionResult(Scenes.QuickSettings),
+ Back to UserActionResult.HideOverlay(Overlays.Bouncer),
+ Swipe.Down to UserActionResult.HideOverlay(Overlays.Bouncer),
)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
index b2d245858196..7cfbf5efce68 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
@@ -22,7 +22,6 @@ import android.view.KeyEvent
import androidx.compose.ui.input.key.KeyEventType
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.compose.animation.scene.SceneKey
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
import com.android.systemui.authentication.domain.interactor.authenticationInteractor
@@ -38,7 +37,7 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.lifecycle.activateIn
import com.android.systemui.res.R
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.testKosmos
import com.android.systemui.user.data.model.SelectedUserModel
import com.android.systemui.user.data.model.SelectionStatus
@@ -86,12 +85,12 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
@Test
fun onShown() =
testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
val password by collectLastValue(underTest.password)
lockDeviceAndOpenPasswordBouncer()
assertThat(password).isEmpty()
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
assertThat(underTest.authenticationMethod).isEqualTo(AuthenticationMethodModel.Password)
}
@@ -111,14 +110,14 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
@Test
fun onPasswordInputChanged() =
testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
val password by collectLastValue(underTest.password)
lockDeviceAndOpenPasswordBouncer()
underTest.onPasswordInputChanged("password")
assertThat(password).isEqualTo("password")
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
}
@Test
@@ -152,7 +151,7 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Password
)
- switchToScene(Scenes.Bouncer)
+ showBouncer()
// No input entered.
@@ -185,7 +184,7 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
@Test
fun onShown_againAfterSceneChange_resetsPassword() =
testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
val password by collectLastValue(underTest.password)
lockDeviceAndOpenPasswordBouncer()
@@ -194,14 +193,14 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
assertThat(password).isEqualTo("password")
// The user doesn't confirm the password, but navigates back to the lockscreen instead.
- switchToScene(Scenes.Lockscreen)
+ hideBouncer()
// The user navigates to the bouncer again.
- switchToScene(Scenes.Bouncer)
+ showBouncer()
// Ensure the previously-entered password is not shown.
assertThat(password).isEmpty()
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
}
@Test
@@ -379,21 +378,28 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
assertThat(underTest.onKeyEvent(KeyEventType.KeyDown, KeyEvent.KEYCODE_SPACE)).isFalse()
}
- private fun TestScope.switchToScene(toScene: SceneKey) {
- val currentScene by collectLastValue(sceneInteractor.currentScene)
- val bouncerHidden = currentScene == Scenes.Bouncer && toScene != Scenes.Bouncer
- sceneInteractor.changeScene(toScene, "reason")
- if (bouncerHidden) underTest.onHidden()
+ private fun TestScope.showBouncer() {
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
+ sceneInteractor.showOverlay(Overlays.Bouncer, "reason")
runCurrent()
- assertThat(currentScene).isEqualTo(toScene)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
+ }
+
+ private fun TestScope.hideBouncer() {
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
+ sceneInteractor.hideOverlay(Overlays.Bouncer, "reason")
+ underTest.onHidden()
+ runCurrent()
+
+ assertThat(currentOverlays).doesNotContain(Overlays.Bouncer)
}
private fun TestScope.lockDeviceAndOpenPasswordBouncer() {
kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Password
)
- switchToScene(Scenes.Bouncer)
+ showBouncer()
}
private suspend fun TestScope.setLockout(isLockedOut: Boolean, failedAttemptCount: Int = 5) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
index ec7d1c3bea3e..4075d1158154 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
@@ -19,7 +19,6 @@ package com.android.systemui.bouncer.ui.viewmodel
import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.compose.animation.scene.SceneKey
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
@@ -36,7 +35,7 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.lifecycle.activateIn
import com.android.systemui.res.R
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.testKosmos
import com.google.android.msdl.data.model.MSDLToken
import com.google.common.truth.Truth.assertThat
@@ -58,7 +57,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
private val testScope = kosmos.testScope
private val authenticationInteractor by lazy { kosmos.authenticationInteractor }
private val sceneInteractor by lazy { kosmos.sceneInteractor }
- private val bouncerViewModel by lazy { kosmos.bouncerSceneContentViewModel }
+ private val bouncerViewModel by lazy { kosmos.bouncerOverlayContentViewModel }
private val msdlPlayer: FakeMSDLPlayer = kosmos.fakeMSDLPlayer
private val bouncerHapticHelper = kosmos.bouncerHapticPlayer
private val underTest =
@@ -81,21 +80,21 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
@Test
fun onShown() =
testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
val selectedDots by collectLastValue(underTest.selectedDots)
val currentDot by collectLastValue(underTest.currentDot)
lockDeviceAndOpenPatternBouncer()
assertThat(selectedDots).isEmpty()
assertThat(currentDot).isNull()
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
assertThat(underTest.authenticationMethod).isEqualTo(AuthenticationMethodModel.Pattern)
}
@Test
fun onDragStart() =
testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
val selectedDots by collectLastValue(underTest.selectedDots)
val currentDot by collectLastValue(underTest.currentDot)
lockDeviceAndOpenPatternBouncer()
@@ -104,7 +103,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
assertThat(selectedDots).isEmpty()
assertThat(currentDot).isNull()
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
}
@Test
@@ -143,7 +142,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
@Test
fun onDragEnd_whenWrong() =
testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
val selectedDots by collectLastValue(underTest.selectedDots)
val currentDot by collectLastValue(underTest.currentDot)
lockDeviceAndOpenPatternBouncer()
@@ -154,7 +153,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
assertThat(selectedDots).isEmpty()
assertThat(currentDot).isNull()
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
}
@Test
@@ -365,21 +364,16 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
)
}
- private fun TestScope.switchToScene(toScene: SceneKey) {
- val currentScene by collectLastValue(sceneInteractor.currentScene)
- val bouncerHidden = currentScene == Scenes.Bouncer && toScene != Scenes.Bouncer
- sceneInteractor.changeScene(toScene, "reason")
- if (bouncerHidden) underTest.onHidden()
- runCurrent()
-
- assertThat(currentScene).isEqualTo(toScene)
- }
-
private fun TestScope.lockDeviceAndOpenPatternBouncer() {
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Pattern
)
- switchToScene(Scenes.Bouncer)
+
+ sceneInteractor.showOverlay(Overlays.Bouncer, "reason")
+ runCurrent()
+
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
}
companion object {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
index 705e8341ff80..2518d2fdd2e5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
@@ -26,7 +26,6 @@ import android.view.KeyEvent.KEYCODE_NUMPAD_0
import androidx.compose.ui.input.key.KeyEventType
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.compose.animation.scene.SceneKey
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
@@ -42,7 +41,7 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.lifecycle.activateIn
import com.android.systemui.res.R
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.testKosmos
import com.google.android.msdl.data.model.MSDLToken
import com.google.common.truth.Truth.assertThat
@@ -181,7 +180,7 @@ class PinBouncerViewModelTest : SysuiTestCase() {
@Test
fun onBackspaceButtonLongPressed() =
testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
lockDeviceAndOpenPinBouncer()
@@ -194,7 +193,7 @@ class PinBouncerViewModelTest : SysuiTestCase() {
underTest.onBackspaceButtonLongPressed()
assertThat(pin).isEmpty()
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
}
@Test
@@ -213,7 +212,7 @@ class PinBouncerViewModelTest : SysuiTestCase() {
@Test
fun onAuthenticateButtonClicked_whenWrong() =
testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
lockDeviceAndOpenPinBouncer()
@@ -226,7 +225,7 @@ class PinBouncerViewModelTest : SysuiTestCase() {
underTest.onAuthenticateButtonClicked()
assertThat(pin).isEmpty()
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
}
@Test
@@ -281,7 +280,7 @@ class PinBouncerViewModelTest : SysuiTestCase() {
val autoConfirmEnabled by
collectLastValue(authenticationInteractor.isAutoConfirmEnabled)
- val currentScene by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
kosmos.fakeAuthenticationRepository.setAutoConfirmFeatureEnabled(true)
@@ -296,7 +295,7 @@ class PinBouncerViewModelTest : SysuiTestCase() {
) // PIN is now wrong!
assertThat(pin).isEmpty()
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
}
@Test
@@ -310,10 +309,10 @@ class PinBouncerViewModelTest : SysuiTestCase() {
assertThat(pin).isNotEmpty()
// The user doesn't confirm the PIN, but navigates back to the lockscreen instead.
- switchToScene(Scenes.Lockscreen)
+ hideBouncer()
// The user navigates to the bouncer again.
- switchToScene(Scenes.Bouncer)
+ showBouncer()
// Ensure the previously-entered PIN is not shown.
assertThat(pin).isEmpty()
@@ -527,19 +526,26 @@ class PinBouncerViewModelTest : SysuiTestCase() {
assertThat(msdlPlayer.latestPropertiesPlayed).isNull()
}
- private fun TestScope.switchToScene(toScene: SceneKey) {
- val currentScene by collectLastValue(sceneInteractor.currentScene)
- val bouncerHidden = currentScene == Scenes.Bouncer && toScene != Scenes.Bouncer
- sceneInteractor.changeScene(toScene, "reason")
- if (bouncerHidden) underTest.onHidden()
+ private fun TestScope.showBouncer() {
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
+ sceneInteractor.showOverlay(Overlays.Bouncer, "reason")
runCurrent()
- assertThat(currentScene).isEqualTo(toScene)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
+ }
+
+ private fun TestScope.hideBouncer() {
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
+ sceneInteractor.hideOverlay(Overlays.Bouncer, "reason")
+ underTest.onHidden()
+ runCurrent()
+
+ assertThat(currentOverlays).doesNotContain(Overlays.Bouncer)
}
private fun TestScope.lockDeviceAndOpenPinBouncer() {
kosmos.fakeAuthenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
- switchToScene(Scenes.Bouncer)
+ showBouncer()
}
companion object {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalUserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalUserActionsViewModelTest.kt
index 619995478ecc..59fda984b3d5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalUserActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalUserActionsViewModelTest.kt
@@ -74,7 +74,8 @@ class CommunalUserActionsViewModelTest : SysuiTestCase() {
setUpState(isShadeTouchable = true, isDeviceUnlocked = false)
assertThat(actions).isNotEmpty()
assertThat(actions?.get(Swipe.End)).isEqualTo(UserActionResult(Scenes.Lockscreen))
- assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer))
+ assertThat(actions?.get(Swipe.Up))
+ .isEqualTo(UserActionResult.ShowOverlay(Overlays.Bouncer))
assertThat(actions?.get(Swipe.Down)).isEqualTo(UserActionResult(Scenes.Shade))
setUpState(isShadeTouchable = false, isDeviceUnlocked = false)
@@ -96,7 +97,8 @@ class CommunalUserActionsViewModelTest : SysuiTestCase() {
setUpState(isShadeTouchable = true, isDeviceUnlocked = false)
assertThat(actions).isNotEmpty()
assertThat(actions?.get(Swipe.End)).isEqualTo(UserActionResult(Scenes.Lockscreen))
- assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer))
+ assertThat(actions?.get(Swipe.Up))
+ .isEqualTo(UserActionResult.ShowOverlay(Overlays.Bouncer))
assertThat(actions?.get(Swipe.Down))
.isEqualTo(UserActionResult(Scenes.Shade, ToSplitShade))
@@ -120,7 +122,8 @@ class CommunalUserActionsViewModelTest : SysuiTestCase() {
setUpState(isShadeTouchable = true, isDeviceUnlocked = false)
assertThat(actions).isNotEmpty()
assertThat(actions?.get(Swipe.End)).isEqualTo(UserActionResult(Scenes.Lockscreen))
- assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer))
+ assertThat(actions?.get(Swipe.Up))
+ .isEqualTo(UserActionResult.ShowOverlay(Overlays.Bouncer))
assertThat(actions?.get(Swipe.Down))
.isEqualTo(UserActionResult.ShowOverlay(Overlays.NotificationsShade))
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
index 799054a92bee..f47aa6b3dc03 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
@@ -85,6 +85,7 @@ import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.scene.data.repository.Idle
import com.android.systemui.scene.data.repository.Transition
import com.android.systemui.scene.data.repository.setTransition
+import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.settings.fakeUserTracker
@@ -602,6 +603,7 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
flowOf(ObservableTransitionState.Idle(CommunalScenes.Communal))
)
// Transitioned to Glanceable hub.
+ kosmos.sceneInteractor.changeScene(Scenes.Communal, "")
kosmos.setTransition(
sceneTransition = Idle(Scenes.Communal),
stateTransition =
@@ -656,6 +658,7 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
keyguardRepository.setKeyguardOccluded(true)
// And on hub
+ kosmos.sceneInteractor.changeScene(Scenes.Communal, "")
kosmos.setTransition(
sceneTransition = Idle(Scenes.Communal),
stateTransition =
@@ -673,6 +676,7 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
assertThat(isCommunalContentFlowFrozen).isEqualTo(true)
// 3. When transitioned to OCCLUDED and activity shows
+ kosmos.sceneInteractor.changeScene(Scenes.Lockscreen, "")
kosmos.setTransition(
sceneTransition = Idle(Scenes.Lockscreen),
stateTransition =
@@ -759,6 +763,7 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
keyguardRepository.setKeyguardOccluded(true)
// And transitioned to hub
+ kosmos.sceneInteractor.changeScene(Scenes.Communal, "")
kosmos.setTransition(
sceneTransition = Idle(Scenes.Communal),
stateTransition =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
index f6016c6479ac..651d474d78b9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
@@ -81,6 +81,7 @@ import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.se
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.testKosmos
@@ -186,15 +187,13 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
underTest = createDeviceEntryFaceAuthRepositoryImpl(faceManager, bypassController)
if (!SceneContainerFlag.isEnabled) {
- mSetFlagsRule.disableFlags(
- AConfigFlags.FLAG_KEYGUARD_WM_STATE_REFACTOR,
- )
+ mSetFlagsRule.disableFlags(AConfigFlags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
}
}
private fun createDeviceEntryFaceAuthRepositoryImpl(
fmOverride: FaceManager? = faceManager,
- bypassControllerOverride: KeyguardBypassController? = bypassController
+ bypassControllerOverride: KeyguardBypassController? = bypassController,
): DeviceEntryFaceAuthRepositoryImpl {
val faceAuthBuffer = logcatTableLogBuffer(kosmos, "face auth")
val faceDetectBuffer = logcatTableLogBuffer(kosmos, "face detect")
@@ -256,7 +255,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
0,
null,
keyguardSessionId,
- faceAuthUiEvent.extraInfo
+ faceAuthUiEvent.extraInfo,
)
}
@@ -289,7 +288,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
authenticationCallback.value.onAuthenticationError(
FACE_ERROR_LOCKOUT_PERMANENT,
- "face locked out"
+ "face locked out",
)
assertThat(lockedOut()).isTrue()
@@ -317,7 +316,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
.thenReturn(
listOf(
createFaceSensorProperties(supportsFaceDetection = false),
- createFaceSensorProperties(supportsFaceDetection = true)
+ createFaceSensorProperties(supportsFaceDetection = true),
)
)
assertThat(createDeviceEntryFaceAuthRepositoryImpl().isDetectionSupported).isFalse()
@@ -326,7 +325,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
.thenReturn(
listOf(
createFaceSensorProperties(supportsFaceDetection = true),
- createFaceSensorProperties(supportsFaceDetection = false)
+ createFaceSensorProperties(supportsFaceDetection = false),
)
)
assertThat(createDeviceEntryFaceAuthRepositoryImpl().isDetectionSupported).isTrue()
@@ -409,7 +408,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
// Auth is done cancelling.
authenticationCallback.value.onAuthenticationError(
FACE_ERROR_CANCELED,
- "First auth attempt cancellation completed"
+ "First auth attempt cancellation completed",
)
val value = authStatus() as ErrorFaceAuthenticationStatus
assertThat(value.msgId).isEqualTo(FACE_ERROR_CANCELED)
@@ -472,7 +471,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
underTest =
createDeviceEntryFaceAuthRepositoryImpl(
fmOverride = null,
- bypassControllerOverride = null
+ bypassControllerOverride = null,
)
fakeUserRepository.setSelectedUserInfo(primaryUser)
@@ -499,7 +498,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
testGatingCheckForFaceAuth {
fakeUserRepository.setSelectedUserInfo(
primaryUser,
- SelectionStatus.SELECTION_IN_PROGRESS
+ SelectionStatus.SELECTION_IN_PROGRESS,
)
}
}
@@ -510,7 +509,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
testGatingCheckForDetect {
fakeUserRepository.setSelectedUserInfo(
userInfo = primaryUser,
- selectionStatus = SelectionStatus.SELECTION_IN_PROGRESS
+ selectionStatus = SelectionStatus.SELECTION_IN_PROGRESS,
)
}
}
@@ -544,11 +543,11 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
testGatingCheckForFaceAuth(sceneContainerEnabled = true) {
kosmos.sceneInteractor.setTransitionState(
MutableStateFlow(
- ObservableTransitionState.Transition(
- fromScene = Scenes.Bouncer,
+ ObservableTransitionState.Transition.hideOverlay(
+ overlay = Overlays.Bouncer,
toScene = Scenes.Gone,
- currentScene = flowOf(Scenes.Bouncer),
- progress = MutableStateFlow(0.2f),
+ currentOverlays = flowOf(setOf(Overlays.Bouncer)),
+ progress = flowOf(.2f),
isInitiatedByUserInput = true,
isUserInputOngoing = flowOf(false),
)
@@ -634,9 +633,11 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
assertThat(canFaceAuthRun()).isFalse()
// but bouncer is shown after that.
- kosmos.sceneInteractor.changeScene(Scenes.Bouncer, "for-test")
+ kosmos.sceneInteractor.showOverlay(Overlays.Bouncer, "for-test")
kosmos.sceneInteractor.setTransitionState(
- MutableStateFlow(ObservableTransitionState.Idle(Scenes.Bouncer))
+ MutableStateFlow(
+ ObservableTransitionState.Idle(Scenes.Lockscreen, setOf(Overlays.Bouncer))
+ )
)
runCurrent()
@@ -666,7 +667,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
assertThat(canFaceAuthRun()).isFalse()
underTest.requestAuthenticate(
FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER,
- fallbackToDetection = true
+ fallbackToDetection = true,
)
faceAuthenticateIsNotCalled()
@@ -687,7 +688,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
assertThat(canFaceAuthRun()).isFalse()
underTest.requestAuthenticate(
FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER,
- fallbackToDetection = true
+ fallbackToDetection = true,
)
faceAuthenticateIsNotCalled()
@@ -704,7 +705,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
keyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.LOCKSCREEN,
to = KeyguardState.OFF,
- testScope
+ testScope,
)
runCurrent()
keyguardTransitionRepository.sendTransitionStep(
@@ -730,7 +731,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
keyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.OFF,
to = KeyguardState.LOCKSCREEN,
- testScope
+ testScope,
)
runCurrent()
@@ -834,7 +835,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
fakeUserRepository.setSelectedUserInfo(
primaryUser,
- SelectionStatus.SELECTION_IN_PROGRESS
+ SelectionStatus.SELECTION_IN_PROGRESS,
)
assertThat(authenticated()).isFalse()
@@ -896,11 +897,11 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
testGatingCheckForDetect(sceneContainerEnabled = true) {
kosmos.sceneInteractor.setTransitionState(
MutableStateFlow(
- ObservableTransitionState.Transition(
- fromScene = Scenes.Bouncer,
+ ObservableTransitionState.Transition.hideOverlay(
+ overlay = Overlays.Bouncer,
toScene = Scenes.Gone,
- currentScene = flowOf(Scenes.Bouncer),
- progress = MutableStateFlow(0.2f),
+ currentOverlays = flowOf(setOf(Overlays.Bouncer)),
+ progress = flowOf(.2f),
isInitiatedByUserInput = true,
isUserInputOngoing = flowOf(false),
)
@@ -1032,7 +1033,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
keyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.DOZING,
to = KeyguardState.GONE,
- testScope
+ testScope,
)
runCurrent()
verify(faceManager).scheduleWatchdog()
@@ -1044,7 +1045,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
keyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.AOD,
to = KeyguardState.GONE,
- testScope
+ testScope,
)
runCurrent()
verify(faceManager).scheduleWatchdog()
@@ -1056,7 +1057,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
keyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.LOCKSCREEN,
to = KeyguardState.GONE,
- testScope
+ testScope,
)
runCurrent()
verify(faceManager).scheduleWatchdog()
@@ -1068,7 +1069,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
keyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.PRIMARY_BOUNCER,
to = KeyguardState.GONE,
- testScope
+ testScope,
)
runCurrent()
verify(faceManager).scheduleWatchdog()
@@ -1085,7 +1086,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
authenticationCallback.value.onAuthenticationError(
FACE_ERROR_HW_UNAVAILABLE,
- "HW unavailable"
+ "HW unavailable",
)
advanceTimeBy(DeviceEntryFaceAuthRepositoryImpl.HAL_ERROR_RETRY_TIMEOUT)
@@ -1137,7 +1138,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
private suspend fun TestScope.testGatingCheckForFaceAuth(
sceneContainerEnabled: Boolean = false,
- gatingCheckModifier: suspend () -> Unit
+ gatingCheckModifier: suspend () -> Unit,
) {
initCollectors()
allPreconditionsToRunFaceAuthAreTrue(sceneContainerEnabled)
@@ -1180,7 +1181,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
private suspend fun TestScope.testGatingCheckForDetect(
sceneContainerEnabled: Boolean = false,
- gatingCheckModifier: suspend () -> Unit
+ gatingCheckModifier: suspend () -> Unit,
) {
initCollectors()
allPreconditionsToRunFaceAuthAreTrue(sceneContainerEnabled)
@@ -1194,7 +1195,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
// Trigger authenticate with detection fallback
underTest.requestAuthenticate(
FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER,
- fallbackToDetection = true
+ fallbackToDetection = true,
)
runCurrent()
@@ -1213,7 +1214,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
// Try to run detect again
underTest.requestAuthenticate(
FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER,
- fallbackToDetection = true
+ fallbackToDetection = true,
)
// Detect won't run because preconditions are not true anymore.
@@ -1242,7 +1243,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
// Keyguard is not going away
kosmos.fakeKeyguardTransitionRepository.sendTransitionStep(
TransitionStep(KeyguardState.OFF, KeyguardState.LOCKSCREEN, value = 1.0f),
- validateStep = false
+ validateStep = false,
)
kosmos.sceneInteractor.setTransitionState(
MutableStateFlow(ObservableTransitionState.Idle(Scenes.Lockscreen))
@@ -1263,7 +1264,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
keyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.AOD,
to = KeyguardState.LOCKSCREEN,
- testScope
+ testScope,
)
runCurrent()
}
@@ -1315,7 +1316,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
any(),
any(),
isNull(),
- any(FaceAuthenticateOptions::class.java)
+ any(FaceAuthenticateOptions::class.java),
)
}
@@ -1334,7 +1335,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
"vendor/model/revision" /* hardwareVersion */,
"1.01" /* firmwareVersion */,
"00000001" /* serialNumber */,
- "" /* softwareVersion */
+ "", /* softwareVersion */
)
)
return FaceSensorPropertiesInternal(
@@ -1345,7 +1346,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
FaceSensorProperties.TYPE_UNKNOWN,
supportsFaceDetection /* supportsFaceDetection */,
true /* supportsSelfIllumination */,
- false /* resetLockoutRequiresChallenge */
+ false, /* resetLockoutRequiresChallenge */
)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt
index e36d2455d316..d2d8ab9d5cb7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt
@@ -55,6 +55,7 @@ import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.se
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.power.shared.model.WakeSleepReason
import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
import com.android.systemui.user.data.model.SelectionStatus
@@ -298,9 +299,12 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
testScope.runTest {
underTest.start()
- kosmos.sceneInteractor.changeScene(Scenes.Bouncer, "for-test")
+ kosmos.sceneInteractor.snapToScene(Scenes.Lockscreen, "for-test")
+ kosmos.sceneInteractor.showOverlay(Overlays.Bouncer, "for-test")
kosmos.sceneInteractor.setTransitionState(
- MutableStateFlow(ObservableTransitionState.Idle(Scenes.Bouncer))
+ MutableStateFlow(
+ ObservableTransitionState.Idle(Scenes.Lockscreen, setOf(Overlays.Bouncer))
+ )
)
runCurrent()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
index 84f08f14a86a..d247137868f4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
@@ -45,6 +45,7 @@ import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticati
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.domain.startable.sceneContainerStartable
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.sysuiStatusBarStateController
import com.android.systemui.testKosmos
@@ -179,7 +180,7 @@ class DeviceEntryInteractorTest : SysuiTestCase() {
kosmos.fakeDeviceEntryRepository.setLockscreenEnabled(true)
switchToScene(Scenes.Lockscreen)
runCurrent()
- switchToScene(Scenes.Bouncer)
+ showBouncer()
val isDeviceEntered by collectLastValue(underTest.isDeviceEntered)
assertThat(isDeviceEntered).isFalse()
@@ -375,6 +376,7 @@ class DeviceEntryInteractorTest : SysuiTestCase() {
fun showOrUnlockDevice_noAlternateBouncer_switchesToBouncerScene() =
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
switchToScene(Scenes.Lockscreen)
assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
@@ -386,7 +388,7 @@ class DeviceEntryInteractorTest : SysuiTestCase() {
underTest.attemptDeviceEntry()
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
}
@Test
@@ -437,6 +439,7 @@ class DeviceEntryInteractorTest : SysuiTestCase() {
assertThat(isDeviceEntered).isFalse()
assertThat(isDeviceEnteredDirectly).isFalse()
val currentScene by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
// Navigate to shade and bouncer:
@@ -446,8 +449,8 @@ class DeviceEntryInteractorTest : SysuiTestCase() {
// be shown and successful authentication should take the user back to where they are,
// the shade scene.
sysuiStatusBarStateController.setLeaveOpenOnKeyguardHide(true)
- switchToScene(Scenes.Bouncer)
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ showBouncer()
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
assertThat(isDeviceEntered).isFalse()
assertThat(isDeviceEnteredDirectly).isFalse()
@@ -465,6 +468,19 @@ class DeviceEntryInteractorTest : SysuiTestCase() {
runCurrent()
}
+ private fun TestScope.showBouncer() {
+ sceneInteractor.showOverlay(Overlays.Bouncer, "reason")
+ sceneInteractor.setTransitionState(
+ flowOf(
+ ObservableTransitionState.Idle(
+ sceneInteractor.currentScene.value,
+ setOf(Overlays.Bouncer),
+ )
+ )
+ )
+ runCurrent()
+ }
+
private suspend fun givenCanShowAlternateBouncer() {
val canShowAlternateBouncer by
testScope.collectLastValue(kosmos.alternateBouncerInteractor.canShowAlternateBouncer)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntrySourceInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntrySourceInteractorTest.kt
index a5c0da52d86d..f15fd28e34f0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntrySourceInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntrySourceInteractorTest.kt
@@ -45,6 +45,7 @@ import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticati
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.phone.dozeScrimController
import com.android.systemui.statusbar.phone.screenOffAnimationController
@@ -145,6 +146,7 @@ class DeviceEntrySourceInteractorTest : SysuiTestCase() {
whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
configureDeviceEntryBiometricAuthSuccessState(isFingerprintAuth = true)
configureBiometricUnlockState(
+ primaryBouncerVisible = false,
alternateBouncerVisible = false,
sceneKey = Scenes.Lockscreen,
)
@@ -167,7 +169,11 @@ class DeviceEntrySourceInteractorTest : SysuiTestCase() {
whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(false)
configureDeviceEntryBiometricAuthSuccessState(isFingerprintAuth = true)
- configureBiometricUnlockState(alternateBouncerVisible = false, sceneKey = Scenes.Dream)
+ configureBiometricUnlockState(
+ primaryBouncerVisible = false,
+ alternateBouncerVisible = false,
+ sceneKey = Scenes.Dream,
+ )
runCurrent()
assertThat(deviceEntryFromBiometricSource)
@@ -185,8 +191,9 @@ class DeviceEntrySourceInteractorTest : SysuiTestCase() {
whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
configureDeviceEntryBiometricAuthSuccessState(isFingerprintAuth = true)
configureBiometricUnlockState(
+ primaryBouncerVisible = true,
alternateBouncerVisible = false,
- sceneKey = Scenes.Bouncer,
+ sceneKey = Scenes.Lockscreen,
)
runCurrent()
@@ -205,6 +212,7 @@ class DeviceEntrySourceInteractorTest : SysuiTestCase() {
whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
configureDeviceEntryBiometricAuthSuccessState(isFingerprintAuth = true)
configureBiometricUnlockState(
+ primaryBouncerVisible = false,
alternateBouncerVisible = false,
sceneKey = Scenes.Lockscreen,
)
@@ -225,6 +233,7 @@ class DeviceEntrySourceInteractorTest : SysuiTestCase() {
whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
configureDeviceEntryBiometricAuthSuccessState(isFingerprintAuth = true)
configureBiometricUnlockState(
+ primaryBouncerVisible = false,
alternateBouncerVisible = true,
sceneKey = Scenes.Lockscreen,
)
@@ -247,6 +256,7 @@ class DeviceEntrySourceInteractorTest : SysuiTestCase() {
whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
configureDeviceEntryBiometricAuthSuccessState(isFaceAuth = true)
configureBiometricUnlockState(
+ primaryBouncerVisible = false,
alternateBouncerVisible = false,
sceneKey = Scenes.Lockscreen,
)
@@ -274,6 +284,7 @@ class DeviceEntrySourceInteractorTest : SysuiTestCase() {
whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
configureDeviceEntryBiometricAuthSuccessState(isFaceAuth = true)
configureBiometricUnlockState(
+ primaryBouncerVisible = false,
alternateBouncerVisible = false,
sceneKey = Scenes.Lockscreen,
)
@@ -295,8 +306,9 @@ class DeviceEntrySourceInteractorTest : SysuiTestCase() {
whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
configureDeviceEntryBiometricAuthSuccessState(isFaceAuth = true)
configureBiometricUnlockState(
+ primaryBouncerVisible = true,
alternateBouncerVisible = false,
- sceneKey = Scenes.Bouncer,
+ sceneKey = Scenes.Lockscreen,
)
runCurrent()
@@ -314,7 +326,11 @@ class DeviceEntrySourceInteractorTest : SysuiTestCase() {
whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
configureDeviceEntryBiometricAuthSuccessState(isFaceAuth = true)
- configureBiometricUnlockState(alternateBouncerVisible = false, sceneKey = Scenes.Shade)
+ configureBiometricUnlockState(
+ primaryBouncerVisible = false,
+ alternateBouncerVisible = false,
+ sceneKey = Scenes.Shade,
+ )
runCurrent()
// MODE_NONE does not dismiss keyguard
@@ -333,6 +349,7 @@ class DeviceEntrySourceInteractorTest : SysuiTestCase() {
whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
configureDeviceEntryBiometricAuthSuccessState(isFaceAuth = true)
configureBiometricUnlockState(
+ primaryBouncerVisible = false,
alternateBouncerVisible = false,
sceneKey = Scenes.Lockscreen,
)
@@ -354,6 +371,7 @@ class DeviceEntrySourceInteractorTest : SysuiTestCase() {
kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(onTop = true)
configureDeviceEntryBiometricAuthSuccessState(isFaceAuth = true)
configureBiometricUnlockState(
+ primaryBouncerVisible = false,
alternateBouncerVisible = true,
sceneKey = Scenes.Lockscreen,
)
@@ -381,13 +399,20 @@ class DeviceEntrySourceInteractorTest : SysuiTestCase() {
}
private fun configureBiometricUnlockState(
+ primaryBouncerVisible: Boolean,
alternateBouncerVisible: Boolean,
sceneKey: SceneKey,
) {
kosmos.keyguardBouncerRepository.setAlternateVisible(alternateBouncerVisible)
kosmos.sceneInteractor.changeScene(sceneKey, "reason")
+ if (primaryBouncerVisible) kosmos.sceneInteractor.showOverlay(Overlays.Bouncer, "reason")
kosmos.sceneInteractor.setTransitionState(
- MutableStateFlow<ObservableTransitionState>(ObservableTransitionState.Idle(sceneKey))
+ MutableStateFlow<ObservableTransitionState>(
+ ObservableTransitionState.Idle(
+ sceneKey,
+ if (primaryBouncerVisible) setOf(Overlays.Bouncer) else emptySet(),
+ )
+ )
)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
index 526510a98e37..b42eddd12e4e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
@@ -77,6 +77,7 @@ import com.android.systemui.navigationbar.gestural.domain.TaskInfo
import com.android.systemui.navigationbar.gestural.domain.TaskMatcher
import com.android.systemui.scene.data.repository.sceneContainerRepository
import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
import com.android.systemui.touch.TouchInsetManager
@@ -1073,7 +1074,8 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() {
assertThat(lifecycleRegistry.currentState).isEqualTo(Lifecycle.State.RESUMED)
// Bouncer shows.
- kosmos.sceneInteractor.changeScene(Scenes.Bouncer, "test")
+ kosmos.sceneInteractor.snapToScene(Scenes.Lockscreen, "test")
+ kosmos.sceneInteractor.showOverlay(Overlays.Bouncer, "test")
testScope.runCurrent()
mMainExecutor.runAllReady()
@@ -1082,6 +1084,7 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() {
// Bouncer closes.
kosmos.sceneInteractor.changeScene(Scenes.Dream, "test")
+ kosmos.sceneInteractor.hideOverlay(Overlays.Bouncer, "test")
testScope.runCurrent()
mMainExecutor.runAllReady()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt
index 102ce0b51c94..69b6e6c84e7e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt
@@ -74,7 +74,8 @@ class DreamUserActionsViewModelTest : SysuiTestCase() {
setUpState(isShadeTouchable = true, isDeviceUnlocked = false)
assertThat(actions).isNotEmpty()
- assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer))
+ assertThat(actions?.get(Swipe.Up))
+ .isEqualTo(UserActionResult.ShowOverlay(Overlays.Bouncer))
assertThat(actions?.get(Swipe.Down)).isEqualTo(UserActionResult(Scenes.Shade))
assertThat(actions?.get(Swipe.Start)).isNull()
assertThat(actions?.get(Swipe.End)).isNull()
@@ -99,7 +100,8 @@ class DreamUserActionsViewModelTest : SysuiTestCase() {
setUpState(isShadeTouchable = true, isDeviceUnlocked = false)
assertThat(actions).isNotEmpty()
- assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer))
+ assertThat(actions?.get(Swipe.Up))
+ .isEqualTo(UserActionResult.ShowOverlay(Overlays.Bouncer))
assertThat(actions?.get(Swipe.Down))
.isEqualTo(UserActionResult(Scenes.Shade, ToSplitShade))
assertThat(actions?.get(Swipe.Start)).isNull()
@@ -126,7 +128,8 @@ class DreamUserActionsViewModelTest : SysuiTestCase() {
setUpState(isShadeTouchable = true, isDeviceUnlocked = false)
assertThat(actions).isNotEmpty()
- assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer))
+ assertThat(actions?.get(Swipe.Up))
+ .isEqualTo(UserActionResult.ShowOverlay(Overlays.Bouncer))
assertThat(actions?.get(Swipe.Down))
.isEqualTo(UserActionResult.ShowOverlay(Overlays.NotificationsShade))
assertThat(actions?.get(Swipe.Start)).isNull()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModelTest.kt
index 57bcc1407e24..63be132dacaa 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModelTest.kt
@@ -248,6 +248,23 @@ class KeyboardTouchpadTutorialViewModelTest : SysuiTestCase() {
}
@Test
+ fun screensOrderUntilFinish_whenAutoProceed() =
+ testScope.runTest {
+ val screens by collectValues(viewModel.screen)
+ val closeActivity by collectLastValue(viewModel.closeActivity)
+
+ peripheralsState(keyboardConnected = true, touchpadConnected = true)
+
+ autoProceed()
+ autoProceed()
+ // No autoproceeding at the last screen
+ goToNextScreen()
+
+ assertThat(screens).containsExactly(BACK_GESTURE, HOME_GESTURE, ACTION_KEY).inOrder()
+ assertThat(closeActivity).isTrue()
+ }
+
+ @Test
fun activityFinishes_ifTouchpadModuleIsNotPresent() =
testScope.runTest {
val viewModel =
@@ -299,6 +316,11 @@ class KeyboardTouchpadTutorialViewModelTest : SysuiTestCase() {
runCurrent()
}
+ private suspend fun TestScope.autoProceed() {
+ viewModel.onAutoProceed()
+ runCurrent()
+ }
+
private fun TestScope.goBack() {
viewModel.onBack()
runCurrent()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
index 32a631b191bf..043daf02f279 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
@@ -8,16 +8,19 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.flags.fakeFeatureFlagsClassic
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.scene.data.repository.Idle
import com.android.systemui.scene.data.repository.setSceneTransition
+import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
import com.android.systemui.utils.GlobalWindowManager
@@ -130,7 +133,7 @@ class ResourceTrimmerTest : SysuiTestCase() {
keyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.LOCKSCREEN,
to = KeyguardState.GONE,
- testScope
+ testScope,
)
verify(globalWindowManager, times(1))
.trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
@@ -141,6 +144,13 @@ class ResourceTrimmerTest : SysuiTestCase() {
@EnableSceneContainer
fun keyguardTransitionsToGone_trimsFontCache_scene_container() =
testScope.runTest {
+ kosmos.sceneInteractor.snapToScene(Scenes.Lockscreen, "reason")
+ kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+ SuccessFingerprintAuthenticationStatus(0, true)
+ )
+ runCurrent()
+
+ kosmos.sceneInteractor.changeScene(Scenes.Gone, "")
kosmos.setSceneTransition(Idle(Scenes.Gone))
verify(globalWindowManager, times(1))
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt
index 425079d7b5d7..5bcf73b4719a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt
@@ -41,7 +41,7 @@ import com.android.systemui.keyguard.data.repository.FakeTrustRepository
import com.android.systemui.kosmos.testScope
import com.android.systemui.res.R
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.testKosmos
import com.android.systemui.user.domain.interactor.SelectedUserInteractor
@@ -173,7 +173,7 @@ class DeviceEntrySideFpsOverlayInteractorTest : SysuiTestCase() {
collectLastValue(underTest.showIndicatorForDeviceEntry)
runCurrent()
- updateBouncerScene(
+ updateBouncer(
isActive = true,
fpsDetectionRunning = true,
isUnlockingWithFpAllowed = true,
@@ -199,7 +199,7 @@ class DeviceEntrySideFpsOverlayInteractorTest : SysuiTestCase() {
collectLastValue(underTest.showIndicatorForDeviceEntry)
runCurrent()
- updateBouncerScene(
+ updateBouncer(
isActive = false,
fpsDetectionRunning = true,
isUnlockingWithFpAllowed = true,
@@ -248,7 +248,7 @@ class DeviceEntrySideFpsOverlayInteractorTest : SysuiTestCase() {
collectLastValue(underTest.showIndicatorForDeviceEntry)
runCurrent()
- updateBouncerScene(
+ updateBouncer(
isActive = true,
fpsDetectionRunning = false,
isUnlockingWithFpAllowed = true,
@@ -264,7 +264,7 @@ class DeviceEntrySideFpsOverlayInteractorTest : SysuiTestCase() {
collectLastValue(underTest.showIndicatorForDeviceEntry)
runCurrent()
- updateBouncerScene(
+ updateBouncer(
isActive = true,
fpsDetectionRunning = true,
isUnlockingWithFpAllowed = false,
@@ -349,15 +349,16 @@ class DeviceEntrySideFpsOverlayInteractorTest : SysuiTestCase() {
)
}
- private fun TestScope.updateBouncerScene(
+ private fun TestScope.updateBouncer(
isActive: Boolean,
fpsDetectionRunning: Boolean,
isUnlockingWithFpAllowed: Boolean,
) {
- kosmos.sceneInteractor.changeScene(
- if (isActive) Scenes.Bouncer else Scenes.Lockscreen,
- "reason",
- )
+ if (isActive) {
+ kosmos.sceneInteractor.showOverlay(Overlays.Bouncer, "reason")
+ } else {
+ kosmos.sceneInteractor.hideOverlay(Overlays.Bouncer, "reason")
+ }
whenever(keyguardUpdateMonitor.isFingerprintDetectionRunning)
.thenReturn(fpsDetectionRunning)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt
index c63f6f65c631..0a5f079dd077 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt
@@ -38,10 +38,12 @@ import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticati
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.data.repository.HideOverlay
import com.android.systemui.scene.data.repository.Idle
import com.android.systemui.scene.data.repository.Transition
import com.android.systemui.scene.data.repository.setSceneTransition
import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
@@ -221,7 +223,7 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() {
@Test
fun doNotResetDismissActionOnUnlockedShade() =
testScope.runTest {
- kosmos.setSceneTransition(Idle(Scenes.Bouncer))
+ kosmos.setSceneTransition(Idle(Scenes.Lockscreen, setOf(Overlays.Bouncer)))
kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.None
)
@@ -238,7 +240,12 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() {
assertThat(wasOnCancelInvoked).isFalse()
kosmos.setSceneTransition(
- Transition(from = Scenes.Bouncer, to = Scenes.Shade, progress = flowOf(1f))
+ HideOverlay(
+ overlay = Overlays.Bouncer,
+ toScene = Scenes.Shade,
+ currentOverlays = flowOf(emptySet()),
+ progress = flowOf(1f),
+ )
)
runCurrent()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt
index 6d53e6c138c7..3fe30b7fb5c0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt
@@ -24,9 +24,11 @@ import com.android.systemui.coroutines.collectValues
import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.KeyguardSurfaceBehindModel
+import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.keyguard.util.mockTopActivityClassName
@@ -34,6 +36,7 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.data.repository.Idle
import com.android.systemui.scene.data.repository.Transition
import com.android.systemui.scene.data.repository.setSceneTransition
+import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shared.system.ActivityManagerWrapper
import com.android.systemui.shared.system.activityManagerWrapper
@@ -84,7 +87,7 @@ class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
assertThat(values)
.containsExactly(
// We're initialized in LOCKSCREEN.
- KeyguardSurfaceBehindModel(alpha = 0f),
+ KeyguardSurfaceBehindModel(alpha = 0f)
)
transitionRepository.sendTransitionStep(
@@ -105,7 +108,7 @@ class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
it.alpha == 1f &&
it.animateFromTranslationY != 0f &&
it.translationY == 0f
- }
+ },
)
transitionRepository.sendTransitionStep(
@@ -125,7 +128,7 @@ class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
it.alpha == 1f &&
it.animateFromTranslationY != 0f &&
it.translationY == 0f
- }
+ },
)
transitionRepository.sendTransitionStep(
@@ -146,7 +149,7 @@ class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
it.translationY == 0f
},
// Once the current state is GONE, we should default to alpha = 1f.
- { it == KeyguardSurfaceBehindModel(alpha = 1f) }
+ { it == KeyguardSurfaceBehindModel(alpha = 1f) },
)
}
@@ -161,7 +164,7 @@ class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
assertThat(values)
.containsExactly(
// We're initialized in LOCKSCREEN.
- KeyguardSurfaceBehindModel(alpha = 0f),
+ KeyguardSurfaceBehindModel(alpha = 0f)
)
.inOrder()
@@ -242,8 +245,7 @@ class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
values.assertValuesMatch(
// We should be at alpha = 0f during the animation.
- { it == KeyguardSurfaceBehindModel(alpha = 0f) },
- )
+ { it == KeyguardSurfaceBehindModel(alpha = 0f) })
}
@Test
@@ -251,14 +253,19 @@ class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
fun testSurfaceBehindModel_toAppSurface_scene_container() =
testScope.runTest {
val values by collectValues(underTest.viewParams)
+ kosmos.sceneInteractor.snapToScene(Scenes.Lockscreen, "")
+ kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+ SuccessFingerprintAuthenticationStatus(0, true)
+ )
runCurrent()
assertThat(values)
.containsExactly(
// We're initialized in LOCKSCREEN.
- KeyguardSurfaceBehindModel(alpha = 0f),
+ KeyguardSurfaceBehindModel(alpha = 0f)
)
+ kosmos.sceneInteractor.changeScene(Scenes.Gone, "")
kosmos.setSceneTransition(Transition(Scenes.Lockscreen, Scenes.Gone))
values.assertValuesMatch(
@@ -270,7 +277,7 @@ class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
it.alpha == 1f &&
it.animateFromTranslationY != 0f &&
it.translationY == 0f
- }
+ },
)
kosmos.setSceneTransition(Idle(Scenes.Gone))
@@ -284,7 +291,7 @@ class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
it.translationY == 0f
},
// Once the current state is GONE, we should default to alpha = 1f.
- { it == KeyguardSurfaceBehindModel(alpha = 1f) }
+ { it == KeyguardSurfaceBehindModel(alpha = 1f) },
)
}
@@ -294,15 +301,20 @@ class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
testScope.runTest {
val values by collectValues(underTest.viewParams)
activityManagerWrapper.mockTopActivityClassName(LAUNCHER_ACTIVITY_NAME)
+ kosmos.sceneInteractor.snapToScene(Scenes.Lockscreen, "")
+ kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+ SuccessFingerprintAuthenticationStatus(0, true)
+ )
runCurrent()
assertThat(values)
.containsExactly(
// We're initialized in LOCKSCREEN.
- KeyguardSurfaceBehindModel(alpha = 0f),
+ KeyguardSurfaceBehindModel(alpha = 0f)
)
.inOrder()
+ kosmos.sceneInteractor.changeScene(Scenes.Gone, "")
kosmos.setSceneTransition(Transition(Scenes.Lockscreen, Scenes.Gone))
assertThat(values)
@@ -340,8 +352,7 @@ class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
values.assertValuesMatch(
// We should be at alpha = 0f during the animation.
- { it == KeyguardSurfaceBehindModel(alpha = 0f) },
- )
+ { it == KeyguardSurfaceBehindModel(alpha = 0f) })
}
@Test
@@ -435,6 +446,13 @@ class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
testScope.runTest {
val isAnimatingSurface by collectLastValue(underTest.isAnimatingSurface)
+ kosmos.sceneInteractor.snapToScene(Scenes.Lockscreen, "")
+ kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+ SuccessFingerprintAuthenticationStatus(0, true)
+ )
+ runCurrent()
+
+ kosmos.sceneInteractor.changeScene(Scenes.Gone, "")
kosmos.setSceneTransition(Idle(Scenes.Gone))
kosmos.notificationLaunchAnimationInteractor.setIsLaunchAnimationRunning(true)
runCurrent()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
index 0b42898d82ae..2d1c905b6db7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
@@ -24,6 +24,7 @@ import com.android.systemui.coroutines.collectValues
import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState
@@ -34,15 +35,20 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
import com.android.systemui.keyguard.shared.model.KeyguardState.OFF
import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
import com.android.systemui.keyguard.shared.model.KeyguardState.UNDEFINED
+import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.keyguard.shared.model.TransitionState.CANCELED
import com.android.systemui.keyguard.shared.model.TransitionState.FINISHED
import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING
import com.android.systemui.keyguard.shared.model.TransitionState.STARTED
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.data.repository.HideOverlay
import com.android.systemui.scene.data.repository.Idle
+import com.android.systemui.scene.data.repository.ShowOverlay
import com.android.systemui.scene.data.repository.Transition
import com.android.systemui.scene.data.repository.setSceneTransition
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
@@ -295,11 +301,13 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
inTransition,
)
- kosmos.setSceneTransition(Transition(Scenes.Gone, Scenes.Bouncer))
+ kosmos.setSceneTransition(
+ ShowOverlay(overlay = Overlays.Bouncer, fromScene = Scenes.Gone)
+ )
assertEquals(listOf(false, true, false, true), inTransition)
- kosmos.setSceneTransition(Idle(Scenes.Bouncer))
+ kosmos.setSceneTransition(Idle(Scenes.Lockscreen, setOf(Overlays.Bouncer)))
assertEquals(listOf(false, true, false, true, false), inTransition)
}
@@ -713,6 +721,11 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
TransitionStep(AOD, DOZING, 1f, FINISHED),
)
+ kosmos.sceneInteractor.snapToScene(Scenes.Lockscreen, "reason")
+ kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+ SuccessFingerprintAuthenticationStatus(0, true)
+ )
+
assertThat(results)
.isEqualTo(
listOf(
@@ -724,6 +737,7 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
assertThat(results).isEqualTo(listOf(false))
+ kosmos.sceneInteractor.changeScene(Scenes.Gone, "reason")
kosmos.setSceneTransition(Idle(Scenes.Gone))
assertThat(results).isEqualTo(listOf(false, true))
@@ -732,6 +746,7 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
assertThat(results).isEqualTo(listOf(false, true))
+ kosmos.sceneInteractor.changeScene(Scenes.Lockscreen, "reason")
kosmos.setSceneTransition(Idle(Scenes.Lockscreen))
assertThat(results).isEqualTo(listOf(false, true, false))
@@ -740,6 +755,7 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
assertThat(results).isEqualTo(listOf(false, true, false))
+ kosmos.sceneInteractor.changeScene(Scenes.Gone, "reason")
kosmos.setSceneTransition(Idle(Scenes.Gone))
assertThat(results).isEqualTo(listOf(false, true, false, true))
@@ -1042,13 +1058,23 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
progress.emit(0.6f)
runCurrent()
- kosmos.setSceneTransition(Transition(Scenes.Gone, Scenes.Bouncer, progress = progress))
+ kosmos.setSceneTransition(
+ ShowOverlay(
+ overlay = Overlays.Bouncer,
+ fromScene = Scenes.Gone,
+ progress = progress,
+ )
+ )
progress.emit(0.1f)
runCurrent()
kosmos.setSceneTransition(
- Transition(Scenes.Bouncer, Scenes.Lockscreen, progress = progress)
+ HideOverlay(
+ overlay = Overlays.Bouncer,
+ toScene = Scenes.Lockscreen,
+ progress = progress,
+ )
)
progress.emit(0.3f)
@@ -1087,12 +1113,20 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
kosmos.setSceneTransition(Idle(Scenes.Gone))
- kosmos.setSceneTransition(Transition(Scenes.Gone, Scenes.Bouncer, progress = progress))
+ kosmos.setSceneTransition(
+ ShowOverlay(
+ overlay = Overlays.Bouncer,
+ fromScene = Scenes.Gone,
+ progress = progress,
+ )
+ )
progress.emit(0.1f)
runCurrent()
- kosmos.setSceneTransition(Transition(Scenes.Bouncer, Scenes.Gone, progress = progress))
+ kosmos.setSceneTransition(
+ HideOverlay(overlay = Overlays.Bouncer, toScene = Scenes.Gone, progress = progress)
+ )
progress.emit(0.3f)
runCurrent()
@@ -1125,7 +1159,13 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
progress1.emit(0.1f)
runCurrent()
- kosmos.setSceneTransition(Transition(Scenes.Gone, Scenes.Bouncer, progress = progress2))
+ kosmos.setSceneTransition(
+ ShowOverlay(
+ overlay = Overlays.Bouncer,
+ fromScene = Scenes.Gone,
+ progress = progress2,
+ )
+ )
progress2.emit(0.3f)
runCurrent()
@@ -1152,8 +1192,14 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
val currentStatesMapped by
collectValues(underTest.transition(Edge.create(LOCKSCREEN, Scenes.Gone)))
+ kosmos.sceneInteractor.snapToScene(Scenes.Lockscreen, "reason")
+ kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+ SuccessFingerprintAuthenticationStatus(0, true)
+ )
+
kosmos.setSceneTransition(Transition(Scenes.Gone, Scenes.Lockscreen))
val sendStep1 = TransitionStep(UNDEFINED, LOCKSCREEN, 0f, STARTED)
+ kosmos.sceneInteractor.changeScene(Scenes.Gone, "reason")
kosmos.setSceneTransition(Idle(Scenes.Gone))
val sendStep2 = TransitionStep(UNDEFINED, LOCKSCREEN, 0.6f, CANCELED)
sendSteps(sendStep1, sendStep2)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
index b7c162b4d6eb..f0eedee48e57 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
@@ -37,11 +37,13 @@ import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.data.model.asIterable
import com.android.systemui.scene.data.model.sceneStackOf
+import com.android.systemui.scene.data.repository.HideOverlay
import com.android.systemui.scene.data.repository.Idle
import com.android.systemui.scene.data.repository.Transition
import com.android.systemui.scene.data.repository.setSceneTransition
import com.android.systemui.scene.domain.interactor.sceneBackInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.mock
@@ -250,12 +252,14 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() {
fun surfaceBehindVisibility_fromBouncerToGone_becomesTrue() =
testScope.runTest {
val isSurfaceBehindVisible by collectLastValue(underTest.value.surfaceBehindVisibility)
- val currentScene by collectLastValue(kosmos.sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(kosmos.sceneInteractor.currentOverlays)
// Before the transition, we start on Bouncer so the surface should start invisible.
- kosmos.setSceneTransition(ObservableTransitionState.Idle(Scenes.Bouncer))
- kosmos.sceneInteractor.changeScene(Scenes.Bouncer, "")
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ kosmos.setSceneTransition(
+ ObservableTransitionState.Idle(Scenes.Lockscreen, setOf(Overlays.Bouncer))
+ )
+ kosmos.sceneInteractor.showOverlay(Overlays.Bouncer, "")
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
assertThat(isSurfaceBehindVisible).isFalse()
// Unlocked with fingerprint.
@@ -267,44 +271,45 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() {
// the
// threshold.
kosmos.setSceneTransition(
- ObservableTransitionState.Transition(
- fromScene = Scenes.Bouncer,
+ ObservableTransitionState.Transition.hideOverlay(
+ overlay = Overlays.Bouncer,
toScene = Scenes.Gone,
- isInitiatedByUserInput = false,
- isUserInputOngoing = flowOf(false),
+ currentOverlays = flowOf(setOf(Overlays.Bouncer)),
progress =
flowOf(
FromPrimaryBouncerTransitionInteractor
.TO_GONE_SURFACE_BEHIND_VISIBLE_THRESHOLD
),
- currentScene = flowOf(Scenes.Bouncer),
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
)
)
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
assertThat(isSurfaceBehindVisible).isFalse()
// Once the transition passes the threshold, the surface should become visible.
kosmos.setSceneTransition(
- ObservableTransitionState.Transition(
- fromScene = Scenes.Bouncer,
+ ObservableTransitionState.Transition.hideOverlay(
+ overlay = Overlays.Bouncer,
toScene = Scenes.Gone,
- isInitiatedByUserInput = false,
- isUserInputOngoing = flowOf(false),
+ currentOverlays = flowOf(setOf(Overlays.Bouncer)),
progress =
flowOf(
FromPrimaryBouncerTransitionInteractor
.TO_GONE_SURFACE_BEHIND_VISIBLE_THRESHOLD + 0.01f
),
- currentScene = flowOf(Scenes.Gone),
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
)
)
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
assertThat(isSurfaceBehindVisible).isTrue()
// After the transition, settles on Gone. Surface behind should stay visible now.
kosmos.setSceneTransition(ObservableTransitionState.Idle(Scenes.Gone))
kosmos.sceneInteractor.changeScene(Scenes.Gone, "")
- assertThat(currentScene).isEqualTo(Scenes.Gone)
+ kosmos.sceneInteractor.hideOverlay(Overlays.Bouncer, "")
+ assertThat(currentOverlays).doesNotContain(Overlays.Bouncer)
assertThat(isSurfaceBehindVisible).isTrue()
}
@@ -1012,6 +1017,7 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() {
kosmos.setSceneTransition(Idle(Scenes.Lockscreen))
val currentScene by collectLastValue(kosmos.sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(kosmos.sceneInteractor.currentOverlays)
assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
val lockscreenVisibility by collectLastValue(underTest.value.lockscreenVisibility)
@@ -1038,12 +1044,16 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() {
assertThat(currentScene).isEqualTo(Scenes.Shade)
assertThat(lockscreenVisibility).isTrue()
- kosmos.setSceneTransition(Idle(Scenes.Bouncer))
- kosmos.sceneInteractor.changeScene(Scenes.Bouncer, "")
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ kosmos.setSceneTransition(Idle(Scenes.Lockscreen, setOf(Overlays.Bouncer)))
+ kosmos.sceneInteractor.snapToScene(Scenes.Lockscreen, "")
+ kosmos.sceneInteractor.showOverlay(Overlays.Bouncer, "")
+ assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
assertThat(lockscreenVisibility).isTrue()
- kosmos.setSceneTransition(Transition(from = Scenes.Bouncer, to = Scenes.Gone))
+ kosmos.setSceneTransition(
+ HideOverlay(overlay = Overlays.Bouncer, toScene = Scenes.Gone)
+ )
assertThat(lockscreenVisibility).isTrue()
kosmos.setSceneTransition(Idle(Scenes.Gone))
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractorTest.kt
index 3cff0fc96af4..41ec065dc560 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractorTest.kt
@@ -1220,13 +1220,13 @@ class LockscreenSceneTransitionInteractorTest : SysuiTestCase() {
progress.value = 0.4f
sceneTransitions.value =
- ObservableTransitionState.Transition(
- Scenes.Lockscreen,
- Scenes.Bouncer,
- flowOf(Scenes.Lockscreen),
- progress,
- false,
- flowOf(false),
+ ObservableTransitionState.Transition.showOverlay(
+ overlay = Overlays.Bouncer,
+ fromScene = Scenes.Lockscreen,
+ currentOverlays = flowOf(setOf(Overlays.Bouncer)),
+ progress = progress,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
)
assertTransition(
@@ -1342,7 +1342,7 @@ class LockscreenSceneTransitionInteractorTest : SysuiTestCase() {
sceneTransitions.value =
ObservableTransitionState.Transition(
Scenes.Gone,
- Scenes.Bouncer,
+ Scenes.Dream,
flowOf(Scenes.Lockscreen),
progress,
false,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelTest.kt
index a31728ce5e18..91cb1ff266c9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelTest.kt
@@ -39,6 +39,7 @@ import com.android.systemui.keyguard.ui.transitions.blurConfig
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.data.repository.sceneContainerRepository
import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.shadeTestUtil
import com.android.systemui.testKosmos
@@ -125,14 +126,15 @@ class LockscreenToPrimaryBouncerTransitionViewModelTest(flags: FlagsParameteriza
kosmos.sceneContainerRepository.setTransitionState(transitionState)
transitionState.value =
- ObservableTransitionState.Transition(
+ ObservableTransitionState.Transition.showOverlay(
+ overlay = Overlays.Bouncer,
fromScene = Scenes.Lockscreen,
- toScene = Scenes.Bouncer,
- emptyFlow(),
- emptyFlow(),
- false,
- emptyFlow(),
+ currentOverlays = emptyFlow(),
+ progress = emptyFlow(),
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = emptyFlow(),
)
+
runCurrent()
// fade out
repository.sendTransitionStep(step(0f, TransitionState.STARTED))
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt
index f357d0c80822..f98ddd240fd0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt
@@ -19,6 +19,7 @@ package com.android.systemui.keyguard.ui.viewmodel
import android.platform.test.annotations.EnableFlags
import android.testing.TestableLooper.RunWithLooper
import androidx.test.filters.SmallTest
+import com.android.compose.animation.scene.ContentKey
import com.android.compose.animation.scene.Edge
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.Swipe
@@ -135,11 +136,11 @@ class LockscreenUserActionsViewModelTest : SysuiTestCase() {
private fun expectedUpDestination(
canSwipeToEnter: Boolean,
isShadeTouchable: Boolean,
- ): SceneKey? {
+ ): ContentKey? {
return when {
!isShadeTouchable -> null
canSwipeToEnter -> Scenes.Gone
- else -> Scenes.Bouncer
+ else -> Overlays.Bouncer
}
}
}
@@ -215,15 +216,17 @@ class LockscreenUserActionsViewModelTest : SysuiTestCase() {
)
)
- val upScene by
- collectLastValue(
- (userActions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene?.let {
- scene ->
- kosmos.sceneInteractor.resolveSceneFamily(scene)
- } ?: flowOf(null)
- )
+ val upContent =
+ userActions?.get(Swipe.Up)?.let { result ->
+ when (result) {
+ is UserActionResult.ChangeScene -> result.toScene
+ is UserActionResult.ShowOverlay -> result.overlay
+ is UserActionResult.HideOverlay -> result.overlay
+ is UserActionResult.ReplaceByOverlay -> result.overlay
+ }
+ }
- assertThat(upScene)
+ assertThat(upContent)
.isEqualTo(
expectedUpDestination(
canSwipeToEnter = canSwipeToEnter,
@@ -292,15 +295,17 @@ class LockscreenUserActionsViewModelTest : SysuiTestCase() {
}
}
- val upScene by
- collectLastValue(
- (userActions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene?.let {
- scene ->
- kosmos.sceneInteractor.resolveSceneFamily(scene)
- } ?: flowOf(null)
- )
+ val upContent =
+ userActions?.get(Swipe.Up)?.let { result ->
+ when (result) {
+ is UserActionResult.ChangeScene -> result.toScene
+ is UserActionResult.ShowOverlay -> result.overlay
+ is UserActionResult.HideOverlay -> result.overlay
+ is UserActionResult.ReplaceByOverlay -> result.overlay
+ }
+ }
- assertThat(upScene)
+ assertThat(upContent)
.isEqualTo(
expectedUpDestination(
canSwipeToEnter = canSwipeToEnter,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/dialog/MediaOutputAdapterLegacyTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/dialog/MediaOutputAdapterLegacyTest.java
index f293614954e9..2db2199602b8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/dialog/MediaOutputAdapterLegacyTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/dialog/MediaOutputAdapterLegacyTest.java
@@ -268,6 +268,10 @@ public class MediaOutputAdapterLegacyTest extends SysuiTestCase {
assertThat(mViewHolder.mSeekBar.getContentDescription()).isNotNull();
assertThat(mViewHolder.mContainerLayout.isFocusable()).isFalse();
+ assertThat(mViewHolder.mContainerLayout.getImportantForAccessibility()).isEqualTo(
+ View.IMPORTANT_FOR_ACCESSIBILITY_NO);
+ assertThat(mViewHolder.mTextContent.getImportantForAccessibility()).isEqualTo(
+ View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
}
@Test
@@ -511,6 +515,11 @@ public class MediaOutputAdapterLegacyTest extends SysuiTestCase {
assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(mViewHolder.mTitleText.getText().toString()).isEqualTo(TEST_DEVICE_NAME_2);
assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.GONE);
+ assertThat(mViewHolder.mContainerLayout.isFocusable()).isTrue();
+ assertThat(mViewHolder.mContainerLayout.getImportantForAccessibility()).isEqualTo(
+ View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+ assertThat(mViewHolder.mTextContent.getImportantForAccessibility()).isEqualTo(
+ View.IMPORTANT_FOR_ACCESSIBILITY_YES);
assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE);
assertThat(mViewHolder.mSubTitleText.getVisibility()).isEqualTo(View.VISIBLE);
@@ -750,7 +759,7 @@ public class MediaOutputAdapterLegacyTest extends SysuiTestCase {
.onCreateViewHolder(new LinearLayout(mContext), 0);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);
- mViewHolder.mEndTouchArea.performClick();
+ mViewHolder.mCheckBox.performClick();
verify(mMediaSwitchingController).addDeviceToPlayMedia(mMediaDevice2);
}
@@ -894,7 +903,7 @@ public class MediaOutputAdapterLegacyTest extends SysuiTestCase {
.onCreateViewHolder(new LinearLayout(mContext), 0);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
- mViewHolder.mEndTouchArea.performClick();
+ mViewHolder.mCheckBox.performClick();
verify(mMediaSwitchingController).removeDeviceFromPlayMedia(mMediaDevice1);
}
@@ -1050,7 +1059,7 @@ public class MediaOutputAdapterLegacyTest extends SysuiTestCase {
new LinearLayout(mContext), MediaItem.MediaItemType.TYPE_DEVICE);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
- mViewHolder.mEndTouchArea.performClick();
+ mViewHolder.mEndClickIcon.performClick();
mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(
new LinearLayout(mContext), MediaItem.MediaItemType.TYPE_DEVICE);
@@ -1073,7 +1082,7 @@ public class MediaOutputAdapterLegacyTest extends SysuiTestCase {
new LinearLayout(mContext), MediaItem.MediaItemType.TYPE_DEVICE);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
- mViewHolder.mEndTouchArea.performClick();
+ mViewHolder.mEndClickIcon.performClick();
mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
.onCreateViewHolder(
new LinearLayout(mContext), MediaItem.MediaItemType.TYPE_DEVICE);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModelTest.kt
index b23cd5e5547f..917f3564a1bd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModelTest.kt
@@ -103,20 +103,6 @@ class NotificationsShadeOverlayContentViewModelTest : SysuiTestCase() {
}
@Test
- fun bouncerShown_hidesShade() =
- testScope.runTest {
- val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
- lockDevice()
- sceneInteractor.showOverlay(Overlays.NotificationsShade, "test")
- assertThat(currentOverlays).contains(Overlays.NotificationsShade)
-
- sceneInteractor.changeScene(Scenes.Bouncer, "test")
- runCurrent()
-
- assertThat(currentOverlays).doesNotContain(Overlays.NotificationsShade)
- }
-
- @Test
fun shadeNotTouchable_hidesShade() =
testScope.runTest {
val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/CastTileTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/CastTileTest.java
index 31a627fe0667..765c5749cd4b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/CastTileTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/CastTileTest.java
@@ -50,6 +50,8 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.QsEventLogger;
import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.shade.domain.interactor.FakeShadeDialogContextInteractor;
+import com.android.systemui.shade.domain.interactor.ShadeDialogContextInteractor;
import com.android.systemui.statusbar.connectivity.IconState;
import com.android.systemui.statusbar.connectivity.NetworkController;
import com.android.systemui.statusbar.connectivity.SignalCallback;
@@ -107,6 +109,8 @@ public class CastTileTest extends SysuiTestCase {
private final FakeConnectivityRepository mConnectivityRepository =
new FakeConnectivityRepository();
private final FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags();
+ private final ShadeDialogContextInteractor mShadeDialogContextInteractor =
+ new FakeShadeDialogContextInteractor(mContext);
private TestableLooper mTestableLooper;
private CastTile mCastTile;
@@ -535,7 +539,8 @@ public class CastTileTest extends SysuiTestCase {
mDialogTransitionAnimator,
mConnectivityRepository,
mJavaAdapter,
- mFeatureFlags
+ mFeatureFlags,
+ mShadeDialogContextInteractor
);
mCastTile.initialize();
@@ -578,7 +583,8 @@ public class CastTileTest extends SysuiTestCase {
mDialogTransitionAnimator,
mConnectivityRepository,
mJavaAdapter,
- mFeatureFlags
+ mFeatureFlags,
+ mShadeDialogContextInteractor
);
mCastTile.initialize();
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModelTest.kt
index bf5f9f4872f0..c69ebab7a170 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModelTest.kt
@@ -99,20 +99,6 @@ class QuickSettingsShadeOverlayContentViewModelTest : SysuiTestCase() {
}
@Test
- fun bouncerShown_hidesShade() =
- testScope.runTest {
- val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
- lockDevice()
- sceneInteractor.showOverlay(Overlays.QuickSettingsShade, "test")
- assertThat(currentOverlays).contains(Overlays.QuickSettingsShade)
-
- sceneInteractor.changeScene(Scenes.Bouncer, "test")
- runCurrent()
-
- assertThat(currentOverlays).doesNotContain(Overlays.QuickSettingsShade)
- }
-
- @Test
fun shadeNotTouchable_hidesShade() =
testScope.runTest {
val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
index c5fac08a4b35..eb630b49359d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
@@ -22,6 +22,7 @@ import android.testing.TestableLooper.RunWithLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.compose.animation.scene.OverlayKey
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.Swipe
import com.android.compose.animation.scene.UserActionResult
@@ -34,7 +35,7 @@ import com.android.systemui.authentication.domain.interactor.authenticationInter
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.bouncer.ui.viewmodel.PasswordBouncerViewModel
import com.android.systemui.bouncer.ui.viewmodel.PinBouncerViewModel
-import com.android.systemui.bouncer.ui.viewmodel.bouncerSceneContentViewModel
+import com.android.systemui.bouncer.ui.viewmodel.bouncerOverlayContentViewModel
import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.flags.EnableSceneContainer
@@ -54,6 +55,7 @@ import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.se
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.domain.startable.sceneContainerStartable
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.fakeSceneDataSource
import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
@@ -87,7 +89,7 @@ import org.junit.runner.RunWith
* Therefore, when adding or modifying test cases, consider whether what you're testing is better
* covered by a more granular unit test.
* * Please reuse the helper methods in this class (for example, [putDeviceToSleep] or
- * [emulateUserDrivenTransition]).
+ * [emulateUserDrivenSceneTransition]).
* * All tests start with the device locked and with a PIN auth method. The class offers useful
* methods like [setAuthMethod], [unlockDevice], [lockDevice], etc. to help you set up a starting
* state that makes more sense for your test case.
@@ -101,7 +103,7 @@ import org.junit.runner.RunWith
@EnableSceneContainer
class SceneFrameworkIntegrationTest : SysuiTestCase() {
private val kosmos = testKosmos()
- private var bouncerSceneJob: Job? = null
+ private var bouncerOverlayJob: Job? = null
@Before
fun setUp() =
@@ -125,7 +127,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
lockscreenUserActionsViewModel.activateIn(testScope)
shadeSceneContentViewModel.activateIn(testScope)
shadeUserActionsViewModel.activateIn(testScope)
- bouncerSceneContentViewModel.activateIn(testScope)
+ bouncerOverlayContentViewModel.activateIn(testScope)
sceneContainerViewModel.activateIn(testScope)
assertWithMessage("Initial scene key mismatch!")
@@ -141,27 +143,29 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
@Test
fun clickLockButtonAndEnterCorrectPin_unlocksDevice() =
kosmos.runTest {
- emulateUserDrivenTransition(Scenes.Bouncer)
+ emulateUserDrivenOverlayTransition(show = Overlays.Bouncer)
fakeSceneDataSource.pause()
enterPin()
emulatePendingTransitionProgress(expectedVisible = false)
assertCurrentScene(Scenes.Gone)
+ assertOverlaysEmpty()
}
@Test
fun swipeUpOnLockscreen_enterCorrectPin_unlocksDevice() =
kosmos.runTest {
val actions by collectLastValue(kosmos.lockscreenUserActionsViewModel.actions)
- val upDestinationSceneKey =
- (actions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene
- assertThat(upDestinationSceneKey).isEqualTo(Scenes.Bouncer)
- emulateUserDrivenTransition(to = upDestinationSceneKey)
+ val upDestinationOverlayKey =
+ (actions?.get(Swipe.Up) as? UserActionResult.ShowOverlay)?.overlay
+ assertThat(upDestinationOverlayKey).isEqualTo(Overlays.Bouncer)
+ emulateUserDrivenOverlayTransition(show = upDestinationOverlayKey)
fakeSceneDataSource.pause()
enterPin()
emulatePendingTransitionProgress(expectedVisible = false)
assertCurrentScene(Scenes.Gone)
+ assertOverlaysEmpty()
}
@Test
@@ -173,7 +177,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
val upDestinationSceneKey =
(actions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene
assertThat(upDestinationSceneKey).isEqualTo(Scenes.Gone)
- emulateUserDrivenTransition(to = upDestinationSceneKey)
+ emulateUserDrivenSceneTransition(to = upDestinationSceneKey)
}
@Test
@@ -184,13 +188,13 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
assertCurrentScene(Scenes.Lockscreen)
// Emulate a user swipe to the shade scene.
- emulateUserDrivenTransition(to = Scenes.Shade)
+ emulateUserDrivenSceneTransition(to = Scenes.Shade)
assertCurrentScene(Scenes.Shade)
val upDestinationSceneKey =
(actions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene
assertThat(upDestinationSceneKey).isEqualTo(Scenes.Lockscreen)
- emulateUserDrivenTransition(to = Scenes.Lockscreen)
+ emulateUserDrivenSceneTransition(to = Scenes.Lockscreen)
}
@Test
@@ -205,17 +209,17 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
assertCurrentScene(Scenes.Lockscreen)
// Emulate a user swipe to dismiss the lockscreen.
- emulateUserDrivenTransition(to = Scenes.Gone)
+ emulateUserDrivenSceneTransition(to = Scenes.Gone)
assertCurrentScene(Scenes.Gone)
// Emulate a user swipe to the shade scene.
- emulateUserDrivenTransition(to = Scenes.Shade)
+ emulateUserDrivenSceneTransition(to = Scenes.Shade)
assertCurrentScene(Scenes.Shade)
val upDestinationSceneKey =
(actions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene
assertThat(upDestinationSceneKey).isEqualTo(Scenes.Gone)
- emulateUserDrivenTransition(to = Scenes.Gone)
+ emulateUserDrivenSceneTransition(to = Scenes.Gone)
}
@Test
@@ -270,6 +274,8 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
wakeUpDevice()
assertCurrentScene(Scenes.Lockscreen)
+ // set UI state to match view-model
+ transitionState.value = ObservableTransitionState.Idle(Scenes.Lockscreen)
unlockDevice()
assertCurrentScene(Scenes.Gone)
}
@@ -302,10 +308,10 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
kosmos.runTest {
setAuthMethod(AuthenticationMethodModel.Password)
val actions by collectLastValue(lockscreenUserActionsViewModel.actions)
- val upDestinationSceneKey =
- (actions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene
- assertThat(upDestinationSceneKey).isEqualTo(Scenes.Bouncer)
- emulateUserDrivenTransition(to = upDestinationSceneKey)
+ val upDestinationOverlayKey =
+ (actions?.get(Swipe.Up) as? UserActionResult.ShowOverlay)?.overlay
+ assertThat(upDestinationOverlayKey).isEqualTo(Overlays.Bouncer)
+ emulateUserDrivenOverlayTransition(show = upDestinationOverlayKey)
fakeSceneDataSource.pause()
dismissIme()
@@ -319,16 +325,16 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
kosmos.runTest {
setAuthMethod(AuthenticationMethodModel.Password)
val actions by collectLastValue(lockscreenUserActionsViewModel.actions)
- val upDestinationSceneKey =
- (actions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene
- assertThat(upDestinationSceneKey).isEqualTo(Scenes.Bouncer)
- emulateUserDrivenTransition(to = upDestinationSceneKey)
+ val upDestinationOverlayKey =
+ (actions?.get(Swipe.Up) as? UserActionResult.ShowOverlay)?.overlay
+ assertThat(upDestinationOverlayKey).isEqualTo(Overlays.Bouncer)
+ emulateUserDrivenOverlayTransition(show = upDestinationOverlayKey)
- val bouncerActionButton by collectLastValue(bouncerSceneContentViewModel.actionButton)
+ val bouncerActionButton by collectLastValue(bouncerOverlayContentViewModel.actionButton)
assertWithMessage("Bouncer action button not visible")
.that(bouncerActionButton)
.isNotNull()
- kosmos.bouncerSceneContentViewModel.onActionButtonClicked(bouncerActionButton!!)
+ kosmos.bouncerOverlayContentViewModel.onActionButtonClicked(bouncerActionButton!!)
// TODO(b/369765704): Assert that an activity was started once we use ActivityStarter.
}
@@ -339,16 +345,16 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
setAuthMethod(AuthenticationMethodModel.Password)
startPhoneCall()
val actions by collectLastValue(lockscreenUserActionsViewModel.actions)
- val upDestinationSceneKey =
- (actions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene
- assertThat(upDestinationSceneKey).isEqualTo(Scenes.Bouncer)
- emulateUserDrivenTransition(to = upDestinationSceneKey)
+ val upDestinationOverlayKey =
+ (actions?.get(Swipe.Up) as? UserActionResult.ShowOverlay)?.overlay
+ assertThat(upDestinationOverlayKey).isEqualTo(Overlays.Bouncer)
+ emulateUserDrivenOverlayTransition(show = upDestinationOverlayKey)
- val bouncerActionButton by collectLastValue(bouncerSceneContentViewModel.actionButton)
+ val bouncerActionButton by collectLastValue(bouncerOverlayContentViewModel.actionButton)
assertWithMessage("Bouncer action button not visible during call")
.that(bouncerActionButton)
.isNotNull()
- kosmos.bouncerSceneContentViewModel.onActionButtonClicked(bouncerActionButton!!)
+ kosmos.bouncerOverlayContentViewModel.onActionButtonClicked(bouncerActionButton!!)
verifyCurrent(mockTelecomManager).showInCallScreen(any())
}
@@ -358,7 +364,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
kosmos.runTest {
setAuthMethod(AuthenticationMethodModel.None)
introduceLockedSim()
- assertCurrentScene(Scenes.Bouncer)
+ assertCurrentOverlay(Overlays.Bouncer)
}
@Test
@@ -366,7 +372,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
kosmos.runTest {
fakeSceneDataSource.pause()
introduceLockedSim()
- emulatePendingTransitionProgress(expectedVisible = true)
+ emulatePendingTransitionProgress()
enterSimPin(
authMethodAfterSimUnlock = AuthenticationMethodModel.None,
enableLockscreen = false,
@@ -380,7 +386,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
kosmos.runTest {
fakeSceneDataSource.pause()
introduceLockedSim()
- emulatePendingTransitionProgress(expectedVisible = true)
+ emulatePendingTransitionProgress()
enterSimPin(authMethodAfterSimUnlock = AuthenticationMethodModel.Pin)
assertCurrentScene(Scenes.Lockscreen)
}
@@ -396,6 +402,18 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
.isEqualTo(expected)
}
+ private fun Kosmos.assertCurrentOverlay(expected: OverlayKey) {
+ assertWithMessage("Expected overlay missing!")
+ .that(currentValue(sceneInteractor.currentOverlays))
+ .contains(expected)
+ }
+
+ private fun Kosmos.assertOverlaysEmpty() {
+ assertWithMessage("Expected no overlays, but at least one was present")
+ .that(currentValue(sceneInteractor.currentOverlays))
+ .isEmpty()
+ }
+
/**
* Returns the [SceneKey] of the current scene as displayed in the UI.
*
@@ -439,9 +457,10 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
}
/**
- * Emulates a gradual transition to the currently pending scene that's sitting in the
- * [fakeSceneDataSource]. This emits a series of progress updates to the [transitionState] and
- * finishes by committing the pending scene as the current scene.
+ * Emulates a gradual transition to the currently pending scene and overlay that are sitting in
+ * the [fakeSceneDataSource]. This emits a series of progress updates to the [transitionState]
+ * and finishes by committing the pending scene as the current scene, and the pending overlay as
+ * the current overlay
*
* In order to use this, the [fakeSceneDataSource] must be paused before this method is called.
*/
@@ -450,49 +469,96 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
.that(fakeSceneDataSource.isPaused)
.isTrue()
- val to = fakeSceneDataSource.pendingScene ?: return
- val from = getCurrentSceneInUi()
+ val fromScene = getCurrentSceneInUi()
+ val toScene = fakeSceneDataSource.pendingScene ?: fromScene
+
+ val fromOverlays =
+ collectLastValue(currentValue(transitionState).currentOverlays()).invoke() ?: emptySet()
+ val toOverlays = fakeSceneDataSource.pendingOverlays ?: fromOverlays
- if (to == from) {
- return
+ val addedOverlays = toOverlays - fromOverlays
+ val removedOverlays = fromOverlays - toOverlays
+ check(
+ addedOverlays.size + removedOverlays.size < 2 &&
+ (addedOverlays.size <= 1 || removedOverlays.size <= 1)
+ ) {
+ "Detected multiple overlays being added/removed. Currently only testing single-overlay transitions."
}
- // Begin to transition.
- val progressFlow = MutableStateFlow(0f)
- transitionState.value =
- ObservableTransitionState.Transition(
- fromScene = getCurrentSceneInUi(),
- toScene = to,
- currentScene = flowOf(to),
- progress = progressFlow,
- isInitiatedByUserInput = false,
- isUserInputOngoing = flowOf(false),
- )
+ if (toScene != fromScene) {
+ // Begin scene transition.
+ val progressFlow = MutableStateFlow(0f)
+ transitionState.value =
+ ObservableTransitionState.Transition(
+ fromScene = getCurrentSceneInUi(),
+ toScene = toScene,
+ currentScene = flowOf(toScene),
+ progress = progressFlow,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
+ )
- // Report progress of transition.
- while (currentValue(progressFlow) < 1f) {
- progressFlow.value += 0.2f
+ // Report progress of transition.
+ while (currentValue(progressFlow) < 1f) {
+ progressFlow.value += 0.2f
+ }
+
+ // End the transition and report the change.
+ transitionState.value = ObservableTransitionState.Idle(toScene)
}
- // End the transition and report the change.
- transitionState.value = ObservableTransitionState.Idle(to)
+ if (addedOverlays.isNotEmpty() || removedOverlays.isNotEmpty()) {
+ // Begin overlay transition.
+ val progressFlow = MutableStateFlow(0f)
+ transitionState.value =
+ if (addedOverlays.size == 1) {
+ ObservableTransitionState.Transition.showOverlay(
+ overlay = addedOverlays.first(),
+ fromScene = toScene,
+ currentOverlays = flowOf(addedOverlays),
+ progress = progressFlow,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
+ )
+ } else {
+ ObservableTransitionState.Transition.hideOverlay(
+ overlay = removedOverlays.first(),
+ toScene = toScene,
+ currentOverlays = flowOf(removedOverlays),
+ progress = progressFlow,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
+ )
+ }
+
+ // Report progress of transition.
+ while (currentValue(progressFlow) < 1f) {
+ progressFlow.value += 0.2f
+ }
+
+ // End the transition and report the change, taking any scene transition into account.
+ transitionState.value = ObservableTransitionState.Idle(toScene, toOverlays)
+ }
fakeSceneDataSource.unpause(force = true)
- assertWithMessage("Visibility mismatch after scene transition from $from to $to!")
+ assertWithMessage(
+ "Visibility mismatch after transition from $fromScene to $toScene and $fromOverlays to $toOverlays!"
+ )
.that(currentValue { sceneContainerViewModel.isVisible })
.isEqualTo(expectedVisible)
- assertThat(currentValue(sceneContainerViewModel.currentScene)).isEqualTo(to)
+ assertThat(currentValue(sceneContainerViewModel.currentScene)).isEqualTo(toScene)
+ assertThat(currentValue(sceneInteractor.currentOverlays)).isEqualTo(toOverlays)
- bouncerSceneJob =
- if (to == Scenes.Bouncer) {
+ bouncerOverlayJob =
+ if (Overlays.Bouncer in addedOverlays) {
testScope.backgroundScope.launch {
- bouncerSceneContentViewModel.authMethodViewModel.collect {
+ bouncerOverlayContentViewModel.authMethodViewModel.collect {
// Do nothing. Need this to turn this otherwise cold flow, hot.
}
}
} else {
- bouncerSceneJob?.cancel()
+ bouncerOverlayJob?.cancel()
null
}
}
@@ -506,7 +572,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
*
* @param to The scene to transition to.
*/
- private fun Kosmos.emulateUserDrivenTransition(to: SceneKey?) {
+ private fun Kosmos.emulateUserDrivenSceneTransition(to: SceneKey?) {
checkNotNull(to)
fakeSceneDataSource.pause()
@@ -515,6 +581,22 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
emulatePendingTransitionProgress(expectedVisible = to != Scenes.Gone)
}
+ private fun Kosmos.emulateUserDrivenOverlayTransition(
+ show: OverlayKey? = null,
+ hide: OverlayKey? = null,
+ ) {
+ fakeSceneDataSource.pause()
+ if (show != null && hide != null) {
+ sceneInteractor.replaceOverlay(from = show, to = hide, "reason")
+ } else if (show != null) {
+ sceneInteractor.showOverlay(overlay = show, "reason")
+ } else if (hide != null) {
+ sceneInteractor.hideOverlay(overlay = hide, "reason")
+ }
+
+ emulatePendingTransitionProgress()
+ }
+
/**
* Locks the device.
*
@@ -548,7 +630,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
.that(currentValue(deviceEntryInteractor.isUnlocked))
.isFalse()
- emulateUserDrivenTransition(Scenes.Bouncer)
+ emulateUserDrivenOverlayTransition(show = Overlays.Bouncer)
fakeSceneDataSource.pause()
enterPin()
@@ -558,17 +640,18 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
/**
* Enters the correct PIN in the bouncer UI.
*
- * Asserts that the current scene is [Scenes.Bouncer] and that the current bouncer UI is a PIN
- * before proceeding.
+ * Asserts that [Overlays.Bouncer] is showing and that the current bouncer UI is a PIN before
+ * proceeding.
*
* Does not assert that the device is locked or unlocked.
*/
private fun Kosmos.enterPin() {
- assertWithMessage("Cannot enter PIN when not on the Bouncer scene!")
- .that(getCurrentSceneInUi())
- .isEqualTo(Scenes.Bouncer)
+ val currentOverlays by collectLastValue(currentValue(transitionState).currentOverlays())
+ assertWithMessage("Cannot enter PIN when Bouncer not showing!")
+ .that(currentOverlays)
+ .contains(Overlays.Bouncer)
val authMethodViewModel by
- collectLastValue(bouncerSceneContentViewModel.authMethodViewModel)
+ collectLastValue(bouncerOverlayContentViewModel.authMethodViewModel)
assertWithMessage("Cannot enter PIN when not using a PIN authentication method!")
.that(authMethodViewModel)
.isInstanceOf(PinBouncerViewModel::class.java)
@@ -583,8 +666,8 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
/**
* Enters the correct PIN in the sim bouncer UI.
*
- * Asserts that the current scene is [Scenes.Bouncer] and that the current bouncer UI is a PIN
- * before proceeding.
+ * Asserts that [Overlays.Bouncer] is showing and that the current bouncer UI is a PIN before
+ * proceeding.
*
* Does not assert that the device is locked or unlocked.
*/
@@ -592,11 +675,12 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
authMethodAfterSimUnlock: AuthenticationMethodModel = AuthenticationMethodModel.None,
enableLockscreen: Boolean = true,
) {
- assertWithMessage("Cannot enter PIN when not on the Bouncer scene!")
- .that(getCurrentSceneInUi())
- .isEqualTo(Scenes.Bouncer)
+ val currentOverlays by collectLastValue(currentValue(transitionState).currentOverlays())
+ assertWithMessage("Cannot enter PIN when Bouncer not showing!")
+ .that(currentOverlays)
+ .contains(Overlays.Bouncer)
val authMethodViewModel by
- collectLastValue(bouncerSceneContentViewModel.authMethodViewModel)
+ collectLastValue(bouncerOverlayContentViewModel.authMethodViewModel)
assertWithMessage("Cannot enter PIN when not using a PIN authentication method!")
.that(authMethodViewModel)
.isInstanceOf(PinBouncerViewModel::class.java)
@@ -643,7 +727,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
/** Emulates the dismissal of the IME (soft keyboard). */
private fun Kosmos.dismissIme() {
- (currentValue(bouncerSceneContentViewModel.authMethodViewModel)
+ (currentValue(bouncerOverlayContentViewModel.authMethodViewModel)
as? PasswordBouncerViewModel)
?.let { it.onImeDismissed() }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneBackInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneBackInteractorTest.kt
index 9cc6c0fa801a..034585331af6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneBackInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneBackInteractorTest.kt
@@ -53,7 +53,7 @@ class SceneBackInteractorTest : SysuiTestCase() {
@Test
@EnableSceneContainer
- fun navigateToQs_thenBouncer_thenBack_whileLocked() =
+ fun navigateToQs_thenBack_whileLocked() =
testScope.runTest {
sceneContainerStartable.start()
@@ -61,8 +61,6 @@ class SceneBackInteractorTest : SysuiTestCase() {
RouteNode(Scenes.Lockscreen, null),
RouteNode(Scenes.Shade, Scenes.Lockscreen),
RouteNode(Scenes.QuickSettings, Scenes.Shade),
- RouteNode(Scenes.Bouncer, Scenes.QuickSettings),
- RouteNode(Scenes.QuickSettings, Scenes.Shade),
RouteNode(Scenes.Shade, Scenes.Lockscreen),
RouteNode(Scenes.Lockscreen, null),
)
@@ -70,57 +68,39 @@ class SceneBackInteractorTest : SysuiTestCase() {
@Test
@EnableSceneContainer
- fun navigateToQs_thenBouncer_thenUnlock() =
+ fun navigateToQs_thenUnlock() =
testScope.runTest {
sceneContainerStartable.start()
assertRoute(
RouteNode(Scenes.Lockscreen, null),
RouteNode(Scenes.Shade, Scenes.Lockscreen),
- RouteNode(Scenes.QuickSettings, Scenes.Shade),
- RouteNode(Scenes.Bouncer, Scenes.QuickSettings, unlockDevice = true),
+ RouteNode(Scenes.QuickSettings, Scenes.Shade, unlockDevice = true),
RouteNode(Scenes.Gone, null),
)
}
@Test
@EnableSceneContainer
- fun navigateToQs_skippingShade_thenBouncer_thenBack_whileLocked() =
+ fun navigateToQs_skippingShade_thenBack_whileLocked() =
testScope.runTest {
sceneContainerStartable.start()
assertRoute(
RouteNode(Scenes.Lockscreen, null),
RouteNode(Scenes.QuickSettings, Scenes.Lockscreen),
- RouteNode(Scenes.Bouncer, Scenes.QuickSettings),
- RouteNode(Scenes.QuickSettings, Scenes.Lockscreen),
RouteNode(Scenes.Lockscreen, null),
)
}
@Test
@EnableSceneContainer
- fun navigateToBouncer_thenBack_whileLocked() =
+ fun navigateToQs_skippingShade_thenBack_thenShade_whileLocked() =
testScope.runTest {
sceneContainerStartable.start()
assertRoute(
RouteNode(Scenes.Lockscreen, null),
- RouteNode(Scenes.Bouncer, Scenes.Lockscreen),
- RouteNode(Scenes.Lockscreen, null),
- )
- }
-
- @Test
- @EnableSceneContainer
- fun navigateToQs_skippingShade_thenBouncer_thenBack_thenShade_whileLocked() =
- testScope.runTest {
- sceneContainerStartable.start()
-
- assertRoute(
- RouteNode(Scenes.Lockscreen, null),
- RouteNode(Scenes.QuickSettings, Scenes.Lockscreen),
- RouteNode(Scenes.Bouncer, Scenes.QuickSettings),
RouteNode(Scenes.QuickSettings, Scenes.Lockscreen),
RouteNode(Scenes.Lockscreen, null),
RouteNode(Scenes.Shade, Scenes.Lockscreen),
@@ -178,9 +158,8 @@ class SceneBackInteractorTest : SysuiTestCase() {
testScope.runTest {
underTest.onSceneChange(from = Scenes.Lockscreen, to = Scenes.Shade)
underTest.onSceneChange(from = Scenes.Shade, to = Scenes.QuickSettings)
- underTest.onSceneChange(from = Scenes.QuickSettings, to = Scenes.Bouncer)
assertThat(underTest.backStack.value.asIterable().toList())
- .isEqualTo(listOf(Scenes.QuickSettings, Scenes.Shade, Scenes.Lockscreen))
+ .isEqualTo(listOf(Scenes.Shade, Scenes.Lockscreen))
underTest.updateBackStack { stack ->
// Reverse the stack, just to see if it can be done:
@@ -188,7 +167,7 @@ class SceneBackInteractorTest : SysuiTestCase() {
}
assertThat(underTest.backStack.value.asIterable().toList())
- .isEqualTo(listOf(Scenes.Lockscreen, Scenes.Shade, Scenes.QuickSettings))
+ .isEqualTo(listOf(Scenes.Lockscreen, Scenes.Shade))
}
private suspend fun TestScope.assertRoute(vararg route: RouteNode) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
index 23a0f6224fb7..559e363d8937 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
@@ -799,4 +799,88 @@ class SceneInteractorTest : SysuiTestCase() {
verify(processor, never()).onSceneAboutToChange(any(), any())
assertThat(fakeSceneDataSource.freezeAndAnimateToCurrentStateCallCount).isEqualTo(0)
}
+
+ @Test
+ fun topmostContent_sceneChange_noOverlays() =
+ kosmos.runTest {
+ val topmostContent by collectLastValue(underTest.topmostContent)
+
+ kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+ SuccessFingerprintAuthenticationStatus(0, true)
+ )
+
+ underTest.snapToScene(Scenes.Lockscreen, "reason")
+
+ assertThat(topmostContent).isEqualTo(Scenes.Lockscreen)
+
+ underTest.changeScene(Scenes.Gone, "reason")
+
+ assertThat(topmostContent).isEqualTo(Scenes.Gone)
+ }
+
+ @Test
+ fun topmostContent_sceneChange_withOverlay() =
+ kosmos.runTest {
+ kosmos.enableDualShade()
+ runCurrent()
+
+ val topmostContent by collectLastValue(underTest.topmostContent)
+
+ kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+ SuccessFingerprintAuthenticationStatus(0, true)
+ )
+
+ underTest.snapToScene(Scenes.Lockscreen, "reason")
+ underTest.showOverlay(Overlays.NotificationsShade, "reason")
+
+ assertThat(topmostContent).isEqualTo(Overlays.NotificationsShade)
+
+ underTest.changeScene(Scenes.Gone, "reason")
+
+ assertThat(topmostContent).isEqualTo(Overlays.NotificationsShade)
+ }
+
+ @Test
+ fun topmostContent_overlayChange_higherZOrder() =
+ kosmos.runTest {
+ kosmos.enableDualShade()
+ runCurrent()
+
+ val topmostContent by collectLastValue(underTest.topmostContent)
+
+ kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+ SuccessFingerprintAuthenticationStatus(0, true)
+ )
+
+ underTest.snapToScene(Scenes.Lockscreen, "reason")
+ underTest.showOverlay(Overlays.NotificationsShade, "reason")
+
+ assertThat(topmostContent).isEqualTo(Overlays.NotificationsShade)
+
+ underTest.showOverlay(Overlays.QuickSettingsShade, "reason")
+
+ assertThat(topmostContent).isEqualTo(Overlays.QuickSettingsShade)
+ }
+
+ @Test
+ fun topmostContent_overlayChange_lowerZOrder() =
+ kosmos.runTest {
+ kosmos.enableDualShade()
+ runCurrent()
+
+ val topmostContent by collectLastValue(underTest.topmostContent)
+
+ kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+ SuccessFingerprintAuthenticationStatus(0, true)
+ )
+
+ underTest.snapToScene(Scenes.Lockscreen, "reason")
+ underTest.showOverlay(Overlays.QuickSettingsShade, "reason")
+
+ assertThat(topmostContent).isEqualTo(Overlays.QuickSettingsShade)
+
+ underTest.showOverlay(Overlays.NotificationsShade, "reason")
+
+ assertThat(topmostContent).isEqualTo(Overlays.QuickSettingsShade)
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
index ae77ac4cc327..9adf24f32c0c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
@@ -475,17 +475,18 @@ class SceneContainerStartableTest : SysuiTestCase() {
@Test
fun switchFromBouncerToGoneWhenDeviceUnlocked() =
testScope.runTest {
- val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
prepareState(
authenticationMethod = AuthenticationMethodModel.Pin,
isDeviceUnlocked = false,
- initialSceneKey = Scenes.Bouncer,
+ initialSceneKey = Scenes.Lockscreen,
+ initialOverlays = setOf(Overlays.Bouncer),
)
- assertThat(currentSceneKey).isEqualTo(Scenes.Bouncer)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
underTest.start()
updateFingerprintAuthStatus(isSuccess = true)
- assertThat(currentSceneKey).isEqualTo(Scenes.Gone)
+ assertThat(currentOverlays).doesNotContain(Overlays.Bouncer)
}
@Test
@@ -548,6 +549,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
fun switchFromBouncerToQuickSettingsWhenDeviceUnlocked_whenLeaveOpenShade() =
testScope.runTest {
val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
val backStack by collectLastValue(sceneBackInteractor.backStack)
kosmos.sysuiStatusBarStateController.leaveOpen = true // leave shade open
@@ -566,14 +568,16 @@ class SceneContainerStartableTest : SysuiTestCase() {
runCurrent()
assertThat(currentSceneKey).isEqualTo(Scenes.QuickSettings)
- sceneInteractor.changeScene(Scenes.Bouncer, "switching to bouncer for test")
- transitionState.value = ObservableTransitionState.Idle(Scenes.Bouncer)
+ sceneInteractor.showOverlay(Overlays.Bouncer, "showing bouncer for test")
+ transitionState.value =
+ ObservableTransitionState.Idle(Scenes.QuickSettings, setOf(Overlays.Bouncer))
runCurrent()
- assertThat(currentSceneKey).isEqualTo(Scenes.Bouncer)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
assertThat(backStack?.asIterable()?.last()).isEqualTo(Scenes.Lockscreen)
updateFingerprintAuthStatus(isSuccess = true)
assertThat(currentSceneKey).isEqualTo(Scenes.QuickSettings)
+ assertThat(currentOverlays).doesNotContain(Overlays.Bouncer)
assertThat(backStack?.asIterable()?.last()).isEqualTo(Scenes.Gone)
}
@@ -581,6 +585,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
fun switchFromBouncerToGoneWhenDeviceUnlocked_whenDoNotLeaveOpenShade() =
testScope.runTest {
val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
kosmos.sysuiStatusBarStateController.leaveOpen = false // don't leave shade open
val transitionState =
@@ -598,13 +603,15 @@ class SceneContainerStartableTest : SysuiTestCase() {
runCurrent()
assertThat(currentSceneKey).isEqualTo(Scenes.QuickSettings)
- sceneInteractor.changeScene(Scenes.Bouncer, "switching to bouncer for test")
- transitionState.value = ObservableTransitionState.Idle(Scenes.Bouncer)
+ sceneInteractor.showOverlay(Overlays.Bouncer, "showing bouncer for test")
+ transitionState.value =
+ ObservableTransitionState.Idle(Scenes.QuickSettings, setOf(Overlays.Bouncer))
runCurrent()
- assertThat(currentSceneKey).isEqualTo(Scenes.Bouncer)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
updateFingerprintAuthStatus(isSuccess = true)
assertThat(currentSceneKey).isEqualTo(Scenes.Gone)
+ assertThat(currentOverlays).doesNotContain(Overlays.Bouncer)
}
@Test
@@ -664,14 +671,21 @@ class SceneContainerStartableTest : SysuiTestCase() {
fun switchToGoneWhenDeviceIsUnlockedAndUserIsOnBouncerWithBypassDisabled() =
testScope.runTest {
val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
- prepareState(isBypassEnabled = false, initialSceneKey = Scenes.Bouncer)
- assertThat(currentSceneKey).isEqualTo(Scenes.Bouncer)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
+ prepareState(
+ isBypassEnabled = false,
+ initialSceneKey = Scenes.Lockscreen,
+ initialOverlays = setOf(Overlays.Bouncer),
+ )
+ assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
underTest.start()
// Authenticate using a passive auth method like face auth while bypass is disabled.
faceAuthRepository.isAuthenticated.value = true
assertThat(currentSceneKey).isEqualTo(Scenes.Gone)
+ assertThat(currentOverlays).doesNotContain(Overlays.Bouncer)
}
@Test
@@ -1192,14 +1206,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
runCurrent()
clearInvocations(sysUiState)
- listOf(
- Scenes.Gone,
- Scenes.Lockscreen,
- Scenes.Bouncer,
- Scenes.Gone,
- Scenes.Shade,
- Scenes.QuickSettings,
- )
+ listOf(Scenes.Gone, Scenes.Lockscreen, Scenes.Gone, Scenes.Shade, Scenes.QuickSettings)
.forEachIndexed { index, sceneKey ->
if (sceneKey == Scenes.Gone) {
updateFingerprintAuthStatus(isSuccess = true)
@@ -1385,19 +1392,13 @@ class SceneContainerStartableTest : SysuiTestCase() {
verify(falsingCollector, never()).onSuccessfulUnlock()
// Move around scenes without unlocking.
- listOf(
- Scenes.Shade,
- Scenes.QuickSettings,
- Scenes.Shade,
- Scenes.Lockscreen,
- Scenes.Bouncer,
- )
- .forEach { sceneKey ->
- sceneInteractor.changeScene(sceneKey, "reason")
- transitionStateFlow.value = ObservableTransitionState.Idle(sceneKey)
- runCurrent()
- verify(falsingCollector, never()).onSuccessfulUnlock()
- }
+ listOf(Scenes.Shade, Scenes.QuickSettings, Scenes.Shade, Scenes.Lockscreen).forEach {
+ sceneKey ->
+ sceneInteractor.changeScene(sceneKey, "reason")
+ transitionStateFlow.value = ObservableTransitionState.Idle(sceneKey)
+ runCurrent()
+ verify(falsingCollector, never()).onSuccessfulUnlock()
+ }
// Changing to the Gone scene should report a successful unlock.
kosmos.authenticationInteractor.authenticate(FakeAuthenticationRepository.DEFAULT_PIN)
@@ -1444,19 +1445,13 @@ class SceneContainerStartableTest : SysuiTestCase() {
verify(falsingCollector, times(1)).onSuccessfulUnlock()
// Move around scenes without unlocking.
- listOf(
- Scenes.Shade,
- Scenes.QuickSettings,
- Scenes.Shade,
- Scenes.Lockscreen,
- Scenes.Bouncer,
- )
- .forEach { sceneKey ->
- sceneInteractor.changeScene(sceneKey, "reason")
- transitionStateFlow.value = ObservableTransitionState.Idle(sceneKey)
- runCurrent()
- verify(falsingCollector, times(1)).onSuccessfulUnlock()
- }
+ listOf(Scenes.Shade, Scenes.QuickSettings, Scenes.Shade, Scenes.Lockscreen).forEach {
+ sceneKey ->
+ sceneInteractor.changeScene(sceneKey, "reason")
+ transitionStateFlow.value = ObservableTransitionState.Idle(sceneKey)
+ runCurrent()
+ verify(falsingCollector, times(1)).onSuccessfulUnlock()
+ }
kosmos.authenticationInteractor.authenticate(FakeAuthenticationRepository.DEFAULT_PIN)
runCurrent()
@@ -1565,13 +1560,13 @@ class SceneContainerStartableTest : SysuiTestCase() {
runCurrent()
verify(falsingCollector).onBouncerHidden()
- sceneInteractor.changeScene(Scenes.Bouncer, "reason")
+ sceneInteractor.showOverlay(Overlays.Bouncer, "reason")
runCurrent()
verify(falsingCollector).onBouncerShown()
updateFingerprintAuthStatus(isSuccess = true)
runCurrent()
- sceneInteractor.changeScene(Scenes.Gone, "reason")
+ sceneInteractor.hideOverlay(Overlays.Bouncer, "reason")
runCurrent()
verify(falsingCollector, times(2)).onBouncerHidden()
}
@@ -1579,7 +1574,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
@Test
fun switchesToBouncer_whenSimBecomesLocked() =
testScope.runTest {
- val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
prepareState(
initialSceneKey = Scenes.Lockscreen,
@@ -1592,17 +1587,18 @@ class SceneContainerStartableTest : SysuiTestCase() {
kosmos.fakeMobileConnectionsRepository.isAnySimSecure.value = true
runCurrent()
- assertThat(currentSceneKey).isEqualTo(Scenes.Bouncer)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
}
@Test
fun switchesToLockscreen_whenSimBecomesUnlocked() =
testScope.runTest {
kosmos.fakeMobileConnectionsRepository.isAnySimSecure.value = true
- val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
prepareState(
- initialSceneKey = Scenes.Bouncer,
+ initialSceneKey = Scenes.Lockscreen,
+ initialOverlays = setOf(Overlays.Bouncer),
authenticationMethod = AuthenticationMethodModel.Pin,
isDeviceUnlocked = false,
)
@@ -1611,7 +1607,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
kosmos.fakeMobileConnectionsRepository.isAnySimSecure.value = false
runCurrent()
- assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
+ assertThat(currentOverlays).doesNotContain(Overlays.Bouncer)
}
@Test
@@ -1700,7 +1696,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
verify(notificationShadeWindowController).setKeyguardShowing(true)
- emulateSceneTransition(transitionStateFlow, Scenes.Bouncer)
+ emulateOverlayTransition(transitionStateFlow, Overlays.Bouncer)
verify(notificationShadeWindowController, times(1)).setKeyguardShowing(true)
emulateSceneTransition(transitionStateFlow, Scenes.Lockscreen)
@@ -1748,9 +1744,9 @@ class SceneContainerStartableTest : SysuiTestCase() {
verify(centralSurfaces).setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true)
clearInvocations(centralSurfaces)
- emulateSceneTransition(
+ emulateOverlayTransition(
transitionStateFlow = transitionStateFlow,
- toScene = Scenes.Bouncer,
+ toOverlay = Overlays.Bouncer,
verifyBeforeTransition = {
verify(centralSurfaces, never()).setInteracting(anyInt(), anyBoolean())
},
@@ -1839,9 +1835,9 @@ class SceneContainerStartableTest : SysuiTestCase() {
verify(centralSurfaces, never()).setInteracting(anyInt(), anyBoolean())
clearInvocations(centralSurfaces)
- emulateSceneTransition(
+ emulateOverlayTransition(
transitionStateFlow = transitionStateFlow,
- toScene = Scenes.Bouncer,
+ toOverlay = Overlays.Bouncer,
verifyBeforeTransition = {
verify(centralSurfaces, never()).setInteracting(anyInt(), anyBoolean())
},
@@ -1926,9 +1922,9 @@ class SceneContainerStartableTest : SysuiTestCase() {
assertThat(currentDesiredOverlays).isEmpty()
clearInvocations(centralSurfaces)
- emulateSceneTransition(
+ emulateOverlayTransition(
transitionStateFlow = transitionStateFlow,
- toScene = Scenes.Bouncer,
+ toOverlay = Overlays.Bouncer,
verifyBeforeTransition = {
verify(centralSurfaces, never()).setInteracting(anyInt(), anyBoolean())
},
@@ -2019,9 +2015,9 @@ class SceneContainerStartableTest : SysuiTestCase() {
assertThat(currentDesiredOverlays).isEmpty()
clearInvocations(centralSurfaces)
- emulateSceneTransition(
+ emulateOverlayTransition(
transitionStateFlow = transitionStateFlow,
- toScene = Scenes.Bouncer,
+ toOverlay = Overlays.Bouncer,
verifyBeforeTransition = {
verify(centralSurfaces, never()).setInteracting(anyInt(), anyBoolean())
},
@@ -2098,32 +2094,42 @@ class SceneContainerStartableTest : SysuiTestCase() {
fun respondToFalsingDetections() =
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
val transitionStateFlow = prepareState()
underTest.start()
runCurrent()
- emulateSceneTransition(transitionStateFlow, toScene = Scenes.Bouncer)
- assertThat(currentScene).isNotEqualTo(Scenes.Lockscreen)
+ emulateOverlayTransition(
+ transitionStateFlow = transitionStateFlow,
+ toOverlay = Overlays.Bouncer,
+ )
+ assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
kosmos.falsingManager.sendFalsingBelief()
+ runCurrent()
assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+ assertThat(currentOverlays).isEmpty()
}
@Test
fun handleBouncerOverscroll() =
testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
val transitionStateFlow = prepareState()
underTest.start()
runCurrent()
- emulateSceneTransition(transitionStateFlow, toScene = Scenes.Bouncer)
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ emulateOverlayTransition(
+ transitionStateFlow = transitionStateFlow,
+ toOverlay = Overlays.Bouncer,
+ )
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
transitionStateFlow.value =
- ObservableTransitionState.Transition(
- fromScene = Scenes.Bouncer,
+ ObservableTransitionState.Transition.hideOverlay(
+ overlay = Overlays.Bouncer,
toScene = Scenes.Lockscreen,
- currentScene = flowOf(Scenes.Bouncer),
+ currentOverlays = flowOf(setOf(Overlays.Bouncer)),
progress = flowOf(-0.4f),
isInitiatedByUserInput = true,
isUserInputOngoing = flowOf(true),
@@ -2137,16 +2143,17 @@ class SceneContainerStartableTest : SysuiTestCase() {
fun switchToLockscreen_whenShadeBecomesNotTouchable() =
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
val isShadeTouchable by collectLastValue(kosmos.shadeInteractor.isShadeTouchable)
val transitionStateFlow = prepareState()
underTest.start()
assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
// Flung to bouncer, 90% of the way there:
transitionStateFlow.value =
- ObservableTransitionState.Transition(
+ ObservableTransitionState.Transition.showOverlay(
+ overlay = Overlays.Bouncer,
fromScene = Scenes.Lockscreen,
- toScene = Scenes.Bouncer,
- currentScene = flowOf(Scenes.Bouncer),
+ currentOverlays = flowOf(setOf(Overlays.Bouncer)),
progress = flowOf(0.9f),
isInitiatedByUserInput = true,
isUserInputOngoing = flowOf(false),
@@ -2159,22 +2166,27 @@ class SceneContainerStartableTest : SysuiTestCase() {
assertThat(isShadeTouchable).isFalse()
assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+ assertThat(currentOverlays).doesNotContain(Overlays.Bouncer)
}
@Test
fun switchToGone_extendUnlock() =
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
prepareState(
- initialSceneKey = Scenes.Bouncer,
+ initialSceneKey = Scenes.Lockscreen,
+ initialOverlays = setOf(Overlays.Bouncer),
authenticationMethod = AuthenticationMethodModel.Pin,
)
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
underTest.start()
fakeTrustRepository.setCurrentUserTrusted(true)
assertThat(currentScene).isEqualTo(Scenes.Gone)
+ assertThat(currentOverlays).doesNotContain(Overlays.Bouncer)
assertThat(uiEventLoggerFake[0].eventId)
.isEqualTo(BouncerUiEvent.BOUNCER_DISMISS_EXTENDED_ACCESS.id)
assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
@@ -2285,12 +2297,15 @@ class SceneContainerStartableTest : SysuiTestCase() {
fun notifyKeyguardDismissCallbacks_whenUnlockingFromBouncer_onDismissSucceeded() =
testScope.runTest {
val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
prepareState(
authenticationMethod = AuthenticationMethodModel.Pin,
isDeviceUnlocked = false,
- initialSceneKey = Scenes.Bouncer,
+ initialSceneKey = Scenes.Lockscreen,
+ initialOverlays = setOf(Overlays.Bouncer),
)
- assertThat(currentSceneKey).isEqualTo(Scenes.Bouncer)
+ assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
underTest.start()
// run all pending dismiss succeeded/cancelled calls from setup:
@@ -2311,7 +2326,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
fun notifyKeyguardDismissCallbacks_whenLeavingBouncer_onDismissCancelled() =
testScope.runTest {
val isUnlocked by collectLastValue(kosmos.deviceEntryInteractor.isUnlocked)
- val currentScene by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
prepareState()
underTest.start()
runCurrent()
@@ -2323,13 +2338,13 @@ class SceneContainerStartableTest : SysuiTestCase() {
kosmos.dismissCallbackRegistry.addCallback(dismissCallback)
// Switch to bouncer:
- sceneInteractor.changeScene(Scenes.Bouncer, "")
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ sceneInteractor.showOverlay(Overlays.Bouncer, "")
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
runCurrent()
// Return to lockscreen when isUnlocked=false:
- sceneInteractor.changeScene(Scenes.Lockscreen, "")
- assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+ sceneInteractor.hideOverlay(Overlays.Bouncer, "")
+ assertThat(currentOverlays).doesNotContain(Overlays.Bouncer)
assertThat(isUnlocked).isFalse()
runCurrent()
kosmos.fakeExecutor.runAllReady()
@@ -2844,6 +2859,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
isDeviceUnlocked: Boolean = false,
isBypassEnabled: Boolean = false,
initialSceneKey: SceneKey? = null,
+ initialOverlays: Set<OverlayKey> = emptySet(),
authenticationMethod: AuthenticationMethodModel? = null,
isLockscreenEnabled: Boolean = true,
startsAwake: Boolean = true,
@@ -2870,7 +2886,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
runCurrent()
val transitionStateFlow =
MutableStateFlow<ObservableTransitionState>(
- ObservableTransitionState.Idle(Scenes.Lockscreen)
+ ObservableTransitionState.Idle(Scenes.Lockscreen, initialOverlays)
)
sceneInteractor.setTransitionState(transitionStateFlow)
initialSceneKey?.let {
@@ -2881,9 +2897,12 @@ class SceneContainerStartableTest : SysuiTestCase() {
runCurrent()
}
- transitionStateFlow.value = ObservableTransitionState.Idle(it)
+ transitionStateFlow.value = ObservableTransitionState.Idle(it, initialOverlays)
sceneInteractor.changeScene(it, "prepareState, initialSceneKey isn't null")
}
+ for (overlay in initialOverlays) {
+ sceneInteractor.showOverlay(overlay, "prepareState, initialOverlays isn't empty")
+ }
if (startsAwake) {
powerInteractor.setAwakeForTest()
} else {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/ScrimStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/ScrimStartableTest.kt
index 572bc4dc4247..46f497054ab9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/ScrimStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/ScrimStartableTest.kt
@@ -18,6 +18,7 @@ package com.android.systemui.scene.domain.startable
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.compose.animation.scene.OverlayKey
import com.android.compose.animation.scene.SceneKey
import com.android.systemui.SysuiTestCase
import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
@@ -33,6 +34,7 @@ import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticati
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.data.repository.setSceneTransition
import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.settings.brightness.domain.interactor.brightnessMirrorShowingInteractor
import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor
@@ -90,34 +92,28 @@ class ScrimStartableTest : SysuiTestCase() {
TestSpec(
id = 2,
expectedState = ScrimState.BOUNCER,
- Preconditions(
- isOnKeyguard = true,
- isCurrentSceneBouncer = true,
- ),
+ Preconditions(isOnKeyguard = true, isIdleOnBouncer = true),
),
TestSpec(
id = 3,
expectedState = ScrimState.BOUNCER_SCRIMMED,
Preconditions(
isOnKeyguard = true,
- isCurrentSceneBouncer = true,
+ isIdleOnBouncer = true,
isBouncerScrimmingNeeded = true,
),
),
TestSpec(
id = 4,
expectedState = ScrimState.BRIGHTNESS_MIRROR,
- Preconditions(
- isOnKeyguard = true,
- isBrightnessMirrorVisible = true,
- ),
+ Preconditions(isOnKeyguard = true, isBrightnessMirrorVisible = true),
),
TestSpec(
id = 5,
expectedState = ScrimState.BRIGHTNESS_MIRROR,
Preconditions(
isOnKeyguard = true,
- isCurrentSceneBouncer = true,
+ isIdleOnBouncer = true,
isBiometricWakeAndUnlock = true,
isBrightnessMirrorVisible = true,
),
@@ -125,42 +121,27 @@ class ScrimStartableTest : SysuiTestCase() {
TestSpec(
id = 6,
expectedState = ScrimState.SHADE_LOCKED,
- Preconditions(
- isOnKeyguard = true,
- isCurrentSceneShade = true,
- ),
+ Preconditions(isOnKeyguard = true, isCurrentSceneShade = true),
),
TestSpec(
id = 7,
expectedState = ScrimState.PULSING,
- Preconditions(
- isOnKeyguard = true,
- isDozing = true,
- isPulsing = true,
- ),
+ Preconditions(isOnKeyguard = true, isDozing = true, isPulsing = true),
),
TestSpec(
id = 8,
expectedState = ScrimState.OFF,
- Preconditions(
- isOnKeyguard = true,
- hasPendingScreenOffCallback = true,
- ),
+ Preconditions(isOnKeyguard = true, hasPendingScreenOffCallback = true),
),
TestSpec(
id = 9,
expectedState = ScrimState.AOD,
- Preconditions(
- isOnKeyguard = true,
- isDozing = true,
- ),
+ Preconditions(isOnKeyguard = true, isDozing = true),
),
TestSpec(
id = 10,
expectedState = ScrimState.GLANCEABLE_HUB,
- Preconditions(
- isIdleOnCommunal = true,
- ),
+ Preconditions(isIdleOnCommunal = true),
),
TestSpec(
id = 11,
@@ -170,39 +151,23 @@ class ScrimStartableTest : SysuiTestCase() {
TestSpec(
id = 12,
expectedState = ScrimState.UNLOCKED,
- Preconditions(
- isDeviceEntered = true,
- ),
+ Preconditions(isDeviceEntered = true),
),
TestSpec(
id = 13,
expectedState = ScrimState.UNLOCKED,
- Preconditions(
- isOnKeyguard = true,
- isBiometricWakeAndUnlock = true,
- ),
- ),
- TestSpec(
- id = 14,
- expectedState = ScrimState.KEYGUARD,
- Preconditions(),
+ Preconditions(isOnKeyguard = true, isBiometricWakeAndUnlock = true),
),
+ TestSpec(id = 14, expectedState = ScrimState.KEYGUARD, Preconditions()),
TestSpec(
id = 15,
expectedState = ScrimState.DREAMING,
- Preconditions(
- isOnKeyguard = true,
- isOccluded = true,
- isDreaming = true,
- ),
+ Preconditions(isOnKeyguard = true, isOccluded = true, isDreaming = true),
),
TestSpec(
id = 16,
expectedState = ScrimState.UNLOCKED,
- Preconditions(
- isOnKeyguard = true,
- isOccluded = true,
- ),
+ Preconditions(isOnKeyguard = true, isOccluded = true),
),
)
}
@@ -253,9 +218,7 @@ class ScrimStartableTest : SysuiTestCase() {
}
/** Sets up the state to match what's specified in the given [preconditions]. */
- private fun TestScope.setUpWith(
- preconditions: Preconditions,
- ) {
+ private fun TestScope.setUpWith(preconditions: Preconditions) {
kosmos.fakeKeyguardBouncerRepository.setAlternateVisible(
preconditions.isAlternateBouncerVisible
)
@@ -272,17 +235,12 @@ class ScrimStartableTest : SysuiTestCase() {
when {
preconditions.isTransitioningToShade ->
- whenTransitioning(
- from = Scenes.Lockscreen,
- to = Scenes.Shade,
- )
+ whenTransitioning(from = Scenes.Lockscreen, to = Scenes.Shade)
preconditions.isTransitioningAwayFromKeyguard ->
- whenTransitioning(
- from = Scenes.Lockscreen,
- to = Scenes.Gone,
- )
+ whenTransitioning(from = Scenes.Lockscreen, to = Scenes.Gone)
preconditions.isCurrentSceneShade -> whenIdle(on = Scenes.Shade)
- preconditions.isCurrentSceneBouncer -> whenIdle(on = Scenes.Bouncer)
+ preconditions.isIdleOnBouncer ->
+ whenIdle(on = Scenes.Lockscreen, overlays = setOf(Overlays.Bouncer))
preconditions.isIdleOnCommunal -> whenIdle(on = Scenes.Communal)
}
@@ -323,9 +281,12 @@ class ScrimStartableTest : SysuiTestCase() {
}
/** Sets up an idle state on the given [on] scene. */
- private fun whenIdle(on: SceneKey) {
- kosmos.setSceneTransition(ObservableTransitionState.Idle(on))
+ private fun whenIdle(on: SceneKey, overlays: Set<OverlayKey> = emptySet()) {
+ kosmos.setSceneTransition(ObservableTransitionState.Idle(on, overlays))
kosmos.sceneInteractor.changeScene(on, "")
+ for (overlay in overlays) {
+ kosmos.sceneInteractor.showOverlay(overlay, "")
+ }
}
/** Sets up a transitioning state between the [given] and [to] scenes. */
@@ -351,7 +312,7 @@ class ScrimStartableTest : SysuiTestCase() {
/** Whether any non-shade nor QS scene is transitioning to a shade or QS scene. */
val isTransitioningToShade: Boolean = false,
val isOccluded: Boolean = false,
- val isCurrentSceneBouncer: Boolean = false,
+ val isIdleOnBouncer: Boolean = false,
val isBiometricWakeAndUnlock: Boolean = false,
/** Whether there's an active transition from lockscreen or bouncer to gone. */
val isTransitioningAwayFromKeyguard: Boolean = false,
@@ -388,7 +349,7 @@ class ScrimStartableTest : SysuiTestCase() {
assertWithMessage(
"isCurrentSceneBouncer cannot be true without isOnKeyguard also being true"
)
- .that(!isCurrentSceneBouncer || isOnKeyguard)
+ .that(!isIdleOnBouncer || isOnKeyguard)
.isTrue()
assertWithMessage(
@@ -400,13 +361,13 @@ class ScrimStartableTest : SysuiTestCase() {
assertWithMessage(
"isCurrentSceneBouncer cannot be true at the same time as isCurrentSceneShade"
)
- .that(!isCurrentSceneBouncer || !isCurrentSceneShade)
+ .that(!isIdleOnBouncer || !isCurrentSceneShade)
.isTrue()
assertWithMessage(
"isCurrentSceneBouncer cannot be true at the same time as isIdleOnCommunal"
)
- .that(!isCurrentSceneBouncer || !isIdleOnCommunal)
+ .that(!isIdleOnBouncer || !isIdleOnCommunal)
.isTrue()
assertWithMessage(
@@ -422,7 +383,7 @@ class ScrimStartableTest : SysuiTestCase() {
assertWithMessage(
"isDeviceEntered cannot be true at the same time as isCurrentSceneBouncer"
)
- .that(!isDeviceEntered || !isCurrentSceneBouncer)
+ .that(!isDeviceEntered || !isIdleOnBouncer)
.isTrue()
assertWithMessage(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/StatusBarStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/StatusBarStartableTest.kt
index 99146d8b1267..eebbc843206b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/StatusBarStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/StatusBarStartableTest.kt
@@ -21,6 +21,7 @@ import android.provider.DeviceConfig
import android.view.WindowManagerPolicyConstants
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.compose.animation.scene.OverlayKey
import com.android.compose.animation.scene.SceneKey
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags
import com.android.internal.statusbar.statusBarService
@@ -40,6 +41,7 @@ import com.android.systemui.power.shared.model.WakeSleepReason
import com.android.systemui.power.shared.model.WakefulnessState
import com.android.systemui.scene.data.repository.setSceneTransition
import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor
import com.android.systemui.testKosmos
@@ -246,16 +248,14 @@ class StatusBarStartableTest : SysuiTestCase() {
}
/** Sets up the state to match what's specified in the given [preconditions]. */
- private fun TestScope.setUpWith(
- preconditions: Preconditions,
- ) {
+ private fun TestScope.setUpWith(preconditions: Preconditions) {
if (!preconditions.isKeyguardShowing) {
kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
SuccessFingerprintAuthenticationStatus(0, true)
)
}
if (preconditions.isForceHideHomeAndRecents) {
- whenIdle(Scenes.Bouncer)
+ whenIdle(Scenes.Lockscreen, setOf(Overlays.Bouncer))
} else if (preconditions.isKeyguardShowing) {
whenIdle(Scenes.Lockscreen)
} else {
@@ -308,9 +308,12 @@ class StatusBarStartableTest : SysuiTestCase() {
}
/** Sets up an idle state on the given [on] scene. */
- private fun whenIdle(on: SceneKey) {
- kosmos.setSceneTransition(ObservableTransitionState.Idle(on))
+ private fun whenIdle(on: SceneKey, overlays: Set<OverlayKey> = emptySet()) {
+ kosmos.setSceneTransition(ObservableTransitionState.Idle(on, overlays))
kosmos.sceneInteractor.changeScene(on, "")
+ for (overlay in overlays) {
+ kosmos.sceneInteractor.showOverlay(overlay, "")
+ }
}
data class Preconditions(
@@ -350,11 +353,7 @@ class StatusBarStartableTest : SysuiTestCase() {
}
}
- data class TestSpec(
- val id: Int,
- val expectedFlags: Int,
- val preconditions: Preconditions,
- ) {
+ data class TestSpec(val id: Int, val expectedFlags: Int, val preconditions: Preconditions) {
override fun toString(): String {
return "id=$id, expected=$expectedFlags, preconditions=$preconditions"
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/shared/model/SceneDataSourceDelegatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/shared/model/SceneDataSourceDelegatorTest.kt
index 2720c5722376..c9dab3479e49 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/shared/model/SceneDataSourceDelegatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/shared/model/SceneDataSourceDelegatorTest.kt
@@ -55,9 +55,9 @@ class SceneDataSourceDelegatorTest : SysuiTestCase() {
testScope.runTest {
val currentScene by collectLastValue(underTest.currentScene)
underTest.setDelegate(null)
- assertThat(currentScene).isNotEqualTo(Scenes.Bouncer)
+ assertThat(currentScene).isNotEqualTo(Scenes.Gone)
- underTest.changeScene(toScene = Scenes.Bouncer)
+ underTest.changeScene(toScene = Scenes.Gone)
assertThat(currentScene).isEqualTo(initialSceneKey)
}
@@ -73,11 +73,11 @@ class SceneDataSourceDelegatorTest : SysuiTestCase() {
fun currentScene_withDelegate_changesScenes() =
testScope.runTest {
val currentScene by collectLastValue(underTest.currentScene)
- assertThat(currentScene).isNotEqualTo(Scenes.Bouncer)
+ assertThat(currentScene).isNotEqualTo(Scenes.Gone)
- underTest.changeScene(toScene = Scenes.Bouncer)
+ underTest.changeScene(toScene = Scenes.Gone)
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ assertThat(currentScene).isEqualTo(Scenes.Gone)
}
@Test
@@ -85,8 +85,8 @@ class SceneDataSourceDelegatorTest : SysuiTestCase() {
testScope.runTest {
val currentScene by collectLastValue(underTest.currentScene)
- fakeSceneDataSource.changeScene(toScene = Scenes.Bouncer)
+ fakeSceneDataSource.changeScene(toScene = Scenes.Gone)
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ assertThat(currentScene).isEqualTo(Scenes.Gone)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/view/SceneJankMonitorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/view/SceneJankMonitorTest.kt
index 984f8fd13cde..9b00e217466c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/view/SceneJankMonitorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/view/SceneJankMonitorTest.kt
@@ -31,6 +31,7 @@ import com.android.systemui.kosmos.runCurrent
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testScope
import com.android.systemui.lifecycle.activateIn
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
@@ -158,22 +159,22 @@ class SceneJankMonitorTest : SysuiTestCase() {
underTest.onTransitionStart(
view = mock(),
from = Scenes.Lockscreen,
- to = Scenes.Bouncer,
+ to = Overlays.Bouncer,
cuj = null,
)
verifyCujCounts(beginAppearCount = 1)
- underTest.onTransitionEnd(from = Scenes.Lockscreen, to = Scenes.Bouncer, cuj = null)
+ underTest.onTransitionEnd(from = Scenes.Lockscreen, to = Overlays.Bouncer, cuj = null)
verifyCujCounts(beginAppearCount = 1, endAppearCount = 1)
// Bouncer disappear CUJ but it doesn't log because the device isn't unlocked.
underTest.onTransitionStart(
view = mock(),
- from = Scenes.Bouncer,
+ from = Overlays.Bouncer,
to = Scenes.Lockscreen,
cuj = null,
)
verifyCujCounts(beginAppearCount = 1, endAppearCount = 1)
- underTest.onTransitionEnd(from = Scenes.Bouncer, to = Scenes.Lockscreen, cuj = null)
+ underTest.onTransitionEnd(from = Overlays.Bouncer, to = Scenes.Lockscreen, cuj = null)
verifyCujCounts(beginAppearCount = 1, endAppearCount = 1)
if (!testUnlockedDisappearance) {
@@ -190,12 +191,12 @@ class SceneJankMonitorTest : SysuiTestCase() {
// Bouncer disappear CUJ and it doeslog because the device is unlocked.
underTest.onTransitionStart(
view = mock(),
- from = Scenes.Bouncer,
+ from = Overlays.Bouncer,
to = Scenes.Gone,
cuj = null,
)
verifyCujCounts(beginAppearCount = 1, endAppearCount = 1, beginDisappearCount = 1)
- underTest.onTransitionEnd(from = Scenes.Bouncer, to = Scenes.Gone, cuj = null)
+ underTest.onTransitionEnd(from = Overlays.Bouncer, to = Scenes.Gone, cuj = null)
verifyCujCounts(
beginAppearCount = 1,
endAppearCount = 1,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerHapticsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerHapticsViewModelTest.kt
index 7330b517ba67..f04f0a3577d8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerHapticsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerHapticsViewModelTest.kt
@@ -164,7 +164,7 @@ class SceneContainerHapticsViewModelTest : SysuiTestCase() {
kosmos.enableDualShade()
// GIVEN an invalid scene transition to play haptics
val invalidTransition =
- createTransitionState(from = Scenes.Bouncer, to = Overlays.NotificationsShade)
+ createTransitionState(from = Scenes.QuickSettings, to = Scenes.Gone)
// WHEN the transition occurs
sceneInteractor.setTransitionState(MutableStateFlow(invalidTransition))
@@ -199,7 +199,7 @@ class SceneContainerHapticsViewModelTest : SysuiTestCase() {
kosmos.enableDualShade()
// GIVEN an invalid scene transition to play haptics
val invalidTransition =
- createTransitionState(from = Scenes.Bouncer, to = Overlays.NotificationsShade)
+ createTransitionState(from = Scenes.QuickSettings, to = Scenes.Gone)
// WHEN the transition occurs
sceneInteractor.setTransitionState(MutableStateFlow(invalidTransition))
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractorImplTest.kt
index 1859e250c6ad..d7b8aff97376 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractorImplTest.kt
@@ -78,7 +78,7 @@ class PanelExpansionInteractorImplTest : SysuiTestCase() {
changeScene(Scenes.Lockscreen) { assertThat(panelExpansion).isEqualTo(1f) }
assertThat(panelExpansion).isEqualTo(1f)
- changeScene(Scenes.Bouncer) { assertThat(panelExpansion).isEqualTo(1f) }
+ showOverlay(Overlays.Bouncer) { assertThat(panelExpansion).isEqualTo(1f) }
assertThat(panelExpansion).isEqualTo(1f)
changeScene(Scenes.Shade) { assertThat(panelExpansion).isEqualTo(1f) }
@@ -133,7 +133,7 @@ class PanelExpansionInteractorImplTest : SysuiTestCase() {
changeScene(Scenes.Lockscreen) { assertThat(panelExpansion).isEqualTo(1f) }
assertThat(panelExpansion).isEqualTo(1f)
- changeScene(Scenes.Bouncer) { assertThat(panelExpansion).isEqualTo(1f) }
+ showOverlay(Overlays.Bouncer) { assertThat(panelExpansion).isEqualTo(1f) }
assertThat(panelExpansion).isEqualTo(1f)
showOverlay(Overlays.NotificationsShade) { assertThat(panelExpansion).isEqualTo(1f) }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/NotificationShadeWindowModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/NotificationShadeWindowModelTest.kt
index 2038adcfc21f..d5537a611f13 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/NotificationShadeWindowModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/NotificationShadeWindowModelTest.kt
@@ -32,6 +32,7 @@ import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
@@ -125,7 +126,7 @@ class NotificationShadeWindowModelTest : SysuiTestCase() {
to = KeyguardState.DREAMING,
value = 1f,
transitionState = TransitionState.FINISHED,
- ),
+ )
)
assertThat(isKeyguardOccluded).isTrue()
@@ -154,7 +155,7 @@ class NotificationShadeWindowModelTest : SysuiTestCase() {
to = KeyguardState.OCCLUDED,
value = 1f,
transitionState = TransitionState.FINISHED,
- ),
+ )
)
assertThat(isKeyguardOccluded).isTrue()
}
@@ -173,7 +174,8 @@ class NotificationShadeWindowModelTest : SysuiTestCase() {
runCurrent()
assertThat(bouncerShowing).isFalse()
- transitionState.value = ObservableTransitionState.Idle(Scenes.Bouncer)
+ transitionState.value =
+ ObservableTransitionState.Idle(Scenes.Lockscreen, setOf(Overlays.Bouncer))
runCurrent()
assertThat(bouncerShowing).isTrue()
}
@@ -204,7 +206,7 @@ class NotificationShadeWindowModelTest : SysuiTestCase() {
val transitionState =
MutableStateFlow<ObservableTransitionState>(
- ObservableTransitionState.Idle(Scenes.Bouncer)
+ ObservableTransitionState.Idle(Scenes.Lockscreen, setOf(Overlays.Bouncer))
)
kosmos.sceneInteractor.setTransitionState(transitionState)
runCurrent()
@@ -219,7 +221,8 @@ class NotificationShadeWindowModelTest : SysuiTestCase() {
AuthenticationMethodModel.Password
)
// go back to bouncer
- transitionState.value = ObservableTransitionState.Idle(Scenes.Bouncer)
+ transitionState.value =
+ ObservableTransitionState.Idle(Scenes.Lockscreen, setOf(Overlays.Bouncer))
runCurrent()
assertThat(bouncerRequiresIme).isTrue()
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
index 83361dad9ff0..c10fd5e18fc5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar
import android.os.IBinder
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
+import android.platform.test.annotations.RequiresFlagsDisabled
import android.testing.TestableLooper.RunWithLooper
import android.view.Choreographer
import android.view.View
@@ -34,7 +35,6 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.res.R
import com.android.systemui.shade.ShadeExpansionChangeEvent
-import com.android.systemui.shared.Flags as SharedFlags
import com.android.systemui.statusbar.phone.BiometricUnlockController
import com.android.systemui.statusbar.phone.DozeParameters
import com.android.systemui.statusbar.phone.ScrimController
@@ -44,11 +44,10 @@ import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.testKosmos
import com.android.systemui.util.WallpaperController
import com.android.systemui.util.mockito.eq
+import com.android.systemui.wallpapers.domain.interactor.WallpaperInteractor
import com.android.systemui.window.domain.interactor.WindowRootViewBlurInteractor
import com.android.wm.shell.appzoomout.AppZoomOut
import com.google.common.truth.Truth.assertThat
-import java.util.Optional
-import java.util.function.Consumer
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -69,6 +68,8 @@ import org.mockito.Mockito.reset
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.junit.MockitoJUnit
+import java.util.Optional
+import java.util.function.Consumer
@RunWith(AndroidJUnit4::class)
@RunWithLooper
@@ -76,6 +77,7 @@ import org.mockito.junit.MockitoJUnit
class NotificationShadeDepthControllerTest : SysuiTestCase() {
private val kosmos = testKosmos()
+ private val applicationScope = kosmos.testScope.backgroundScope
@Mock private lateinit var windowRootViewBlurInteractor: WindowRootViewBlurInteractor
@Mock private lateinit var statusBarStateController: StatusBarStateController
@Mock private lateinit var blurUtils: BlurUtils
@@ -84,6 +86,7 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
@Mock private lateinit var keyguardInteractor: KeyguardInteractor
@Mock private lateinit var choreographer: Choreographer
@Mock private lateinit var wallpaperController: WallpaperController
+ @Mock private lateinit var wallpaperInteractor: WallpaperInteractor
@Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController
@Mock private lateinit var dumpManager: DumpManager
@Mock private lateinit var appZoomOutOptional: Optional<AppZoomOut>
@@ -128,12 +131,14 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
keyguardInteractor,
choreographer,
wallpaperController,
+ wallpaperInteractor,
notificationShadeWindowController,
dozeParameters,
context,
ResourcesSplitShadeStateController(),
windowRootViewBlurInteractor,
appZoomOutOptional,
+ applicationScope,
dumpManager,
configurationController,
)
@@ -310,19 +315,21 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
}
@Test
- @DisableFlags(SharedFlags.FLAG_AMBIENT_AOD)
- fun onDozeAmountChanged_appliesBlur() {
+ fun onDozeAmountChanged_doesNotApplyBlurWithAmbientAod() {
+ notificationShadeDepthController.wallpaperSupportsAmbientMode = false
+
statusBarStateListener.onDozeAmountChanged(1f, 1f)
notificationShadeDepthController.updateBlurCallback.doFrame(0)
- verify(blurUtils).applyBlur(any(), eq(maxBlur), eq(false))
+ verify(blurUtils).applyBlur(any(), eq(0), eq(false))
}
@Test
- @EnableFlags(SharedFlags.FLAG_AMBIENT_AOD)
- fun onDozeAmountChanged_doesNotApplyBlurWithAmbientAod() {
+ fun onDozeAmountChanged_appliesBlurWithAmbientAod() {
+ notificationShadeDepthController.wallpaperSupportsAmbientMode = true
+
statusBarStateListener.onDozeAmountChanged(1f, 1f)
notificationShadeDepthController.updateBlurCallback.doFrame(0)
- verify(blurUtils).applyBlur(any(), eq(0), eq(false))
+ verify(blurUtils).applyBlur(any(), eq(maxBlur), eq(false))
}
@Test
@@ -353,6 +360,7 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_NOTIFICATION_SHADE_BLUR)
fun updateBlurCallback_setsOpaque_whenScrim() {
scrimVisibilityCaptor.value.accept(ScrimController.OPAQUE)
notificationShadeDepthController.updateBlurCallback.doFrame(0)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
index 7a982a30981f..6a222c619332 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
@@ -253,6 +253,7 @@ class StatusBarStateControllerImplTest(flags: FlagsParameterization) : SysuiTest
underTest.addCallback(listener)
val currentScene by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
val deviceUnlockStatus by
collectLastValue(kosmos.deviceUnlockedInteractor.deviceUnlockStatus)
@@ -269,9 +270,9 @@ class StatusBarStateControllerImplTest(flags: FlagsParameterization) : SysuiTest
// Call start to begin hydrating based on the scene framework:
underTest.start()
- sceneInteractor.changeScene(toScene = Scenes.Bouncer, loggingReason = "reason")
+ sceneInteractor.showOverlay(overlay = Overlays.Bouncer, loggingReason = "reason")
runCurrent()
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
assertThat(statusBarState).isEqualTo(StatusBarState.KEYGUARD)
sceneInteractor.changeScene(toScene = Scenes.Shade, loggingReason = "reason")
@@ -373,13 +374,12 @@ class StatusBarStateControllerImplTest(flags: FlagsParameterization) : SysuiTest
// Call start to begin hydrating based on the scene framework:
underTest.start()
- sceneInteractor.changeScene(Scenes.Bouncer, loggingReason = "reason")
+ sceneInteractor.showOverlay(Overlays.Bouncer, loggingReason = "reason")
runCurrent()
- assertThat(currentScene).isEqualTo(Scenes.Bouncer)
- assertThat(currentOverlays).isEmpty()
+ assertThat(currentOverlays).contains(Overlays.Bouncer)
assertThat(statusBarState).isEqualTo(StatusBarState.KEYGUARD)
- sceneInteractor.changeScene(Scenes.Lockscreen, loggingReason = "reason")
+ sceneInteractor.hideOverlay(Overlays.Bouncer, loggingReason = "reason")
runCurrent()
sceneInteractor.showOverlay(Overlays.NotificationsShade, loggingReason = "reason")
@@ -507,6 +507,11 @@ class StatusBarStateControllerImplTest(flags: FlagsParameterization) : SysuiTest
testScope.runTest {
underTest.start()
underTest.setLeaveOpenOnKeyguardHide(true)
+ kosmos.sceneInteractor.snapToScene(Scenes.Lockscreen, "")
+ kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+ SuccessFingerprintAuthenticationStatus(0, true)
+ )
+ runCurrent()
keyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.AOD,
@@ -515,6 +520,7 @@ class StatusBarStateControllerImplTest(flags: FlagsParameterization) : SysuiTest
)
assertThat(underTest.leaveOpenOnKeyguardHide()).isEqualTo(true)
+ kosmos.sceneInteractor.changeScene(Scenes.Gone, "")
kosmos.setTransition(
sceneTransition = Idle(Scenes.Gone),
stateTransition =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
index 719924c865fd..1b5b0d6ff897 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
@@ -72,7 +72,6 @@ import org.mockito.kotlin.whenever
/** Tests for [OngoingActivityChipsViewModel] when the [StatusBarNotifChips] flag is disabled. */
@SmallTest
@RunWith(AndroidJUnit4::class)
-@EnableFlags(StatusBarChipsModernization.FLAG_NAME)
@DisableFlags(StatusBarNotifChips.FLAG_NAME)
class OngoingActivityChipsViewModelTest : SysuiTestCase() {
private val kosmos = testKosmos().useUnconfinedTestDispatcher()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt
index 67415de86d9b..e7be20e7c3cb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt
@@ -88,6 +88,7 @@ class StackStateAnimatorTest : SysuiTestCase() {
/* delay= */ 0L,
/* duration= */ ANIMATION_DURATION_HEADS_UP_APPEAR.toLong(),
/* isHeadsUpAppear= */ true,
+ /* isHeadsUpCycling= */ false,
/* onEndRunnable= */ null,
)
}
@@ -111,6 +112,7 @@ class StackStateAnimatorTest : SysuiTestCase() {
/* delay= */ 0L,
/* duration= */ ANIMATION_DURATION_HEADS_UP_APPEAR.toLong(),
/* isHeadsUpAppear= */ true,
+ /* isHeadsUpCycling= */ false,
/* onEndRunnable= */ null,
)
}
@@ -128,6 +130,7 @@ class StackStateAnimatorTest : SysuiTestCase() {
/* delay= */ eq(0L),
/* translationDirection= */ eq(0f),
/* isHeadsUpAnimation= */ eq(true),
+ /* isHeadsUpCycling= */ eq(false),
/* onStartedRunnable= */ any(),
/* onFinishedRunnable= */ runnableCaptor.capture(),
/* animationListener= */ any(),
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
index c630a1c1e006..e7c571dfcaf3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
@@ -62,6 +62,8 @@ import com.android.systemui.res.R
import com.android.systemui.scene.data.repository.Idle
import com.android.systemui.scene.data.repository.Transition
import com.android.systemui.scene.data.repository.setTransition
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.domain.interactor.enableDualShade
@@ -363,6 +365,8 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
assertThat(alpha).isEqualTo(1f)
// Start transitioning to glanceable hub
+ kosmos.sceneInteractor.changeScene(Scenes.Lockscreen, "")
+
val progress = 0.6f
kosmos.setTransition(
sceneTransition = Transition(from = Scenes.Lockscreen, to = Scenes.Communal),
@@ -396,6 +400,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
assertThat(alpha).isIn(Range.closed(0f, 1f))
// Finish transition to glanceable hub
+ kosmos.sceneInteractor.changeScene(Scenes.Communal, "")
kosmos.setTransition(
sceneTransition = Idle(Scenes.Communal),
stateTransition =
@@ -432,6 +437,8 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
assertThat(alpha).isEqualTo(1f)
// Start transitioning to glanceable hub
+ kosmos.sceneInteractor.snapToScene(Scenes.Lockscreen, "")
+
val progress = 0.6f
kosmos.setTransition(
sceneTransition = Transition(from = Scenes.Lockscreen, to = Scenes.Communal),
@@ -464,6 +471,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
assertThat(alpha).isEqualTo(0)
// Finish transition to glanceable hub
+ kosmos.sceneInteractor.changeScene(Scenes.Communal, "")
kosmos.setTransition(
sceneTransition = Idle(Scenes.Communal),
stateTransition =
@@ -492,6 +500,8 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
assertThat(alpha).isEqualTo(0f)
// Start transitioning to glanceable hub
+ kosmos.sceneInteractor.changeScene(Scenes.Lockscreen, "")
+
val progress = 0.6f
kosmos.setTransition(
sceneTransition = Transition(from = Scenes.Lockscreen, to = Scenes.Communal),
@@ -524,6 +534,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
assertThat(alpha).isEqualTo(0)
// Finish transition to glanceable hub
+ kosmos.sceneInteractor.changeScene(Scenes.Communal, "")
kosmos.setTransition(
sceneTransition = Idle(Scenes.Communal),
stateTransition =
@@ -587,7 +598,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
assertThat(isOnLockscreen).isTrue()
kosmos.setTransition(
- sceneTransition = Idle(Scenes.Bouncer),
+ sceneTransition = Idle(Scenes.Lockscreen, setOf(Overlays.Bouncer)),
stateTransition = TransitionStep(from = LOCKSCREEN, to = PRIMARY_BOUNCER),
)
assertThat(isOnLockscreen).isTrue()
@@ -601,7 +612,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
val isOnLockscreen by collectLastValue(underTest.isOnLockscreen)
setTransition(
- sceneTransition = Idle(Scenes.Bouncer),
+ sceneTransition = Idle(Scenes.Lockscreen, setOf(Overlays.Bouncer)),
stateTransition = TransitionStep(from = LOCKSCREEN, to = PRIMARY_BOUNCER),
)
assertThat(isOnLockscreen).isTrue()
@@ -659,6 +670,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
assertThat(isOnGlanceableHubWithoutShade).isFalse()
// Move to glanceable hub
+ kosmos.sceneInteractor.changeScene(Scenes.Communal, "")
kosmos.setTransition(
sceneTransition = Idle(Scenes.Communal),
stateTransition = TransitionStep(from = LOCKSCREEN, to = GLANCEABLE_HUB),
@@ -681,6 +693,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
shadeTestUtil.setQsExpansion(0f)
shadeTestUtil.setLockscreenShadeExpansion(0f)
+ kosmos.sceneInteractor.changeScene(Scenes.Communal, "")
kosmos.setTransition(
sceneTransition = Idle(Scenes.Communal),
stateTransition = TransitionStep(from = LOCKSCREEN, to = GLANCEABLE_HUB),
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/KeyguardBypassInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/KeyguardBypassInteractorTest.kt
index 091fbb65bcf9..c966f52b6c73 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/KeyguardBypassInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/KeyguardBypassInteractorTest.kt
@@ -29,6 +29,7 @@ import com.android.systemui.keyguard.domain.interactor.keyguardQuickAffordanceIn
import com.android.systemui.keyguard.domain.interactor.pulseExpansionInteractor
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.shadeTestUtil
import com.android.systemui.testKosmos
@@ -147,10 +148,11 @@ class KeyguardBypassInteractorTest : SysuiTestCase() {
}
private fun setScene(bouncerShowing: Boolean, onLockscreenScene: Boolean) {
- if (bouncerShowing) {
- kosmos.sceneInteractor.changeScene(Scenes.Bouncer, "reason")
- } else if (onLockscreenScene) {
+ if (onLockscreenScene) {
kosmos.sceneInteractor.changeScene(Scenes.Lockscreen, "reason")
+ if (bouncerShowing) {
+ kosmos.sceneInteractor.showOverlay(Overlays.Bouncer, "reason")
+ }
} else {
kosmos.sceneInteractor.changeScene(Scenes.Shade, "reason")
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
index 8a796fc33608..7e8ee1b156df 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
@@ -522,11 +522,12 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
}
@Test
- fun isHomeStatusBarAllowedByScene_sceneBouncer_false() =
+ fun isHomeStatusBarAllowedByScene_overlayBouncer_false() =
kosmos.runTest {
val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
- kosmos.sceneContainerRepository.snapToScene(Scenes.Bouncer)
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
+ kosmos.sceneContainerRepository.showOverlay(Overlays.Bouncer)
assertThat(latest).isFalse()
}
@@ -1052,7 +1053,8 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
- kosmos.sceneContainerRepository.snapToScene(Scenes.Bouncer)
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
+ kosmos.sceneContainerRepository.showOverlay(Overlays.Bouncer)
assertThat(clockVisible!!.visibility).isEqualTo(View.INVISIBLE)
assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
index 4ab1c0b1af6b..fea0320fc7e3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
@@ -154,7 +154,8 @@ class KeyguardStatusBarViewModelTest(flags: FlagsParameterization) : SysuiTestCa
testScope.runTest {
val latest by collectLastValue(underTest.isVisible)
- kosmos.sceneContainerRepository.snapToScene(Scenes.Bouncer)
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
+ kosmos.sceneContainerRepository.showOverlay(Overlays.Bouncer)
assertThat(latest).isFalse()
}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
index a0bf7f00b11c..d3218ad8c9fb 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
@@ -203,8 +203,6 @@ public interface QS extends FragmentBase {
*/
void setIsNotificationPanelFullWidth(boolean isFullWidth);
- default void setQSExpandingOrCollapsing(boolean isQSExpandingOrCollapsing) {}
-
/**
* Callback for when QSPanel container is scrolled
*/
diff --git a/packages/SystemUI/res/anim/volume_dialog_ringer_close.xml b/packages/SystemUI/res/anim/volume_dialog_ringer_close.xml
new file mode 100644
index 000000000000..e7ba52c3fae0
--- /dev/null
+++ b/packages/SystemUI/res/anim/volume_dialog_ringer_close.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ 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.
+ -->
+
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:controlX1="0.20"
+ android:controlY1="0.00"
+ android:controlX2="0.00"
+ android:controlY2="1.00" /> \ No newline at end of file
diff --git a/packages/SystemUI/res/anim/volume_dialog_ringer_open.xml b/packages/SystemUI/res/anim/volume_dialog_ringer_open.xml
new file mode 100644
index 000000000000..3b18eefc2552
--- /dev/null
+++ b/packages/SystemUI/res/anim/volume_dialog_ringer_open.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ 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.
+ -->
+
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:controlX1="0.05"
+ android:controlY1="0.70"
+ android:controlX2="0.10"
+ android:controlY2="1.00" /> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/media_output_list_group_divider.xml b/packages/SystemUI/res/layout/media_output_list_group_divider.xml
index c351912de295..fa5ad0d981c1 100644
--- a/packages/SystemUI/res/layout/media_output_list_group_divider.xml
+++ b/packages/SystemUI/res/layout/media_output_list_group_divider.xml
@@ -20,14 +20,14 @@
android:id="@+id/device_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/media_output_dialog_margin_horizontal"
+ android:layout_marginEnd="56dp"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_gravity="center_vertical|start"
- android:layout_marginStart="@dimen/media_output_dialog_margin_horizontal"
- android:layout_marginEnd="56dp"
android:ellipsize="end"
android:maxLines="1"
android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
diff --git a/packages/SystemUI/res/layout/media_output_list_item_advanced.xml b/packages/SystemUI/res/layout/media_output_list_item_advanced.xml
index d297ec46e1e1..6b868b3c7379 100644
--- a/packages/SystemUI/res/layout/media_output_list_item_advanced.xml
+++ b/packages/SystemUI/res/layout/media_output_list_item_advanced.xml
@@ -20,7 +20,8 @@
android:id="@+id/device_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingHorizontal="@dimen/media_output_dialog_margin_horizontal"
+ android:layout_marginHorizontal="@dimen/media_output_dialog_margin_horizontal"
+ android:focusable="true"
android:baselineAligned="false">
<FrameLayout
android:layout_weight="1"
@@ -77,6 +78,7 @@
</FrameLayout>
<LinearLayout
+ android:id="@+id/text_content"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_gravity="center_vertical|start"
@@ -86,7 +88,7 @@
android:layout_marginStart="72dp">
<TextView
android:id="@+id/title"
- android:importantForAccessibility="no"
+ android:focusable="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
@@ -96,6 +98,7 @@
android:textSize="16sp"/>
<TextView
android:id="@+id/subtitle"
+ android:focusable="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:marqueeRepeatLimit="marquee_forever"
@@ -124,7 +127,6 @@
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="16dp"
- android:indeterminate="true"
android:layout_gravity="end|center"
android:indeterminateOnly="true"
android:importantForAccessibility="no"
@@ -135,30 +137,23 @@
android:layout_width="@dimen/media_output_dialog_item_height"
android:layout_height="@dimen/media_output_dialog_item_height"
android:visibility="gone"
- android:layout_marginBottom="6dp"
android:layout_marginStart="7dp"
- android:layout_gravity="end|center"
- android:gravity="center"
android:background="@drawable/media_output_item_background_active">
<CheckBox
android:id="@+id/check_box"
- android:focusable="false"
- android:importantForAccessibility="no"
- android:layout_gravity="center"
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:button="@drawable/media_output_item_check_box"
+ android:foreground="@drawable/media_output_item_check_box"
+ android:foregroundGravity="center"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:button="@null"
android:visibility="gone"
/>
- <ImageView
- android:id="@+id/media_output_item_end_click_icon"
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:focusable="false"
- android:importantForAccessibility="no"
- android:layout_gravity="center"
- android:indeterminate="true"
- android:indeterminateOnly="true"
+ <ImageButton
+ android:id="@+id/end_area_image_button"
+ android:background="@android:color/transparent"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:contentDescription="@null"
android:visibility="gone"/>
</FrameLayout>
</LinearLayout> \ No newline at end of file
diff --git a/packages/SystemUI/res/values-land-television/dimens.xml b/packages/SystemUI/res/values-land-television/dimens.xml
index d3bafbca4bb7..b1a46a6805ff 100644
--- a/packages/SystemUI/res/values-land-television/dimens.xml
+++ b/packages/SystemUI/res/values-land-television/dimens.xml
@@ -20,7 +20,7 @@
<dimen name="volume_dialog_panel_width">48dp</dimen>
<dimen name="volume_dialog_panel_width_half">24dp</dimen>
<dimen name="volume_dialog_panel_transparent_padding">24dp</dimen>
- <dimen name="volume_dialog_slider_width">4dp</dimen>
+ <dimen name="volume_dialog_slider_width_legacy">4dp</dimen>
<dimen name="volume_dialog_slider_corner_radius">@dimen/volume_dialog_slider_width</dimen>
<dimen name="volume_dialog_background_blur_radius">31dp</dimen>
<dimen name="volume_tool_tip_right_margin">136dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index e97919e092a9..084495f4b196 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -592,6 +592,12 @@
<!-- Content description of the button to expand the group of devices. [CHAR LIMIT=NONE] -->
<string name="accessibility_expand_group">Expand group.</string>
+ <!-- Content description of the button to add a device to a group. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_add_device_to_group">Add device to group.</string>
+
+ <!-- Content description of the button to remove a device from a group. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_remove_device_from_group">Remove device from group.</string>
+
<!-- Content description of the button to open the application . [CHAR LIMIT=NONE] -->
<string name="accessibility_open_application">Open application.</string>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index f6d0f4e26d26..63101d430c6c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -156,7 +156,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.res.R;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
-import com.android.systemui.scene.shared.model.Scenes;
+import com.android.systemui.scene.shared.model.Overlays;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shade.ShadeDisplayAware;
import com.android.systemui.shared.system.TaskStackChangeListener;
@@ -2925,12 +2925,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
) {
SceneContainerFlag.assertInNewMode();
return isPrimaryBouncerFullyShown(transitionState)
- || transitionState.isTransitioning(null, Scenes.Bouncer);
+ || transitionState.isTransitioning(null, Overlays.Bouncer);
}
private boolean isPrimaryBouncerFullyShown(ObservableTransitionState transitionState) {
SceneContainerFlag.assertInNewMode();
- return transitionState.isIdle(Scenes.Bouncer);
+ return transitionState.isIdle(Overlays.Bouncer);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
index 7039d5e7d9b0..75503e8575f0 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
@@ -147,9 +147,7 @@ constructor(
/** The scene to show when bouncer is dismissed. */
val dismissDestination: Flow<SceneKey> =
- sceneBackInteractor.backScene
- .filter { it != Scenes.Bouncer }
- .map { it ?: Scenes.Lockscreen }
+ sceneBackInteractor.backScene.map { it ?: Scenes.Lockscreen }
/** Notifies that the user has places down a pointer, not necessarily dragging just yet. */
fun onDown() {
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt
index 116c9415bd11..7f268315e566 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt
@@ -10,7 +10,7 @@ import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlags
import com.android.systemui.bouncer.ui.BouncerDialogFactory
import com.android.systemui.bouncer.ui.viewmodel.BouncerContainerViewModel
-import com.android.systemui.bouncer.ui.viewmodel.BouncerSceneContentViewModel
+import com.android.systemui.bouncer.ui.viewmodel.BouncerOverlayContentViewModel
import com.android.systemui.bouncer.ui.viewmodel.KeyguardBouncerViewModel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
@@ -46,7 +46,7 @@ constructor(
val keyguardInteractor: KeyguardInteractor,
val selectedUserInteractor: SelectedUserInteractor,
val legacyInteractor: PrimaryBouncerInteractor,
- val viewModelFactory: BouncerSceneContentViewModel.Factory,
+ val viewModelFactory: BouncerOverlayContentViewModel.Factory,
val dialogFactory: BouncerDialogFactory,
val bouncerContainerViewModelFactory: BouncerContainerViewModel.Factory,
)
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/ComposeBouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/ComposeBouncerViewBinder.kt
index 2dce28409b57..33cebf70554f 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/ComposeBouncerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/ComposeBouncerViewBinder.kt
@@ -6,11 +6,12 @@ import androidx.activity.OnBackPressedDispatcherOwner
import androidx.activity.setViewTreeOnBackPressedDispatcherOwner
import androidx.compose.ui.platform.ComposeView
import androidx.lifecycle.Lifecycle
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.bouncer.ui.BouncerDialogFactory
import com.android.systemui.bouncer.ui.composable.BouncerContainer
import com.android.systemui.bouncer.ui.viewmodel.BouncerContainerViewModel
-import com.android.systemui.bouncer.ui.viewmodel.BouncerSceneContentViewModel
+import com.android.systemui.bouncer.ui.viewmodel.BouncerOverlayContentViewModel
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.lifecycle.WindowLifecycleState
import com.android.systemui.lifecycle.repeatWhenAttached
@@ -20,7 +21,6 @@ import com.android.systemui.util.kotlin.sample
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.awaitCancellation
-import com.android.app.tracing.coroutines.launchTraced as launch
/** View binder responsible for binding the compose version of the bouncer. */
object ComposeBouncerViewBinder {
@@ -32,7 +32,7 @@ object ComposeBouncerViewBinder {
legacyInteractor: PrimaryBouncerInteractor,
keyguardInteractor: KeyguardInteractor,
selectedUserInteractor: SelectedUserInteractor,
- viewModelFactory: BouncerSceneContentViewModel.Factory,
+ viewModelFactory: BouncerOverlayContentViewModel.Factory,
dialogFactory: BouncerDialogFactory,
bouncerContainerViewModelFactory: BouncerContainerViewModel.Factory,
) {
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/composable/BouncerContainer.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/composable/BouncerContainer.kt
index c59c6816a350..204eb3ec9753 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/composable/BouncerContainer.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/composable/BouncerContainer.kt
@@ -24,14 +24,14 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.android.compose.theme.PlatformTheme
import com.android.systemui.bouncer.ui.BouncerDialogFactory
-import com.android.systemui.bouncer.ui.viewmodel.BouncerSceneContentViewModel
+import com.android.systemui.bouncer.ui.viewmodel.BouncerOverlayContentViewModel
import com.android.systemui.compose.modifiers.sysuiResTag
import com.android.systemui.lifecycle.rememberViewModel
/** Container that includes the compose bouncer and is meant to be included in legacy keyguard. */
@Composable
fun BouncerContainer(
- viewModelFactory: BouncerSceneContentViewModel.Factory,
+ viewModelFactory: BouncerOverlayContentViewModel.Factory,
dialogFactory: BouncerDialogFactory,
) {
PlatformTheme {
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerOverlayContentViewModel.kt
index 5deb751ced27..b944d1acac9d 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerOverlayContentViewModel.kt
@@ -51,8 +51,8 @@ import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
-/** Models UI state for the content of the bouncer scene. */
-class BouncerSceneContentViewModel
+/** Models UI state for the content of the bouncer overlay. */
+class BouncerOverlayContentViewModel
@AssistedInject
constructor(
@Application private val applicationContext: Context,
@@ -445,6 +445,6 @@ constructor(
@AssistedFactory
interface Factory {
- fun create(): BouncerSceneContentViewModel
+ fun create(): BouncerOverlayContentViewModel
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModel.kt
index f50a2ab1d803..aafc0e1a9c67 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModel.kt
@@ -20,29 +20,24 @@ import com.android.compose.animation.scene.Back
import com.android.compose.animation.scene.Swipe
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
-import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.ui.viewmodel.UserActionsViewModel
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
-import kotlinx.coroutines.flow.map
/**
* Models UI state for user actions that can lead to navigation to other scenes when showing the
- * bouncer scene.
+ * bouncer overlay.
*/
-class BouncerUserActionsViewModel
-@AssistedInject
-constructor(private val bouncerInteractor: BouncerInteractor) : UserActionsViewModel() {
+class BouncerUserActionsViewModel @AssistedInject constructor() : UserActionsViewModel() {
override suspend fun hydrateActions(setActions: (Map<UserAction, UserActionResult>) -> Unit) {
- bouncerInteractor.dismissDestination
- .map { prevScene ->
- mapOf(
- Back to UserActionResult(prevScene),
- Swipe.Down to UserActionResult(prevScene),
- )
- }
- .collect { actions -> setActions(actions) }
+ setActions(
+ mapOf(
+ Back to UserActionResult.HideOverlay(Overlays.Bouncer),
+ Swipe.Down to UserActionResult.HideOverlay(Overlays.Bouncer),
+ )
+ )
}
@AssistedFactory
diff --git a/packages/SystemUI/src/com/android/systemui/common/shared/colors/SurfaceEffectColors.kt b/packages/SystemUI/src/com/android/systemui/common/shared/colors/SurfaceEffectColors.kt
index 7c2fc7fe3aee..5e8c21f9abf5 100644
--- a/packages/SystemUI/src/com/android/systemui/common/shared/colors/SurfaceEffectColors.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/shared/colors/SurfaceEffectColors.kt
@@ -20,12 +20,19 @@ import android.content.res.Resources
object SurfaceEffectColors {
@JvmStatic
- fun Resources.surfaceEffect0(): Int {
- return getColor(com.android.internal.R.color.surface_effect_0)
+ fun surfaceEffect0(r: Resources): Int {
+ return r.getColor(com.android.internal.R.color.surface_effect_0)
+ }
+ @JvmStatic
+ fun surfaceEffect1(r: Resources): Int {
+ return r.getColor(com.android.internal.R.color.surface_effect_1)
+ }
+ @JvmStatic
+ fun surfaceEffect2(r: Resources): Int {
+ return r.getColor(com.android.internal.R.color.surface_effect_2)
}
-
@JvmStatic
- fun Resources.surfaceEffect1(): Int {
- return getColor(com.android.internal.R.color.surface_effect_1)
+ fun surfaceEffect3(r: Resources): Int {
+ return r.getColor(com.android.internal.R.color.surface_effect_3)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
index 59beb1ed6c10..c8280d7fa152 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
@@ -113,7 +113,7 @@ constructor(
val canShowEditMode =
allOf(
keyguardTransitionInteractor.isFinishedIn(
- scene = Scenes.Gone,
+ content = Scenes.Gone,
stateWithoutSceneContainer = KeyguardState.GONE,
),
communalInteractor.editModeOpen,
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalUserActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalUserActionsViewModel.kt
index be1d005a0198..a1ff552827b2 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalUserActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalUserActionsViewModel.kt
@@ -20,6 +20,7 @@ import com.android.compose.animation.scene.Swipe
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.ui.viewmodel.UserActionsViewModel
import com.android.systemui.shade.domain.interactor.ShadeInteractor
@@ -55,9 +56,11 @@ constructor(
shadeModeInteractor.shadeMode,
) { isDeviceUnlocked, shadeMode ->
buildList {
- val bouncerOrGone =
- if (isDeviceUnlocked) Scenes.Gone else Scenes.Bouncer
- add(Swipe.Up to bouncerOrGone)
+ if (isDeviceUnlocked) {
+ add(Swipe.Up to Scenes.Gone)
+ } else {
+ add(Swipe.Up to Overlays.Bouncer)
+ }
add(Swipe.End to Scenes.Lockscreen)
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
index 6473b1c30586..d7859c985c7b 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
@@ -168,7 +168,7 @@ constructor(
override val isCommunalContentFlowFrozen: Flow<Boolean> =
allOf(
keyguardTransitionInteractor.isFinishedIn(
- scene = Scenes.Communal,
+ content = Scenes.Communal,
stateWithoutSceneContainer = KeyguardState.GLANCEABLE_HUB,
),
keyguardInteractor.isKeyguardOccluded,
@@ -204,7 +204,7 @@ constructor(
override val isFocusable: Flow<Boolean> =
combine(
keyguardTransitionInteractor.isFinishedIn(
- scene = Scenes.Communal,
+ content = Scenes.Communal,
stateWithoutSceneContainer = KeyguardState.GLANCEABLE_HUB,
),
communalInteractor.isIdleOnCommunal,
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt
index 514242b41eb1..69378b475938 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt
@@ -20,6 +20,7 @@ import android.app.StatusBarManager
import android.content.Context
import android.hardware.face.FaceManager
import android.os.CancellationSignal
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.internal.logging.InstanceId
import com.android.internal.logging.UiEventLogger
import com.android.systemui.Dumpable
@@ -59,8 +60,8 @@ import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
-import com.android.systemui.scene.shared.model.Scenes.Bouncer
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.user.data.model.SelectionStatus
import com.android.systemui.user.data.repository.UserRepository
@@ -87,7 +88,6 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
-import com.android.app.tracing.coroutines.launchTraced as launch
import kotlinx.coroutines.withContext
/**
@@ -138,7 +138,7 @@ interface DeviceEntryFaceAuthRepository {
private data class AuthenticationRequest(
val uiEvent: FaceAuthUiEvent,
- val fallbackToDetection: Boolean
+ val fallbackToDetection: Boolean,
)
@SysUISingleton
@@ -248,11 +248,11 @@ constructor(
Pair(isLockedOut.isFalse(), "isNotInLockOutState"),
Pair(
keyguardRepository.isKeyguardDismissible.isFalse(),
- "keyguardIsNotDismissible"
+ "keyguardIsNotDismissible",
),
Pair(
biometricSettingsRepository.isFaceAuthCurrentlyAllowed,
- "isFaceAuthCurrentlyAllowed"
+ "isFaceAuthCurrentlyAllowed",
),
Pair(isAuthenticated.isFalse(), "faceNotAuthenticated"),
)
@@ -273,15 +273,15 @@ constructor(
biometricSettingsRepository.isFaceAuthCurrentlyAllowed
.isFalse()
.or(keyguardRepository.isKeyguardDismissible),
- "faceAuthIsNotCurrentlyAllowedOrCurrentUserIsTrusted"
+ "faceAuthIsNotCurrentlyAllowedOrCurrentUserIsTrusted",
),
// We don't want to run face detect if fingerprint can be used to unlock the
// device
// but it's not possible to authenticate with FP from the bouncer (UDFPS)
Pair(
and(isUdfps(), deviceEntryFingerprintAuthRepository.isRunning).isFalse(),
- "udfpsAuthIsNotPossibleAnymore"
- )
+ "udfpsAuthIsNotPossibleAnymore",
+ ),
)
.andAllFlows("canFaceDetectRun", faceDetectLog)
.flowOn(backgroundDispatcher)
@@ -318,7 +318,7 @@ constructor(
powerInteractor.isAsleep,
combine(
keyguardTransitionInteractor.isFinishedIn(
- scene = Scenes.Gone,
+ content = Scenes.Gone,
stateWithoutSceneContainer = KeyguardState.GONE,
),
keyguardInteractor.statusBarState,
@@ -350,7 +350,7 @@ constructor(
faceAuthLogger.clearingPendingAuthRequest(
loggingContext,
pendingAuthenticateRequest.value?.uiEvent,
- pendingAuthenticateRequest.value?.fallbackToDetection
+ pendingAuthenticateRequest.value?.fallbackToDetection,
)
pendingAuthenticateRequest.value = null
}
@@ -387,7 +387,7 @@ constructor(
),
Pair(
biometricSettingsRepository.isFaceAuthEnrolledAndEnabled,
- "isFaceAuthEnrolledAndEnabled"
+ "isFaceAuthEnrolledAndEnabled",
),
Pair(
if (SceneContainerFlag.isEnabled) {
@@ -399,13 +399,13 @@ constructor(
} else {
keyguardRepository.isKeyguardGoingAway.isFalse()
},
- "keyguardNotGoingAway"
+ "keyguardNotGoingAway",
),
Pair(
keyguardTransitionInteractor
.isInTransitionWhere(toStatePredicate = KeyguardState::deviceIsAsleepInState)
.isFalse(),
- "deviceNotTransitioningToAsleepState"
+ "deviceNotTransitioningToAsleepState",
),
Pair(
keyguardInteractor.isSecureCameraActive
@@ -413,29 +413,31 @@ constructor(
.or(
alternateBouncerInteractor.isVisible.or(
if (SceneContainerFlag.isEnabled) {
- sceneInteractor.get().transitionState.map { it.isIdle(Bouncer) }
+ sceneInteractor.get().transitionState.map {
+ it.isIdle(overlay = Overlays.Bouncer)
+ }
} else {
keyguardInteractor.primaryBouncerShowing
}
)
),
- "secureCameraNotActiveOrAnyBouncerIsShowing"
+ "secureCameraNotActiveOrAnyBouncerIsShowing",
),
Pair(
biometricSettingsRepository.isFaceAuthSupportedInCurrentPosture,
- "isFaceAuthSupportedInCurrentPosture"
+ "isFaceAuthSupportedInCurrentPosture",
),
Pair(
biometricSettingsRepository.isCurrentUserInLockdown.isFalse(),
- "userHasNotLockedDownDevice"
+ "userHasNotLockedDownDevice",
),
Pair(keyguardRepository.isKeyguardShowing, "isKeyguardShowing"),
Pair(
userRepository.selectedUser
.map { it.selectionStatus == SelectionStatus.SELECTION_IN_PROGRESS }
.isFalse(),
- "userSwitchingInProgress"
- )
+ "userSwitchingInProgress",
+ ),
)
}
@@ -486,7 +488,7 @@ constructor(
errorCode,
errString,
errorStatus.isLockoutError(),
- errorStatus.isCancellationError()
+ errorStatus.isCancellationError(),
)
onFaceAuthRequestCompleted()
}
@@ -524,7 +526,7 @@ constructor(
faceAuthLogger.attemptingRetryAfterHardwareError(retryCount)
requestAuthenticate(
FaceAuthUiEvent.FACE_AUTH_TRIGGERED_RETRY_AFTER_HW_UNAVAILABLE,
- fallbackToDetection = false
+ fallbackToDetection = false,
)
}
}
@@ -551,7 +553,7 @@ constructor(
if (pendingAuthenticateRequest.value != null) {
faceAuthLogger.ignoredFaceAuthTrigger(
pendingAuthenticateRequest.value?.uiEvent,
- "Previously queued trigger skipped due to new request"
+ "Previously queued trigger skipped due to new request",
)
}
faceAuthLogger.queueingRequest(uiEvent, fallbackToDetection)
@@ -574,7 +576,7 @@ constructor(
pending?.uiEvent,
canRunAuth,
canRunDetect,
- cancelInProgress
+ cancelInProgress,
)
return@combine null
} else {
@@ -613,7 +615,7 @@ constructor(
0,
null,
keyguardSessionId,
- uiEvent.extraInfo
+ uiEvent.extraInfo,
)
faceAuthLogger.authenticating(uiEvent)
faceManager?.authenticate(
@@ -624,28 +626,28 @@ constructor(
SysUiFaceAuthenticateOptions(
currentUserId,
uiEvent,
- wakeReason = uiEvent.extraInfo
+ wakeReason = uiEvent.extraInfo,
)
- .toFaceAuthenticateOptions()
+ .toFaceAuthenticateOptions(),
)
}
} else if (canRunDetection.value) {
if (fallbackToDetection) {
faceAuthLogger.ignoredFaceAuthTrigger(
uiEvent,
- "face auth gating check is false, falling back to detection."
+ "face auth gating check is false, falling back to detection.",
)
detect(uiEvent)
} else {
faceAuthLogger.ignoredFaceAuthTrigger(
uiEvent = uiEvent,
- "face auth gating check is false and fallback to detection is not requested"
+ "face auth gating check is false and fallback to detection is not requested",
)
}
} else {
faceAuthLogger.ignoredFaceAuthTrigger(
uiEvent,
- "face auth & detect gating check is false"
+ "face auth & detect gating check is false",
)
}
}
@@ -669,7 +671,7 @@ constructor(
it,
detectionCallback,
SysUiFaceAuthenticateOptions(currentUserId, uiEvent, uiEvent.extraInfo)
- .toFaceAuthenticateOptions()
+ .toFaceAuthenticateOptions(),
)
}
}
@@ -695,7 +697,7 @@ constructor(
_isAuthRunning.value,
_isLockedOut.value,
cancellationInProgress.value,
- pendingAuthenticateRequest.value?.uiEvent
+ pendingAuthenticateRequest.value?.uiEvent,
)
_authenticationStatus.value = ErrorFaceAuthenticationStatus.cancelNotReceivedError()
onFaceAuthRequestCompleted()
@@ -759,7 +761,7 @@ private fun Flow<Boolean>.isFalse(): Flow<Boolean> {
private fun List<Pair<Flow<Boolean>, String>>.andAllFlows(
combinedLoggingInfo: String,
- tableLogBuffer: TableLogBuffer
+ tableLogBuffer: TableLogBuffer,
): Flow<Boolean> {
return combine(this.map { it.first }) {
val combinedValue =
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
index 5fc924b14814..58310e9c3e9a 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
@@ -30,6 +30,7 @@ import com.android.systemui.scene.data.model.asIterable
import com.android.systemui.scene.domain.SceneFrameworkTableLog
import com.android.systemui.scene.domain.interactor.SceneBackInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.util.kotlin.pairwise
import com.android.systemui.utils.coroutines.flow.mapLatestConflated
@@ -238,8 +239,8 @@ constructor(
if (alternateBouncerInteractor.canShowAlternateBouncer.value) {
alternateBouncerInteractor.forceShow()
} else {
- sceneInteractor.changeScene(
- toScene = Scenes.Bouncer,
+ sceneInteractor.showOverlay(
+ overlay = Overlays.Bouncer,
loggingReason = "request to unlock device while authentication required",
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntrySourceInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntrySourceInteractor.kt
index eb82c7d4ce6a..5de2ed231275 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntrySourceInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntrySourceInteractor.kt
@@ -33,6 +33,7 @@ import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticati
import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_DISMISS_BOUNCER
import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_NONE
@@ -84,14 +85,14 @@ constructor(
sceneInteractor: SceneInteractor,
dumpManager: DumpManager,
) : FlowDumperImpl(dumpManager) {
- private val isShowingBouncerScene: Flow<Boolean> =
+ private val isShowingBouncerOverlay: Flow<Boolean> =
sceneInteractor.transitionState
.map { transitionState ->
- transitionState.isIdle(Scenes.Bouncer) ||
- transitionState.isTransitioning(null, Scenes.Bouncer)
+ transitionState.isIdle(overlay = Overlays.Bouncer) ||
+ transitionState.isTransitioning(null, Overlays.Bouncer)
}
.distinctUntilChanged()
- .dumpWhileCollecting("isShowingBouncerScene")
+ .dumpWhileCollecting("isShowingBouncerOverlay")
private val isUnlockedWithStrongFaceUnlock =
deviceEntryFaceAuthInteractor.authenticationStatus
@@ -115,14 +116,14 @@ constructor(
isUnlockedWithStrongFaceUnlock,
sceneContainerOcclusionInteractor.isOccludingActivityShown,
sceneInteractor.currentScene,
- isShowingBouncerScene,
+ isShowingBouncerOverlay,
) {
isAlternateBouncerVisible,
isBypassAvailable,
isFaceStrongBiometric,
isOccluded,
currentScene,
- isShowingBouncerScene ->
+ isShowingBouncerOverlay ->
val isUnlockingAllowed =
keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(isFaceStrongBiometric)
val bypass = isBypassAvailable || authController.isUdfpsFingerDown()
@@ -140,7 +141,7 @@ constructor(
isUnlockingAllowed && isOccluded -> MODE_UNLOCK_COLLAPSING
- (isShowingBouncerScene || isAlternateBouncerVisible) && isUnlockingAllowed ->
+ (isShowingBouncerOverlay || isAlternateBouncerVisible) && isUnlockingAllowed ->
MODE_DISMISS_BOUNCER
isUnlockingAllowed && bypass -> MODE_UNLOCK_COLLAPSING
@@ -158,14 +159,16 @@ constructor(
alternateBouncerInteractor.isVisible,
authenticationInteractor.authenticationMethod,
sceneInteractor.currentScene,
+ sceneInteractor.currentOverlays,
isUnlockedWithStrongFingerprintUnlock,
- isShowingBouncerScene,
+ isShowingBouncerOverlay,
) {
alternateBouncerVisible,
authenticationMethod,
currentScene,
+ currentOverlays,
isFingerprintStrongBiometric,
- isShowingBouncerScene ->
+ isShowingBouncerOverlay ->
val unlockingAllowed =
keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
isFingerprintStrongBiometric
@@ -185,11 +188,12 @@ constructor(
unlockingAllowed && currentScene == Scenes.Dream ->
MODE_WAKE_AND_UNLOCK_FROM_DREAM
- isShowingBouncerScene && unlockingAllowed -> MODE_DISMISS_BOUNCER
+ isShowingBouncerOverlay && unlockingAllowed -> MODE_DISMISS_BOUNCER
unlockingAllowed -> MODE_UNLOCK_COLLAPSING
- currentScene != Scenes.Bouncer && !alternateBouncerVisible -> MODE_SHOW_BOUNCER
+ Overlays.Bouncer !in currentOverlays && !alternateBouncerVisible ->
+ MODE_SHOW_BOUNCER
else -> MODE_NONE
}
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt
index 4b90e1d52ea0..0d0105404726 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt
@@ -50,6 +50,7 @@ import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.res.R
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.user.data.model.SelectionStatus
import com.android.systemui.user.data.repository.UserRepository
@@ -237,7 +238,7 @@ constructor(
private val isBouncerVisible: Flow<Boolean> by lazy {
if (SceneContainerFlag.isEnabled) {
- sceneInteractor.get().transitionState.map { it.isIdle(Scenes.Bouncer) }
+ sceneInteractor.get().transitionState.map { it.isIdle(Overlays.Bouncer) }
} else {
primaryBouncerInteractor.get().isShowing
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
index 3dd2561614b7..599c945db064 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
@@ -51,7 +51,7 @@ import com.android.systemui.dreams.dagger.DreamOverlayModule;
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.keyguard.shared.model.KeyguardState;
import com.android.systemui.res.R;
-import com.android.systemui.scene.shared.model.Scenes;
+import com.android.systemui.scene.shared.model.Overlays;
import com.android.systemui.shade.ShadeExpansionChangeEvent;
import com.android.systemui.shade.domain.interactor.ShadeInteractor;
import com.android.systemui.statusbar.BlurUtils;
@@ -281,7 +281,7 @@ public class DreamOverlayContainerViewController extends
mView,
FlowKt.distinctUntilChanged(combineFlows(
mKeyguardTransitionInteractor.isFinishedIn(
- Scenes.Bouncer, KeyguardState.PRIMARY_BOUNCER),
+ Overlays.Bouncer, KeyguardState.PRIMARY_BOUNCER),
mKeyguardTransitionInteractor.isFinishedIn(
KeyguardState.ALTERNATE_BOUNCER),
mShadeInteractor.isAnyExpanded(),
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
index 3132ec2b98e3..a2bcb98e36fe 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
@@ -47,7 +47,7 @@ import androidx.lifecycle.ServiceLifecycleDispatcher;
import androidx.lifecycle.ViewModelStore;
import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
-import com.android.compose.animation.scene.SceneKey;
+import com.android.compose.animation.scene.OverlayKey;
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.policy.PhoneWindow;
@@ -72,6 +72,7 @@ import com.android.systemui.navigationbar.gestural.domain.GestureInteractor;
import com.android.systemui.navigationbar.gestural.domain.TaskMatcher;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
+import com.android.systemui.scene.shared.model.Overlays;
import com.android.systemui.scene.shared.model.Scenes;
import com.android.systemui.shade.ShadeExpansionChangeEvent;
import com.android.systemui.touch.TouchInsetManager;
@@ -82,6 +83,7 @@ import kotlinx.coroutines.Job;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.CancellationException;
import java.util.function.Consumer;
@@ -221,10 +223,11 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
}
};
- private final Consumer<SceneKey> mCurrentSceneConsumer = new Consumer<>() {
+ private final Consumer<Set<OverlayKey>> mCurrentOverlaysConsumer = new Consumer<>() {
@Override
- public void accept(SceneKey currentScene) {
- mExecutor.execute(() -> updateBouncerShowingLocked(currentScene == Scenes.Bouncer));
+ public void accept(Set<OverlayKey> currentOverlays) {
+ mExecutor.execute(() ->
+ updateBouncerShowingLocked(currentOverlays.contains(Overlays.Bouncer)));
}
};
@@ -430,8 +433,8 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
mFlows.add(collectFlow(getLifecycle(), communalInteractor.isCommunalVisible(),
mCommunalVisibleConsumer));
if (SceneContainerFlag.isEnabled()) {
- mFlows.add(collectFlow(getLifecycle(), sceneInteractor.getCurrentScene(),
- mCurrentSceneConsumer));
+ mFlows.add(collectFlow(getLifecycle(), sceneInteractor.getCurrentOverlays(),
+ mCurrentOverlaysConsumer));
} else {
mFlows.add(collectFlow(getLifecycle(), keyguardInteractor.primaryBouncerShowing,
mBouncerShowingConsumer));
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt
index 7437d3e215d5..de869961fb9f 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt
@@ -20,6 +20,7 @@ import com.android.compose.animation.scene.Swipe
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.ui.viewmodel.UserActionsViewModel
import com.android.systemui.shade.domain.interactor.ShadeInteractor
@@ -55,9 +56,11 @@ constructor(
shadeModeInteractor.shadeMode,
) { isDeviceUnlocked, shadeMode ->
buildList {
- val bouncerOrGone =
- if (isDeviceUnlocked) Scenes.Gone else Scenes.Bouncer
- add(Swipe.Up to bouncerOrGone)
+ if (isDeviceUnlocked) {
+ add(Swipe.Up to Scenes.Gone)
+ } else {
+ add(Swipe.Up to Overlays.Bouncer)
+ }
addAll(
when (shadeMode) {
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/TouchpadTutorialScreensProvider.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/TouchpadTutorialScreensProvider.kt
index 7d2492a41e82..bea79fdb6aee 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/TouchpadTutorialScreensProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/TouchpadTutorialScreensProvider.kt
@@ -21,8 +21,16 @@ import androidx.compose.runtime.Composable
interface TouchpadTutorialScreensProvider {
@Composable
- fun BackGesture(onDoneButtonClicked: () -> Unit, onBack: () -> Unit, isAutoProceed: Boolean)
+ fun BackGesture(
+ onDoneButtonClicked: () -> Unit,
+ onBack: () -> Unit,
+ onAutoProceed: (suspend () -> Unit)?,
+ )
@Composable
- fun HomeGesture(onDoneButtonClicked: () -> Unit, onBack: () -> Unit, isAutoProceed: Boolean)
+ fun HomeGesture(
+ onDoneButtonClicked: () -> Unit,
+ onBack: () -> Unit,
+ onAutoProceed: (suspend () -> Unit)?,
+ )
}
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 ee875c484ca6..8e4e4c09e9f2 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
@@ -108,6 +108,7 @@ fun ActionTutorialContent(
actionState: TutorialActionState,
onDoneButtonClicked: () -> Unit,
config: TutorialScreenConfig,
+ onAutoProceed: (suspend () -> Unit)? = null,
) {
Column(
verticalArrangement = Arrangement.Center,
@@ -137,9 +138,12 @@ fun ActionTutorialContent(
onDoneButtonClicked = onDoneButtonClicked,
modifier = Modifier.padding(horizontal = 60.dp).graphicsLayer { alpha = buttonAlpha },
enabled = actionState is Finished,
- isNext = config.hasNextButton,
+ isNext = onAutoProceed != null,
)
}
+ if (actionState is Finished) {
+ LaunchedEffect(Unit) { onAutoProceed?.invoke() }
+ }
}
@Composable
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 65adc148b6ae..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
@@ -28,7 +28,6 @@ data class TutorialScreenConfig(
val colors: Colors,
val strings: Strings,
val animations: Animations,
- val hasNextButton: Boolean = false,
) {
data class Colors(
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt
index 086705fbd7ba..8cc1865a6b7e 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt
@@ -147,7 +147,7 @@ fun KeyboardTouchpadTutorialContainer(
.BackGesture(
onDoneButtonClicked = vm::onDoneButtonClicked,
onBack = vm::onBack,
- isAutoProceed = isAutoProceed,
+ onAutoProceed = if (isAutoProceed) vm::onAutoProceed else null,
)
HOME_GESTURE ->
touchpadScreens
@@ -155,7 +155,7 @@ fun KeyboardTouchpadTutorialContainer(
.HomeGesture(
onDoneButtonClicked = vm::onDoneButtonClicked,
onBack = vm::onBack,
- isAutoProceed = isScopeAll,
+ onAutoProceed = if (isScopeAll) vm::onAutoProceed else null,
)
ACTION_KEY ->
ActionKeyTutorialScreen(
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModel.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModel.kt
index eeb4b697a5fc..90e3af4db6fa 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModel.kt
@@ -42,6 +42,8 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import java.util.Optional
+import kotlin.time.Duration.Companion.seconds
+import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
@@ -49,6 +51,7 @@ import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterNot
import kotlinx.coroutines.flow.runningFold
+@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
class KeyboardTouchpadTutorialViewModel(
private val gesturesInteractor: Optional<TouchpadGesturesInteractor>,
private val keyboardTouchpadConnectionInteractor: KeyboardTouchpadConnectionInteractor,
@@ -149,7 +152,16 @@ class KeyboardTouchpadTutorialViewModel(
clearDeviceStateForScreen(_screen.value)
}
+ suspend fun onAutoProceed() {
+ delay(AUTO_PROCEED_DELAY)
+ progressToNextScreen()
+ }
+
fun onDoneButtonClicked() {
+ progressToNextScreen()
+ }
+
+ private fun progressToNextScreen() {
var nextScreen = screenSequence.nextScreen(_screen.value)
while (nextScreen != null) {
if (requiredHardwarePresent(nextScreen)) {
@@ -250,6 +262,10 @@ class KeyboardTouchpadTutorialViewModel(
private object SingleScreenOnly : ScreenSequence {
override fun nextScreen(current: Screen): Screen? = null
}
+
+ companion object {
+ private val AUTO_PROCEED_DELAY = 3.seconds
+ }
}
enum class RequiredHardware {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt
index b3027edb5f0a..b8ee20bc973b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt
@@ -19,6 +19,7 @@ package com.android.systemui.keyguard
import android.annotation.WorkerThread
import android.content.ComponentCallbacks2
import android.util.Log
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
@@ -31,7 +32,6 @@ import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.filter
-import com.android.app.tracing.coroutines.launchTraced as launch
/**
* Releases cached resources on allocated by keyguard.
@@ -54,7 +54,7 @@ constructor(
Log.d(LOG_TAG, "Resource trimmer registered.")
applicationScope.launch(context = bgDispatcher) {
keyguardTransitionInteractor
- .isFinishedIn(scene = Scenes.Gone, stateWithoutSceneContainer = GONE)
+ .isFinishedIn(content = Scenes.Gone, stateWithoutSceneContainer = GONE)
.filter { isOnGone -> isOnGone }
.collect { onKeyguardGone() }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt
index 6367b5c2df8e..65ea6735c64b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt
@@ -22,12 +22,11 @@ import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository
import com.android.systemui.res.R
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
-import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.shade.ShadeDisplayAware
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
@@ -59,9 +58,9 @@ constructor(
private val isSideFpsIndicatorOnPrimaryBouncerEnabled: Boolean
get() = context.resources.getBoolean(R.bool.config_show_sidefps_hint_on_bouncer)
- private val isBouncerSceneActive: Flow<Boolean> =
+ private val isBouncerOverlayActive: Flow<Boolean> =
if (SceneContainerFlag.isEnabled) {
- sceneInteractor.currentScene.map { it == Scenes.Bouncer }.distinctUntilChanged()
+ sceneInteractor.currentOverlays.map { Overlays.Bouncer in it }.distinctUntilChanged()
} else {
flowOf(false)
}
@@ -73,7 +72,7 @@ constructor(
primaryBouncerInteractor.startingToHide,
primaryBouncerInteractor.startingDisappearAnimation.filterNotNull(),
// Bouncer scene visibility changes.
- isBouncerSceneActive,
+ isBouncerOverlayActive,
deviceEntryFingerprintAuthRepository.shouldUpdateIndicatorVisibility.filter { it },
)
.map {
@@ -105,7 +104,7 @@ constructor(
private fun isBouncerActive(): Boolean {
if (SceneContainerFlag.isEnabled) {
- return sceneInteractor.currentScene.value == Scenes.Bouncer
+ return Overlays.Bouncer in sceneInteractor.currentOverlays.value
}
return primaryBouncerInteractor.isBouncerShowing() &&
!primaryBouncerInteractor.isAnimatingAway()
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBypassInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBypassInteractor.kt
index d793064f918e..762403d8cf31 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBypassInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBypassInteractor.kt
@@ -21,6 +21,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dump.DumpManager
import com.android.systemui.keyguard.data.repository.KeyguardBypassRepository
import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.util.kotlin.FlowDumperImpl
@@ -61,7 +62,9 @@ constructor(
.flatMapLatest { isBypassAvailable ->
if (isBypassAvailable) {
combine(
- sceneInteractor.currentScene.map { scene -> scene == Scenes.Bouncer },
+ sceneInteractor.currentOverlays.map { overlays ->
+ Overlays.Bouncer in overlays
+ },
alternateBouncerInteractor.isVisible,
sceneInteractor.currentScene.map { scene -> scene == Scenes.Lockscreen },
keyguardQuickAffordanceInteractor.launchingAffordance,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt
index d8c707f9baeb..4c238f4e9f8a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt
@@ -101,7 +101,7 @@ constructor(
.map {}
} else {
transitionInteractor
- .isFinishedIn(scene = Scenes.Gone, stateWithoutSceneContainer = GONE)
+ .isFinishedIn(content = Scenes.Gone, stateWithoutSceneContainer = GONE)
.filter { it }
.map {}
}
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 f84d29f57cc7..7977000ed5c8 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
@@ -248,7 +248,7 @@ constructor(
val topClippingBounds: Flow<Int?> by lazy {
combineTransform(
keyguardTransitionInteractor
- .transitionValue(scene = Scenes.Gone, stateWithoutSceneContainer = GONE)
+ .transitionValue(content = Scenes.Gone, stateWithoutSceneContainer = GONE)
.map { it == 1f }
.onStart { emit(false) }
.distinctUntilChanged(),
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractor.kt
index 278a98f8b157..f2d7d914c817 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractor.kt
@@ -97,7 +97,7 @@ constructor(
powerInteractor.detailedWakefulness
.sample(
transitionInteractor.isFinishedIn(
- scene = Scenes.Gone,
+ content = Scenes.Gone,
stateWithoutSceneContainer = KeyguardState.GONE,
),
::Pair,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt
index b9784f14fa1c..8e0cb84c1781 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt
@@ -63,7 +63,7 @@ constructor(
edgeWithoutSceneContainer = Edge.create(to = KeyguardState.GONE),
),
transitionInteractor.isFinishedIn(
- scene = Scenes.Gone,
+ content = Scenes.Gone,
stateWithoutSceneContainer = KeyguardState.GONE,
),
notificationLaunchInteractor.isLaunchAnimationRunning,
@@ -74,18 +74,14 @@ constructor(
// If the notification launch animation is running, leave the alpha at 0f.
// The ActivityLaunchAnimator will morph it from the notification at the
// appropriate time.
- return@combine KeyguardSurfaceBehindModel(
- alpha = 0f,
- )
+ return@combine KeyguardSurfaceBehindModel(alpha = 0f)
} else if (
inWindowLauncherUnlockAnimationInteractor.get().isLauncherUnderneath()
) {
// The Launcher icons have their own translation/alpha animations during the
// in-window animation. We'll just make the surface visible and let Launcher
// do its thing.
- return@combine KeyguardSurfaceBehindModel(
- alpha = 1f,
- )
+ return@combine KeyguardSurfaceBehindModel(alpha = 1f)
} else {
// Otherwise, animate a surface in via alpha/translation, and apply the
// swipe velocity (if available) to the translation spring.
@@ -113,10 +109,10 @@ constructor(
notificationLaunchInteractor.isLaunchAnimationRunning
.sample(
transitionInteractor.isFinishedIn(
- scene = Scenes.Gone,
+ content = Scenes.Gone,
stateWithoutSceneContainer = KeyguardState.GONE,
),
- ::Pair
+ ::Pair,
)
.map { (animationRunning, isOnGone) -> animationRunning && !isOnGone }
.onStart { emit(false) }
@@ -126,10 +122,9 @@ constructor(
* means we're going to animate the surface, even if animators aren't yet running).
*/
val isAnimatingSurface =
- combine(
- repository.isAnimatingSurface,
- isNotificationLaunchAnimationRunningOnKeyguard,
- ) { animatingSurface, animatingLaunch ->
+ combine(repository.isAnimatingSurface, isNotificationLaunchAnimationRunningOnKeyguard) {
+ animatingSurface,
+ animatingLaunch ->
animatingSurface || animatingLaunch
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
index 3b4a1488095a..af58d10f3066 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
@@ -23,6 +23,7 @@ import com.android.app.tracing.coroutines.flow.filterTraced
import com.android.app.tracing.coroutines.flow.traceAs
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.app.tracing.coroutines.traceCoroutine
+import com.android.compose.animation.scene.ContentKey
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.compose.animation.scene.SceneKey
import com.android.systemui.Flags.keyguardTransitionForceFinishOnScreenOff
@@ -236,28 +237,28 @@ constructor(
if (!SceneContainerFlag.isEnabled) {
return flow
}
- if (edge.isSceneWildcardEdge()) {
+ if (edge.isContentWildcardEdge()) {
return simulateTransitionStepsForSceneTransitions(edge)
}
return flow.filterTraced("stl-filter") { step ->
- val fromScene =
+ val fromContent =
when (edge) {
- is Edge.StateToState -> edge.from?.mapToSceneContainerScene()
- is Edge.StateToScene -> edge.from?.mapToSceneContainerScene()
- is Edge.SceneToState -> edge.from
+ is Edge.StateToState -> edge.from?.mapToSceneContainerContent()
+ is Edge.StateToContent -> edge.from?.mapToSceneContainerContent()
+ is Edge.ContentToState -> edge.from
}
- val toScene =
+ val toContent =
when (edge) {
- is Edge.StateToState -> edge.to?.mapToSceneContainerScene()
- is Edge.StateToScene -> edge.to
- is Edge.SceneToState -> edge.to?.mapToSceneContainerScene()
+ is Edge.StateToState -> edge.to?.mapToSceneContainerContent()
+ is Edge.StateToContent -> edge.to
+ is Edge.ContentToState -> edge.to?.mapToSceneContainerContent()
}
val isTransitioningBetweenLockscreenStates =
- fromScene.isLockscreenOrNull() && toScene.isLockscreenOrNull()
+ fromContent.isLockscreenOrNull() && toContent.isLockscreenOrNull()
val isTransitioningBetweenDesiredScenes =
- sceneInteractor.transitionState.value.isTransitioning(fromScene, toScene)
+ sceneInteractor.transitionState.value.isTransitioning(fromContent, toContent)
// When in STL A -> B settles in A we can't do the same in KTF as KTF requires us to
// start B -> A to get back to A. [LockscreenSceneTransitionInteractor] will emit these
@@ -266,8 +267,8 @@ constructor(
// this condition to not filter out the STARTED and FINISHED step of the "artificially"
// reversed B -> A transition.
val belongsToInstantReversedTransition =
- sceneInteractor.transitionState.value.isIdle(toScene) &&
- sceneTransitionPair.value.previousValue.isTransitioning(toScene, fromScene)
+ sceneInteractor.topmostContent.value == toContent &&
+ sceneTransitionPair.value.previousValue.isTransitioning(toContent, fromContent)
// We can't compare the terminal step with the current sceneTransition because
// a) STL has no guarantee that it will settle in Idle() when finished/canceled
@@ -276,7 +277,7 @@ constructor(
val terminalStepBelongsToPreviousTransition =
(step.transitionState == TransitionState.FINISHED ||
step.transitionState == TransitionState.CANCELED) &&
- sceneTransitionPair.value.previousValue.isTransitioning(fromScene, toScene)
+ sceneTransitionPair.value.previousValue.isTransitioning(fromContent, toContent)
return@filterTraced isTransitioningBetweenLockscreenStates ||
isTransitioningBetweenDesiredScenes ||
@@ -285,7 +286,7 @@ constructor(
}
}
- private fun SceneKey?.isLockscreenOrNull() = this == Scenes.Lockscreen || this == null
+ private fun ContentKey?.isLockscreenOrNull() = this == Scenes.Lockscreen || this == null
/**
* This function will return a flow that simulates TransitionSteps based on STL movements
@@ -317,8 +318,8 @@ constructor(
when (edge) {
is Edge.StateToState ->
throw IllegalStateException("Should not be reachable.")
- is Edge.SceneToState -> it.isTransitioning(from = edge.from)
- is Edge.StateToScene -> it.isTransitioning(to = edge.to)
+ is Edge.ContentToState -> it.isTransitioning(from = edge.from)
+ is Edge.StateToContent -> it.isTransitioning(to = edge.to)
}
if (!isMatchingTransition) {
return@flatMapLatestWithFinished flowOf()
@@ -361,41 +362,43 @@ constructor(
*/
private fun <T> Flow<T>.flatMapLatestWithFinished(
transform: suspend (T) -> Flow<TransitionStep>
- ): Flow<TransitionStep> = channelFlow {
- var job: Job? = null
- var startedEmitted = false
-
- coroutineScope {
- collect { value ->
- traceCoroutine("cancelAndJoin") { job?.cancelAndJoin() }
-
- job = launch("inner") {
- val innerFlow = transform(value)
- try {
- innerFlow.collect { step ->
- if (step.transitionState == TransitionState.STARTED) {
- startedEmitted = true
+ ): Flow<TransitionStep> =
+ channelFlow {
+ var job: Job? = null
+ var startedEmitted = false
+
+ coroutineScope {
+ collect { value ->
+ traceCoroutine("cancelAndJoin") { job?.cancelAndJoin() }
+
+ job =
+ launch("inner") {
+ val innerFlow = transform(value)
+ try {
+ innerFlow.collect { step ->
+ if (step.transitionState == TransitionState.STARTED) {
+ startedEmitted = true
+ }
+ traceCoroutine("send($step)") { send(step) }
+ }
+ } finally {
+ if (startedEmitted) {
+ val step =
+ TransitionStep(
+ from = UNDEFINED,
+ to = UNDEFINED,
+ value = 1f,
+ transitionState = TransitionState.FINISHED,
+ )
+ traceCoroutine("send($step)") { send(step) }
+ startedEmitted = false
+ }
+ }
}
- traceCoroutine("send($step)") { send(step) }
- }
- } finally {
- if (startedEmitted) {
- val step =
- TransitionStep(
- from = UNDEFINED,
- to = UNDEFINED,
- value = 1f,
- transitionState = TransitionState.FINISHED,
- )
- traceCoroutine("send($step)") { send(step) }
- startedEmitted = false
- }
}
}
}
- }
- }
- .traceAs("flatMapLatestWithFinished")
+ .traceAs("flatMapLatestWithFinished")
/**
* Converts old KTF states to UNDEFINED when [SceneContainerFlag] is enabled.
@@ -414,17 +417,17 @@ constructor(
from = edge.from?.mapToSceneContainerState(),
to = edge.to?.mapToSceneContainerState(),
)
- is Edge.SceneToState -> Edge.create(UNDEFINED, edge.to)
- is Edge.StateToScene -> Edge.create(edge.from, UNDEFINED)
+ is Edge.ContentToState -> Edge.create(UNDEFINED, edge.to)
+ is Edge.StateToContent -> Edge.create(edge.from, UNDEFINED)
}
}
fun transitionValue(
- scene: SceneKey? = null,
+ content: ContentKey? = null,
stateWithoutSceneContainer: KeyguardState,
): Flow<Float> {
- return if (SceneContainerFlag.isEnabled && scene != null) {
- sceneInteractor.transitionProgress(scene)
+ return if (SceneContainerFlag.isEnabled && content != null) {
+ sceneInteractor.transitionProgress(content)
} else {
transitionValue(stateWithoutSceneContainer)
}
@@ -439,7 +442,7 @@ constructor(
fun transitionValue(state: KeyguardState): Flow<Float> {
if (SceneContainerFlag.isEnabled && state != state.mapToSceneContainerState()) {
Log.e(TAG, "SceneContainer is enabled but a deprecated state $state is used.")
- return transitionValue(state.mapToSceneContainerScene()!!, state)
+ return transitionValue(state.mapToSceneContainerContent()!!, state)
}
return getTransitionValueFlow(state)
}
@@ -533,13 +536,13 @@ constructor(
*/
fun isInTransition(edge: Edge, edgeWithoutSceneContainer: Edge? = null): Flow<Boolean> {
return if (SceneContainerFlag.isEnabled) {
- if (edge.isSceneWildcardEdge()) {
+ if (edge.isContentWildcardEdge()) {
sceneInteractor.transitionState.map {
when (edge) {
is Edge.StateToState ->
throw IllegalStateException("Should not be reachable.")
- is Edge.SceneToState -> it.isTransitioning(from = edge.from)
- is Edge.StateToScene -> it.isTransitioning(to = edge.to)
+ is Edge.ContentToState -> it.isTransitioning(from = edge.from)
+ is Edge.StateToContent -> it.isTransitioning(to = edge.to)
}
}
} else {
@@ -581,10 +584,15 @@ constructor(
return finishedKeyguardState.map { stateMatcher(it) }.distinctUntilChanged()
}
- fun isFinishedIn(scene: SceneKey, stateWithoutSceneContainer: KeyguardState): Flow<Boolean> {
+ fun isFinishedIn(
+ content: ContentKey,
+ stateWithoutSceneContainer: KeyguardState,
+ ): Flow<Boolean> {
return if (SceneContainerFlag.isEnabled) {
- sceneInteractor.transitionState.map {
- it.isIdle(scene) || it.isTransitioning(from = scene)
+ combine(sceneInteractor.topmostContent, sceneInteractor.transitionState) {
+ topmostContent,
+ state ->
+ topmostContent == content || state.isTransitioning(from = content)
}
} else {
isFinishedIn(stateWithoutSceneContainer)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
index 61cf2cdab92d..68d595ebf0b6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
@@ -61,7 +61,7 @@ constructor(
private val defaultSurfaceBehindVisibility =
combine(
transitionInteractor.isFinishedIn(
- scene = Scenes.Gone,
+ content = Scenes.Gone,
stateWithoutSceneContainer = KeyguardState.GONE,
),
wakeToGoneInteractor.canWakeDirectlyToGone,
@@ -121,7 +121,7 @@ constructor(
when {
state.isTransitioning(from = Scenes.Lockscreen, to = Scenes.Gone) ->
isDeviceEnteredDirectly
- state.isTransitioning(from = Scenes.Bouncer, to = Scenes.Gone) ->
+ state.isTransitioning(from = Overlays.Bouncer, to = Scenes.Gone) ->
(state as Transition).progress.map { progress ->
progress >
FromPrimaryBouncerTransitionInteractor
@@ -179,7 +179,7 @@ constructor(
edgeWithoutSceneContainer = Edge.create(to = KeyguardState.GONE),
),
transitionInteractor.isFinishedIn(
- scene = Scenes.Gone,
+ content = Scenes.Gone,
stateWithoutSceneContainer = KeyguardState.GONE,
),
surfaceBehindInteractor.isAnimatingSurface,
@@ -202,21 +202,23 @@ constructor(
when (it) {
is Idle -> {
when (it.currentScene) {
- in keyguardScenes -> flowOf(true)
- in nonKeyguardScenes -> flowOf(false)
- in keyguardAgnosticScenes -> isDeviceNotEnteredDirectly
+ in keyguardContent -> flowOf(true)
+ in nonKeyguardContent -> flowOf(false)
+ in keyguardAgnosticContent -> isDeviceNotEnteredDirectly
else ->
throw IllegalStateException("Unknown scene: ${it.currentScene}")
}
}
is Transition -> {
when {
- it.isTransitioningSets(from = keyguardScenes) -> flowOf(true)
- it.isTransitioningSets(from = nonKeyguardScenes) -> flowOf(false)
- it.isTransitioningSets(from = keyguardAgnosticScenes) ->
+ it.isTransitioningSets(from = keyguardContent) -> flowOf(true)
+ it.isTransitioningSets(from = nonKeyguardContent) -> flowOf(false)
+ it.isTransitioningSets(from = keyguardAgnosticContent) ->
isDeviceNotEnteredDirectly
else ->
- throw IllegalStateException("Unknown scene: ${it.fromContent}")
+ throw IllegalStateException(
+ "Unknown content: ${it.fromContent}"
+ )
}
}
}
@@ -330,22 +332,23 @@ constructor(
companion object {
/**
- * Scenes that are part of the keyguard and are shown when the device is locked or when the
+ * Content that is part of the keyguard and are shown when the device is locked or when the
* keyguard still needs to be dismissed.
*/
- val keyguardScenes = setOf(Scenes.Lockscreen, Scenes.Bouncer, Scenes.Communal, Scenes.Dream)
+ val keyguardContent =
+ setOf(Scenes.Lockscreen, Overlays.Bouncer, Scenes.Communal, Scenes.Dream)
/**
- * Scenes that don't belong in the keyguard family and cannot show when the device is locked
- * or when the keyguard still needs to be dismissed.
+ * Content that doesn't belong in the keyguard family and cannot show when the device is
+ * locked or when the keyguard still needs to be dismissed.
*/
- private val nonKeyguardScenes = setOf(Scenes.Gone)
+ private val nonKeyguardContent = setOf(Scenes.Gone)
/**
- * Scenes that can show regardless of device lock or keyguard dismissal states. Other
+ * Content that can show regardless of device lock or keyguard dismissal states. Other
* sources of state need to be consulted to know whether the device has been entered or not.
*/
- private val keyguardAgnosticScenes =
+ private val keyguardAgnosticContent =
setOf(
Scenes.Shade,
Scenes.QuickSettings,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/Edge.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/Edge.kt
index 1306b2690c05..4cc4d271357c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/Edge.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/Edge.kt
@@ -16,7 +16,7 @@
package com.android.systemui.keyguard.shared.model
import android.util.Log
-import com.android.compose.animation.scene.SceneKey
+import com.android.compose.animation.scene.ContentKey
import com.android.systemui.keyguard.shared.model.KeyguardState.UNDEFINED
import com.android.systemui.scene.shared.flag.SceneContainerFlag
@@ -29,8 +29,8 @@ sealed class Edge {
fun verifyValidKeyguardStates() {
when (this) {
is StateToState -> verifyValidKeyguardStates(from, to)
- is SceneToState -> verifyValidKeyguardStates(null, to)
- is StateToScene -> verifyValidKeyguardStates(from, null)
+ is ContentToState -> verifyValidKeyguardStates(null, to)
+ is StateToContent -> verifyValidKeyguardStates(from, null)
}
}
@@ -66,19 +66,16 @@ sealed class Edge {
}
} else {
if (from == UNDEFINED || to == UNDEFINED) {
- Log.e(
- TAG,
- "UNDEFINED should not be used when scene container is disabled",
- )
+ Log.e(TAG, "UNDEFINED should not be used when scene container is disabled")
}
}
}
- fun isSceneWildcardEdge(): Boolean {
+ fun isContentWildcardEdge(): Boolean {
return when (this) {
is StateToState -> false
- is SceneToState -> to == null
- is StateToScene -> from == null
+ is ContentToState -> to == null
+ is StateToContent -> from == null
}
}
@@ -89,9 +86,9 @@ sealed class Edge {
}
}
- data class StateToScene(val from: KeyguardState? = null, val to: SceneKey) : Edge()
+ data class StateToContent(val from: KeyguardState? = null, val to: ContentKey) : Edge()
- data class SceneToState(val from: SceneKey, val to: KeyguardState? = null) : Edge()
+ data class ContentToState(val from: ContentKey, val to: KeyguardState? = null) : Edge()
companion object {
private const val TAG = "Edge"
@@ -102,11 +99,11 @@ sealed class Edge {
@JvmStatic
@JvmOverloads
- fun create(from: KeyguardState? = null, to: SceneKey) = StateToScene(from, to)
+ fun create(from: KeyguardState? = null, to: ContentKey) = StateToContent(from, to)
@JvmStatic
@JvmOverloads
- fun create(from: SceneKey, to: KeyguardState? = null) = SceneToState(from, to)
+ fun create(from: ContentKey, to: KeyguardState? = null) = ContentToState(from, to)
/**
* This edge is a placeholder for when an edge needs to be passed but there is no edge for
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt
index f0e79b8590a0..21bfb5f79abb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt
@@ -16,8 +16,9 @@
package com.android.systemui.keyguard.shared.model
import android.util.Log
-import com.android.compose.animation.scene.SceneKey
+import com.android.compose.animation.scene.ContentKey
import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
/** List of all possible states to transition to/from */
@@ -130,7 +131,7 @@ enum class KeyguardState {
}
}
- fun mapToSceneContainerScene(): SceneKey? {
+ fun mapToSceneContainerContent(): ContentKey? {
return when (this) {
OFF,
DOZING,
@@ -140,7 +141,7 @@ enum class KeyguardState {
OCCLUDED,
LOCKSCREEN -> Scenes.Lockscreen
GLANCEABLE_HUB -> Scenes.Communal
- PRIMARY_BOUNCER -> Scenes.Bouncer
+ PRIMARY_BOUNCER -> Overlays.Bouncer
GONE -> Scenes.Gone
UNDEFINED -> null
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt
index 43cce4b1c40c..74d471c7c1d6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt
@@ -27,7 +27,7 @@ import com.android.systemui.keyguard.ui.transitions.BlurConfig
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
import com.android.systemui.scene.shared.flag.SceneContainerFlag
-import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.ui.composable.transitions.TO_BOUNCER_FADE_FRACTION
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
@@ -49,7 +49,7 @@ constructor(
animationFlow
.setup(
duration = FromAlternateBouncerTransitionInteractor.TO_PRIMARY_BOUNCER_DURATION,
- edge = Edge.create(from = ALTERNATE_BOUNCER, to = Scenes.Bouncer),
+ edge = Edge.create(from = ALTERNATE_BOUNCER, to = Overlays.Bouncer),
)
.setupWithoutSceneContainer(
edge = Edge.create(from = ALTERNATE_BOUNCER, to = PRIMARY_BOUNCER)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerTransitionViewModel.kt
index 8b5e3b9756e3..a22d21ae1371 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerTransitionViewModel.kt
@@ -26,7 +26,7 @@ import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.BlurConfig
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
-import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.shared.model.Overlays
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
@@ -44,7 +44,7 @@ constructor(blurConfig: BlurConfig, animationFlow: KeyguardTransitionAnimationFl
animationFlow
.setup(
duration = FromAodTransitionInteractor.TO_PRIMARY_BOUNCER_DURATION,
- edge = Edge.create(from = AOD, to = Scenes.Bouncer),
+ edge = Edge.create(from = AOD, to = Overlays.Bouncer),
)
.setupWithoutSceneContainer(edge = Edge.create(from = AOD, to = PRIMARY_BOUNCER))
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModel.kt
index ff96e035bc81..2c712d106a6e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModel.kt
@@ -26,7 +26,7 @@ import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.BlurConfig
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
-import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.shared.model.Overlays
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
@@ -45,7 +45,7 @@ constructor(private val blurConfig: BlurConfig, animationFlow: KeyguardTransitio
animationFlow
.setup(
duration = TO_PRIMARY_BOUNCER_DURATION,
- edge = Edge.create(from = DOZING, to = Scenes.Bouncer),
+ edge = Edge.create(from = DOZING, to = Overlays.Bouncer),
)
.setupWithoutSceneContainer(edge = Edge.create(from = DOZING, to = PRIMARY_BOUNCER))
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
index def87a8e2717..d4676bc9c146 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
@@ -40,6 +40,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING
import com.android.systemui.keyguard.shared.model.TransitionState.STARTED
import com.android.systemui.keyguard.ui.StateToValue
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shade.ui.viewmodel.NotificationShadeWindowModel
@@ -182,7 +183,7 @@ constructor(
edgeWithoutSceneContainer = Edge.create(from = LOCKSCREEN, to = GONE),
),
keyguardTransitionInteractor.isInTransition(
- edge = Edge.create(from = Scenes.Bouncer, to = LOCKSCREEN),
+ edge = Edge.create(from = Overlays.Bouncer, to = LOCKSCREEN),
edgeWithoutSceneContainer =
Edge.create(from = PRIMARY_BOUNCER, to = LOCKSCREEN),
),
@@ -226,7 +227,7 @@ constructor(
.map { it > 1f - offToLockscreenTransitionViewModel.alphaStartAt }
.onStart { emit(false) },
keyguardTransitionInteractor
- .transitionValue(scene = Scenes.Gone, stateWithoutSceneContainer = GONE)
+ .transitionValue(content = Scenes.Gone, stateWithoutSceneContainer = GONE)
.map { it == 1f }
.onStart { emit(false) },
)
@@ -361,7 +362,7 @@ constructor(
.map { it > 0f }
.onStart { emit(false) },
keyguardTransitionInteractor.isFinishedIn(
- scene = Scenes.Gone,
+ content = Scenes.Gone,
stateWithoutSceneContainer = GONE,
),
deviceEntryInteractor.isBypassEnabled,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt
index b96c879157dc..3758afa61ed4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt
@@ -27,7 +27,7 @@ import com.android.systemui.keyguard.ui.transitions.BlurConfig
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
import com.android.systemui.scene.shared.flag.SceneContainerFlag
-import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.ui.composable.transitions.TO_BOUNCER_FADE_FRACTION
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
@@ -50,7 +50,7 @@ constructor(
animationFlow
.setup(
duration = FromLockscreenTransitionInteractor.TO_PRIMARY_BOUNCER_DURATION,
- edge = Edge.create(from = LOCKSCREEN, to = Scenes.Bouncer),
+ edge = Edge.create(from = LOCKSCREEN, to = Overlays.Bouncer),
)
.setupWithoutSceneContainer(edge = Edge.create(from = LOCKSCREEN, to = PRIMARY_BOUNCER))
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModel.kt
index 06c27d31cc3b..0eeb6c66c3bc 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModel.kt
@@ -21,6 +21,7 @@ import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.ui.viewmodel.UserActionsViewModel
import com.android.systemui.shade.domain.interactor.ShadeInteractor
@@ -60,7 +61,11 @@ constructor(
occlusionInteractor.isOccludingActivityShown,
) { isDeviceUnlocked, shadeMode, isOccluded ->
buildList {
- add(Swipe.Up to if (isDeviceUnlocked) Scenes.Gone else Scenes.Bouncer)
+ if (isDeviceUnlocked) {
+ add(Swipe.Up to Scenes.Gone)
+ } else {
+ add(Swipe.Up to Overlays.Bouncer)
+ }
addAll(
when (shadeMode) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModel.kt
index dc75829f95ee..32bad8ed0146 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModel.kt
@@ -26,7 +26,7 @@ import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.BlurConfig
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
-import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.shared.model.Overlays
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.flow.Flow
@@ -49,7 +49,7 @@ constructor(
animationFlow
.setup(
duration = FromPrimaryBouncerTransitionInteractor.TO_AOD_DURATION,
- edge = Edge.create(from = Scenes.Bouncer, to = AOD),
+ edge = Edge.create(from = Overlays.Bouncer, to = AOD),
)
.setupWithoutSceneContainer(edge = Edge.create(from = PRIMARY_BOUNCER, to = AOD))
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModel.kt
index 7f431bc3e0f9..1b533440454c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModel.kt
@@ -26,7 +26,7 @@ import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.BlurConfig
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
-import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.shared.model.Overlays
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
@@ -49,7 +49,7 @@ constructor(
animationFlow
.setup(
duration = TO_DOZING_DURATION,
- edge = Edge.create(from = Scenes.Bouncer, to = DOZING),
+ edge = Edge.create(from = Overlays.Bouncer, to = DOZING),
)
.setupWithoutSceneContainer(edge = Edge.create(from = PRIMARY_BOUNCER, to = DOZING))
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
index 9cb03874e412..5a111aa519fc 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
@@ -28,7 +28,7 @@ import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.BlurConfig
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
-import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.shared.model.Overlays
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.flow.Flow
@@ -50,7 +50,7 @@ constructor(
animationFlow
.setup(
duration = FromPrimaryBouncerTransitionInteractor.TO_LOCKSCREEN_DURATION,
- edge = Edge.create(from = Scenes.Bouncer, to = LOCKSCREEN),
+ edge = Edge.create(from = Overlays.Bouncer, to = LOCKSCREEN),
)
.setupWithoutSceneContainer(edge = Edge.create(from = PRIMARY_BOUNCER, to = LOCKSCREEN))
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
index 55d8b8c4def0..bfd48c825424 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
@@ -683,7 +683,7 @@ constructor(
internal fun listenForAnyStateToGoneKeyguardTransition(scope: CoroutineScope): Job {
return scope.launch {
keyguardTransitionInteractor
- .isFinishedIn(scene = Scenes.Gone, stateWithoutSceneContainer = GONE)
+ .isFinishedIn(content = Scenes.Gone, stateWithoutSceneContainer = GONE)
.filter { it }
.collect {
showMediaCarousel()
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt
index b64cb3dd456a..f06c4cce0daa 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt
@@ -58,6 +58,7 @@ import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.CrossFadeHelper
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.SysuiStatusBarStateController
+import com.android.systemui.statusbar.featurepods.popups.StatusBarPopupChips
import com.android.systemui.statusbar.notification.stack.StackStateAnimator
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.ConfigurationController
@@ -229,7 +230,7 @@ constructor(
else result.setIntersect(animationStartClipping, targetClipping)
}
- private val mediaHosts = arrayOfNulls<MediaHost>(LOCATION_COMMUNAL_HUB + 1)
+ private val mediaHosts = arrayOfNulls<MediaHost>(LOCATION_STATUS_BAR_POPUP + 1)
/**
* The last location where this view was at before going to the desired location. This is useful
@@ -374,6 +375,15 @@ constructor(
}
}
+ /** Is the Media Control StatusBarPopup showing */
+ var isMediaControlPopupShowing: Boolean = false
+ set(value) {
+ if (field != value && StatusBarPopupChips.isEnabled) {
+ field = value
+ updateDesiredLocation(forceNoAnimation = true)
+ }
+ }
+
/** Are location changes currently blocked? */
private val blockLocationChanges: Boolean
get() {
@@ -1225,6 +1235,7 @@ constructor(
// Keep the current location until we're allowed to again
return desiredLocation
}
+
val onLockscreen =
(!bypassController.bypassEnabled && (statusbarState == StatusBarState.KEYGUARD))
@@ -1234,6 +1245,8 @@ constructor(
(onCommunalNotDreaming && qsExpansion == 0.0f) || onCommunalDreamingAndShadeExpanding
val location =
when {
+ isMediaControlPopupShowing && StatusBarPopupChips.isEnabled ->
+ LOCATION_STATUS_BAR_POPUP
dreamOverlayActive && dreamMediaComplicationActive -> LOCATION_DREAM_OVERLAY
onCommunal -> LOCATION_COMMUNAL_HUB
(qsExpansion > 0.0f || inSplitShade) && !onLockscreen -> LOCATION_QS
@@ -1377,6 +1390,9 @@ constructor(
/** Attached to a view in the communal UI grid */
const val LOCATION_COMMUNAL_HUB = 4
+ /** Attached to a popup that is shown with a media control chip in the status bar */
+ const val LOCATION_STATUS_BAR_POPUP = 5
+
/** Attached at the root of the hierarchy in an overlay */
const val IN_OVERLAY = -1000
@@ -1422,6 +1438,7 @@ private annotation class TransformationType
MediaHierarchyManager.LOCATION_LOCKSCREEN,
MediaHierarchyManager.LOCATION_DREAM_OVERLAY,
MediaHierarchyManager.LOCATION_COMMUNAL_HUB,
+ MediaHierarchyManager.LOCATION_STATUS_BAR_POPUP,
MediaHierarchyManager.LOCATION_UNKNOWN,
],
)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaUiEventLogger.kt b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaUiEventLogger.kt
index 09f973cca343..f0da226129bf 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaUiEventLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaUiEventLogger.kt
@@ -45,7 +45,7 @@ class MediaUiEventLogger @Inject constructor(private val logger: UiEventLogger)
uid: Int,
packageName: String,
instanceId: InstanceId,
- playbackLocation: Int
+ playbackLocation: Int,
) {
val event =
when (playbackLocation) {
@@ -61,7 +61,7 @@ class MediaUiEventLogger @Inject constructor(private val logger: UiEventLogger)
uid: Int,
packageName: String,
instanceId: InstanceId,
- playbackLocation: Int
+ playbackLocation: Int,
) {
val event =
when (playbackLocation) {
@@ -112,7 +112,7 @@ class MediaUiEventLogger @Inject constructor(private val logger: UiEventLogger)
MediaUiEvent.OPEN_SETTINGS_LONG_PRESS,
uid,
packageName,
- instanceId
+ instanceId,
)
}
@@ -156,6 +156,8 @@ class MediaUiEventLogger @Inject constructor(private val logger: UiEventLogger)
MediaUiEvent.MEDIA_CAROUSEL_LOCATION_DREAM
MediaHierarchyManager.LOCATION_COMMUNAL_HUB ->
MediaUiEvent.MEDIA_CAROUSEL_LOCATION_COMMUNAL
+ MediaHierarchyManager.LOCATION_STATUS_BAR_POPUP ->
+ MediaUiEvent.MEDIA_CAROUSEL_LOCATION_STATUS_BAR_POPUP
else -> throw IllegalArgumentException("Unknown media carousel location $location")
}
logger.log(event)
@@ -166,7 +168,7 @@ class MediaUiEventLogger @Inject constructor(private val logger: UiEventLogger)
MediaUiEvent.MEDIA_RECOMMENDATION_ADDED,
0,
packageName,
- instanceId
+ instanceId,
)
}
@@ -175,7 +177,7 @@ class MediaUiEventLogger @Inject constructor(private val logger: UiEventLogger)
MediaUiEvent.MEDIA_RECOMMENDATION_REMOVED,
0,
packageName,
- instanceId
+ instanceId,
)
}
@@ -184,7 +186,7 @@ class MediaUiEventLogger @Inject constructor(private val logger: UiEventLogger)
MediaUiEvent.MEDIA_RECOMMENDATION_ACTIVATED,
uid,
packageName,
- instanceId
+ instanceId,
)
}
@@ -194,7 +196,7 @@ class MediaUiEventLogger @Inject constructor(private val logger: UiEventLogger)
0,
packageName,
instanceId,
- position
+ position,
)
}
@@ -203,7 +205,7 @@ class MediaUiEventLogger @Inject constructor(private val logger: UiEventLogger)
MediaUiEvent.MEDIA_RECOMMENDATION_CARD_TAP,
0,
packageName,
- instanceId
+ instanceId,
)
}
@@ -212,7 +214,7 @@ class MediaUiEventLogger @Inject constructor(private val logger: UiEventLogger)
MediaUiEvent.MEDIA_OPEN_BROADCAST_DIALOG,
uid,
packageName,
- instanceId
+ instanceId,
)
}
@@ -221,7 +223,7 @@ class MediaUiEventLogger @Inject constructor(private val logger: UiEventLogger)
MediaUiEvent.MEDIA_CAROUSEL_SINGLE_PLAYER,
uid,
packageName,
- instanceId
+ instanceId,
)
}
@@ -230,7 +232,7 @@ class MediaUiEventLogger @Inject constructor(private val logger: UiEventLogger)
MediaUiEvent.MEDIA_CAROUSEL_MULTIPLE_PLAYERS,
uid,
packageName,
- instanceId
+ instanceId,
)
}
}
@@ -280,6 +282,8 @@ enum class MediaUiEvent(val metricId: Int) : UiEventLogger.UiEventEnum {
MEDIA_CAROUSEL_LOCATION_DREAM(1040),
@UiEvent(doc = "The media carousel moved to the communal hub UI")
MEDIA_CAROUSEL_LOCATION_COMMUNAL(1520),
+ @UiEvent(doc = "The media carousel moved to the status bar popup")
+ MEDIA_CAROUSEL_LOCATION_STATUS_BAR_POPUP(2170),
@UiEvent(doc = "A media recommendation card was added to the media carousel")
MEDIA_RECOMMENDATION_ADDED(1041),
@UiEvent(doc = "A media recommendation card was removed from the media carousel")
diff --git a/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java b/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java
index 45a3a8ce60c4..662a9c739ff6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java
@@ -49,6 +49,7 @@ public interface MediaModule {
String KEYGUARD = "media_keyguard";
String DREAM = "dream";
String COMMUNAL_HUB = "communal_Hub";
+ String POPUP = "popup";
/** */
@Provides
@@ -102,7 +103,26 @@ public interface MediaModule {
@Provides
@SysUISingleton
@Named(COMMUNAL_HUB)
- static MediaHost providesCommunalMediaHost(MediaHost.MediaHostStateHolder stateHolder,
+ static MediaHost providesCommunalMediaHost(
+ MediaHost.MediaHostStateHolder stateHolder,
+ MediaHierarchyManager hierarchyManager,
+ MediaDataManager dataManager,
+ MediaHostStatesManager statesManager,
+ MediaCarouselController carouselController,
+ MediaCarouselControllerLogger logger) {
+ return new MediaHost(
+ stateHolder,
+ hierarchyManager,
+ dataManager,
+ statesManager,
+ carouselController,
+ logger);
+ }
+
+ @Provides
+ @SysUISingleton
+ @Named(POPUP)
+ static MediaHost providesPopupMediaHost(MediaHost.MediaHostStateHolder stateHolder,
MediaHierarchyManager hierarchyManager, MediaDataManager dataManager,
MediaHostStatesManager statesManager, MediaCarouselController carouselController,
MediaCarouselControllerLogger logger) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapterLegacy.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapterLegacy.java
index ea4418427698..f8e57ef489aa 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapterLegacy.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapterLegacy.java
@@ -36,6 +36,7 @@ import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.widget.CheckBox;
import android.widget.FrameLayout;
+import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.SeekBar;
@@ -44,7 +45,6 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
-import androidx.core.widget.CompoundButtonCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.android.media.flags.Flags;
@@ -130,6 +130,7 @@ public class MediaOutputAdapterLegacy extends MediaOutputAdapterBase {
final ViewGroup mContainerLayout;
final FrameLayout mItemLayout;
final FrameLayout mIconAreaLayout;
+ final ViewGroup mTextContent;
final TextView mTitleText;
final TextView mSubTitleText;
final TextView mVolumeValueText;
@@ -138,7 +139,7 @@ public class MediaOutputAdapterLegacy extends MediaOutputAdapterBase {
final ImageView mStatusIcon;
final CheckBox mCheckBox;
final ViewGroup mEndTouchArea;
- final ImageView mEndClickIcon;
+ final ImageButton mEndClickIcon;
@VisibleForTesting
MediaOutputSeekbar mSeekBar;
private final float mInactiveRadius;
@@ -152,6 +153,7 @@ public class MediaOutputAdapterLegacy extends MediaOutputAdapterBase {
super(view, context);
mContainerLayout = view.requireViewById(R.id.device_container);
mItemLayout = view.requireViewById(R.id.item_layout);
+ mTextContent = view.requireViewById(R.id.text_content);
mTitleText = view.requireViewById(R.id.title);
mSubTitleText = view.requireViewById(R.id.subtitle);
mTitleIcon = view.requireViewById(R.id.title_icon);
@@ -160,7 +162,7 @@ public class MediaOutputAdapterLegacy extends MediaOutputAdapterBase {
mStatusIcon = view.requireViewById(R.id.media_output_item_status);
mCheckBox = view.requireViewById(R.id.check_box);
mEndTouchArea = view.requireViewById(R.id.end_action_area);
- mEndClickIcon = view.requireViewById(R.id.media_output_item_end_click_icon);
+ mEndClickIcon = view.requireViewById(R.id.end_area_image_button);
mVolumeValueText = view.requireViewById(R.id.volume_value);
mIconAreaLayout = view.requireViewById(R.id.icon_area);
mInactiveRadius = mContext.getResources().getDimension(
@@ -178,9 +180,7 @@ public class MediaOutputAdapterLegacy extends MediaOutputAdapterBase {
mStatusIcon.setVisibility(View.GONE);
mEndTouchArea.setVisibility(View.GONE);
mEndClickIcon.setVisibility(View.GONE);
- mEndTouchArea.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
mContainerLayout.setOnClickListener(null);
- mContainerLayout.setContentDescription(null);
mTitleText.setTextColor(mController.getColorItemContent());
mSubTitleText.setTextColor(mController.getColorItemContent());
mVolumeValueText.setTextColor(mController.getColorItemContent());
@@ -188,7 +188,7 @@ public class MediaOutputAdapterLegacy extends MediaOutputAdapterBase {
updateIconAreaClickListener(null);
mSeekBar.setProgressTintList(
ColorStateList.valueOf(mController.getColorSeekbarProgress()));
- enableFocusPropertyForView(mContainerLayout);
+ updateContainerContentA11yImportance(true /* isImportant */);
renderItem(mediaItem, position);
}
@@ -256,10 +256,10 @@ public class MediaOutputAdapterLegacy extends MediaOutputAdapterBase {
mSeekBar.setVisibility(showSeekBar ? View.VISIBLE : View.GONE);
if (showSeekBar) {
initSeekbar(device, isCurrentSeekbarInvisible);
- disableFocusPropertyForView(mContainerLayout);
+ updateContainerContentA11yImportance(false /* isImportant */);
mSeekBar.setContentDescription(contentDescription);
} else {
- enableFocusPropertyForView(mContainerLayout);
+ updateContainerContentA11yImportance(true /* isImportant */);
}
}
@@ -268,18 +268,22 @@ public class MediaOutputAdapterLegacy extends MediaOutputAdapterBase {
boolean isCurrentSeekbarInvisible = mSeekBar.getVisibility() == View.GONE;
mSeekBar.setVisibility(View.VISIBLE);
initGroupSeekbar(isCurrentSeekbarInvisible);
- disableFocusPropertyForView(mContainerLayout);
+ updateContainerContentA11yImportance(false /* isImportant */);
mSeekBar.setContentDescription(contentDescription);
}
- private void disableFocusPropertyForView(View view) {
- view.setFocusable(false);
- view.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
- }
-
- private void enableFocusPropertyForView(View view) {
- view.setFocusable(true);
- view.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
+ /**
+ * Sets the a11y importance for the device container and it's text content. Making the
+ * container not important for a11y is required when the seekbar is visible.
+ */
+ private void updateContainerContentA11yImportance(boolean isImportant) {
+ mContainerLayout.setFocusable(isImportant);
+ mContainerLayout.setImportantForAccessibility(
+ isImportant ? View.IMPORTANT_FOR_ACCESSIBILITY_YES
+ : View.IMPORTANT_FOR_ACCESSIBILITY_NO);
+ mTextContent.setImportantForAccessibility(
+ isImportant ? View.IMPORTANT_FOR_ACCESSIBILITY_YES
+ : View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
}
void updateSubtitle(@Nullable String subtitle) {
@@ -576,26 +580,22 @@ public class MediaOutputAdapterLegacy extends MediaOutputAdapterBase {
mEndClickIcon.setImageTintList(
ColorStateList.valueOf(mController.getColorItemContent()));
mEndClickIcon.setOnClickListener(clickListener);
- mEndTouchArea.setOnClickListener(v -> mEndClickIcon.performClick());
Drawable drawable = mContext.getDrawable(iconDrawableId);
mEndClickIcon.setImageDrawable(drawable);
if (drawable instanceof AnimatedVectorDrawable) {
((AnimatedVectorDrawable) drawable).start();
}
- if (Flags.enableOutputSwitcherDeviceGrouping()) {
- mEndClickIcon.setContentDescription(mContext.getString(accessibilityStringId));
- }
+ mEndClickIcon.setContentDescription(mContext.getString(accessibilityStringId));
}
private void updateEndAreaForGroupCheckBox(@NonNull MediaDevice device,
@NonNull GroupStatus groupStatus) {
boolean isEnabled = isGroupCheckboxEnabled(groupStatus);
- mEndTouchArea.setOnClickListener(
- isEnabled ? (v) -> mCheckBox.performClick() : null);
- mEndTouchArea.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
updateEndAreaColor(groupStatus.selected() ? mController.getColorSeekbarProgress()
: mController.getColorItemBackground());
- mEndTouchArea.setContentDescription(getDeviceItemContentDescription(device));
+ mCheckBox.setContentDescription(mContext.getString(
+ groupStatus.selected() ? R.string.accessibility_remove_device_from_group
+ : R.string.accessibility_add_device_to_group));
mCheckBox.setOnCheckedChangeListener(null);
mCheckBox.setChecked(groupStatus.selected());
mCheckBox.setOnCheckedChangeListener(
@@ -606,10 +606,7 @@ public class MediaOutputAdapterLegacy extends MediaOutputAdapterBase {
}
private void setCheckBoxColor(CheckBox checkBox, int color) {
- int[][] states = {{android.R.attr.state_checked}, {}};
- int[] colors = {color, color};
- CompoundButtonCompat.setButtonTintList(checkBox, new
- ColorStateList(states, colors));
+ checkBox.setForegroundTintList(ColorStateList.valueOf(color));
}
private boolean shouldShowGroupCheckbox(@NonNull GroupStatus groupStatus) {
diff --git a/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt b/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt
index 0bf4c7e8d9f9..ea515c96d3f0 100644
--- a/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt
+++ b/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt
@@ -103,7 +103,7 @@ constructor(
it.scene == Scenes.QuickSettings ||
Overlays.QuickSettingsShade in it.overlays
},
- SYSUI_STATE_BOUNCER_SHOWING to { it.scene == Scenes.Bouncer },
+ SYSUI_STATE_BOUNCER_SHOWING to { Overlays.Bouncer in it.overlays },
SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING to
{
it.scene == Scenes.Lockscreen && !it.invisibleDueToOcclusion
diff --git a/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModel.kt
index c43c1a999fcb..18b4b7d2b5cf 100644
--- a/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModel.kt
@@ -22,7 +22,6 @@ import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.Hydrator
import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel
import com.android.systemui.statusbar.disableflags.domain.interactor.DisableFlagsInteractor
@@ -96,18 +95,6 @@ constructor(
launch { hydrator.activate() }
launch {
- sceneInteractor.currentScene.collect { currentScene ->
- when (currentScene) {
- // TODO(b/369513770): The ShadeSession should be preserved in this scenario.
- Scenes.Bouncer ->
- shadeInteractor.collapseNotificationsShade(
- loggingReason = "bouncer shown while shade is open"
- )
- }
- }
- }
-
- launch {
shadeInteractor.isShadeTouchable
.distinctUntilChanged()
.filter { !it }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
index 5930a24e01a0..6ad8bae05d7a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
@@ -306,7 +306,6 @@ constructor(
sceneState,
viewModel.containerViewModel.editModeViewModel.isEditing,
snapshotFlow { viewModel.expansionState }.map { it.progress },
- snapshotFlow { viewModel.isQSExpandingOrCollapsing },
)
}
@@ -538,10 +537,6 @@ constructor(
return qqsVisible.value
}
- override fun setQSExpandingOrCollapsing(isQSExpandingOrCollapsing: Boolean) {
- viewModel.isQSExpandingOrCollapsing = isQSExpandingOrCollapsing
- }
-
private fun setListenerCollections() {
lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
@@ -882,7 +877,6 @@ private suspend fun synchronizeQsState(
state: MutableSceneTransitionLayoutState,
editMode: Flow<Boolean>,
expansion: Flow<Float>,
- isQSExpandingOrCollapsing: Flow<Boolean>,
) {
coroutineScope {
val animationScope = this
@@ -894,46 +888,31 @@ private suspend fun synchronizeQsState(
currentTransition = null
}
- var lastValidProgress = 0f
- combine(editMode, expansion, isQSExpandingOrCollapsing, ::Triple).collectLatest {
- (editMode, progress, isQSExpandingOrCollapsing) ->
+ editMode.combine(expansion, ::Pair).collectLatest { (editMode, progress) ->
if (editMode && state.currentScene != SceneKeys.EditMode) {
state.setTargetScene(SceneKeys.EditMode, animationScope)?.second?.join()
} else if (!editMode && state.currentScene == SceneKeys.EditMode) {
state.setTargetScene(SceneKeys.QuickSettings, animationScope)?.second?.join()
}
-
if (!editMode) {
- if (!isQSExpandingOrCollapsing) {
- if (progress == 0f) {
- snapTo(QuickQuickSettings)
- return@collectLatest
- }
+ when (progress) {
+ 0f -> snapTo(QuickQuickSettings)
+ 1f -> snapTo(QuickSettings)
+ else -> {
+ val transition = currentTransition
+ if (transition != null) {
+ transition.progress = progress
+ return@collectLatest
+ }
- if (progress == 1f) {
- snapTo(QuickSettings)
- return@collectLatest
+ val newTransition =
+ ExpansionTransition(progress).also { currentTransition = it }
+ state.startTransitionImmediately(
+ animationScope = animationScope,
+ transition = newTransition,
+ )
}
}
-
- var progress = progress
- if (progress >= 0f || progress <= 1f) {
- lastValidProgress = progress
- } else {
- progress = lastValidProgress
- }
-
- val transition = currentTransition
- if (transition != null) {
- transition.progress = progress
- return@collectLatest
- }
-
- val newTransition = ExpansionTransition(progress).also { currentTransition = it }
- state.startTransitionImmediately(
- animationScope = animationScope,
- transition = newTransition,
- )
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
index b829bbce2f18..767acc5fa76a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
@@ -35,6 +35,7 @@ import com.android.systemui.animation.ShadeInterpolation
import com.android.systemui.classifier.Classifier
import com.android.systemui.classifier.domain.interactor.FalsingInteractor
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
+import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.Edge
@@ -60,7 +61,7 @@ import com.android.systemui.qs.panels.ui.viewmodel.MediaInRowInLandscapeViewMode
import com.android.systemui.qs.panels.ui.viewmodel.QuickQuickSettingsViewModel
import com.android.systemui.qs.ui.viewmodel.QuickSettingsContainerViewModel
import com.android.systemui.res.R
-import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.shade.LargeScreenHeaderHelper
import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.shade.domain.interactor.ShadeInteractor
@@ -306,8 +307,6 @@ constructor(
val animateTilesExpansion: Boolean
get() = inFirstPage && !mediaSuddenlyAppearingInLandscape
- var isQSExpandingOrCollapsing by mutableStateOf(false)
-
private val inFirstPage: Boolean
get() = inFirstPageViewModel.inFirstPage
@@ -434,7 +433,7 @@ constructor(
initialValue = false,
source =
keyguardTransitionInteractor.isInTransition(
- Edge.create(to = Scenes.Bouncer),
+ Edge.create(to = Overlays.Bouncer),
Edge.create(to = KeyguardState.PRIMARY_BOUNCER),
),
)
@@ -541,7 +540,6 @@ constructor(
println("proposedTranslation", proposedTranslation)
println("expansionState", expansionState)
println("forceQS", forceQs)
- println("isShadeExpandingOrCollapsing", isQSExpandingOrCollapsing)
printSection("Derived values") {
println("headerTranslation", headerTranslation)
println("translationScaleY", translationScaleY)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 30c2adf89e9b..c60e3da9d833 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -54,6 +54,7 @@ import com.android.systemui.qs.QsEventLogger;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.res.R;
+import com.android.systemui.shade.domain.interactor.ShadeDialogContextInteractor;
import com.android.systemui.statusbar.connectivity.NetworkController;
import com.android.systemui.statusbar.connectivity.SignalCallback;
import com.android.systemui.statusbar.connectivity.WifiIndicators;
@@ -89,6 +90,7 @@ public class CastTile extends QSTileImpl<BooleanState> {
private final Callback mCallback = new Callback();
private final TileJavaAdapter mJavaAdapter;
private final FeatureFlags mFeatureFlags;
+ private final ShadeDialogContextInteractor mShadeDialogContextInteractor;
private boolean mCastTransportAllowed;
private boolean mHotspotConnected;
@@ -110,7 +112,8 @@ public class CastTile extends QSTileImpl<BooleanState> {
DialogTransitionAnimator dialogTransitionAnimator,
ConnectivityRepository connectivityRepository,
TileJavaAdapter javaAdapter,
- FeatureFlags featureFlags
+ FeatureFlags featureFlags,
+ ShadeDialogContextInteractor shadeDialogContextInteractor
) {
super(host, uiEventLogger, backgroundLooper, mainHandler, falsingManager, metricsLogger,
statusBarStateController, activityStarter, qsLogger);
@@ -120,6 +123,7 @@ public class CastTile extends QSTileImpl<BooleanState> {
mDialogTransitionAnimator = dialogTransitionAnimator;
mJavaAdapter = javaAdapter;
mFeatureFlags = featureFlags;
+ mShadeDialogContextInteractor = shadeDialogContextInteractor;
mController.observe(this, mCallback);
mKeyguard.observe(this, mCallback);
if (!mFeatureFlags.isEnabled(SIGNAL_CALLBACK_DEPRECATION)) {
@@ -220,7 +224,7 @@ public class CastTile extends QSTileImpl<BooleanState> {
mUiHandler.post(() -> {
final DialogHolder holder = new DialogHolder();
final Dialog dialog = MediaRouteDialogPresenter.createDialog(
- mContext,
+ mShadeDialogContextInteractor.getContext(),
ROUTE_TYPE_REMOTE_DISPLAY,
v -> {
ActivityTransitionAnimator.Controller controller =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModel.kt
index 0add3f515ebf..f75dadd5ef0f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModel.kt
@@ -18,7 +18,6 @@ package com.android.systemui.qs.ui.viewmodel
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor
import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimShape
@@ -47,18 +46,6 @@ constructor(
override suspend fun onActivated(): Nothing {
coroutineScope {
launch {
- sceneInteractor.currentScene.collect { currentScene ->
- when (currentScene) {
- // TODO(b/369513770): The ShadeSession should be preserved in this scenario.
- Scenes.Bouncer ->
- shadeInteractor.collapseQuickSettingsShade(
- loggingReason = "bouncer shown while shade is open"
- )
- }
- }
- }
-
- launch {
shadeInteractor.isShadeTouchable
.distinctUntilChanged()
.filter { !it }
diff --git a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
index ea11d202b119..2dc4a8d53920 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
@@ -39,7 +39,7 @@ import dagger.multibindings.IntoMap
@Module(
includes =
[
- BouncerSceneModule::class,
+ BouncerOverlayModule::class,
CommunalSceneModule::class,
DreamSceneModule::class,
EmptySceneModule::class,
@@ -98,13 +98,16 @@ interface SceneContainerFrameworkModule {
Scenes.Communal,
Scenes.Dream,
Scenes.Lockscreen,
- Scenes.Bouncer,
Scenes.QuickSettings,
Scenes.Shade,
),
initialSceneKey = Scenes.Lockscreen,
overlayKeys =
- listOfNotNull(Overlays.NotificationsShade, Overlays.QuickSettingsShade),
+ listOfNotNull(
+ Overlays.NotificationsShade,
+ Overlays.QuickSettingsShade,
+ Overlays.Bouncer,
+ ),
navigationDistances =
mapOf(
Scenes.Gone to 0,
@@ -113,7 +116,6 @@ interface SceneContainerFrameworkModule {
Scenes.Dream to 2,
Scenes.Shade to 3,
Scenes.QuickSettings to 4,
- Scenes.Bouncer to 5,
),
transitionsBuilder = SceneContainerTransitions(),
)
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt
index 8845bb7ceeb9..a982f70d80e2 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt
@@ -18,6 +18,7 @@ package com.android.systemui.scene
import com.android.systemui.scene.domain.SceneDomainModule
import com.android.systemui.scene.domain.resolver.HomeSceneFamilyResolverModule
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.SceneContainerConfig
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.ui.composable.SceneContainerTransitions
@@ -28,7 +29,7 @@ import dagger.Provides
@Module(
includes =
[
- BouncerSceneModule::class,
+ BouncerOverlayModule::class,
EmptySceneModule::class,
GoneSceneModule::class,
LockscreenSceneModule::class,
@@ -47,11 +48,10 @@ object ShadelessSceneContainerFrameworkModule {
return SceneContainerConfig(
// Note that this list is in z-order. The first one is the bottom-most and the last one
// is top-most.
- sceneKeys = listOf(Scenes.Gone, Scenes.Lockscreen, Scenes.Bouncer),
+ sceneKeys = listOf(Scenes.Gone, Scenes.Lockscreen),
initialSceneKey = Scenes.Lockscreen,
- overlayKeys = emptyList(),
- navigationDistances =
- mapOf(Scenes.Gone to 0, Scenes.Lockscreen to 0, Scenes.Bouncer to 1),
+ overlayKeys = listOf(Overlays.Bouncer),
+ navigationDistances = mapOf(Scenes.Gone to 0, Scenes.Lockscreen to 0),
transitionsBuilder = SceneContainerTransitions(),
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt
index c96ea03f057a..64abb843fad8 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt
@@ -136,7 +136,7 @@ constructor(
when (this) {
Overlays.NotificationsShade -> false
Overlays.QuickSettingsShade -> false
- Scenes.Bouncer -> false
+ Overlays.Bouncer -> false
Scenes.Communal -> true
Scenes.Dream -> false
Scenes.Gone -> true
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
index 01180859b1d2..07f13cbdd0e7 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
@@ -42,6 +42,7 @@ import com.android.systemui.util.kotlin.pairwise
import dagger.Lazy
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
@@ -203,20 +204,30 @@ constructor(
repository.isSceneContainerUserInputOngoing
/**
- * The amount of transition into or out of the given [scene].
+ * The amount of transition into or out of the given [content].
*
* The value will be `0` if not in this scene or `1` when fully in the given scene.
*/
- fun transitionProgress(scene: SceneKey): Flow<Float> {
+ @OptIn(ExperimentalCoroutinesApi::class)
+ fun transitionProgress(content: ContentKey): Flow<Float> {
return transitionState.flatMapLatest { transition ->
when (transition) {
is ObservableTransitionState.Idle -> {
- flowOf(if (transition.currentScene == scene) 1f else 0f)
+ flowOf(
+ if (
+ transition.currentScene == content ||
+ content in transition.currentOverlays
+ ) {
+ 1f
+ } else {
+ 0f
+ }
+ )
}
is ObservableTransitionState.Transition -> {
when {
- transition.toContent == scene -> transition.progress
- transition.fromContent == scene -> transition.progress.map { 1f - it }
+ transition.toContent == content -> transition.progress
+ transition.fromContent == content -> transition.progress.map { 1f - it }
else -> flowOf(0f)
}
}
@@ -238,6 +249,9 @@ constructor(
* If [forceSettleToTargetScene] is `true` and the target scene is the same as the current
* scene, any current transition will be canceled and an animation to the target scene will be
* started.
+ *
+ * If [Overlays.Bouncer] is showing, we trigger an instant scene change as it will not be user-
+ * visible, and trigger a transition to hide the bouncer.
*/
@JvmOverloads
fun changeScene(
@@ -249,6 +263,7 @@ constructor(
) {
val currentSceneKey = currentScene.value
val resolvedScene = sceneFamilyResolvers.get()[toScene]?.resolvedScene?.value ?: toScene
+ val bouncerShowing = Overlays.Bouncer in currentOverlays.value
if (resolvedScene == currentSceneKey && forceSettleToTargetScene) {
logger.logSceneChangeCancellation(scene = resolvedScene, sceneState = sceneState)
@@ -265,6 +280,12 @@ constructor(
loggingReason = loggingReason,
)
) {
+ if (bouncerShowing) {
+ hideOverlay(
+ Overlays.Bouncer,
+ "Scene change cancelled but hiding bouncer for: ($loggingReason)",
+ )
+ }
return
}
@@ -278,14 +299,20 @@ constructor(
isInstant = false,
)
- repository.changeScene(resolvedScene, transitionKey)
+ if (bouncerShowing) {
+ repository.snapToScene(resolvedScene)
+ hideOverlay(Overlays.Bouncer, "Hiding on changeScene for: ($loggingReason)")
+ } else {
+ repository.changeScene(resolvedScene, transitionKey)
+ }
}
/**
* Requests a scene change to the given scene.
*
* The change is instantaneous and not animated; it will be observable in the next frame and
- * there will be no transition animation.
+ * there will be no transition animation. If [Overlays.Bouncer] is showing, it will instantly be
+ * hidden.
*/
fun snapToScene(toScene: SceneKey, loggingReason: String) {
val currentSceneKey = currentScene.value
@@ -316,6 +343,7 @@ constructor(
)
repository.snapToScene(resolvedScene)
+ instantlyHideOverlay(Overlays.Bouncer, "Hiding on snapToScene for: ($loggingReason)")
}
/**
@@ -662,6 +690,16 @@ constructor(
false
}
+ to == Overlays.Bouncer && currentScene.value == Scenes.Gone -> {
+ logger.logSceneChangeRejection(
+ from = from,
+ to = to,
+ originalChangeReason = loggingReason,
+ rejectionReason = "Cannot show Bouncer over Gone scene",
+ )
+ false
+ }
+
else -> true
}
}
@@ -767,4 +805,41 @@ constructor(
)
}
}
+
+ /**
+ * Based off of the ordering of [allContentKeys], returns the key of the highest z-order content
+ * out of [content].
+ */
+ private fun determineTopmostContent(content: Set<ContentKey>): ContentKey {
+ // Assuming allContentKeys is sorted by ascending z-order.
+ return checkNotNull(allContentKeys.findLast { it in content }) {
+ "Could not find unknown content $content in allContentKeys $allContentKeys"
+ }
+ }
+
+ /** Optimization for common case where overlays is empty. */
+ private fun determineTopmostContent(scene: SceneKey, overlays: Set<OverlayKey>): ContentKey {
+ return if (overlays.isEmpty()) {
+ scene
+ } else {
+ determineTopmostContent(overlays)
+ }
+ }
+
+ /**
+ * The current content that has the highest z-order out of all currently shown scenes and
+ * overlays.
+ *
+ * Note that during a transition between content, a different content may have the highest z-
+ * order. Only the one provided by this flow is considered the current logical topmost content.
+ */
+ @Deprecated("Only to be used for compatibility with KeyguardTransitionFramework")
+ val topmostContent: StateFlow<ContentKey> =
+ combine(currentScene, currentOverlays, ::determineTopmostContent)
+ .stateInTraced(
+ name = "topmostContent",
+ scope = applicationScope,
+ started = SharingStarted.Eagerly,
+ initialValue = determineTopmostContent(currentScene.value, currentOverlays.value),
+ )
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractor.kt
index 79226138d07a..68ce26954aa3 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractor.kt
@@ -87,7 +87,7 @@ constructor(
)
is ObservableTransitionState.Transition ->
if (
- state.fromContent == Scenes.Bouncer &&
+ state.fromContent == Overlays.Bouncer &&
state.toContent == Scenes.Lockscreen
) {
// Lockscreen is not visible during preview stage of predictive back
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
index 218ad477c45e..4753b9ac0457 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
@@ -18,6 +18,7 @@ package com.android.systemui.scene.domain.startable
import android.app.StatusBarManager
import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.compose.animation.scene.OverlayKey
import com.android.compose.animation.scene.SceneKey
import com.android.internal.logging.UiEventLogger
import com.android.keyguard.AuthInteractionProperties
@@ -45,7 +46,7 @@ import com.android.systemui.keyguard.DismissCallbackRegistry
import com.android.systemui.keyguard.domain.interactor.KeyguardEnabledInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.TrustInteractor
-import com.android.systemui.keyguard.domain.interactor.WindowManagerLockscreenVisibilityInteractor.Companion.keyguardScenes
+import com.android.systemui.keyguard.domain.interactor.WindowManagerLockscreenVisibilityInteractor.Companion.keyguardContent
import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.model.SceneContainerPlugin
import com.android.systemui.model.SysUiState
@@ -98,7 +99,6 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.distinctUntilChangedBy
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterIsInstance
-import kotlinx.coroutines.flow.filterNot
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
@@ -345,12 +345,10 @@ constructor(
applicationScope.launch {
// TODO (b/308001302): Move this to a bouncer specific interactor.
bouncerInteractor.onImeHiddenByUser.collectLatest {
- if (sceneInteractor.currentScene.value == Scenes.Bouncer) {
- sceneInteractor.changeScene(
- toScene = Scenes.Lockscreen,
- loggingReason = "IME hidden",
- )
- }
+ sceneInteractor.hideOverlay(
+ overlay = Overlays.Bouncer,
+ loggingReason = "IME hidden.",
+ )
}
}
}
@@ -364,26 +362,28 @@ constructor(
.collect { (isAnySimLocked, unlockStatus) ->
when {
isAnySimLocked -> {
- switchToScene(
- targetSceneKey = Scenes.Bouncer,
+ sceneInteractor.showOverlay(
+ overlay = Overlays.Bouncer,
loggingReason = "Need to authenticate locked SIM card.",
)
}
unlockStatus.isUnlocked &&
deviceEntryInteractor.canSwipeToEnter.value == false -> {
+ val loggingReason =
+ "All SIM cards unlocked and device already unlocked and " +
+ "lockscreen doesn't require a swipe to dismiss."
switchToScene(
targetSceneKey = Scenes.Gone,
- loggingReason =
- "All SIM cards unlocked and device already unlocked and " +
- "lockscreen doesn't require a swipe to dismiss.",
+ loggingReason = loggingReason,
)
}
else -> {
+ val loggingReason =
+ "All SIM cards unlocked and device still locked" +
+ " or lockscreen still requires a swipe to dismiss."
switchToScene(
targetSceneKey = Scenes.Lockscreen,
- loggingReason =
- "All SIM cards unlocked and device still locked" +
- " or lockscreen still requires a swipe to dismiss.",
+ loggingReason = loggingReason,
)
}
}
@@ -393,26 +393,40 @@ constructor(
private fun handleDeviceUnlockStatus() {
applicationScope.launch {
- // Track the previous scene (sans Bouncer), so that we know where to go when the device
- // is unlocked whilst on the bouncer.
+ // Track the previous scene, so that we know where to go when the device is unlocked
+ // whilst on the bouncer.
val previousScene =
- sceneBackInteractor.backScene
- .filterNot { it == Scenes.Bouncer }
- .stateIn(this, SharingStarted.Eagerly, initialValue = null)
+ sceneBackInteractor.backScene.stateIn(
+ this,
+ SharingStarted.Eagerly,
+ initialValue = null,
+ )
deviceUnlockedInteractor.deviceUnlockStatus
.mapNotNull { deviceUnlockStatus ->
- val renderedScenes =
+ val (renderedScenes: List<SceneKey>, renderedOverlays) =
when (val transitionState = sceneInteractor.transitionState.value) {
- is ObservableTransitionState.Idle -> setOf(transitionState.currentScene)
- is ObservableTransitionState.Transition ->
- setOf(transitionState.fromContent, transitionState.toContent)
+ is ObservableTransitionState.Idle ->
+ listOf(transitionState.currentScene) to
+ transitionState.currentOverlays
+ is ObservableTransitionState.Transition.ChangeScene ->
+ listOf(transitionState.fromScene, transitionState.toScene) to
+ transitionState.currentOverlays
+ is ObservableTransitionState.Transition.OverlayTransition ->
+ listOf(transitionState.currentScene) to
+ setOfNotNull(
+ transitionState.toContent.takeIf { it is OverlayKey },
+ transitionState.fromContent.takeIf { it is OverlayKey },
+ )
}
val isOnLockscreen = renderedScenes.contains(Scenes.Lockscreen)
val isAlternateBouncerVisible = alternateBouncerInteractor.isVisibleState()
- val isOnPrimaryBouncer = renderedScenes.contains(Scenes.Bouncer)
+ val isOnPrimaryBouncer = Overlays.Bouncer in renderedOverlays
if (!deviceUnlockStatus.isUnlocked) {
- return@mapNotNull if (renderedScenes.any { it in keyguardScenes }) {
- // Already on a keyguard scene, no need to change scenes.
+ return@mapNotNull if (
+ renderedScenes.any { it in keyguardContent } ||
+ Overlays.Bouncer in renderedOverlays
+ ) {
+ // Already on a keyguard scene or bouncer, no need to change scenes.
null
} else {
// The device locked while on a scene that's not a keyguard scene, go
@@ -450,24 +464,25 @@ constructor(
}
isOnPrimaryBouncer -> {
// When the device becomes unlocked in primary Bouncer,
- // notify dismiss succeeded and go to previous scene or Gone.
+ // notify dismiss succeeded and remain in current scene or switch to
+ // Gone.
dismissCallbackRegistry.notifyDismissSucceeded()
+ // if transition is a scene change, take the destination scene
+ val targetScene = renderedScenes.last()
if (
- previousScene.value == Scenes.Lockscreen ||
+ targetScene == Scenes.Lockscreen ||
!statusBarStateController.leaveOpenOnKeyguardHide()
) {
Scenes.Gone to
"device was unlocked with bouncer showing and shade" +
" didn't need to be left open"
} else {
- val prevScene = previousScene.value
- val targetScene = prevScene ?: Scenes.Gone
- if (targetScene != Scenes.Gone) {
+ if (previousScene.value != Scenes.Gone) {
replaceLockscreenSceneOnBackStack()
}
targetScene to
"device was unlocked with primary bouncer showing," +
- " from sceneKey=$prevScene"
+ " from sceneKey=$targetScene"
}
}
isOnLockscreen ->
@@ -575,8 +590,8 @@ constructor(
authenticationInteractor.get().getAuthenticationMethod() ==
AuthenticationMethodModel.Sim
) {
- switchToScene(
- targetSceneKey = Scenes.Bouncer,
+ sceneInteractor.showOverlay(
+ overlay = Overlays.Bouncer,
loggingReason = "device is starting to wake up with a locked sim",
)
}
@@ -791,11 +806,11 @@ constructor(
}
applicationScope.launch {
- sceneInteractor.currentScene
- .map { it == Scenes.Bouncer }
+ sceneInteractor.currentOverlays
+ .map { Overlays.Bouncer in it }
.distinctUntilChanged()
- .collect { switchedToBouncerScene ->
- if (switchedToBouncerScene) {
+ .collect { switchedToBouncerOverlay ->
+ if (switchedToBouncerOverlay) {
falsingCollector.onBouncerShown()
} else {
falsingCollector.onBouncerHidden()
@@ -812,7 +827,10 @@ constructor(
falsingManager.addFalsingBeliefListener(listener)
awaitClose { falsingManager.removeFalsingBeliefListener(listener) }
}
- .collect { switchToScene(Scenes.Lockscreen, "Falsing detected.") }
+ .collect {
+ val loggingReason = "Falsing detected."
+ switchToScene(Scenes.Lockscreen, loggingReason)
+ }
}
}
@@ -827,7 +845,7 @@ constructor(
.mapNotNull { it as? ObservableTransitionState.Idle }
.map { it.currentScene to it.currentOverlays }
.distinctUntilChanged()
- .map { (sceneKey, currentOverlays) ->
+ .map { (currentScene, currentOverlays) ->
when {
// When locked, showing the lockscreen scene should be reported
// as "interacting" while showing other scenes should report as
@@ -837,9 +855,9 @@ constructor(
// implementation. The real reason why is lost to lore and myth.
Overlays.NotificationsShade in currentOverlays -> false
Overlays.QuickSettingsShade in currentOverlays -> null
- sceneKey == Scenes.Lockscreen -> true
- sceneKey == Scenes.Bouncer -> false
- sceneKey == Scenes.Shade -> false
+ Overlays.Bouncer in currentOverlays -> false
+ currentScene == Scenes.Lockscreen -> true
+ currentScene == Scenes.Shade -> false
else -> null
}
}
@@ -865,7 +883,7 @@ constructor(
.filterIsInstance<ObservableTransitionState.Transition>()
// Only consider user-initiated (e.g. drags) that go from bouncer to lockscreen.
.filter { transition ->
- transition.fromContent == Scenes.Bouncer &&
+ transition.fromContent == Overlays.Bouncer &&
transition.toContent == Scenes.Lockscreen &&
transition.isInitiatedByUserInput
}
@@ -954,14 +972,13 @@ constructor(
private fun notifyKeyguardDismissCancelledCallbacks() {
applicationScope.launch {
- combine(deviceEntryInteractor.isUnlocked, sceneInteractor.currentScene.pairwise()) {
+ combine(deviceEntryInteractor.isUnlocked, sceneInteractor.currentOverlays.pairwise()) {
isUnlocked,
- (from, to) ->
- when {
- from != Scenes.Bouncer -> false
- to != Scenes.Gone && !isUnlocked -> true
- else -> false
- }
+ overlayChange ->
+ val difference = overlayChange.previousValue - overlayChange.newValue
+ !isUnlocked &&
+ sceneInteractor.currentScene.value != Scenes.Gone &&
+ Overlays.Bouncer in difference
}
.collect { notifyKeyguardDismissCancelled ->
if (notifyKeyguardDismissCancelled) {
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/ScrimStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/ScrimStartable.kt
index 522dfabb8b61..305dcfb6a528 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/ScrimStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/ScrimStartable.kt
@@ -17,6 +17,7 @@
package com.android.systemui.scene.domain.startable
import androidx.annotation.VisibleForTesting
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.compose.animation.scene.ContentKey
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.compose.animation.scene.OverlayKey
@@ -49,7 +50,6 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
-import com.android.app.tracing.coroutines.launchTraced as launch
@SysUISingleton
class ScrimStartable
@@ -108,12 +108,12 @@ constructor(
// This is true when the lockscreen scene is either the current scene or somewhere
// in the navigation back stack of scenes.
val isOnKeyguard = !isDeviceEntered
- val isCurrentSceneBouncer = currentScene == Scenes.Bouncer
- // This is true when moving away from one of the keyguard scenes to the gone scene.
+ val isOnBouncer = Overlays.Bouncer in currentOverlays
+ // This is true when moving away from the lockscreen scene to the gone scene.
// It happens only when unlocking or when dismissing a dismissible lockscreen.
val isTransitioningAwayFromKeyguard =
transitionState is ObservableTransitionState.Transition.ChangeScene &&
- transitionState.fromScene.isKeyguard() &&
+ transitionState.fromScene == Scenes.Lockscreen &&
transitionState.toScene == Scenes.Gone
// This is true when any of the shade scenes or overlays is the current content.
@@ -144,7 +144,7 @@ constructor(
// Assume scrim state for shade is already correct and do nothing
null
}
- } else if (isCurrentSceneBouncer && !unlocking) {
+ } else if (isOnBouncer && !unlocking) {
// Bouncer needs the front scrim when it's on top of an activity, tapping on a
// notification, editing QS or being dismissed by
// FLAG_DISMISS_KEYGUARD_ACTIVITY.
@@ -215,10 +215,6 @@ constructor(
}
}
- private fun SceneKey.isKeyguard(): Boolean {
- return this == Scenes.Lockscreen || this == Scenes.Bouncer
- }
-
private fun ContentKey.isShade(): Boolean {
return this == Scenes.Shade ||
this == Scenes.QuickSettings ||
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/StatusBarStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/StatusBarStartable.kt
index 7d09c457e8c1..4c8926a7bad0 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/StatusBarStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/StatusBarStartable.kt
@@ -24,6 +24,8 @@ import android.os.IBinder
import android.os.RemoteException
import android.provider.DeviceConfig
import android.util.Log
+import com.android.app.tracing.coroutines.launchTraced as launch
+import com.android.compose.animation.scene.OverlayKey
import com.android.compose.animation.scene.SceneKey
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags
import com.android.internal.statusbar.IStatusBarService
@@ -43,14 +45,13 @@ import com.android.systemui.power.shared.model.WakefulnessModel
import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
-import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.user.domain.interactor.SelectedUserInteractor
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
-import com.android.app.tracing.coroutines.launchTraced as launch
import kotlinx.coroutines.withContext
@SysUISingleton
@@ -93,6 +94,7 @@ constructor(
navigationInteractor.isGesturalMode,
authenticationInteractor.authenticationMethod,
powerInteractor.detailedWakefulness,
+ sceneInteractor.currentOverlays,
) { values ->
val selectedUserId = values[0] as Int
val currentScene = values[1] as SceneKey
@@ -102,8 +104,9 @@ constructor(
val isGesturalMode = values[5] as Boolean
val authenticationMethod = values[6] as AuthenticationMethodModel
val wakefulnessModel = values[7] as WakefulnessModel
+ val overlays = values[8] as Set<OverlayKey>
- val isForceHideHomeAndRecents = currentScene == Scenes.Bouncer
+ val isForceHideHomeAndRecents = Overlays.Bouncer in overlays
val isKeyguardShowing = !isDeviceEntered
val isPowerGestureIntercepted =
with(wakefulnessModel) {
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/Overlays.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/Overlays.kt
index c47a85082032..238de4af0d1e 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/Overlays.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/Overlays.kt
@@ -25,6 +25,12 @@ import com.android.compose.animation.scene.OverlayKey
*/
object Overlays {
/**
+ * The bouncer is the overlay that displays authentication challenges like PIN, password, or
+ * pattern.
+ */
+ @JvmField val Bouncer = OverlayKey("bouncer")
+
+ /**
* The notifications shade overlay primarily shows a scrollable list of notifications.
*
* It's used only in the dual shade configuration, where there are two separate shades: one for
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scenes.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scenes.kt
index 16492efa658a..8332522dd129 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scenes.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scenes.kt
@@ -24,12 +24,6 @@ import com.android.compose.animation.scene.SceneKey
* PLEASE KEEP THE KEYS SORTED ALPHABETICALLY.
*/
object Scenes {
- /**
- * The bouncer is the scene that displays authentication challenges like PIN, password, or
- * pattern.
- */
- @JvmField val Bouncer = SceneKey("bouncer")
-
/** The communal scene shows the glanceable hub when device is locked and docked. */
@JvmField val Communal = SceneKey("communal")
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneJankMonitor.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneJankMonitor.kt
index 48a49c60d8a2..48a3dede5def 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneJankMonitor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneJankMonitor.kt
@@ -27,7 +27,7 @@ import com.android.systemui.authentication.shared.model.AuthenticationMethodMode
import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.Hydrator
-import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.shared.model.Overlays
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@@ -95,7 +95,7 @@ constructor(
private fun calculatedCuj(from: ContentKey, to: ContentKey): Int? {
val isDeviceUnlocked = deviceUnlockedInteractor.deviceUnlockStatus.value.isUnlocked
return when {
- to == Scenes.Bouncer ->
+ to == Overlays.Bouncer ->
when (authMethod) {
is AuthenticationMethodModel.Pin,
is AuthenticationMethodModel.Sim -> Cuj.CUJ_LOCKSCREEN_PIN_APPEAR
@@ -104,7 +104,7 @@ constructor(
is AuthenticationMethodModel.None -> null
null -> null
}
- from == Scenes.Bouncer && isDeviceUnlocked ->
+ from == Overlays.Bouncer && isDeviceUnlocked ->
when (authMethod) {
is AuthenticationMethodModel.Pin,
is AuthenticationMethodModel.Sim -> Cuj.CUJ_LOCKSCREEN_PIN_DISAPPEAR
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
index efdf5bee2c7b..a81fcec94989 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
@@ -318,7 +318,7 @@ constructor(
private fun isInteractionAllowedByFalsing(content: ContentKey): Boolean {
val interactionTypeOrNull =
when (content) {
- Scenes.Bouncer -> Classifier.BOUNCER_UNLOCK
+ Overlays.Bouncer -> Classifier.BOUNCER_UNLOCK
Scenes.Gone -> Classifier.UNLOCK
Scenes.Shade,
Overlays.NotificationsShade -> Classifier.NOTIFICATION_DRAG_DOWN
diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java
index 34b3324f81da..d05837261b89 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java
@@ -105,14 +105,15 @@ import com.android.systemui.util.kotlin.JavaAdapter;
import dalvik.annotation.optimization.NeverCompile;
+import dagger.Lazy;
+
+import kotlin.Unit;
+
import java.io.PrintWriter;
import javax.inject.Inject;
import javax.inject.Provider;
-import dagger.Lazy;
-import kotlin.Unit;
-
/** Handles QuickSettings touch handling, expansion and animation state. */
@SysUISingleton
public class QuickSettingsControllerImpl implements QuickSettingsController, Dumpable {
@@ -2365,16 +2366,8 @@ public class QuickSettingsControllerImpl implements QuickSettingsController, Dum
return;
}
if (startTracing) {
- if (mQs != null) {
- mQs.setQSExpandingOrCollapsing(true);
- }
-
monitor.begin(mPanelView, Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE);
} else {
- if (mQs != null) {
- mQs.setQSExpandingOrCollapsing(false);
- }
-
if (wasCancelled) {
monitor.cancel(Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/NotificationShadeWindowModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/NotificationShadeWindowModel.kt
index 9655d928a9b9..a3bfbbc8eb1a 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/NotificationShadeWindowModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/NotificationShadeWindowModel.kt
@@ -28,6 +28,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.GLANCEABLE_HUB
import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.util.kotlin.BooleanFlowOperators.any
import com.android.systemui.util.kotlin.sample
@@ -92,7 +93,7 @@ constructor(
val isBouncerShowing: Flow<Boolean> =
when {
SceneContainerFlag.isEnabled -> {
- sceneInteractor.get().transitionState.map { it.isIdle(Scenes.Bouncer) }
+ sceneInteractor.get().transitionState.map { it.isIdle(Overlays.Bouncer) }
}
ComposeBouncerFlags.isOnlyComposeBouncerEnabled() -> primaryBouncerInteractor.isShowing
else ->
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
index 3db004848d22..84266e805773 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
@@ -38,13 +38,13 @@ import com.android.systemui.Flags
import com.android.systemui.Flags.spatialModelAppPushback
import com.android.systemui.animation.ShadeInterpolation
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dump.DumpManager
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.shade.ShadeExpansionChangeEvent
import com.android.systemui.shade.ShadeExpansionListener
-import com.android.systemui.shared.Flags.ambientAod
import com.android.systemui.statusbar.phone.BiometricUnlockController
import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK
import com.android.systemui.statusbar.phone.DozeParameters
@@ -53,8 +53,11 @@ import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.statusbar.policy.SplitShadeStateController
import com.android.systemui.util.WallpaperController
+import com.android.systemui.wallpapers.domain.interactor.WallpaperInteractor
import com.android.systemui.window.domain.interactor.WindowRootViewBlurInteractor
import com.android.wm.shell.appzoomout.AppZoomOut
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
import java.io.PrintWriter
import java.util.Optional
import javax.inject.Inject
@@ -76,12 +79,14 @@ constructor(
private val keyguardInteractor: KeyguardInteractor,
private val choreographer: Choreographer,
private val wallpaperController: WallpaperController,
+ private val wallpaperInteractor: WallpaperInteractor,
private val notificationShadeWindowController: NotificationShadeWindowController,
private val dozeParameters: DozeParameters,
@ShadeDisplayAware private val context: Context,
private val splitShadeStateController: SplitShadeStateController,
private val windowRootViewBlurInteractor: WindowRootViewBlurInteractor,
private val appZoomOutOptional: Optional<AppZoomOut>,
+ @Application private val applicationScope: CoroutineScope,
dumpManager: DumpManager,
configurationController: ConfigurationController,
) : ShadeExpansionListener, Dumpable {
@@ -110,6 +115,8 @@ constructor(
private var prevTimestamp: Long = -1
private var prevShadeDirection = 0
private var prevShadeVelocity = 0f
+ private var prevDozeAmount: Float = 0f
+ @VisibleForTesting var wallpaperSupportsAmbientMode: Boolean = false
// tracks whether app launch transition is in progress. This involves two independent factors
// that control blur, shade expansion and app launch animation from outside sysui.
// They can complete out of order, this flag will be reset by the animation that finishes later.
@@ -219,7 +226,15 @@ constructor(
}
/** Blur radius of the wake-up animation on this frame. */
- private var wakeAndUnlockBlurRadius = 0f
+ private var wakeBlurRadius = 0f
+ set(value) {
+ if (field == value) return
+ field = value
+ scheduleUpdate()
+ }
+
+ /** Blur radius of the unlock animation on this frame. */
+ private var unlockBlurRadius = 0f
set(value) {
if (field == value) return
field = value
@@ -246,14 +261,16 @@ constructor(
ShadeInterpolation.getNotificationScrimAlpha(qsPanelExpansion) * shadeExpansion
combinedBlur = max(combinedBlur, blurUtils.blurRadiusOfRatio(qsExpandedRatio))
combinedBlur = max(combinedBlur, blurUtils.blurRadiusOfRatio(transitionToFullShadeProgress))
- var shadeRadius = max(combinedBlur, wakeAndUnlockBlurRadius)
+ var shadeRadius = max(combinedBlur, max(wakeBlurRadius, unlockBlurRadius))
if (areBlursDisabledForAppLaunch || blursDisabledForUnlock) {
shadeRadius = 0f
}
var blur = shadeRadius.toInt()
- val zoomOut = blurRadiusToZoomOut(blurRadius = shadeRadius)
+ // If the blur comes from waking up, we don't want to zoom out the background
+ val zoomOut =
+ if (shadeRadius != wakeBlurRadius) blurRadiusToZoomOut(blurRadius = shadeRadius) else 0f
// Make blur be 0 if it is necessary to stop blur effect.
if (scrimsVisible) {
if (!Flags.notificationShadeBlur()) {
@@ -338,14 +355,14 @@ constructor(
startDelay = keyguardStateController.keyguardFadingAwayDelay
interpolator = Interpolators.FAST_OUT_SLOW_IN
addUpdateListener { animation: ValueAnimator ->
- wakeAndUnlockBlurRadius =
+ unlockBlurRadius =
blurUtils.blurRadiusOfRatio(animation.animatedValue as Float)
}
addListener(
object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
keyguardAnimator = null
- wakeAndUnlockBlurRadius = 0f
+ unlockBlurRadius = 0f
}
}
)
@@ -381,15 +398,20 @@ constructor(
}
override fun onDozeAmountChanged(linear: Float, eased: Float) {
- wakeAndUnlockBlurRadius =
- if (ambientAod()) {
- 0f
- } else {
- blurUtils.blurRadiusOfRatio(eased)
- }
+ prevDozeAmount = eased
+ updateWakeBlurRadius(prevDozeAmount)
}
}
+ private fun updateWakeBlurRadius(ratio: Float) {
+ wakeBlurRadius =
+ if (!wallpaperSupportsAmbientMode) {
+ 0f
+ } else {
+ blurUtils.blurRadiusOfRatio(ratio)
+ }
+ }
+
init {
dumpManager.registerCriticalDumpable(javaClass.name, this)
if (WAKE_UP_ANIMATION_ENABLED) {
@@ -411,6 +433,12 @@ constructor(
}
}
)
+ applicationScope.launch {
+ wallpaperInteractor.wallpaperSupportsAmbientMode.collect { supported ->
+ wallpaperSupportsAmbientMode = supported
+ updateWakeBlurRadius(prevDozeAmount)
+ }
+ }
initBlurListeners()
}
@@ -585,7 +613,8 @@ constructor(
it.println("shouldApplyShadeBlur: ${shouldApplyShadeBlur()}")
it.println("shadeAnimation: ${shadeAnimation.radius}")
it.println("brightnessMirrorRadius: ${brightnessMirrorSpring.radius}")
- it.println("wakeAndUnlockBlur: $wakeAndUnlockBlurRadius")
+ it.println("wakeBlur: $wakeBlurRadius")
+ it.println("unlockBlur: $wakeBlurRadius")
it.println("blursDisabledForAppLaunch: $blursDisabledForAppLaunch")
it.println("appLaunchTransitionIsInProgress: $appLaunchTransitionIsInProgress")
it.println("qsPanelExpansion: $qsPanelExpansion")
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index 0dfc63ea8619..08ecc64bda02 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -627,7 +627,6 @@ public class StatusBarStateControllerImpl implements
boolean alternateBouncerIsVisible) {
SceneContainerFlag.isUnexpectedlyInLegacyMode();
- final boolean onBouncer = currentScene.equals(Scenes.Bouncer);
final boolean onCommunal = currentScene.equals(Scenes.Communal);
final boolean onGone = currentScene.equals(Scenes.Gone);
final boolean onDream = currentScene.equals(Scenes.Dream);
@@ -635,8 +634,8 @@ public class StatusBarStateControllerImpl implements
final boolean onQuickSettings = currentScene.equals(Scenes.QuickSettings);
final boolean onShade = currentScene.equals(Scenes.Shade);
+ final boolean overlaidBouncer = currentOverlays.contains(Overlays.Bouncer);
final boolean overCommunal = SceneStackKt.contains(backStack, Scenes.Communal);
- final boolean overLockscreen = SceneStackKt.contains(backStack, Scenes.Lockscreen);
final boolean overShade = SceneStackKt.contains(backStack, Scenes.Shade);
final boolean overlaidShade = currentOverlays.contains(Overlays.NotificationsShade);
@@ -669,14 +668,13 @@ public class StatusBarStateControllerImpl implements
// 3. backStack contains a keyguardish scene (Lockscreen or Communal).
// 4. the alternate bouncer is visible.
- final boolean onKeyguardish = onLockscreen || onBouncer || onCommunal;
- final boolean overKeyguardish = overLockscreen || overCommunal;
+ final boolean onKeyguardish = onLockscreen || overlaidBouncer || onCommunal;
if (isOccluded) {
// Occlusion is special; even though the device is still technically on the lockscreen,
// the UI behaves as if it is unlocked.
newState = StatusBarState.SHADE;
- } else if (onKeyguardish || overKeyguardish || alternateBouncerIsVisible) {
+ } else if (onKeyguardish || overCommunal || alternateBouncerIsVisible) {
// We get here if we are on or over a keyguardish scene, even if isUnlocked is true; we
// want to return SHADE_LOCKED or KEYGUARD until we are also neither on nor over a
// keyguardish scene.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/domain/interactor/StatusBarKeyguardViewManagerInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/domain/interactor/StatusBarKeyguardViewManagerInteractor.kt
index 9ca110e8c561..352d660eb29a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/domain/interactor/StatusBarKeyguardViewManagerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/domain/interactor/StatusBarKeyguardViewManagerInteractor.kt
@@ -37,10 +37,7 @@ import kotlinx.coroutines.flow.merge
/**
* Whether to set the status bar keyguard view occluded or not, and whether to animate that change.
*/
-data class OccludedState(
- val occluded: Boolean,
- val animate: Boolean = false,
-)
+data class OccludedState(val occluded: Boolean, val animate: Boolean = false)
/** Handles logic around calls to [StatusBarKeyguardViewManager] in legacy code. */
@Deprecated("Will be removed once all of SBKVM's responsibilies are refactored.")
@@ -93,12 +90,12 @@ constructor(
private val occlusionStateFromFinishedStep =
combine(
keyguardTransitionInteractor.isFinishedIn(
- scene = Scenes.Gone,
+ content = Scenes.Gone,
stateWithoutSceneContainer = KeyguardState.GONE,
),
keyguardTransitionInteractor.isFinishedIn(KeyguardState.OCCLUDED),
keyguardOcclusionInteractor.isShowWhenLockedActivityOnTop,
- ::Triple
+ ::Triple,
)
.map { (isOnGone, isOnOccluded, showWhenLockedOnTop) ->
// If we're FINISHED in OCCLUDED, we want to render as occluded. We also need to
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/ui/compose/MediaControlPopup.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/ui/compose/MediaControlPopup.kt
new file mode 100644
index 000000000000..80bdb7f8a05f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/ui/compose/MediaControlPopup.kt
@@ -0,0 +1,56 @@
+/*
+ * 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.systemui.statusbar.featurepods.media.ui.compose
+
+import android.widget.FrameLayout
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.viewinterop.AndroidView
+import com.android.systemui.media.controls.ui.view.MediaHost
+import com.android.systemui.res.R
+
+/** Displays a popup containing media controls. Embeds the MediaCarousel within a Compose popup. */
+@Composable
+fun MediaControlPopup(mediaHost: MediaHost, modifier: Modifier = Modifier) {
+ AndroidView(
+ modifier =
+ modifier
+ .width(400.dp)
+ .height(200.dp)
+ .clip(
+ shape =
+ RoundedCornerShape(dimensionResource(R.dimen.notification_corner_radius))
+ ),
+ factory = { _ ->
+ mediaHost.hostView.apply {
+ layoutParams =
+ FrameLayout.LayoutParams(
+ FrameLayout.LayoutParams.MATCH_PARENT,
+ FrameLayout.LayoutParams.MATCH_PARENT,
+ )
+ }
+ mediaHost.hostView
+ },
+ onReset = {},
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopup.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopup.kt
index 8a66904ea59b..ead51482b561 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopup.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopup.kt
@@ -28,7 +28,9 @@ import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Popup
import androidx.compose.ui.window.PopupProperties
+import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.res.R
+import com.android.systemui.statusbar.featurepods.media.ui.compose.MediaControlPopup
import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipId
import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipModel
@@ -37,7 +39,7 @@ import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipM
* status bar.
*/
@Composable
-fun StatusBarPopup(viewModel: PopupChipModel.Shown) {
+fun StatusBarPopup(viewModel: PopupChipModel.Shown, mediaHost: MediaHost) {
val density = Density(LocalContext.current)
Popup(
properties =
@@ -56,7 +58,7 @@ fun StatusBarPopup(viewModel: PopupChipModel.Shown) {
Box(modifier = Modifier.padding(8.dp).wrapContentSize()) {
when (viewModel.chipId) {
is PopupChipId.MediaControl -> {
- // TODO(b/385202114): Populate MediaControlPopup contents.
+ MediaControlPopup(mediaHost = mediaHost)
}
}
// Future popup types will be handled here.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopupChipsContainer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopupChipsContainer.kt
index 16538c93cf35..f5f1f2028aa2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopupChipsContainer.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopupChipsContainer.kt
@@ -20,14 +20,37 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
+import com.android.systemui.media.controls.ui.view.MediaHost
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipId
import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipModel
/** Container view that holds all right hand side chips in the status bar. */
@Composable
-fun StatusBarPopupChipsContainer(chips: List<PopupChipModel.Shown>, modifier: Modifier = Modifier) {
+fun StatusBarPopupChipsContainer(
+ chips: List<PopupChipModel.Shown>,
+ mediaHost: MediaHost,
+ onMediaControlPopupVisibilityChanged: (Boolean) -> Unit,
+ modifier: Modifier = Modifier,
+) {
+ if (!SceneContainerFlag.isEnabled) {
+ val isMediaControlPopupShown =
+ remember(chips) {
+ chips.any { it.chipId == PopupChipId.MediaControl && it.isPopupShown }
+ }
+
+ LaunchedEffect(isMediaControlPopupShown) {
+ onMediaControlPopupVisibilityChanged(isMediaControlPopupShown)
+ }
+ }
+
// TODO(b/385353140): Add padding and spacing for this container according to UX specs.
Box {
Row(
@@ -37,7 +60,7 @@ fun StatusBarPopupChipsContainer(chips: List<PopupChipModel.Shown>, modifier: Mo
chips.forEach { chip ->
StatusBarPopupChip(chip)
if (chip.isPopupShown) {
- StatusBarPopup(chip)
+ StatusBarPopup(viewModel = chip, mediaHost = mediaHost)
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java
index 26bc5b14d357..d1063d95a305 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java
@@ -117,6 +117,7 @@ public class RankingCoordinator implements Coordinator {
@Override
public boolean isInSection(PipelineEntry entry) {
return !mHighPriorityProvider.isHighPriority(entry)
+ && entry.getRepresentativeEntry() != null
&& !entry.getRepresentativeEntry().isAmbient();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/ConnectedDisplaysStatusBarNotificationIconViewStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/ConnectedDisplaysStatusBarNotificationIconViewStore.kt
index eb55856d994b..5760b5f79c74 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/ConnectedDisplaysStatusBarNotificationIconViewStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/ConnectedDisplaysStatusBarNotificationIconViewStore.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.notification.icon.ui.viewbinder
+import android.util.Log
import com.android.systemui.display.domain.interactor.DisplayWindowPropertiesInteractor
import com.android.systemui.lifecycle.Activatable
import com.android.systemui.statusbar.StatusBarIconView
@@ -61,9 +62,16 @@ constructor(
}
override fun iconView(key: String): StatusBarIconView? {
- val entry = notifCollection.getEntry(key) ?: return null
- val displayWindowProperties =
- displayWindowPropertiesInteractor.getForStatusBar(displayId) ?: return null
+ val entry = notifCollection.getEntry(key)
+ if (entry == null) {
+ Log.w(TAG, "No notification entry found for key: $key")
+ return null
+ }
+ val displayWindowProperties = displayWindowPropertiesInteractor.getForStatusBar(displayId)
+ if (displayWindowProperties == null) {
+ Log.w(TAG, "No display properties found for display id: $displayId")
+ return null
+ }
return cachedIcons.computeIfAbsent(key) {
val context = displayWindowProperties.context
iconManager.createSbIconView(context, entry)
@@ -93,4 +101,8 @@ constructor(
interface Factory {
fun create(displayId: Int): ConnectedDisplaysStatusBarNotificationIconViewStore
}
+
+ companion object {
+ private const val TAG = "ConnectedDisplaysNotifIconViewStore"
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index b0773276a3e9..4ed9dcee072e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -16,8 +16,10 @@
package com.android.systemui.statusbar.notification.row;
+import static com.android.systemui.Flags.notificationAppearNonlinear;
import static com.android.systemui.Flags.notificationBackgroundTintOptimization;
import static com.android.systemui.Flags.notificationRowTransparency;
+import static com.android.systemui.Flags.physicalNotificationMovement;
import static com.android.systemui.statusbar.notification.row.ExpandableView.ClipSide.BOTTOM;
import static com.android.systemui.statusbar.notification.row.ExpandableView.ClipSide.TOP;
@@ -71,7 +73,8 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
* #ALPHA_APPEAR_START_FRACTION.
*/
- private static final float ALPHA_APPEAR_START_FRACTION = .7f;
+ private static final float ALPHA_APPEAR_START_FRACTION =
+ notificationAppearNonlinear() ? .55f : .7f;
/**
* The content should show fully with progress at #ALPHA_APPEAR_END_FRACTION
* The start of the animation is at #ALPHA_APPEAR_START_FRACTION
@@ -111,6 +114,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
private float mOverrideAmount;
private boolean mShadowHidden;
private boolean mIsHeadsUpAnimation;
+ private boolean mIsHeadsUpCycling;
/* In order to track headsup longpress coorindate. */
protected Point mTargetPoint;
private boolean mDismissed;
@@ -349,10 +353,12 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
@Override
public long performRemoveAnimation(long duration, long delay, float translationDirection,
- boolean isHeadsUpAnimation, Runnable onStartedRunnable, Runnable onFinishedRunnable,
- AnimatorListenerAdapter animationListener, ClipSide clipSide) {
+ boolean isHeadsUpAnimation, boolean isHeadsUpCycling, Runnable onStartedRunnable,
+ Runnable onFinishedRunnable, AnimatorListenerAdapter animationListener,
+ ClipSide clipSide) {
enableAppearDrawing(true);
mIsHeadsUpAnimation = isHeadsUpAnimation;
+ mIsHeadsUpCycling = isHeadsUpCycling;
if (mDrawingAppearAnimation) {
startAppearAnimation(false /* isAppearing */, translationDirection,
delay, duration, onStartedRunnable, onFinishedRunnable, animationListener,
@@ -370,9 +376,10 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
@Override
public void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear,
- Runnable onFinishRunnable) {
+ boolean isHeadsUpCycling, Runnable onFinishRunnable) {
enableAppearDrawing(true);
mIsHeadsUpAnimation = isHeadsUpAppear;
+ mIsHeadsUpCycling = isHeadsUpCycling;
if (mDrawingAppearAnimation) {
startAppearAnimation(true /* isAppearing */, isHeadsUpAppear ? 0.0f : -1.0f, delay,
duration, null, null, null, ClipSide.BOTTOM);
@@ -404,14 +411,14 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
targetValue = 0.0f;
}
- if (NotificationHeadsUpCycling.isEnabled()) {
- // TODO(b/316404716): add avalanche filtering
+ if (NotificationHeadsUpCycling.isEnabled() && !useNonLinearAnimation()) {
mCurrentAppearInterpolator = Interpolators.LINEAR;
}
mAppearAnimator = ValueAnimator.ofFloat(mAppearAnimationFraction,
targetValue);
- mAppearAnimator.setInterpolator(mCurrentAppearInterpolator);
+ mAppearAnimator.setInterpolator(
+ useNonLinearAnimation() ? Interpolators.LINEAR : mCurrentAppearInterpolator);
mAppearAnimator.setDuration(
(long) (duration * Math.abs(mAppearAnimationFraction - targetValue)));
mAppearAnimator.addUpdateListener(animation -> {
@@ -530,7 +537,13 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
* @param clipSide Which side if view we want to clip from
*/
private void updateAppearRect(ClipSide clipSide) {
- float interpolatedFraction = mAppearAnimationFraction;
+ float interpolatedFraction;
+ if (useNonLinearAnimation()) {
+ interpolatedFraction = mCurrentAppearInterpolator.getInterpolation(
+ mAppearAnimationFraction);
+ } else {
+ interpolatedFraction = mAppearAnimationFraction;
+ }
mAppearAnimationTranslation = (1.0f - interpolatedFraction) * mAnimationTranslationY;
final int fullHeight = getActualHeight();
float height = fullHeight * interpolatedFraction;
@@ -558,6 +571,11 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
}
}
+ private boolean useNonLinearAnimation() {
+ return notificationAppearNonlinear() && (!mIsHeadsUpCycling
+ || physicalNotificationMovement());
+ }
+
private void updateAppearRect() {
updateAppearRect(ClipSide.BOTTOM);
}
@@ -567,7 +585,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
mAppearAnimationFraction,
ALPHA_APPEAR_START_FRACTION,
ALPHA_APPEAR_END_FRACTION,
- Interpolators.ALPHA_IN
+ notificationAppearNonlinear() ? mCurrentAppearInterpolator : Interpolators.ALPHA_IN
);
}
@@ -813,6 +831,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
pw.print("mDrawingAppearAnimation", mDrawingAppearAnimation);
pw.print("mAppearAnimationFraction", mAppearAnimationFraction);
pw.print("mIsHeadsUpAnimation", mIsHeadsUpAnimation);
+ pw.print("mIsHeadsUpCycling", mIsHeadsUpCycling);
pw.print("mTargetPoint", mTargetPoint);
pw.println();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index d2800d7c1b71..4c744086fea4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -3494,20 +3494,17 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
@Override
public void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear,
- Runnable onFinishRunnable) {
+ boolean isHeadsUpCycling, Runnable onFinishRunnable) {
mLogger.logStartAppearAnimation(mLoggingKey, /* isAppear = */ true);
- super.performAddAnimation(delay, duration, isHeadsUpAppear, onFinishRunnable);
+ super.performAddAnimation(delay, duration, isHeadsUpAppear, isHeadsUpCycling,
+ onFinishRunnable);
}
@Override
- public long performRemoveAnimation(
- long duration,
- long delay,
- float translationDirection,
- boolean isHeadsUpAnimation,
- Runnable onStartedRunnable,
- Runnable onFinishedRunnable,
- AnimatorListenerAdapter animationListener, ClipSide clipSide) {
+ public long performRemoveAnimation(long duration, long delay, float translationDirection,
+ boolean isHeadsUpAnimation, boolean isHeadsUpCycling, Runnable onStartedRunnable,
+ Runnable onFinishedRunnable, AnimatorListenerAdapter animationListener,
+ ClipSide clipSide) {
mLogger.logStartAppearAnimation(mLoggingKey, /* isAppear = */ false);
if (mMenuRow != null && mMenuRow.isMenuVisible()) {
Animator anim = getTranslateViewAnimator(0f, null /* listener */);
@@ -3522,9 +3519,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
@Override
public void onAnimationEnd(Animator animation) {
- ExpandableNotificationRow.super.performRemoveAnimation(
- duration, delay, translationDirection, isHeadsUpAnimation,
- null, onFinishedRunnable, animationListener, ClipSide.BOTTOM);
+ ExpandableNotificationRow.super.performRemoveAnimation(duration, delay,
+ translationDirection, isHeadsUpAnimation, isHeadsUpCycling, null,
+ onFinishedRunnable, animationListener, ClipSide.BOTTOM);
}
});
anim.start();
@@ -3532,8 +3529,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
}
return super.performRemoveAnimation(duration, delay, translationDirection,
- isHeadsUpAnimation, onStartedRunnable, onFinishedRunnable, animationListener,
- clipSide);
+ isHeadsUpAnimation, isHeadsUpCycling, onStartedRunnable, onFinishedRunnable,
+ animationListener, clipSide);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index da664f864f06..292f74a65554 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -467,7 +467,8 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable, Ro
* remove animation should be performed upwards,
* such that the child appears to be going away to the top. 1
* Should mean the opposite.
- * @param isHeadsUpAnimation Is this a headsUp animation.
+ * @param isHeadsUpAnimation Is this a headsUp animation
+ * @param isHeadsUpCycling Is this the cycling heads up animation
* @param onFinishedRunnable A runnable which should be run when the animation is finished.
* @param animationListener An animation listener to add to the animation.
* @return The additional delay, in milliseconds, that this view needs to add before the
@@ -475,7 +476,7 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable, Ro
*/
public abstract long performRemoveAnimation(long duration,
long delay, float translationDirection, boolean isHeadsUpAnimation,
- Runnable onStartedRunnable,
+ boolean isHeadsUpCycling, Runnable onStartedRunnable,
Runnable onFinishedRunnable,
AnimatorListenerAdapter animationListener, ClipSide clipSide);
@@ -485,11 +486,12 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable, Ro
}
public void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear) {
- performAddAnimation(delay, duration, isHeadsUpAppear, null);
+ performAddAnimation(delay, duration, isHeadsUpAppear, false /* isHeadsUpCycling */,
+ null);
}
public abstract void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear,
- Runnable onEndRunnable);
+ boolean isHeadsUpCycling, Runnable onEndRunnable);
public int getPinnedHeadsUpHeight() {
return getIntrinsicHeight();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
index c31f4ad5c3f1..4b2b1688bde6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
@@ -998,6 +998,10 @@ public class NotificationContentInflater implements NotificationRowContentBinder
entry.setPromotedNotificationContentModel(result.mPromotedContent);
}
+ if (PromotedNotificationUiForceExpanded.isEnabled()) {
+ row.setPromotedOngoing(entry.isOngoingPromoted());
+ }
+
boolean setRepliesAndActions = true;
if ((reInflateFlags & FLAG_CONTENT_VIEW_CONTRACTED) != 0) {
if (result.inflatedContentView != null) {
@@ -1130,9 +1134,6 @@ public class NotificationContentInflater implements NotificationRowContentBinder
entry.setHeadsUpStatusBarText(result.headsUpStatusBarText);
entry.setHeadsUpStatusBarTextPublic(result.headsUpStatusBarTextPublic);
- if (PromotedNotificationUiForceExpanded.isEnabled()) {
- row.setPromotedOngoing(entry.isOngoingPromoted());
- }
Trace.endAsyncSection(APPLY_TRACE_METHOD, System.identityHashCode(row));
if (endListener != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java
index cd228e7872c1..a064d1c5b701 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java
@@ -260,7 +260,7 @@ public abstract class StackScrollerDecorView extends ExpandableView {
@Override
public long performRemoveAnimation(long duration, long delay,
float translationDirection, boolean isHeadsUpAnimation,
- Runnable onStartedRunnable,
+ boolean isHeadsUpCycling, Runnable onStartedRunnable,
Runnable onFinishedRunnable,
AnimatorListenerAdapter animationListener, ClipSide clipSide) {
// TODO: Use duration
@@ -279,7 +279,7 @@ public abstract class StackScrollerDecorView extends ExpandableView {
@Override
public void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear,
- Runnable endRunnable) {
+ boolean isHeadsUpCycling, Runnable endRunnable) {
// TODO: use delay and duration
setContentVisibleAnimated(true);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
index e8affaa4b60f..e9eecdd8a26f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
@@ -31,7 +31,6 @@ import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
import android.widget.DateTimeView;
-import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
@@ -42,7 +41,6 @@ import com.android.app.animation.Interpolators;
import com.android.internal.widget.CachingIconView;
import com.android.internal.widget.NotificationCloseButton;
import com.android.internal.widget.NotificationExpandButton;
-import com.android.systemui.Flags;
import com.android.systemui.res.R;
import com.android.systemui.statusbar.TransformableView;
import com.android.systemui.statusbar.ViewTransformationHelper;
@@ -69,7 +67,6 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper imple
private CachingIconView mIcon;
private NotificationCloseButton mCloseButton;
private NotificationExpandButton mExpandButton;
- private FrameLayout mExpandButtonSpacer;
private View mAltExpandTarget;
private View mIconContainer;
protected NotificationHeaderView mNotificationHeader;
@@ -157,10 +154,6 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper imple
mHeaderText = mView.findViewById(com.android.internal.R.id.header_text);
mAppNameText = mView.findViewById(com.android.internal.R.id.app_name_text);
mExpandButton = mView.findViewById(com.android.internal.R.id.expand_button);
- if (Flags.uiRichOngoingForceExpanded()) {
- mExpandButtonSpacer =
- mView.findViewById(com.android.internal.R.id.expand_button_spacer);
- }
mAltExpandTarget = mView.findViewById(com.android.internal.R.id.alternate_expand_target);
mIconContainer = mView.findViewById(com.android.internal.R.id.conversation_icon_container);
mWorkProfileImage = mView.findViewById(com.android.internal.R.id.profile_badge);
@@ -302,9 +295,6 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper imple
boolean expandable,
View.OnClickListener onClickListener,
boolean requestLayout) {
- if (Flags.uiRichOngoingForceExpanded() && mExpandButtonSpacer != null) {
- mExpandButtonSpacer.setVisibility(expandable ? GONE : VISIBLE);
- }
mExpandButton.setVisibility(expandable ? VISIBLE : GONE);
mExpandButton.setOnClickListener(expandable ? onClickListener : null);
if (mAltExpandTarget != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
index 3ccf5063cd68..b9aa57145c7c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
@@ -33,6 +33,7 @@ import android.graphics.drawable.Icon;
import android.service.notification.StatusBarNotification;
import android.util.ArraySet;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
@@ -42,6 +43,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ContrastColorUtil;
import com.android.internal.widget.NotificationActionListLayout;
import com.android.systemui.Dependency;
+import com.android.systemui.Flags;
import com.android.systemui.UiOffloadThread;
import com.android.systemui.res.R;
import com.android.systemui.statusbar.CrossFadeHelper;
@@ -51,6 +53,7 @@ import com.android.systemui.statusbar.notification.ImageTransformState;
import com.android.systemui.statusbar.notification.TransformState;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.HybridNotificationView;
+import com.android.systemui.util.DimensionKt;
import java.util.function.Consumer;
@@ -186,9 +189,43 @@ public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapp
mActions = mView.findViewById(com.android.internal.R.id.actions);
mRemoteInputHistory = mView.findViewById(
com.android.internal.R.id.notification_material_reply_container);
+
+ adjustTitleAndRightIconForPromotedOngoing();
updatePendingIntentCancellations();
}
+ private void adjustTitleAndRightIconForPromotedOngoing() {
+ if (Flags.uiRichOngoingForceExpanded() && mRow.isPromotedOngoing() && mRightIcon != null) {
+ final int horizontalMargin;
+ if (notificationsRedesignTemplates()) {
+ horizontalMargin = mView.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.notification_2025_margin);
+ } else {
+ horizontalMargin = (int) DimensionKt.dpToPx(16, mView.getContext());
+ }
+
+ // position right icon to the right available space from expander.
+ final ViewGroup.MarginLayoutParams rightIconLP =
+ (ViewGroup.MarginLayoutParams) mRightIcon.getLayoutParams();
+ rightIconLP.setMarginEnd(horizontalMargin);
+ mRightIcon.setLayoutParams(rightIconLP);
+
+ // align top line view to start of the right icon.
+ final int iconSize = mView.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.notification_right_icon_size);
+ final int marginEnd = 2 * horizontalMargin + iconSize;
+ mNotificationTopLine.setHeaderTextMarginEnd(marginEnd);
+
+ // title has too much margin on the right, so we need to reduce it
+ if (mTitle != null) {
+ final ViewGroup.MarginLayoutParams titleLP =
+ (ViewGroup.MarginLayoutParams) mTitle.getLayoutParams();
+ titleLP.setMarginEnd(marginEnd);
+ mTitle.setLayoutParams(titleLP);
+ }
+ }
+ }
+
@Nullable
protected final Icon getLargeIcon(Notification n) {
Icon modernLargeIcon = n.getLargeIcon();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaContainerView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaContainerView.kt
index bd7bd596438a..4d10a527d53b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaContainerView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaContainerView.kt
@@ -70,14 +70,15 @@ class MediaContainerView(context: Context, attrs: AttributeSet?) : ExpandableVie
}
override fun performRemoveAnimation(
- duration: Long,
- delay: Long,
- translationDirection: Float,
- isHeadsUpAnimation: Boolean,
- onStartedRunnable: Runnable?,
- onFinishedRunnable: Runnable?,
- animationListener: AnimatorListenerAdapter?,
- clipSide: ClipSide
+ duration: Long,
+ delay: Long,
+ translationDirection: Float,
+ isHeadsUpAnimation: Boolean,
+ isHeadsUpCycling: Boolean,
+ onStartedRunnable: Runnable?,
+ onFinishedRunnable: Runnable?,
+ animationListener: AnimatorListenerAdapter?,
+ clipSide: ClipSide,
): Long {
return 0
}
@@ -86,7 +87,8 @@ class MediaContainerView(context: Context, attrs: AttributeSet?) : ExpandableVie
delay: Long,
duration: Long,
isHeadsUpAppear: Boolean,
- onEnd: Runnable?
+ isHeadsUpCycling: Boolean,
+ onEnd: Runnable?,
) {
// No animation, it doesn't need it, this would be local
}
@@ -103,9 +105,7 @@ class MediaContainerView(context: Context, attrs: AttributeSet?) : ExpandableVie
assertMediaContainerVisibility(visibility)
}
- /**
- * visibility should be aligned with MediaContainerView visibility on the keyguard.
- */
+ /** visibility should be aligned with MediaContainerView visibility on the keyguard. */
private fun isVisibilityValid(visibility: Int): Boolean {
val currentViewState = viewState as? MediaContainerViewState ?: return true
val shouldBeGone = !currentViewState.shouldBeVisible
@@ -113,8 +113,7 @@ class MediaContainerView(context: Context, attrs: AttributeSet?) : ExpandableVie
}
/**
- * b/298213983
- * MediaContainerView's visibility is changed to VISIBLE when it should be GONE.
+ * b/298213983 MediaContainerView's visibility is changed to VISIBLE when it should be GONE.
* This method check this state and logs.
*/
private fun assertMediaContainerVisibility(visibility: Int) {
@@ -122,8 +121,10 @@ class MediaContainerView(context: Context, attrs: AttributeSet?) : ExpandableVie
if (currentViewState is MediaContainerViewState) {
if (!currentViewState.shouldBeVisible && visibility == VISIBLE) {
- Log.wtf("MediaContainerView", "MediaContainerView should be GONE " +
- "but its visibility changed to VISIBLE")
+ Log.wtf(
+ "MediaContainerView",
+ "MediaContainerView should be GONE " + "but its visibility changed to VISIBLE",
+ )
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
index 5e0d57ebb3fe..2b052236a921 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
@@ -506,8 +506,8 @@ public class StackStateAnimator {
}
changingView.performRemoveAnimation(ANIMATION_DURATION_APPEAR_DISAPPEAR,
0 /* delay */, translationDirection, false /* isHeadsUpAppear */,
- startAnimation, postAnimation, getGlobalAnimationFinishedListener(),
- ExpandableView.ClipSide.BOTTOM);
+ false /* isHeadsUpCycling */, startAnimation, postAnimation,
+ getGlobalAnimationFinishedListener(), ExpandableView.ClipSide.BOTTOM);
needsCustomAnimation = true;
} else if (event.animationType ==
NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_REMOVE_SWIPED_OUT) {
@@ -538,7 +538,7 @@ public class StackStateAnimator {
};
}
changingView.performAddAnimation(0, ANIMATION_DURATION_HEADS_UP_CYCLING,
- /* isHeadsUpAppear= */ true, onAnimationEnd);
+ /* isHeadsUpAppear= */ true, /* isHeadsUpCycling= */ true, onAnimationEnd);
} else if (event.animationType == ANIMATION_TYPE_HEADS_UP_APPEAR) {
mHeadsUpAppearChildren.add(changingView);
@@ -559,7 +559,7 @@ public class StackStateAnimator {
onAnimationEnd = () -> mLogger.appearAnimationEnded(finalKey);
}
changingView.performAddAnimation(0, ANIMATION_DURATION_HEADS_UP_APPEAR,
- /* isHeadsUpAppear= */ true, onAnimationEnd);
+ /* isHeadsUpAppear= */ true, /* isHeadsUpCycling= */ false, onAnimationEnd);
} else if (event.animationType == ANIMATION_TYPE_HEADS_UP_CYCLING_OUT) {
mHeadsUpDisappearChildren.add(changingView);
Runnable endRunnable = null;
@@ -629,6 +629,7 @@ public class StackStateAnimator {
// translation, the actual translation is in StackScrollAlgorithm.
/* translationDirection= */ 0.0f,
/* isHeadsUpAnimation= */ true,
+ /* isHeadsUpCycling= */ true,
startAnimation, postAnimation,
getGlobalAnimationFinishedListener(), ExpandableView.ClipSide.TOP);
mAnimationProperties.delay += removeAnimationDelay;
@@ -706,6 +707,7 @@ public class StackStateAnimator {
long removeAnimationDelay = changingView.performRemoveAnimation(
ANIMATION_DURATION_HEADS_UP_DISAPPEAR,
0, 0.0f, true /* isHeadsUpAppear */,
+ false /* isHeadsUpCycling */,
startAnimation, postAnimation,
getGlobalAnimationFinishedListener(), ExpandableView.ClipSide.BOTTOM);
mAnimationProperties.delay += removeAnimationDelay;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
index 08d98a1d53e5..1dbaf2f0f401 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
@@ -147,7 +147,7 @@ constructor(
sceneInteractor.transitionState.map { transition: ObservableTransitionState ->
transition is Transition &&
transition.fromContent == Scenes.Lockscreen &&
- (transition.toContent == Scenes.Bouncer || transition.toContent == Scenes.Gone)
+ (transition.toContent == Overlays.Bouncer || transition.toContent == Scenes.Gone)
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
index 34b65603542c..877aa76590e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
@@ -76,6 +76,7 @@ import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToLockscreenTran
import com.android.systemui.keyguard.ui.viewmodel.ViewStateAccessor
import com.android.systemui.res.R
import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.LargeScreenHeaderHelper
import com.android.systemui.shade.ShadeDisplayAware
@@ -307,7 +308,7 @@ constructor(
keyguardTransitionInteractor.transitionValue(ALTERNATE_BOUNCER).map { it > 0f },
keyguardTransitionInteractor
.transitionValue(
- scene = Scenes.Bouncer,
+ content = Overlays.Bouncer,
stateWithoutSceneContainer = PRIMARY_BOUNCER,
)
.map { it > 0f },
@@ -361,7 +362,7 @@ constructor(
private val isOnGlanceableHub: Flow<Boolean> =
combine(
keyguardTransitionInteractor.isFinishedIn(
- scene = Scenes.Communal,
+ content = Scenes.Communal,
stateWithoutSceneContainer = GLANCEABLE_HUB,
),
anyOf(
@@ -638,7 +639,7 @@ constructor(
anyOf(
isKeyguardOccluded,
keyguardTransitionInteractor
- .transitionValue(scene = Scenes.Gone, stateWithoutSceneContainer = GONE)
+ .transitionValue(content = Scenes.Gone, stateWithoutSceneContainer = GONE)
.map { it == 1f },
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index bc297699c41a..8c44fe56d269 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -84,7 +84,7 @@ import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
-import com.android.systemui.scene.shared.model.Scenes;
+import com.android.systemui.scene.shared.model.Overlays;
import com.android.systemui.shade.ShadeController;
import com.android.systemui.shade.ShadeExpansionChangeEvent;
import com.android.systemui.shade.ShadeExpansionListener;
@@ -724,8 +724,10 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
if (!primaryBouncerIsShowing()) {
if (SceneContainerFlag.isEnabled()) {
mCentralSurfaces.hideKeyguard();
- mSceneInteractorLazy.get().changeScene(
- Scenes.Bouncer, "StatusBarKeyguardViewManager.showBouncerOrKeyguard");
+ mSceneInteractorLazy.get().showOverlay(
+ Overlays.Bouncer,
+ "StatusBarKeyguardViewManager.showBouncerOrKeyguard"
+ );
} else {
if (Flags.simPinRaceConditionOnRestart()) {
if (mPrimaryBouncerInteractor.show(/* isScrimmed= */ true)) {
@@ -816,8 +818,8 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
/* clearDismissAction= */ !SceneContainerFlag.isEnabled());
if (mKeyguardStateController.isShowing() && !isBouncerShowing()) {
if (SceneContainerFlag.isEnabled()) {
- mSceneInteractorLazy.get().changeScene(
- Scenes.Bouncer,
+ mSceneInteractorLazy.get().showOverlay(
+ Overlays.Bouncer,
"primary bouncer requested"
);
} else {
@@ -915,8 +917,10 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
// we'll handle the dismiss action after keyguard is gone, so just show the
// bouncer
if (SceneContainerFlag.isEnabled()) {
- mSceneInteractorLazy.get().changeScene(
- Scenes.Bouncer, "StatusBarKeyguardViewManager.dismissWithAction");
+ mSceneInteractorLazy.get().showOverlay(
+ Overlays.Bouncer,
+ "StatusBarKeyguardViewManager.dismissWithAction"
+ );
} else {
mPrimaryBouncerInteractor.show(/* isScrimmed= */ true);
}
@@ -926,8 +930,10 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
mPrimaryBouncerInteractor.setDismissAction(
mAfterKeyguardGoneAction, mKeyguardGoneCancelAction);
if (SceneContainerFlag.isEnabled()) {
- mSceneInteractorLazy.get().changeScene(
- Scenes.Bouncer, "StatusBarKeyguardViewManager.dismissWithAction");
+ mSceneInteractorLazy.get().showOverlay(
+ Overlays.Bouncer,
+ "StatusBarKeyguardViewManager.dismissWithAction"
+ );
} else {
mPrimaryBouncerInteractor.show(/* isScrimmed= */ true);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
index 39a1b46292b0..4189221d8a83 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
@@ -37,6 +37,10 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.theme.PlatformTheme
import com.android.keyguard.AlphaOptimizedLinearLayout
import com.android.systemui.lifecycle.rememberViewModel
+import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager
+import com.android.systemui.media.controls.ui.view.MediaHost
+import com.android.systemui.media.controls.ui.view.MediaHostState
+import com.android.systemui.media.dagger.MediaModule.POPUP
import com.android.systemui.plugins.DarkIconDispatcher
import com.android.systemui.res.R
import com.android.systemui.statusbar.chips.ui.compose.OngoingActivityChips
@@ -67,6 +71,7 @@ import com.android.systemui.statusbar.pipeline.shared.ui.model.VisibilityModel
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel.HomeStatusBarViewModelFactory
import javax.inject.Inject
+import javax.inject.Named
/** Factory to simplify the dependency management for [StatusBarRoot] */
class StatusBarRootFactory
@@ -81,6 +86,8 @@ constructor(
private val ongoingCallController: OngoingCallController,
private val darkIconDispatcherStore: DarkIconDispatcherStore,
private val eventAnimationInteractor: SystemStatusEventAnimationInteractor,
+ private val mediaHierarchyManager: MediaHierarchyManager,
+ @Named(POPUP) private val mediaHost: MediaHost,
) {
fun create(root: ViewGroup, andThen: (ViewGroup) -> Unit): ComposeView {
val composeView = ComposeView(root.context)
@@ -99,6 +106,8 @@ constructor(
ongoingCallController = ongoingCallController,
darkIconDispatcher = darkIconDispatcher,
eventAnimationInteractor = eventAnimationInteractor,
+ mediaHierarchyManager = mediaHierarchyManager,
+ mediaHost = mediaHost,
onViewCreated = andThen,
)
}
@@ -130,6 +139,8 @@ fun StatusBarRoot(
ongoingCallController: OngoingCallController,
darkIconDispatcher: DarkIconDispatcher,
eventAnimationInteractor: SystemStatusEventAnimationInteractor,
+ mediaHierarchyManager: MediaHierarchyManager,
+ mediaHost: MediaHost,
onViewCreated: (ViewGroup) -> Unit,
) {
val displayId = parent.context.displayId
@@ -237,6 +248,15 @@ fun StatusBarRoot(
// Add a composable container for `StatusBarPopupChip`s
if (StatusBarPopupChips.isEnabled) {
+ with(mediaHost) {
+ expansion = MediaHostState.EXPANDED
+ expandedMatchesParentHeight = true
+ showsOnlyActiveMedia = true
+ falsingProtectionNeeded = false
+ disablePagination = true
+ init(MediaHierarchyManager.LOCATION_STATUS_BAR_POPUP)
+ }
+
val endSideContent =
phoneStatusBarView.requireViewById<AlphaOptimizedLinearLayout>(
R.id.status_bar_end_side_content
@@ -256,7 +276,12 @@ fun StatusBarRoot(
setContent {
StatusBarPopupChipsContainer(
- chips = statusBarViewModel.popupChips
+ chips = statusBarViewModel.popupChips,
+ mediaHost = mediaHost,
+ onMediaControlPopupVisibilityChanged = { popupShowing ->
+ mediaHierarchyManager.isMediaControlPopupShowing =
+ popupShowing
+ },
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt
index 7d9a7d49cf7f..2dc17f40a380 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt
@@ -78,6 +78,7 @@ constructor(
currentScene == Scenes.Lockscreen &&
Overlays.NotificationsShade !in currentOverlays &&
Overlays.QuickSettingsShade !in currentOverlays &&
+ Overlays.Bouncer !in currentOverlays &&
!isDozing &&
!showHeadsUpStatusBar
}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt
index d8a9527b22ab..d2f1d3cb7b47 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt
@@ -133,14 +133,14 @@ private class ScreensProvider(
override fun BackGesture(
onDoneButtonClicked: () -> Unit,
onBack: () -> Unit,
- isAutoProceed: Boolean,
+ onAutoProceed: (suspend () -> Unit)?,
) {
BackGestureTutorialScreen(
backGestureScreenViewModel,
easterEggGestureViewModel,
onDoneButtonClicked,
onBack,
- isAutoProceed,
+ onAutoProceed,
)
}
@@ -148,14 +148,14 @@ private class ScreensProvider(
override fun HomeGesture(
onDoneButtonClicked: () -> Unit,
onBack: () -> Unit,
- isAutoProceed: Boolean,
+ onAutoProceed: (suspend () -> Unit)?,
) {
HomeGestureTutorialScreen(
homeGestureScreenViewModel,
easterEggGestureViewModel,
onDoneButtonClicked,
onBack,
- isAutoProceed,
+ onAutoProceed,
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt
index c28483c55952..2e2a97d9702f 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt
@@ -33,7 +33,7 @@ fun BackGestureTutorialScreen(
easterEggGestureViewModel: EasterEggGestureViewModel,
onDoneButtonClicked: () -> Unit,
onBack: () -> Unit,
- isAutoProceed: Boolean = false,
+ onAutoProceed: (suspend () -> Unit)? = null,
) {
val screenConfig =
TutorialScreenConfig(
@@ -48,7 +48,6 @@ fun BackGestureTutorialScreen(
bodyErrorResId = R.string.touchpad_back_gesture_error_body,
),
animations = TutorialScreenConfig.Animations(educationResId = R.raw.trackpad_back_edu),
- hasNextButton = isAutoProceed,
)
GestureTutorialScreen(
screenConfig = screenConfig,
@@ -61,6 +60,7 @@ fun BackGestureTutorialScreen(
onEasterEggFinished = easterEggGestureViewModel::onEasterEggFinished,
onDoneButtonClicked = onDoneButtonClicked,
onBack = onBack,
+ onAutoProceed = onAutoProceed,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt
index 47c82e309d9b..db3e31ba2e61 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt
@@ -49,6 +49,7 @@ fun GestureTutorialScreen(
onEasterEggFinished: () -> Unit,
onDoneButtonClicked: () -> Unit,
onBack: () -> Unit,
+ onAutoProceed: (suspend () -> Unit)? = null,
) {
BackHandler(onBack = onBack)
var cachedTutorialState: TutorialActionState by
@@ -64,7 +65,7 @@ fun GestureTutorialScreen(
easterEggTriggered,
onEasterEggFinished,
) {
- ActionTutorialContent(tutorialState, onDoneButtonClicked, screenConfig)
+ ActionTutorialContent(tutorialState, onDoneButtonClicked, screenConfig, onAutoProceed)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt
index b238a8db31f8..3e27dfb07624 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt
@@ -32,7 +32,7 @@ fun HomeGestureTutorialScreen(
easterEggGestureViewModel: EasterEggGestureViewModel,
onDoneButtonClicked: () -> Unit,
onBack: () -> Unit,
- isAutoProceed: Boolean = false,
+ onAutoProceed: (suspend () -> Unit)? = null,
) {
val screenConfig =
TutorialScreenConfig(
@@ -47,7 +47,6 @@ fun HomeGestureTutorialScreen(
bodyErrorResId = R.string.touchpad_home_gesture_error_body,
),
animations = TutorialScreenConfig.Animations(educationResId = R.raw.trackpad_home_edu),
- hasNextButton = isAutoProceed,
)
GestureTutorialScreen(
screenConfig = screenConfig,
@@ -60,6 +59,7 @@ fun HomeGestureTutorialScreen(
onEasterEggFinished = easterEggGestureViewModel::onEasterEggFinished,
onDoneButtonClicked = onDoneButtonClicked,
onBack = onBack,
+ onAutoProceed = onAutoProceed,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt
index 0bdf99e49b1b..14eede6f6816 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt
@@ -24,6 +24,7 @@ import android.widget.ImageButton
import androidx.annotation.LayoutRes
import androidx.compose.ui.util.fastForEachIndexed
import androidx.constraintlayout.motion.widget.MotionLayout
+import androidx.constraintlayout.motion.widget.MotionScene
import androidx.dynamicanimation.animation.FloatValueHolder
import androidx.dynamicanimation.animation.SpringAnimation
import androidx.dynamicanimation.animation.SpringForce
@@ -47,6 +48,7 @@ import com.android.systemui.volume.dialog.ui.viewmodel.VolumeDialogViewModel
import javax.inject.Inject
import kotlin.properties.Delegates
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.mapLatest
@@ -55,6 +57,7 @@ private const val CLOSE_DRAWER_DELAY = 300L
// Ensure roundness and color of button is updated when progress is changed by a minimum fraction.
private const val BUTTON_MIN_VISIBLE_CHANGE = 0.05F
+@OptIn(ExperimentalCoroutinesApi::class)
@VolumeDialogScope
class VolumeDialogRingerViewBinder
@Inject
@@ -208,6 +211,13 @@ constructor(
ringerState.orientation,
ringerBackgroundView,
)
+ drawerContainer
+ .getTransition(R.id.close_to_open_transition)
+ .setInterpolatorInfo(
+ MotionScene.Transition.INTERPOLATE_REFERENCE_ID,
+ null,
+ R.anim.volume_dialog_ringer_open,
+ )
drawerContainer.transitionToState(
R.id.volume_dialog_ringer_drawer_open
)
@@ -370,6 +380,12 @@ constructor(
orientation: Int,
) {
setTransition(R.id.close_to_open_transition)
+ getTransition(R.id.close_to_open_transition)
+ .setInterpolatorInfo(
+ MotionScene.Transition.INTERPOLATE_REFERENCE_ID,
+ null,
+ R.anim.volume_dialog_ringer_close,
+ )
updateCloseState(this, selectedIndex, orientation, ringerBackground)
transitionToState(R.id.volume_dialog_ringer_drawer_close)
}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
index e76401528ff6..b23efcea1c2c 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
@@ -23,6 +23,7 @@ import static android.service.notification.NotificationListenerService.REASON_AP
import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL_ALL;
import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED;
import static android.service.notification.NotificationListenerService.REASON_PACKAGE_BANNED;
+import static android.service.notification.NotificationListenerService.REASON_PACKAGE_CHANGED;
import static android.service.notification.NotificationStats.DISMISSAL_BUBBLE;
import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
@@ -451,7 +452,8 @@ public class BubblesManager {
public void onEntryRemoved(NotificationEntry entry,
@NotifCollection.CancellationReason int reason) {
if (reason == REASON_APP_CANCEL || reason == REASON_APP_CANCEL_ALL
- || reason == REASON_PACKAGE_BANNED) {
+ || reason == REASON_PACKAGE_BANNED
+ || reason == REASON_PACKAGE_CHANGED) {
BubblesManager.this.onEntryRemoved(entry);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index e2cfbc6f764c..a42f5d3f67ea 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -65,6 +65,8 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static java.util.Collections.emptySet;
+
import android.app.Activity;
import android.app.ActivityTaskManager;
import android.app.IActivityTaskManager;
@@ -155,6 +157,7 @@ import com.android.systemui.log.SessionTracker;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
+import com.android.systemui.scene.shared.model.Overlays;
import com.android.systemui.scene.shared.model.Scenes;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shared.system.TaskStackChangeListener;
@@ -190,6 +193,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Random;
+import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@@ -2775,7 +2779,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
private void setPrimaryBouncerVisibility(boolean isVisible) {
if (SceneContainerFlag.isEnabled()) {
ObservableTransitionState transitionState = new ObservableTransitionState.Idle(
- isVisible ? Scenes.Bouncer : Scenes.Lockscreen);
+ Scenes.Lockscreen, isVisible ? Set.of(Overlays.Bouncer) : emptySet());
when(mSceneInteractor.getTransitionState()).thenReturn(
MutableStateFlow(transitionState));
onTransitionStateChanged(transitionState);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/composable/BouncerContentTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/composable/BouncerContentTest.kt
index 1320223cabf3..4e08596adc21 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/composable/BouncerContentTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/composable/BouncerContentTest.kt
@@ -33,7 +33,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.bouncer.ui.BouncerDialogFactory
-import com.android.systemui.bouncer.ui.viewmodel.bouncerSceneContentViewModelFactory
+import com.android.systemui.bouncer.ui.viewmodel.bouncerOverlayContentViewModelFactory
import com.android.systemui.flags.Flags
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.lifecycle.rememberViewModel
@@ -98,9 +98,9 @@ class BouncerContentTest : SysuiTestCase() {
BouncerContent(
viewModel =
rememberViewModel("test") {
- kosmos.bouncerSceneContentViewModelFactory.create()
+ kosmos.bouncerOverlayContentViewModelFactory.create()
},
- layout = BouncerSceneLayout.BESIDE_USER_SWITCHER,
+ layout = BouncerOverlayLayout.BESIDE_USER_SWITCHER,
modifier = Modifier.fillMaxSize().testTag("BouncerContent"),
dialogFactory = bouncerDialogFactory,
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt
index aaf5559290df..58bae308bcdf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt
@@ -881,8 +881,15 @@ class MediaCarouselControllerTest(flags: FlagsParameterization) : SysuiTestCase(
var updatedVisibility = false
mediaCarouselController.updateHostVisibility = { updatedVisibility = true }
mediaCarouselController.mediaCarousel = mediaCarousel
+ kosmos.sceneInteractor.snapToScene(Scenes.Lockscreen, "")
+ kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+ SuccessFingerprintAuthenticationStatus(0, true)
+ )
+ runCurrent()
val job = mediaCarouselController.listenForAnyStateToGoneKeyguardTransition(this)
+
+ kosmos.sceneInteractor.changeScene(Scenes.Gone, "")
kosmos.setSceneTransition(Idle(Scenes.Gone))
verify(mediaCarousel).visibility = View.VISIBLE
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt
index 6ca4ae2d2259..14b14126b7f6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt
@@ -17,6 +17,7 @@
package com.android.systemui.media.controls.ui.controller
import android.graphics.Rect
+import android.platform.test.annotations.EnableFlags
import android.provider.Settings
import android.testing.TestableLooper
import android.view.ViewGroup
@@ -36,7 +37,6 @@ import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.data.repository.keyguardRepository
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.kosmos.testScope
@@ -50,6 +50,7 @@ import com.android.systemui.res.R
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.SysuiStatusBarStateController
+import com.android.systemui.statusbar.featurepods.popups.StatusBarPopupChips
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.FakeConfigurationController
import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -581,6 +582,36 @@ class MediaHierarchyManagerTest : SysuiTestCase() {
}
@Test
+ @EnableFlags(StatusBarPopupChips.FLAG_NAME)
+ fun testStatusBarPopupLocation() =
+ testScope.runTest {
+ mediaHierarchyManager.isMediaControlPopupShowing = true
+ runCurrent()
+
+ verify(mediaCarouselController)
+ .onDesiredLocationChanged(
+ eq(MediaHierarchyManager.LOCATION_STATUS_BAR_POPUP),
+ nullable(),
+ eq(false),
+ anyLong(),
+ anyLong(),
+ )
+ clearInvocations(mediaCarouselController)
+
+ mediaHierarchyManager.isMediaControlPopupShowing = false
+ runCurrent()
+
+ verify(mediaCarouselController)
+ .onDesiredLocationChanged(
+ eq(MediaHierarchyManager.LOCATION_QQS),
+ any<MediaHostState>(),
+ eq(false),
+ anyLong(),
+ anyLong(),
+ )
+ }
+
+ @Test
fun testCommunalLocationVisibilityWithShadeShowing() =
testScope.runTest {
whenever(mediaDataManager.hasActiveMediaOrRecommendation()).thenReturn(true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
index 99b99ee1860b..0c0ef9d5edfe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
@@ -549,7 +549,7 @@ class NotificationGutsManagerWithScenesTest : SysuiTestCase() {
if (isVisible) {
Scenes.Lockscreen
} else {
- Scenes.Bouncer
+ Scenes.Communal
}
sceneInteractor.changeScene(key, "test")
sceneInteractor.setTransitionState(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 10886760b521..ffb861db182c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -113,7 +113,7 @@ import java.util.Map;
@SmallTest
// TODO(b/381263619) there are more changes and tweaks required to match the new bouncer/shade specs
// Disabling for now but it will be fixed before the flag is fully ramped up.
-@DisableFlags(Flags.FLAG_BOUNCER_UI_REVAMP)
+@DisableFlags({Flags.FLAG_BOUNCER_UI_REVAMP, Flags.FLAG_NOTIFICATION_SHADE_BLUR})
public class ScrimControllerTest extends SysuiTestCase {
@Rule public Expect mExpect = Expect.create();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index dde6e2ee1866..0d99c0e8cab8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -93,7 +93,7 @@ import com.android.systemui.navigationbar.TaskbarDelegate;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
-import com.android.systemui.scene.shared.model.Scenes;
+import com.android.systemui.scene.shared.model.Overlays;
import com.android.systemui.shade.NotificationShadeWindowView;
import com.android.systemui.shade.ShadeController;
import com.android.systemui.shade.ShadeExpansionChangeEvent;
@@ -927,7 +927,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
@EnableSceneContainer
public void showPrimaryBouncer() {
mStatusBarKeyguardViewManager.showPrimaryBouncer(false);
- verify(mSceneInteractor).changeScene(eq(Scenes.Bouncer), anyString());
+ verify(mSceneInteractor).showOverlay(eq(Overlays.Bouncer), anyString());
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index a38d71b178e9..68d84ecaf4b1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -25,6 +25,7 @@ import static android.service.notification.NotificationListenerService.NOTIFICAT
import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED;
import static android.service.notification.NotificationListenerService.REASON_PACKAGE_BANNED;
+import static android.service.notification.NotificationListenerService.REASON_PACKAGE_CHANGED;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.server.notification.Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING;
@@ -1126,6 +1127,18 @@ public class BubblesTest extends SysuiTestCase {
}
@Test
+ public void testNotifsPackageChanged_entryListenerRemove() {
+ mEntryListener.onEntryAdded(mRow);
+ mBubbleController.updateBubble(mBubbleEntry);
+
+ assertTrue(mBubbleController.hasBubbles());
+
+ // Removes the notification
+ mEntryListener.onEntryRemoved(mRow, REASON_PACKAGE_CHANGED);
+ assertFalse(mBubbleController.hasBubbles());
+ }
+
+ @Test
public void removeBubble_intercepted() {
mEntryListener.onEntryAdded(mRow);
mBubbleController.updateBubble(mBubbleEntry);
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 3bfd95816cf0..4d1c271d6a41 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
@@ -34,9 +34,7 @@ import com.android.systemui.user.domain.interactor.selectedUserInteractor
import com.android.systemui.user.ui.viewmodel.userSwitcherViewModel
import kotlinx.coroutines.flow.StateFlow
-val Kosmos.bouncerUserActionsViewModel by Fixture {
- BouncerUserActionsViewModel(bouncerInteractor = bouncerInteractor)
-}
+val Kosmos.bouncerUserActionsViewModel by Fixture { BouncerUserActionsViewModel() }
val Kosmos.bouncerUserActionsViewModelFactory by Fixture {
object : BouncerUserActionsViewModel.Factory {
@@ -46,8 +44,8 @@ val Kosmos.bouncerUserActionsViewModelFactory by Fixture {
}
}
-val Kosmos.bouncerSceneContentViewModel by Fixture {
- BouncerSceneContentViewModel(
+val Kosmos.bouncerOverlayContentViewModel by Fixture {
+ BouncerOverlayContentViewModel(
applicationContext = applicationContext,
bouncerInteractor = bouncerInteractor,
authenticationInteractor = authenticationInteractor,
@@ -65,10 +63,10 @@ val Kosmos.bouncerSceneContentViewModel by Fixture {
)
}
-val Kosmos.bouncerSceneContentViewModelFactory by Fixture {
- object : BouncerSceneContentViewModel.Factory {
- override fun create(): BouncerSceneContentViewModel {
- return bouncerSceneContentViewModel
+val Kosmos.bouncerOverlayContentViewModelFactory by Fixture {
+ object : BouncerOverlayContentViewModel.Factory {
+ override fun create(): BouncerOverlayContentViewModel {
+ return bouncerOverlayContentViewModel
}
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneKosmos.kt
index f0350acd83ca..3bd8729ab173 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneKosmos.kt
@@ -32,7 +32,6 @@ var Kosmos.sceneKeys by Fixture {
Scenes.QuickSettings,
Scenes.Shade,
Scenes.Lockscreen,
- Scenes.Bouncer,
Scenes.Gone,
Scenes.Communal,
Scenes.Dream,
@@ -42,7 +41,7 @@ var Kosmos.sceneKeys by Fixture {
val Kosmos.initialSceneKey by Fixture { Scenes.Lockscreen }
var Kosmos.overlayKeys by Fixture {
- listOf(Overlays.NotificationsShade, Overlays.QuickSettingsShade)
+ listOf(Overlays.NotificationsShade, Overlays.QuickSettingsShade, Overlays.Bouncer)
}
val Kosmos.fakeOverlaysByKeys by Fixture { overlayKeys.associateWith { FakeOverlay(it) } }
@@ -62,7 +61,6 @@ var Kosmos.sceneContainerConfig by Fixture {
Scenes.Dream to 2,
Scenes.Shade to 3,
Scenes.QuickSettings to 4,
- Scenes.Bouncer to 5,
)
SceneContainerConfig(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryUtil.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryUtil.kt
index c95b2dcb08b6..025608a87eff 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryUtil.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryUtil.kt
@@ -17,6 +17,7 @@
package com.android.systemui.scene.data.repository
import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.compose.animation.scene.OverlayKey
import com.android.compose.animation.scene.SceneKey
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
@@ -38,7 +39,7 @@ suspend fun Kosmos.setTransition(
stateTransition: TransitionStep? = null,
fillInStateSteps: Boolean = true,
scope: TestScope = testScope,
- repository: SceneContainerRepository = sceneContainerRepository
+ repository: SceneContainerRepository = sceneContainerRepository,
) {
var state: TransitionStep? = stateTransition
if (SceneContainerFlag.isEnabled) {
@@ -61,7 +62,7 @@ suspend fun Kosmos.setTransition(
fun Kosmos.setSceneTransition(
transition: ObservableTransitionState,
scope: TestScope = testScope,
- repository: SceneContainerRepository = sceneContainerRepository
+ repository: SceneContainerRepository = sceneContainerRepository,
) {
repository.setTransitionState(mutableTransitionState)
mutableTransitionState.value = transition
@@ -76,7 +77,7 @@ fun Transition(
isInitiatedByUserInput: Boolean = false,
isUserInputOngoing: Flow<Boolean> = flowOf(false),
previewProgress: Flow<Float> = flowOf(0f),
- isInPreviewStage: Flow<Boolean> = flowOf(false)
+ isInPreviewStage: Flow<Boolean> = flowOf(false),
): ObservableTransitionState.Transition {
return ObservableTransitionState.Transition(
fromScene = from,
@@ -86,17 +87,64 @@ fun Transition(
isInitiatedByUserInput = isInitiatedByUserInput,
isUserInputOngoing = isUserInputOngoing,
previewProgress = previewProgress,
- isInPreviewStage = isInPreviewStage
+ isInPreviewStage = isInPreviewStage,
)
}
-fun Idle(currentScene: SceneKey): ObservableTransitionState.Idle {
- return ObservableTransitionState.Idle(currentScene)
+fun ShowOverlay(
+ overlay: OverlayKey,
+ fromScene: SceneKey,
+ currentOverlays: Flow<Set<OverlayKey>> = flowOf(setOf(overlay)),
+ progress: Flow<Float> = flowOf(0f),
+ isInitiatedByUserInput: Boolean = false,
+ isUserInputOngoing: Flow<Boolean> = flowOf(false),
+ previewProgress: Flow<Float> = flowOf(0f),
+ isInPreviewStage: Flow<Boolean> = flowOf(false),
+): ObservableTransitionState.Transition {
+ return ObservableTransitionState.Transition.showOverlay(
+ overlay = overlay,
+ fromScene = fromScene,
+ currentOverlays = currentOverlays,
+ progress = progress,
+ isInitiatedByUserInput = isInitiatedByUserInput,
+ isUserInputOngoing = isUserInputOngoing,
+ previewProgress = previewProgress,
+ isInPreviewStage = isInPreviewStage,
+ )
+}
+
+fun HideOverlay(
+ overlay: OverlayKey,
+ toScene: SceneKey,
+ currentOverlays: Flow<Set<OverlayKey>> = flowOf(setOf(overlay)),
+ progress: Flow<Float> = flowOf(0f),
+ isInitiatedByUserInput: Boolean = false,
+ isUserInputOngoing: Flow<Boolean> = flowOf(false),
+ previewProgress: Flow<Float> = flowOf(0f),
+ isInPreviewStage: Flow<Boolean> = flowOf(false),
+): ObservableTransitionState.Transition {
+ return ObservableTransitionState.Transition.hideOverlay(
+ overlay = overlay,
+ toScene = toScene,
+ currentOverlays = currentOverlays,
+ progress = progress,
+ isInitiatedByUserInput = isInitiatedByUserInput,
+ isUserInputOngoing = isUserInputOngoing,
+ previewProgress = previewProgress,
+ isInPreviewStage = isInPreviewStage,
+ )
+}
+
+fun Idle(
+ currentScene: SceneKey,
+ currentOverlays: Set<OverlayKey> = emptySet(),
+): ObservableTransitionState.Idle {
+ return ObservableTransitionState.Idle(currentScene, currentOverlays)
}
private fun getStateWithUndefined(
sceneTransition: ObservableTransitionState,
- state: TransitionStep
+ state: TransitionStep,
): TransitionStep {
return when (sceneTransition) {
is ObservableTransitionState.Idle -> {
@@ -109,7 +157,7 @@ private fun getStateWithUndefined(
state.to
},
value = state.value,
- transitionState = state.transitionState
+ transitionState = state.transitionState,
)
}
is ObservableTransitionState.Transition -> {
@@ -127,7 +175,7 @@ private fun getStateWithUndefined(
state.from
},
value = state.value,
- transitionState = state.transitionState
+ transitionState = state.transitionState,
)
}
else -> state
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/model/FakeSceneDataSource.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/model/FakeSceneDataSource.kt
index f9917ac680e0..66a190c0bb99 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/model/FakeSceneDataSource.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/model/FakeSceneDataSource.kt
@@ -115,8 +115,14 @@ class FakeSceneDataSource(initialSceneKey: SceneKey, val testScope: TestScope) :
* If [force] is `true`, there will be no check that [isPaused] is true.
*
* If [expectedScene] is provided, will assert that it's indeed the latest called.
+ *
+ * If [expectedOverlays] is provided, will assert they are indeed present.
*/
- fun unpause(force: Boolean = false, expectedScene: SceneKey? = null) {
+ fun unpause(
+ force: Boolean = false,
+ expectedScene: SceneKey? = null,
+ expectedOverlays: Set<OverlayKey>? = null,
+ ) {
check(force || _isPaused) { "Can't unpause what's already not paused!" }
_isPaused = false
@@ -128,9 +134,12 @@ class FakeSceneDataSource(initialSceneKey: SceneKey, val testScope: TestScope) :
check(expectedScene == null || currentScene.value == expectedScene) {
"""
Unexpected scene while unpausing.
- Expected $expectedScene but was $currentScene.
+ Expected $expectedScene but was ${currentScene.value}.
"""
.trimIndent()
}
+ check(expectedOverlays == null || expectedOverlays == currentOverlays.value) {
+ "Expected $expectedOverlays, but instead found overlays ${currentOverlays.value}."
+ }
}
}
diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java
index cb01727524da..1ac971104486 100644
--- a/services/core/java/com/android/server/om/OverlayManagerSettings.java
+++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java
@@ -544,6 +544,7 @@ final class OverlayManagerSettings {
// and overwritten.
throw new XmlPullParserException("old version " + oldVersion + "; ignoring");
case 3:
+ case 4:
// Upgrading from version 3 to 5 is not a breaking change so do not ignore the
// overlay file.
return;
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java
index 6bec34ef7063..38aa57f785e5 100644
--- a/services/core/java/com/android/server/pm/DeletePackageHelper.java
+++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java
@@ -24,6 +24,7 @@ import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
import static android.content.pm.PackageManager.DELETE_SUCCEEDED;
import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.os.UserHandle.USER_ALL;
import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
import static com.android.server.pm.PackageManagerService.DEBUG_COMPRESSION;
@@ -122,7 +123,7 @@ final class DeletePackageHelper {
final boolean res;
final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
- ? UserHandle.USER_ALL : userId;
+ ? USER_ALL : userId;
final PackageSetting uninstalledPs;
final PackageSetting disabledSystemPs;
@@ -183,7 +184,7 @@ final class DeletePackageHelper {
if (libraryInfo != null) {
boolean flagSdkLibIndependence = Flags.sdkLibIndependence();
for (int currUserId : allUsers) {
- if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
+ if (removeUser != USER_ALL && removeUser != currUserId) {
continue;
}
var libClientPackagesPair = computer.getPackagesUsingSharedLibrary(
@@ -227,7 +228,7 @@ final class DeletePackageHelper {
&& ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
// We're downgrading a system app, which will apply to all users, so
// freeze them all during the downgrade
- freezeUser = UserHandle.USER_ALL;
+ freezeUser = USER_ALL;
priorUserStates = new SparseArray<>();
for (int i = 0; i < allUsers.length; i++) {
PackageUserState userState = uninstalledPs.readUserState(allUsers[i]);
@@ -421,7 +422,7 @@ final class DeletePackageHelper {
if (PackageManagerServiceUtils.isSystemApp(ps)) {
final boolean deleteSystem = (flags & PackageManager.DELETE_SYSTEM_APP) != 0;
final boolean deleteAllUsers =
- user == null || user.getIdentifier() == UserHandle.USER_ALL;
+ user == null || user.getIdentifier() == USER_ALL;
if ((!deleteSystem || deleteAllUsers) && disabledPs == null) {
Slog.w(TAG, "Attempt to delete unknown system package "
+ ps.getPkg().getPackageName());
@@ -464,9 +465,9 @@ final class DeletePackageHelper {
Manifest.permission.SUSPEND_APPS, packageName, userId) == PERMISSION_GRANTED);
}
- final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
+ final int userId = user == null ? USER_ALL : user.getIdentifier();
// Remember which users are affected, before the installed states are modified
- outInfo.mRemovedUsers = userId == UserHandle.USER_ALL
+ outInfo.mRemovedUsers = userId == USER_ALL
? ps.queryUsersInstalledOrHasData(allUserHandles)
: new int[]{userId};
outInfo.populateBroadcastUsers(ps);
@@ -479,7 +480,7 @@ final class DeletePackageHelper {
outInfo.mRemovedPackageVersionCode = ps.getVersionCode();
if ((!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)
- && userId != UserHandle.USER_ALL) {
+ && userId != USER_ALL) {
// The caller is asking that the package only be deleted for a single
// user. To do this, we just mark its uninstalled state and delete
// its data. If this is a system app, we only allow this to happen if
@@ -552,7 +553,7 @@ final class DeletePackageHelper {
for (final int affectedUserId : outInfo.mRemovedUsers) {
if (hadSuspendAppsPermission.get(affectedUserId)) {
mPm.unsuspendForSuspendingPackage(snapshot, packageName,
- affectedUserId /*suspendingUserId*/, true /*inAllUsers*/);
+ affectedUserId /*suspendingUserId*/, USER_ALL);
mPm.removeAllDistractingPackageRestrictions(snapshot, affectedUserId);
}
}
@@ -590,7 +591,7 @@ final class DeletePackageHelper {
@GuardedBy("mPm.mLock")
private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user, int flags) {
- final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
+ final int[] userIds = (user == null || user.getIdentifier() == USER_ALL)
? mUserManagerInternal.getUserIds()
: new int[] {user.getIdentifier()};
for (int nextUserId : userIds) {
@@ -687,7 +688,7 @@ final class DeletePackageHelper {
flags |= PackageManager.DELETE_KEEP_DATA;
}
try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
- deleteInstalledPackageLIF(deletedPs, UserHandle.USER_ALL, true, flags, allUserHandles,
+ deleteInstalledPackageLIF(deletedPs, USER_ALL, true, flags, allUserHandles,
outInfo, writeSettings);
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerInternalBase.java b/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
index ed568b823159..f5230c57c597 100644
--- a/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
+++ b/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
@@ -689,7 +689,7 @@ abstract class PackageManagerInternalBase extends PackageManagerInternal {
final int suspendingUserId =
crossUserSuspensionEnabledRo() ? UserHandle.USER_SYSTEM : affectedUser;
mService.unsuspendForSuspendingPackage(
- snapshot(), PLATFORM_PACKAGE_NAME, suspendingUserId, /* inAllUsers= */ false);
+ snapshot(), PLATFORM_PACKAGE_NAME, suspendingUserId, affectedUser);
}
@Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 91a1c9c12cb8..021da6f27deb 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -34,6 +34,7 @@ import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET;
import static android.crashrecovery.flags.Flags.refactorCrashrecovery;
import static android.os.Process.INVALID_UID;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
+import static android.os.UserHandle.USER_ALL;
import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL;
@@ -1587,13 +1588,13 @@ public class PackageManagerService implements PackageSender, TestUtilityService
}
void scheduleWritePackageRestrictions(UserHandle user) {
- final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
+ final int userId = user == null ? USER_ALL : user.getIdentifier();
scheduleWritePackageRestrictions(userId);
}
void scheduleWritePackageRestrictions(@CanBeALL @UserIdInt int userId) {
invalidatePackageInfoCache();
- if (userId == UserHandle.USER_ALL) {
+ if (userId == USER_ALL) {
synchronized (mDirtyUsers) {
for (int aUserId : mUserManager.getUserIds()) {
mDirtyUsers.add(aUserId);
@@ -1806,7 +1807,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
private void installAllowlistedSystemPackages() {
if (mUserManager.installWhitelistedSystemPackages(isFirstBoot(), isDeviceUpgrading(),
mExistingPackages)) {
- scheduleWritePackageRestrictions(UserHandle.USER_ALL);
+ scheduleWritePackageRestrictions(USER_ALL);
scheduleWriteSettings();
}
}
@@ -2393,7 +2394,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
final PackageSetting ps = packageSettings.valueAt(i);
if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.getVolumeUuid())) {
// No apps are running this early, so no need to freeze
- mAppDataHelper.clearAppDataLIF(ps.getPkg(), UserHandle.USER_ALL,
+ mAppDataHelper.clearAppDataLIF(ps.getPkg(), USER_ALL,
FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
| Installer.FLAG_CLEAR_CODE_CACHE_ONLY
| Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);
@@ -3076,7 +3077,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
@NonNull
int[] resolveUserIds(@CanBeALL @UserIdInt int userId) {
- return (userId == UserHandle.USER_ALL) ? mUserManager.getUserIds() : new int[] { userId };
+ return (userId == USER_ALL) ? mUserManager.getUserIds() : new int[]{userId};
}
private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
@@ -3109,7 +3110,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
}
void killApplication(String pkgName, @AppIdInt int appId, String reason, int exitInfoReason) {
- killApplication(pkgName, appId, UserHandle.USER_ALL, reason, exitInfoReason);
+ killApplication(pkgName, appId, USER_ALL, reason, exitInfoReason);
}
void killApplication(String pkgName, @AppIdInt int appId,
@@ -3229,23 +3230,24 @@ public class PackageManagerService implements PackageSender, TestUtilityService
}
/**
- * @param inAllUsers Whether to unsuspend packages suspended by the given package in other
- * users. This flag is only used when cross-user suspension is enabled.
+ * @param suspendingUserId The user that has suspended apps using the suspending package.
+ * @param targetUserId The user whose apps should be unsuspended. Pass {@code USER_ALL} to
+ * unsuspend for all users.
*/
void unsuspendForSuspendingPackage(@NonNull Computer computer, String suspendingPackage,
- @UserIdInt int suspendingUserId, boolean inAllUsers) {
+ @UserIdInt int suspendingUserId, @CanBeALL @UserIdInt int targetUserId) {
// TODO: This can be replaced by a special parameter to iterate all packages, rather than
// this weird pre-collect of all packages.
final String[] allPackages = computer.getPackageStates().keySet().toArray(new String[0]);
final Predicate<UserPackage> suspenderPredicate =
UserPackage.of(suspendingUserId, suspendingPackage)::equals;
- if (!crossUserSuspensionEnabledRo() || !inAllUsers) {
+ if (!crossUserSuspensionEnabledRo() || targetUserId != USER_ALL) {
mSuspendPackageHelper.removeSuspensionsBySuspendingPackage(computer,
- allPackages, suspenderPredicate, suspendingUserId);
+ allPackages, suspenderPredicate, targetUserId);
} else {
- for (int targetUserId: mUserManager.getUserIds()) {
+ for (int user : mUserManager.getUserIds()) {
mSuspendPackageHelper.removeSuspensionsBySuspendingPackage(
- computer, allPackages, suspenderPredicate, targetUserId);
+ computer, allPackages, suspenderPredicate, user);
}
}
}
@@ -3382,7 +3384,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
&& !snapshot.isCallerSameApp(packageName, callingUid)) {
return false;
}
- return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
+ return isPackageDeviceAdmin(packageName, USER_ALL);
}
// TODO(b/261957226): centralise this logic in DPM
@@ -3406,7 +3408,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
// Does it contain a device admin for any user?
int[] allUsers = mUserManager.getUserIds();
int[] targetUsers;
- if (userId == UserHandle.USER_ALL) {
+ if (userId == USER_ALL) {
targetUsers = allUsers;
} else {
targetUsers = new int[]{userId};
@@ -4153,7 +4155,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
// This app should not generally be allowed to get disabled by the UI, but
// if it ever does, we don't want to end up with some of the user's apps
// permanently suspended.
- unsuspendForSuspendingPackage(computer, packageName, userId, true /* inAllUsers */);
+ unsuspendForSuspendingPackage(computer, packageName, userId, USER_ALL);
removeAllDistractingPackageRestrictions(computer, userId);
}
success = true;
@@ -4244,9 +4246,9 @@ public class PackageManagerService implements PackageSender, TestUtilityService
};
mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
.getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
- false, co, UserHandle.USER_ALL);
+ false, co, USER_ALL);
mContext.getContentResolver().registerContentObserver(android.provider.Settings.Secure
- .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_ALL);
+ .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, USER_ALL);
co.onChange(true);
mAppsFilter.onSystemReady(LocalServices.getService(PackageManagerInternal.class));
@@ -4774,7 +4776,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
final Computer snapshot = snapshotComputer();
final AndroidPackage pkg = snapshot.getPackage(packageName);
try (PackageFreezer ignored =
- freezePackage(packageName, UserHandle.USER_ALL,
+ freezePackage(packageName, USER_ALL,
"clearApplicationProfileData",
ApplicationExitInfo.REASON_OTHER, null /* request */)) {
try (PackageManagerTracedLock installLock = mInstallLock.acquireLock()) {
@@ -4820,7 +4822,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
public void run() {
mHandler.removeCallbacks(this);
final boolean succeeded;
- try (PackageFreezer freezer = freezePackage(packageName, UserHandle.USER_ALL,
+ try (PackageFreezer freezer = freezePackage(packageName, USER_ALL,
"clearApplicationUserData",
ApplicationExitInfo.REASON_USER_REQUESTED, null /* request */,
/* waitAppKilled= */ true)) {
@@ -4847,7 +4849,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
== PERMISSION_GRANTED) {
final Computer snapshot = snapshotComputer();
unsuspendForSuspendingPackage(
- snapshot, packageName, userId, true /* inAllUsers */);
+ snapshot, packageName, userId, USER_ALL);
removeAllDistractingPackageRestrictions(snapshot, userId);
synchronized (mLock) {
flushPackageRestrictionsAsUserInternalLocked(userId);
@@ -6372,13 +6374,13 @@ public class PackageManagerService implements PackageSender, TestUtilityService
if (mComponentResolver.updateMimeGroup(snapshotComputer(), packageName, mimeGroup)) {
Binder.withCleanCallingIdentity(() -> {
mPreferredActivityHelper.clearPackagePreferredActivities(packageName,
- UserHandle.USER_ALL);
+ USER_ALL);
// Send the ACTION_PACKAGE_CHANGED when the mimeGroup has changes
final Computer snapShot = snapshotComputer();
final ArrayList<String> components = new ArrayList<>(
Collections.singletonList(packageName));
final int appId = packageState.getAppId();
- final int[] userIds = resolveUserIds(UserHandle.USER_ALL);
+ final int[] userIds = resolveUserIds(USER_ALL);
final String reason = "The mimeGroup is changed";
for (int i = 0; i < userIds.length; i++) {
final PackageUserStateInternal pkgUserState =
diff --git a/services/tests/mockingservicestests/res/xml/expectedUserWakeupList_1.xml b/services/tests/mockingservicestests/res/xml/expectedUserWakeupList_1.xml
new file mode 100644
index 000000000000..21e6dab518fc
--- /dev/null
+++ b/services/tests/mockingservicestests/res/xml/expectedUserWakeupList_1.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+<users version="1">
+ <user user_id="10" />
+ <user user_id="11" />
+</users> \ No newline at end of file
diff --git a/services/tests/mockingservicestests/res/xml/expectedUserWakeupList_2.xml b/services/tests/mockingservicestests/res/xml/expectedUserWakeupList_2.xml
new file mode 100644
index 000000000000..d0b371f060da
--- /dev/null
+++ b/services/tests/mockingservicestests/res/xml/expectedUserWakeupList_2.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+<users version="1">
+ <user user_id="10" />
+</users> \ No newline at end of file
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/UserWakeupStoreTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/UserWakeupStoreTest.java
index 72883e269a65..240284a42406 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/UserWakeupStoreTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/UserWakeupStoreTest.java
@@ -23,15 +23,21 @@ import static com.android.server.alarm.UserWakeupStore.USER_START_TIME_DEVIATION
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import android.content.res.AssetManager;
+import android.content.res.XmlResourceParser;
import android.os.Environment;
import android.os.FileUtils;
import android.os.SystemClock;
+import android.util.Xml;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.XmlUtils;
+import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.testing.ExtendedMockitoRule;
import org.junit.After;
@@ -40,8 +46,11 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
+import org.xmlpull.v1.XmlPullParserException;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.ExecutorService;
@@ -55,6 +64,7 @@ public class UserWakeupStoreTest {
private static final File TEST_SYSTEM_DIR = new File(InstrumentationRegistry
.getInstrumentation().getContext().getDataDir(), "alarmsTestDir");
private static final File ROOT_DIR = new File(TEST_SYSTEM_DIR, UserWakeupStore.ROOT_DIR_NAME);
+ private static final String USERS_FILE_NAME = "usersWithAlarmClocks.xml";
private ExecutorService mMockExecutorService = null;
UserWakeupStore mUserWakeupStore;
@@ -105,7 +115,7 @@ public class UserWakeupStoreTest {
Collections.sort(userWakeups);
assertEquals(userIds, userWakeups);
- final File file = new File(ROOT_DIR , "usersWithAlarmClocks.xml");
+ final File file = new File(ROOT_DIR, USERS_FILE_NAME);
assertTrue(file.exists());
}
@@ -178,5 +188,47 @@ public class UserWakeupStoreTest {
assertTrue(mUserWakeupStore.getWakeupTimeForUser(USER_ID_2) - realtime
< 3 * BUFFER_TIME_MS + USER_START_TIME_DEVIATION_LIMIT_MS);
}
- //TODO: b/330264023 - Add tests for I/O in usersWithAlarmClocks.xml.
+
+ @Test
+ public void testWriteWakeups_xmlIsOrdered() {
+ mUserWakeupStore.addUserWakeup(USER_ID_1, TEST_TIMESTAMP - 19_000);
+ mUserWakeupStore.addUserWakeup(USER_ID_2, TEST_TIMESTAMP - 7_000);
+ assertFileContentsMatchExpectedXml("res/xml/expectedUserWakeupList_1.xml");
+ }
+
+ @Test
+ public void testWriteWakeups_containsOneEntryPerUser() {
+ mUserWakeupStore.addUserWakeup(USER_ID_1, TEST_TIMESTAMP - 19_000);
+ mUserWakeupStore.addUserWakeup(USER_ID_1, TEST_TIMESTAMP - 7_000);
+ assertFileContentsMatchExpectedXml("res/xml/expectedUserWakeupList_2.xml");
+ }
+
+ private static void assertFileContentsMatchExpectedXml(String expectedContentsFile) {
+ final File actual = new File(ROOT_DIR, USERS_FILE_NAME);
+ AssetManager assetManager =
+ InstrumentationRegistry.getInstrumentation().getContext().getAssets();
+ try (FileInputStream actualFis = new FileInputStream(actual)) {
+ final TypedXmlPullParser actualParser = Xml.resolvePullParser(actualFis);
+ final XmlResourceParser expectedParser = assetManager.openXmlResourceParser(
+ expectedContentsFile);
+ for (XmlUtils.nextElement(expectedParser), XmlUtils.nextElement(actualParser);
+ actualParser.getEventType() != XmlResourceParser.END_DOCUMENT
+ && expectedParser.getEventType() != XmlResourceParser.END_DOCUMENT;
+ XmlUtils.nextElement(actualParser), XmlUtils.nextElement(expectedParser)) {
+ assertEquals("Event types differ ", expectedParser.getEventType(),
+ actualParser.getEventType());
+ for (int i = 0; i < expectedParser.getAttributeCount(); i++) {
+ assertEquals("Attribute names differ at index " + i,
+ expectedParser.getAttributeName(i), actualParser.getAttributeName(i));
+ assertEquals("Attribute values differ at index " + i,
+ expectedParser.getAttributeValue(i), actualParser.getAttributeValue(i));
+ }
+ }
+ // Ensure they are both at the end of document
+ assertEquals("One of the parsers has not reached the EOF",
+ expectedParser.getEventType(), actualParser.getEventType());
+ } catch (IOException | XmlPullParserException e) {
+ fail(e.getLocalizedMessage());
+ }
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/om/OverlayManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/om/OverlayManagerSettingsTests.java
index ad3855f4c28f..b1cf9059fdc4 100644
--- a/services/tests/servicestests/src/com/android/server/om/OverlayManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/om/OverlayManagerSettingsTests.java
@@ -37,10 +37,12 @@ import android.text.TextUtils;
import android.util.Xml;
import androidx.annotation.NonNull;
-import androidx.test.runner.AndroidJUnit4;
import com.android.modules.utils.TypedXmlPullParser;
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -56,7 +58,7 @@ import java.util.Set;
import javax.annotation.Nullable;
-@RunWith(AndroidJUnit4.class)
+@RunWith(JUnitParamsRunner.class)
public class OverlayManagerSettingsTests {
private OverlayManagerSettings mSettings;
private static final int USER_0 = 0;
@@ -439,6 +441,39 @@ public class OverlayManagerSettingsTests {
}
@Test
+ @Parameters(method = "getPreviousVersions")
+ public void testRestoreWithPreviousVersion(int version) throws Exception {
+ final String xml =
+ "<?xml version='1.0' encoding='utf-8' standalone='yes'?>\n"
+ + "<overlays version='" + version + "'>\n"
+ + "<item packageName='com.test.overlay'\n"
+ + " overlayName='test'\n"
+ + " userId='1234'\n"
+ + " targetPackageName='com.test.target'\n"
+ + " baseCodePath='/data/app/com.test.overlay-1/base.apk'\n"
+ + " state='" + STATE_DISABLED + "'\n"
+ + " isEnabled='false'\n"
+ + " category='test-category'\n"
+ + " isStatic='false'\n"
+ + " priority='0' />\n"
+ + "</overlays>\n";
+ ByteArrayInputStream is = new ByteArrayInputStream(xml.getBytes(UTF_8));
+
+ mSettings.restore(is);
+ final OverlayIdentifier identifier = new OverlayIdentifier("com.test.overlay", "test");
+ OverlayInfo oi = mSettings.getOverlayInfo(identifier, 1234);
+ assertNotNull(oi);
+ assertEquals("com.test.overlay", oi.packageName);
+ assertEquals("test", oi.overlayName);
+ assertEquals("com.test.target", oi.targetPackageName);
+ assertEquals("/data/app/com.test.overlay-1/base.apk", oi.baseCodePath);
+ assertEquals(1234, oi.userId);
+ assertEquals(STATE_DISABLED, oi.state);
+ assertFalse(mSettings.getEnabled(identifier, 1234));
+ assertTrue(oi.constraints.isEmpty());
+ }
+
+ @Test
public void testPersistAndRestore() throws Exception {
insertSetting(OVERLAY_A_USER0);
insertSetting(OVERLAY_B_USER1);
@@ -585,4 +620,11 @@ public class OverlayManagerSettingsTests {
TextUtils.join(",", expected), TextUtils.join(",", actual)));
}
}
+
+ private static Integer[] getPreviousVersions() {
+ return new Integer[]{
+ 3,
+ 4,
+ };
+ }
}
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java
index 42279e40fa33..04335df8c454 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java
@@ -20,14 +20,14 @@ import static android.os.VibrationAttributes.USAGE_RINGTONE;
import static android.os.VibrationEffect.Composition.PRIMITIVE_CLICK;
import static android.os.VibrationEffect.Composition.PRIMITIVE_SPIN;
import static android.os.VibrationEffect.Composition.PRIMITIVE_TICK;
+import static android.os.VibrationEffect.EFFECT_CLICK;
+import static android.os.VibrationEffect.EFFECT_TICK;
import static android.os.VibrationEffect.VibrationParameter.targetAmplitude;
import static android.os.VibrationEffect.VibrationParameter.targetFrequency;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
@@ -189,7 +189,7 @@ public class VibrationThreadTest {
public void vibrate_noVibrator_ignoresVibration() {
mVibratorProviders.clear();
CombinedVibration effect = CombinedVibration.createParallel(
- VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
+ VibrationEffect.get(EFFECT_CLICK));
HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
@@ -200,8 +200,8 @@ public class VibrationThreadTest {
@Test
public void vibrate_missingVibrators_ignoresVibration() {
CombinedVibration effect = CombinedVibration.startSequential()
- .addNext(2, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
- .addNext(3, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
+ .addNext(2, VibrationEffect.get(EFFECT_CLICK))
+ .addNext(3, VibrationEffect.get(EFFECT_TICK))
.combine();
HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
@@ -222,11 +222,12 @@ public class VibrationThreadTest {
verify(mManagerHooks).noteVibratorOff(eq(UID));
verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id), anyLong());
verifyCallbacksTriggered(vibration, Status.FINISHED);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
- assertEquals(Arrays.asList(expectedOneShot(10)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
- assertEquals(expectedAmplitudes(100), mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id))
+ .containsExactly(expectedOneShot(10)).inOrder();
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getAmplitudes())
+ .containsExactlyElementsIn(expectedAmplitudes(100)).inOrder();
}
@Test
@@ -239,11 +240,11 @@ public class VibrationThreadTest {
verify(mManagerHooks).noteVibratorOff(eq(UID));
verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id), anyLong());
verifyCallbacksTriggered(vibration, Status.FINISHED);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
- assertEquals(Arrays.asList(expectedOneShot(10)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
- assertTrue(mVibratorProviders.get(VIBRATOR_ID).getAmplitudes().isEmpty());
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id))
+ .containsExactly(expectedOneShot(10)).inOrder();
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getAmplitudes()).isEmpty();
}
@Test
@@ -259,12 +260,12 @@ public class VibrationThreadTest {
verify(mManagerHooks).noteVibratorOff(eq(UID));
verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id), anyLong());
verifyCallbacksTriggered(vibration, Status.FINISHED);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
- assertEquals(Arrays.asList(expectedOneShot(15)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
- assertEquals(expectedAmplitudes(1, 2, 3),
- mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id))
+ .containsExactly(expectedOneShot(15)).inOrder();
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getAmplitudes())
+ .containsExactlyElementsIn(expectedAmplitudes(1, 2, 3)).inOrder();
}
@Test
@@ -285,11 +286,12 @@ public class VibrationThreadTest {
waitForCompletion();
verify(mStatsLoggerMock, never()).logVibrationParamRequestTimeout(UID);
- assertEquals(Arrays.asList(expectedOneShot(15)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id))
+ .containsExactly(expectedOneShot(15)).inOrder();
List<Float> amplitudes = mVibratorProviders.get(VIBRATOR_ID).getAmplitudes();
for (int i = 0; i < amplitudes.size(); i++) {
- assertTrue(amplitudes.get(i) < 1 / 255f);
+ assertWithMessage("For amplitude index %s", i)
+ .that(amplitudes.get(i)).isLessThan(1 / 255f);
}
}
@@ -309,10 +311,10 @@ public class VibrationThreadTest {
waitForCompletion();
verify(mStatsLoggerMock).logVibrationParamRequestTimeout(UID);
- assertEquals(Arrays.asList(expectedOneShot(15)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
- assertEquals(expectedAmplitudes(1, 1, 1),
- mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id))
+ .containsExactly(expectedOneShot(15)).inOrder();
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getAmplitudes())
+ .containsExactlyElementsIn(expectedAmplitudes(1, 1, 1)).inOrder();
}
@Test
@@ -325,31 +327,33 @@ public class VibrationThreadTest {
VibrationEffect effect = VibrationEffect.createWaveform(new long[]{5, 5, 5}, amplitudes, 0);
HalVibration vibration = startThreadAndDispatcher(effect);
- assertTrue(
+ assertThat(
waitUntil(() -> fakeVibrator.getAmplitudes().size() > 2 * amplitudes.length,
- TEST_TIMEOUT_MILLIS));
+ TEST_TIMEOUT_MILLIS)).isTrue();
// Vibration still running after 2 cycles.
- assertTrue(mThread.isRunningVibrationId(vibration.id));
- assertTrue(mControllers.get(VIBRATOR_ID).isVibrating());
+ assertThat(mThread.isRunningVibrationId(vibration.id)).isTrue();
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isTrue();
Vibration.EndInfo cancelVibrationInfo = new Vibration.EndInfo(Status.CANCELLED_SUPERSEDED,
new CallerInfo(VibrationAttributes.createForUsage(VibrationAttributes.USAGE_ALARM),
/* uid= */ 1, /* deviceId= */ -1, /* opPkg= */ null, /* reason= */ null));
mVibrationConductor.notifyCancelled(cancelVibrationInfo, /* immediate= */ false);
waitForCompletion();
- assertFalse(mThread.isRunningVibrationId(vibration.id));
+ assertThat(mThread.isRunningVibrationId(vibration.id)).isFalse();
verify(mManagerHooks).noteVibratorOn(eq(UID), anyLong());
verify(mManagerHooks).noteVibratorOff(eq(UID));
verifyCallbacksTriggered(vibration, Status.CANCELLED_SUPERSEDED);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
List<Float> playedAmplitudes = fakeVibrator.getAmplitudes();
- assertFalse(fakeVibrator.getEffectSegments(vibration.id).isEmpty());
- assertFalse(playedAmplitudes.isEmpty());
+ assertThat(fakeVibrator.getEffectSegments(vibration.id)).isNotEmpty();
+ assertThat(playedAmplitudes).isNotEmpty();
for (int i = 0; i < playedAmplitudes.size(); i++) {
- assertEquals(amplitudes[i % amplitudes.length] / 255f, playedAmplitudes.get(i), 1e-5);
+ assertWithMessage("For amplitude index %s", i)
+ .that(amplitudes[i % amplitudes.length] / 255f)
+ .isWithin(1e-5f).of(playedAmplitudes.get(i));
}
}
@@ -364,15 +368,16 @@ public class VibrationThreadTest {
new long[]{1, 10, 100}, amplitudes, 0);
HalVibration vibration = startThreadAndDispatcher(effect);
- assertTrue(waitUntil(() -> !fakeVibrator.getAmplitudes().isEmpty(), TEST_TIMEOUT_MILLIS));
+ assertThat(waitUntil(() -> !fakeVibrator.getAmplitudes().isEmpty(), TEST_TIMEOUT_MILLIS))
+ .isTrue();
mVibrationConductor.notifyCancelled(
new Vibration.EndInfo(Status.CANCELLED_BY_USER), /* immediate= */ false);
waitForCompletion();
verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_USER);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
- assertEquals(Arrays.asList(expectedOneShot(5000)),
- fakeVibrator.getEffectSegments(vibration.id));
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
+ assertThat(fakeVibrator.getEffectSegments(vibration.id))
+ .containsExactly(expectedOneShot(5000)).inOrder();
}
@Test
@@ -391,7 +396,7 @@ public class VibrationThreadTest {
assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id))
- .isEqualTo(expectedOneShots(100L, 150L));
+ .containsExactlyElementsIn(expectedOneShots(100L, 150L)).inOrder();
}
@Test
@@ -412,7 +417,7 @@ public class VibrationThreadTest {
assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id))
- .isEqualTo(expectedOneShots(200L, 50L));
+ .containsExactlyElementsIn(expectedOneShots(200L, 50L)).inOrder();
}
@EnableFlags(Flags.FLAG_FIX_VIBRATION_THREAD_CALLBACK_HANDLING)
@@ -433,8 +438,8 @@ public class VibrationThreadTest {
// 300ms ON (100ms + 200ms looping to the start and skipping first 0ms)
// 150ms ON (100ms + 50ms, skips 0ms)
// 300ms ON (100ms + 200ms looping to the start and skipping first 0ms)
- assertTrue(waitUntil(() -> fakeVibrator.getEffectSegments(vibration.id).size() >= 5,
- 5000L + TEST_TIMEOUT_MILLIS));
+ assertThat(waitUntil(() -> fakeVibrator.getEffectSegments(vibration.id).size() >= 5,
+ 5000L + TEST_TIMEOUT_MILLIS)).isTrue();
mVibrationConductor.notifyCancelled(
new Vibration.EndInfo(Status.CANCELLED_BY_USER), /* immediate= */ false);
waitForCompletion();
@@ -444,7 +449,8 @@ public class VibrationThreadTest {
assertThat(
mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id).subList(0, 5))
- .isEqualTo(expectedOneShots(200L, 150L, 300L, 150L, 300L));
+ .containsExactlyElementsIn(expectedOneShots(200L, 150L, 300L, 150L, 300L))
+ .inOrder();
}
@EnableFlags(Flags.FLAG_FIX_VIBRATION_THREAD_CALLBACK_HANDLING)
@@ -468,7 +474,7 @@ public class VibrationThreadTest {
// First callback ignored, did not cause the vibrator to turn back on during the 400ms step.
assertThat(fakeVibrator.getEffectSegments(vibration.id))
- .isEqualTo(expectedOneShots(200L, 400L));
+ .containsExactlyElementsIn(expectedOneShots(200L, 400L)).inOrder();
}
@Test
@@ -490,16 +496,16 @@ public class VibrationThreadTest {
.compose();
HalVibration vibration = startThreadAndDispatcher(repeatingEffect);
- assertTrue(waitUntil(() -> !fakeVibrator.getEffectSegments(vibration.id).isEmpty(),
- TEST_TIMEOUT_MILLIS));
+ assertThat(waitUntil(() -> !fakeVibrator.getEffectSegments(vibration.id).isEmpty(),
+ TEST_TIMEOUT_MILLIS)).isTrue();
mVibrationConductor.notifyCancelled(
new Vibration.EndInfo(Status.CANCELLED_BY_USER), /* immediate= */ false);
waitForCompletion();
// PWLE size max was used to generate a single vibrate call with 10 segments.
verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_USER);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
- assertEquals(10, fakeVibrator.getEffectSegments(vibration.id).size());
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
+ assertThat(fakeVibrator.getEffectSegments(vibration.id)).hasSize(10);
}
@Test
@@ -519,16 +525,16 @@ public class VibrationThreadTest {
.compose();
HalVibration vibration = startThreadAndDispatcher(repeatingEffect);
- assertTrue(waitUntil(() -> !fakeVibrator.getEffectSegments(vibration.id).isEmpty(),
- TEST_TIMEOUT_MILLIS));
+ assertThat(waitUntil(() -> !fakeVibrator.getEffectSegments(vibration.id).isEmpty(),
+ TEST_TIMEOUT_MILLIS)).isTrue();
mVibrationConductor.notifyCancelled(
new Vibration.EndInfo(Status.CANCELLED_BY_SCREEN_OFF), /* immediate= */ false);
waitForCompletion();
// Composition size max was used to generate a single vibrate call with 10 primitives.
verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_SCREEN_OFF);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
- assertEquals(10, fakeVibrator.getEffectSegments(vibration.id).size());
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
+ assertThat(fakeVibrator.getEffectSegments(vibration.id)).hasSize(10);
}
@Test
@@ -542,15 +548,16 @@ public class VibrationThreadTest {
new long[]{5000, 500, 50}, amplitudes, 0);
HalVibration vibration = startThreadAndDispatcher(effect);
- assertTrue(waitUntil(() -> !fakeVibrator.getAmplitudes().isEmpty(), TEST_TIMEOUT_MILLIS));
+ assertThat(waitUntil(() -> !fakeVibrator.getAmplitudes().isEmpty(), TEST_TIMEOUT_MILLIS))
+ .isTrue();
mVibrationConductor.notifyCancelled(
new Vibration.EndInfo(Status.CANCELLED_BY_USER), /* immediate= */ false);
waitForCompletion();
verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_USER);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
- assertEquals(Arrays.asList(expectedOneShot(5550)),
- fakeVibrator.getEffectSegments(vibration.id));
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
+ assertThat(fakeVibrator.getEffectSegments(vibration.id))
+ .containsExactly(expectedOneShot(5550)).inOrder();
}
@LargeTest
@@ -566,23 +573,24 @@ public class VibrationThreadTest {
/* amplitudes= */ new int[]{1, 2}, /* repeat= */ 0);
HalVibration vibration = startThreadAndDispatcher(effect);
- assertTrue(waitUntil(() -> fakeVibrator.getEffectSegments(vibration.id).size() > 1,
- expectedOnDuration + TEST_TIMEOUT_MILLIS));
+ assertThat(waitUntil(() -> fakeVibrator.getEffectSegments(vibration.id).size() > 1,
+ expectedOnDuration + TEST_TIMEOUT_MILLIS)).isTrue();
mVibrationConductor.notifyCancelled(
new Vibration.EndInfo(Status.CANCELLED_BY_USER), /* immediate= */ false);
waitForCompletion();
verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_USER);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
List<VibrationEffectSegment> effectSegments = fakeVibrator.getEffectSegments(vibration.id);
// First time, turn vibrator ON for the expected fixed duration.
- assertEquals(expectedOnDuration, effectSegments.get(0).getDuration());
+ assertThat(effectSegments.get(0).getDuration()).isEqualTo(expectedOnDuration);
// Vibrator turns off in the middle of the second execution of the first step. Expect it to
// be turned back ON at least for the fixed duration + the remaining duration of the step.
- assertTrue(expectedOnDuration < effectSegments.get(1).getDuration());
+ assertThat(effectSegments.get(1).getDuration()).isGreaterThan(expectedOnDuration);
// Set amplitudes for a cycle {1, 2}, start second loop then turn it back on to same value.
- assertEquals(expectedAmplitudes(1, 2, 1, 1),
- mVibratorProviders.get(VIBRATOR_ID).getAmplitudes().subList(0, 4));
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getAmplitudes().subList(0, 4))
+ .containsExactlyElementsIn(expectedAmplitudes(1, 2, 1, 1))
+ .inOrder();
}
@Test
@@ -598,9 +606,9 @@ public class VibrationThreadTest {
.compose();
HalVibration vibration = startThreadAndDispatcher(effect);
- assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
- TEST_TIMEOUT_MILLIS));
- assertTrue(mThread.isRunningVibrationId(vibration.id));
+ assertThat(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
+ TEST_TIMEOUT_MILLIS)).isTrue();
+ assertThat(mThread.isRunningVibrationId(vibration.id)).isTrue();
// Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
// fail at waitForCompletion(vibrationThread) if the vibration not cancelled immediately.
@@ -614,7 +622,7 @@ public class VibrationThreadTest {
cancellingThread.join();
verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_SETTINGS_UPDATE);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
}
@Test
@@ -628,9 +636,9 @@ public class VibrationThreadTest {
VibrationEffect effect = VibrationEffect.createVendorEffect(createTestVendorData());
HalVibration vibration = startThreadAndDispatcher(effect);
- assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
- TEST_TIMEOUT_MILLIS));
- assertTrue(mThread.isRunningVibrationId(vibration.id));
+ assertThat(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
+ TEST_TIMEOUT_MILLIS)).isTrue();
+ assertThat(mThread.isRunningVibrationId(vibration.id)).isTrue();
// Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
// fail at waitForCompletion(vibrationThread) if the vibration not cancelled immediately.
@@ -644,7 +652,7 @@ public class VibrationThreadTest {
cancellingThread.join();
verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_SETTINGS_UPDATE);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
}
@Test
@@ -655,9 +663,9 @@ public class VibrationThreadTest {
VibrationEffect effect = VibrationEffect.createWaveform(new long[]{100}, new int[]{100}, 0);
HalVibration vibration = startThreadAndDispatcher(effect);
- assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
- TEST_TIMEOUT_MILLIS));
- assertTrue(mThread.isRunningVibrationId(vibration.id));
+ assertThat(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
+ TEST_TIMEOUT_MILLIS)).isTrue();
+ assertThat(mThread.isRunningVibrationId(vibration.id)).isTrue();
// Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
// fail at waitForCompletion(vibrationThread) if the vibration not cancelled immediately.
@@ -671,7 +679,7 @@ public class VibrationThreadTest {
cancellingThread.join();
verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_SCREEN_OFF);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
}
@Test
@@ -686,10 +694,10 @@ public class VibrationThreadTest {
verify(mManagerHooks).noteVibratorOff(eq(UID));
verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id), anyLong());
verifyCallbacksTriggered(vibration, Status.FINISHED);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
- assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_THUD)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id))
+ .containsExactly(expectedPrebaked(VibrationEffect.EFFECT_THUD)).inOrder();
}
@Test
@@ -698,7 +706,7 @@ public class VibrationThreadTest {
VibrationEffect fallback = VibrationEffect.createOneShot(10, 100);
HalVibration vibration = createVibration(CombinedVibration.createParallel(
- VibrationEffect.get(VibrationEffect.EFFECT_CLICK)));
+ VibrationEffect.get(EFFECT_CLICK)));
vibration.fillFallbacks(unused -> fallback);
startThreadAndDispatcher(vibration);
waitForCompletion();
@@ -707,16 +715,17 @@ public class VibrationThreadTest {
verify(mManagerHooks).noteVibratorOff(eq(UID));
verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id), anyLong());
verifyCallbacksTriggered(vibration, Status.FINISHED);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
- assertEquals(Arrays.asList(expectedOneShot(10)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
- assertEquals(expectedAmplitudes(100), mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id))
+ .containsExactly(expectedOneShot(10)).inOrder();
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getAmplitudes())
+ .containsExactlyElementsIn(expectedAmplitudes(100)).inOrder();
}
@Test
public void vibrate_singleVibratorPrebakedAndUnsupportedEffect_ignoresVibration() {
- VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
+ VibrationEffect effect = VibrationEffect.get(EFFECT_CLICK);
HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
@@ -725,7 +734,7 @@ public class VibrationThreadTest {
verify(mControllerCallbacks, never())
.onComplete(eq(VIBRATOR_ID), eq(vibration.id), anyLong());
verifyCallbacksTriggered(vibration, Status.IGNORED_UNSUPPORTED);
- assertTrue(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id).isEmpty());
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id)).isEmpty();
}
@Test
@@ -745,8 +754,7 @@ public class VibrationThreadTest {
assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
assertThat(mVibratorProviders.get(VIBRATOR_ID).getVendorEffects(vibration.id))
- .containsExactly(effect)
- .inOrder();
+ .containsExactly(effect).inOrder();
}
@Test
@@ -766,11 +774,12 @@ public class VibrationThreadTest {
verify(mManagerHooks).noteVibratorOff(eq(UID));
verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id), anyLong());
verifyCallbacksTriggered(vibration, Status.FINISHED);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
- assertEquals(Arrays.asList(
- expectedPrimitive(PRIMITIVE_CLICK, 1, 0),
- expectedPrimitive(PRIMITIVE_TICK, 0.5f, 0)),
- fakeVibrator.getEffectSegments(vibration.id));
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
+ assertThat(fakeVibrator.getEffectSegments(vibration.id))
+ .containsExactly(
+ expectedPrimitive(PRIMITIVE_CLICK, 1, 0),
+ expectedPrimitive(PRIMITIVE_TICK, 0.5f, 0))
+ .inOrder();
}
@Test
@@ -787,7 +796,7 @@ public class VibrationThreadTest {
verify(mControllerCallbacks, never())
.onComplete(eq(VIBRATOR_ID), eq(vibration.id), anyLong());
verifyCallbacksTriggered(vibration, Status.IGNORED_UNSUPPORTED);
- assertTrue(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id).isEmpty());
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id)).isEmpty();
}
@Test
@@ -804,7 +813,7 @@ public class VibrationThreadTest {
verify(mControllerCallbacks, never())
.onComplete(eq(VIBRATOR_ID), eq(vibration.id), anyLong());
verifyCallbacksTriggered(vibration, Status.IGNORED_UNSUPPORTED);
- assertTrue(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id).isEmpty());
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id)).isEmpty();
}
@Test
@@ -826,14 +835,14 @@ public class VibrationThreadTest {
// Vibrator compose called twice.
verify(mControllerCallbacks, times(2))
.onComplete(eq(VIBRATOR_ID), eq(vibration.id), anyLong());
- assertEquals(3, fakeVibrator.getEffectSegments(vibration.id).size());
+ assertThat(fakeVibrator.getEffectSegments(vibration.id)).hasSize(3);
}
@Test
@DisableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
public void vibrate_singleVibratorComposedEffects_runsDifferentVibrations() {
FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
- fakeVibrator.setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+ fakeVibrator.setSupportedEffects(EFFECT_CLICK);
fakeVibrator.setSupportedPrimitives(PRIMITIVE_CLICK, PRIMITIVE_TICK);
fakeVibrator.setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS,
IVibrator.CAP_COMPOSE_PWLE_EFFECTS, IVibrator.CAP_AMPLITUDE_CONTROL);
@@ -847,13 +856,13 @@ public class VibrationThreadTest {
.addEffect(VibrationEffect.createOneShot(10, 100))
.addPrimitive(PRIMITIVE_CLICK, 1f)
.addPrimitive(PRIMITIVE_TICK, 0.5f)
- .addEffect(VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
+ .addEffect(VibrationEffect.get(EFFECT_CLICK))
.addEffect(VibrationEffect.startWaveform()
.addTransition(Duration.ofMillis(10),
targetAmplitude(1), targetFrequency(100))
.addTransition(Duration.ofMillis(20), targetFrequency(120))
.build())
- .addEffect(VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
+ .addEffect(VibrationEffect.get(EFFECT_CLICK))
.compose();
HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
@@ -864,33 +873,37 @@ public class VibrationThreadTest {
verify(mControllerCallbacks, times(5))
.onComplete(eq(VIBRATOR_ID), eq(vibration.id), anyLong());
verifyCallbacksTriggered(vibration, Status.FINISHED);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
- assertEquals(Arrays.asList(
- expectedOneShot(10),
- expectedPrimitive(PRIMITIVE_CLICK, 1, 0),
- expectedPrimitive(PRIMITIVE_TICK, 0.5f, 0),
- expectedPrebaked(VibrationEffect.EFFECT_CLICK),
- expectedRamp(/* startAmplitude= */ 0, /* endAmplitude= */ 0.5f,
- /* startFrequencyHz= */ 150, /* endFrequencyHz= */ 100, /* duration= */ 10),
- expectedRamp(/* startAmplitude= */ 0.5f, /* endAmplitude= */ 0.7f,
- /* startFrequencyHz= */ 100, /* endFrequencyHz= */ 120, /* duration= */ 20),
- expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
- assertEquals(expectedAmplitudes(100), mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id))
+ .containsExactly(
+ expectedOneShot(10),
+ expectedPrimitive(PRIMITIVE_CLICK, 1, 0),
+ expectedPrimitive(PRIMITIVE_TICK, 0.5f, 0),
+ expectedPrebaked(EFFECT_CLICK),
+ expectedRamp(/* startAmplitude= */ 0, /* endAmplitude= */ 0.5f,
+ /* startFrequencyHz= */ 150, /* endFrequencyHz= */ 100,
+ /* duration= */ 10),
+ expectedRamp(/* startAmplitude= */ 0.5f, /* endAmplitude= */ 0.7f,
+ /* startFrequencyHz= */ 100, /* endFrequencyHz= */ 120,
+ /* duration= */ 20),
+ expectedPrebaked(EFFECT_CLICK))
+ .inOrder();
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getAmplitudes())
+ .containsExactlyElementsIn(expectedAmplitudes(100)).inOrder();
}
@Test
public void vibrate_singleVibratorComposedWithFallback_replacedInTheMiddleOfComposition() {
FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
- fakeVibrator.setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+ fakeVibrator.setSupportedEffects(EFFECT_CLICK);
fakeVibrator.setSupportedPrimitives(PRIMITIVE_CLICK, PRIMITIVE_TICK);
fakeVibrator.setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
VibrationEffect fallback = VibrationEffect.createOneShot(10, 100);
VibrationEffect effect = VibrationEffect.startComposition()
- .addEffect(VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
+ .addEffect(VibrationEffect.get(EFFECT_CLICK))
.addPrimitive(PRIMITIVE_CLICK, 1f)
- .addEffect(VibrationEffect.get(VibrationEffect.EFFECT_TICK))
+ .addEffect(VibrationEffect.get(EFFECT_TICK))
.addPrimitive(PRIMITIVE_TICK, 0.5f)
.compose();
HalVibration vibration = createVibration(CombinedVibration.createParallel(effect));
@@ -904,18 +917,19 @@ public class VibrationThreadTest {
verify(mControllerCallbacks, times(4))
.onComplete(eq(VIBRATOR_ID), eq(vibration.id), anyLong());
verifyCallbacksTriggered(vibration, Status.FINISHED);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
List<VibrationEffectSegment> segments =
mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id);
- assertTrue("Wrong segments: " + segments, segments.size() >= 4);
- assertTrue(segments.get(0) instanceof PrebakedSegment);
- assertTrue(segments.get(1) instanceof PrimitiveSegment);
+ assertWithMessage("Wrong segments: %s", segments).that(segments.size()).isGreaterThan(3);
+ assertThat(segments.get(0)).isInstanceOf(PrebakedSegment.class);
+ assertThat(segments.get(1)).isInstanceOf(PrimitiveSegment.class);
for (int i = 2; i < segments.size() - 1; i++) {
// One or more step segments as fallback for the EFFECT_TICK.
- assertTrue(segments.get(i) instanceof StepSegment);
+ assertWithMessage("For segment index %s", i)
+ .that(segments.get(i)).isInstanceOf(StepSegment.class);
}
- assertTrue(segments.get(segments.size() - 1) instanceof PrimitiveSegment);
+ assertThat(segments.get(segments.size() - 1)).isInstanceOf(PrimitiveSegment.class);
}
@Test
@@ -942,14 +956,15 @@ public class VibrationThreadTest {
verify(mManagerHooks).noteVibratorOff(eq(UID));
verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id), anyLong());
verifyCallbacksTriggered(vibration, Status.FINISHED);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
- assertEquals(Arrays.asList(
- expectedPwle(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f, /*timeMillis=*/ 0),
- expectedPwle(/*amplitude=*/ 0.1f, /*frequencyHz=*/ 60f, /*timeMillis=*/ 20),
- expectedPwle(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 30),
- expectedPwle(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 20),
- expectedPwle(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 30)
- ), fakeVibrator.getEffectPwlePoints(vibration.id));
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
+ assertThat(fakeVibrator.getEffectPwlePoints(vibration.id))
+ .containsExactly(
+ expectedPwle(0.0f, 60f, 0),
+ expectedPwle(0.1f, 60f, 20),
+ expectedPwle(0.3f, 100f, 30),
+ expectedPwle(0.4f, 120f, 20),
+ expectedPwle(0.0f, 120f, 30))
+ .inOrder();
}
@@ -978,13 +993,14 @@ public class VibrationThreadTest {
verify(mManagerHooks).noteVibratorOff(eq(UID));
verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id), anyLong());
verifyCallbacksTriggered(vibration, Status.FINISHED);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
- assertEquals(Arrays.asList(
- expectedPwle(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 150f, /*timeMillis=*/ 0),
- expectedPwle(/*amplitude=*/ 1.0f, /*frequencyHz=*/ 150f, /*timeMillis=*/ 20),
- expectedPwle(/*amplitude=*/ 1.0f, /*frequencyHz=*/ 150f, /*timeMillis=*/ 100),
- expectedPwle(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 150f, /*timeMillis=*/ 100)
- ), fakeVibrator.getEffectPwlePoints(vibration.id));
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
+ assertThat(fakeVibrator.getEffectPwlePoints(vibration.id))
+ .containsExactly(
+ expectedPwle(0.0f, 150f, 0),
+ expectedPwle(1.0f, 150f, 20),
+ expectedPwle(1.0f, 150f, 100),
+ expectedPwle(0.0f, 150f, 100))
+ .inOrder();
}
@@ -1014,15 +1030,15 @@ public class VibrationThreadTest {
verify(mManagerHooks).noteVibratorOff(eq(UID));
verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id), anyLong());
verifyCallbacksTriggered(vibration, Status.FINISHED);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
- assertEquals(Arrays.asList(
- expectedPwle(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 30f, /*timeMillis=*/ 0),
- expectedPwle(/*amplitude=*/ 0.1f, /*frequencyHz=*/ 60f, /*timeMillis=*/ 20),
- expectedPwle(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 30),
- expectedPwle(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 20),
- expectedPwle(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 30)
- ), fakeVibrator.getEffectPwlePoints(vibration.id));
-
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
+ assertThat(fakeVibrator.getEffectPwlePoints(vibration.id))
+ .containsExactly(
+ expectedPwle(0.0f, 30f, 0),
+ expectedPwle(0.1f, 60f, 20),
+ expectedPwle(0.3f, 100f, 30),
+ expectedPwle(0.4f, 120f, 20),
+ expectedPwle(0.0f, 120f, 30))
+ .inOrder();
}
@Test
@@ -1054,18 +1070,17 @@ public class VibrationThreadTest {
// Using best split points instead of max-packing PWLEs.
verify(mControllerCallbacks, times(3))
.onComplete(eq(VIBRATOR_ID), eq(vibration.id), anyLong());
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
-
- assertEquals(Arrays.asList(
- expectedPwle(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 0),
- expectedPwle(/*amplitude=*/ 0.8f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 30),
- expectedPwle(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 30),
- expectedPwle(/*amplitude=*/ 0.9f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 0),
- expectedPwle(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 30),
- expectedPwle(/*amplitude=*/ 0.6f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 0),
- expectedPwle(/*amplitude=*/ 0.7f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 30)
- ), fakeVibrator.getEffectPwlePoints(vibration.id));
-
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
+ assertThat(fakeVibrator.getEffectPwlePoints(vibration.id))
+ .containsExactly(
+ expectedPwle(0.0f, 100f, 0),
+ expectedPwle(0.8f, 100f, 30),
+ expectedPwle(0.0f, 100f, 30),
+ expectedPwle(0.9f, 100f, 0),
+ expectedPwle(0.4f, 100f, 30),
+ expectedPwle(0.6f, 100f, 0),
+ expectedPwle(0.7f, 100f, 30))
+ .inOrder();
}
@Test
@@ -1094,17 +1109,21 @@ public class VibrationThreadTest {
verify(mManagerHooks).noteVibratorOff(eq(UID));
verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id), anyLong());
verifyCallbacksTriggered(vibration, Status.FINISHED);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
- assertEquals(Arrays.asList(
- expectedRamp(/* amplitude= */ 1, /* frequencyHz= */ 150, /* duration= */ 10),
- expectedRamp(/* startAmplitude= */ 1, /* endAmplitude= */ 0,
- /* startFrequencyHz= */ 150, /* endFrequencyHz= */ 150, /* duration= */ 20),
- expectedRamp(/* amplitude= */ 0.5f, /* frequencyHz= */ 100, /* duration= */ 30),
- expectedRamp(/* startAmplitude= */ 0.5f, /* endAmplitude= */ 0.6f,
- /* startFrequencyHz= */ 100, /* endFrequencyHz= */ 200,
- /* duration= */ 40)),
- fakeVibrator.getEffectSegments(vibration.id));
- assertEquals(Arrays.asList(Braking.CLAB), fakeVibrator.getBraking(vibration.id));
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
+ assertThat(fakeVibrator.getEffectSegments(vibration.id))
+ .containsExactly(
+ expectedRamp(/* amplitude= */ 1, /* frequencyHz= */ 150,
+ /* duration= */ 10),
+ expectedRamp(/* startAmplitude= */ 1, /* endAmplitude= */ 0,
+ /* startFrequencyHz= */ 150, /* endFrequencyHz= */ 150,
+ /* duration= */ 20),
+ expectedRamp(/* amplitude= */ 0.5f, /* frequencyHz= */ 100,
+ /* duration= */ 30),
+ expectedRamp(/* startAmplitude= */ 0.5f, /* endAmplitude= */ 0.6f,
+ /* startFrequencyHz= */ 100, /* endFrequencyHz= */ 200,
+ /* duration= */ 40))
+ .inOrder();
+ assertThat(fakeVibrator.getBraking(vibration.id)).containsExactly(Braking.CLAB).inOrder();
}
@Test
@@ -1137,7 +1156,7 @@ public class VibrationThreadTest {
// Using best split points instead of max-packing PWLEs.
verify(mControllerCallbacks, times(3))
.onComplete(eq(VIBRATOR_ID), eq(vibration.id), anyLong());
- assertEquals(6, fakeVibrator.getEffectSegments(vibration.id).size());
+ assertThat(fakeVibrator.getEffectSegments(vibration.id)).hasSize(6);
}
@Test
@@ -1148,15 +1167,16 @@ public class VibrationThreadTest {
VibrationEffect effect = VibrationEffect.createWaveform(new long[]{5}, new int[]{100}, 0);
HalVibration vibration = startThreadAndDispatcher(effect);
- assertTrue(waitUntil(() -> fakeVibrator.getAmplitudes().size() > 2, TEST_TIMEOUT_MILLIS));
+ assertThat(waitUntil(() -> fakeVibrator.getAmplitudes().size() > 2, TEST_TIMEOUT_MILLIS))
+ .isTrue();
// Vibration still running after 2 cycles.
- assertTrue(mThread.isRunningVibrationId(vibration.id));
- assertTrue(mControllers.get(VIBRATOR_ID).isVibrating());
+ assertThat(mThread.isRunningVibrationId(vibration.id)).isTrue();
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isTrue();
mVibrationConductor.notifyCancelled(
new Vibration.EndInfo(Status.CANCELLED_BINDER_DIED), /* immediate= */ false);
waitForCompletion();
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
verifyCallbacksTriggered(vibration, Status.CANCELLED_BINDER_DIED);
}
@@ -1176,11 +1196,11 @@ public class VibrationThreadTest {
@Test
public void vibrate_multipleExistingAndMissingVibrators_vibratesOnlyExistingOnes() {
- mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_TICK);
+ mVibratorProviders.get(1).setSupportedEffects(EFFECT_TICK);
CombinedVibration effect = CombinedVibration.startParallel()
- .addVibrator(VIBRATOR_ID, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
- .addVibrator(2, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
+ .addVibrator(VIBRATOR_ID, VibrationEffect.get(EFFECT_TICK))
+ .addVibrator(2, VibrationEffect.get(EFFECT_TICK))
.combine();
HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
@@ -1190,21 +1210,21 @@ public class VibrationThreadTest {
verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id), anyLong());
verify(mControllerCallbacks, never()).onComplete(eq(2), eq(vibration.id), anyLong());
verifyCallbacksTriggered(vibration, Status.FINISHED);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
- assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_TICK)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id))
+ .containsExactly(expectedPrebaked(EFFECT_TICK)).inOrder();
}
@Test
public void vibrate_multipleMono_runsSameEffectInAllVibrators() {
mockVibrators(1, 2, 3);
- mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
- mVibratorProviders.get(2).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
- mVibratorProviders.get(3).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+ mVibratorProviders.get(1).setSupportedEffects(EFFECT_CLICK);
+ mVibratorProviders.get(2).setSupportedEffects(EFFECT_CLICK);
+ mVibratorProviders.get(3).setSupportedEffects(EFFECT_CLICK);
CombinedVibration effect = CombinedVibration.createParallel(
- VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
+ VibrationEffect.get(EFFECT_CLICK));
HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
@@ -1214,23 +1234,23 @@ public class VibrationThreadTest {
verify(mControllerCallbacks).onComplete(eq(2), eq(vibration.id), anyLong());
verify(mControllerCallbacks).onComplete(eq(3), eq(vibration.id), anyLong());
verifyCallbacksTriggered(vibration, Status.FINISHED);
- assertFalse(mControllers.get(1).isVibrating());
- assertFalse(mControllers.get(2).isVibrating());
- assertFalse(mControllers.get(3).isVibrating());
+ assertThat(mControllers.get(1).isVibrating()).isFalse();
+ assertThat(mControllers.get(2).isVibrating()).isFalse();
+ assertThat(mControllers.get(3).isVibrating()).isFalse();
- VibrationEffectSegment expected = expectedPrebaked(VibrationEffect.EFFECT_CLICK);
- assertEquals(Arrays.asList(expected),
- mVibratorProviders.get(1).getEffectSegments(vibration.id));
- assertEquals(Arrays.asList(expected),
- mVibratorProviders.get(2).getEffectSegments(vibration.id));
- assertEquals(Arrays.asList(expected),
- mVibratorProviders.get(3).getEffectSegments(vibration.id));
+ VibrationEffectSegment expected = expectedPrebaked(EFFECT_CLICK);
+ assertThat(mVibratorProviders.get(1).getEffectSegments(vibration.id))
+ .containsExactly(expected).inOrder();
+ assertThat(mVibratorProviders.get(2).getEffectSegments(vibration.id))
+ .containsExactly(expected).inOrder();
+ assertThat(mVibratorProviders.get(3).getEffectSegments(vibration.id))
+ .containsExactly(expected).inOrder();
}
@Test
public void vibrate_multipleStereo_runsVibrationOnRightVibrators() {
mockVibrators(1, 2, 3, 4);
- mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+ mVibratorProviders.get(1).setSupportedEffects(EFFECT_CLICK);
mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
mVibratorProviders.get(3).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
mVibratorProviders.get(4).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
@@ -1240,7 +1260,7 @@ public class VibrationThreadTest {
.addPrimitive(PRIMITIVE_CLICK)
.compose();
CombinedVibration effect = CombinedVibration.startParallel()
- .addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
+ .addVibrator(1, VibrationEffect.get(EFFECT_CLICK))
.addVibrator(2, VibrationEffect.createOneShot(10, 100))
.addVibrator(3, VibrationEffect.createWaveform(
new long[]{10, 10}, new int[]{1, 2}, -1))
@@ -1256,21 +1276,23 @@ public class VibrationThreadTest {
verify(mControllerCallbacks).onComplete(eq(3), eq(vibration.id), anyLong());
verify(mControllerCallbacks).onComplete(eq(4), eq(vibration.id), anyLong());
verifyCallbacksTriggered(vibration, Status.FINISHED);
- assertFalse(mControllers.get(1).isVibrating());
- assertFalse(mControllers.get(2).isVibrating());
- assertFalse(mControllers.get(3).isVibrating());
- assertFalse(mControllers.get(4).isVibrating());
-
- assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
- mVibratorProviders.get(1).getEffectSegments(vibration.id));
- assertEquals(Arrays.asList(expectedOneShot(10)),
- mVibratorProviders.get(2).getEffectSegments(vibration.id));
- assertEquals(expectedAmplitudes(100), mVibratorProviders.get(2).getAmplitudes());
- assertEquals(Arrays.asList(expectedOneShot(20)),
- mVibratorProviders.get(3).getEffectSegments(vibration.id));
- assertEquals(expectedAmplitudes(1, 2), mVibratorProviders.get(3).getAmplitudes());
- assertEquals(Arrays.asList(expectedPrimitive(PRIMITIVE_CLICK, 1, 0)),
- mVibratorProviders.get(4).getEffectSegments(vibration.id));
+ assertThat(mControllers.get(1).isVibrating()).isFalse();
+ assertThat(mControllers.get(2).isVibrating()).isFalse();
+ assertThat(mControllers.get(3).isVibrating()).isFalse();
+ assertThat(mControllers.get(4).isVibrating()).isFalse();
+
+ assertThat(mVibratorProviders.get(1).getEffectSegments(vibration.id))
+ .containsExactly(expectedPrebaked(EFFECT_CLICK)).inOrder();
+ assertThat(mVibratorProviders.get(2).getEffectSegments(vibration.id))
+ .containsExactly(expectedOneShot(10)).inOrder();
+ assertThat(mVibratorProviders.get(2).getAmplitudes())
+ .containsExactlyElementsIn(expectedAmplitudes(100)).inOrder();
+ assertThat(mVibratorProviders.get(3).getEffectSegments(vibration.id))
+ .containsExactly(expectedOneShot(20)).inOrder();
+ assertThat(mVibratorProviders.get(3).getAmplitudes())
+ .containsExactlyElementsIn(expectedAmplitudes(1, 2)).inOrder();
+ assertThat(mVibratorProviders.get(4).getEffectSegments(vibration.id))
+ .containsExactly(expectedPrimitive(PRIMITIVE_CLICK, 1, 0)).inOrder();
}
@Test
@@ -1279,13 +1301,13 @@ public class VibrationThreadTest {
mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
mVibratorProviders.get(2).setSupportedPrimitives(PRIMITIVE_CLICK);
- mVibratorProviders.get(3).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+ mVibratorProviders.get(3).setSupportedEffects(EFFECT_CLICK);
VibrationEffect composed = VibrationEffect.startComposition()
.addPrimitive(PRIMITIVE_CLICK)
.compose();
CombinedVibration effect = CombinedVibration.startSequential()
- .addNext(3, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), /* delay= */ 50)
+ .addNext(3, VibrationEffect.get(EFFECT_CLICK), /* delay= */ 50)
.addNext(1, VibrationEffect.createOneShot(10, 100), /* delay= */ 50)
.addNext(2, composed, /* delay= */ 50)
.combine();
@@ -1306,17 +1328,18 @@ public class VibrationThreadTest {
batteryVerifier.verify(mManagerHooks).noteVibratorOff(eq(UID));
verifyCallbacksTriggered(vibration, Status.FINISHED);
- assertFalse(mControllers.get(1).isVibrating());
- assertFalse(mControllers.get(2).isVibrating());
- assertFalse(mControllers.get(3).isVibrating());
+ assertThat(mControllers.get(1).isVibrating()).isFalse();
+ assertThat(mControllers.get(2).isVibrating()).isFalse();
+ assertThat(mControllers.get(3).isVibrating()).isFalse();
- assertEquals(Arrays.asList(expectedOneShot(10)),
- mVibratorProviders.get(1).getEffectSegments(vibration.id));
- assertEquals(expectedAmplitudes(100), mVibratorProviders.get(1).getAmplitudes());
- assertEquals(Arrays.asList(expectedPrimitive(PRIMITIVE_CLICK, 1, 0)),
- mVibratorProviders.get(2).getEffectSegments(vibration.id));
- assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
- mVibratorProviders.get(3).getEffectSegments(vibration.id));
+ assertThat(mVibratorProviders.get(1).getEffectSegments(vibration.id))
+ .containsExactly(expectedOneShot(10)).inOrder();
+ assertThat(mVibratorProviders.get(1).getAmplitudes())
+ .containsExactlyElementsIn(expectedAmplitudes(100)).inOrder();
+ assertThat(mVibratorProviders.get(2).getEffectSegments(vibration.id))
+ .containsExactly(expectedPrimitive(PRIMITIVE_CLICK, 1, 0)).inOrder();
+ assertThat(mVibratorProviders.get(3).getEffectSegments(vibration.id))
+ .containsExactly(expectedPrebaked(EFFECT_CLICK)).inOrder();
}
@Test
@@ -1339,10 +1362,10 @@ public class VibrationThreadTest {
when(mManagerHooks.triggerSyncedVibration(eq(vibration.id))).thenReturn(true);
startThreadAndDispatcher(vibration);
- assertTrue(waitUntil(
+ assertThat(waitUntil(
() -> !mVibratorProviders.get(1).getEffectSegments(vibration.id).isEmpty()
&& !mVibratorProviders.get(2).getEffectSegments(vibration.id).isEmpty(),
- TEST_TIMEOUT_MILLIS));
+ TEST_TIMEOUT_MILLIS)).isTrue();
mVibrationConductor.notifySyncedVibrationComplete();
waitForCompletion();
@@ -1353,17 +1376,17 @@ public class VibrationThreadTest {
verifyCallbacksTriggered(vibration, Status.FINISHED);
VibrationEffectSegment expected = expectedPrimitive(PRIMITIVE_CLICK, 1, 100);
- assertEquals(Arrays.asList(expected),
- mVibratorProviders.get(1).getEffectSegments(vibration.id));
- assertEquals(Arrays.asList(expected),
- mVibratorProviders.get(2).getEffectSegments(vibration.id));
+ assertThat(mVibratorProviders.get(1).getEffectSegments(vibration.id))
+ .containsExactly(expected).inOrder();
+ assertThat(mVibratorProviders.get(2).getEffectSegments(vibration.id))
+ .containsExactly(expected).inOrder();
}
@Test
public void vibrate_multipleSynced_callsPrepareAndTriggerCallbacks() {
int[] vibratorIds = new int[]{1, 2, 3, 4};
mockVibrators(vibratorIds);
- mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+ mVibratorProviders.get(1).setSupportedEffects(EFFECT_CLICK);
mVibratorProviders.get(4).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
mVibratorProviders.get(4).setSupportedPrimitives(PRIMITIVE_CLICK);
when(mManagerHooks.prepareSyncedVibration(anyLong(), any())).thenReturn(true);
@@ -1372,7 +1395,7 @@ public class VibrationThreadTest {
.addPrimitive(PRIMITIVE_CLICK)
.compose();
CombinedVibration effect = CombinedVibration.startParallel()
- .addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
+ .addVibrator(1, VibrationEffect.get(EFFECT_CLICK))
.addVibrator(2, VibrationEffect.createOneShot(10, 100))
.addVibrator(3, VibrationEffect.createWaveform(new long[]{10}, new int[]{100}, -1))
.addVibrator(4, composed)
@@ -1417,24 +1440,26 @@ public class VibrationThreadTest {
verify(mManagerHooks, never()).triggerSyncedVibration(eq(vibration.id));
verify(mManagerHooks, never()).cancelSyncedVibration();
- assertEquals(Arrays.asList(expectedOneShot(10)),
- mVibratorProviders.get(1).getEffectSegments(vibration.id));
- assertEquals(expectedAmplitudes(100), mVibratorProviders.get(1).getAmplitudes());
- assertEquals(Arrays.asList(expectedOneShot(5)),
- mVibratorProviders.get(2).getEffectSegments(vibration.id));
- assertEquals(expectedAmplitudes(200), mVibratorProviders.get(2).getAmplitudes());
+ assertThat(mVibratorProviders.get(1).getEffectSegments(vibration.id))
+ .containsExactly(expectedOneShot(10)).inOrder();
+ assertThat(mVibratorProviders.get(1).getAmplitudes())
+ .containsExactlyElementsIn(expectedAmplitudes(100)).inOrder();
+ assertThat(mVibratorProviders.get(2).getEffectSegments(vibration.id))
+ .containsExactly(expectedOneShot(5)).inOrder();
+ assertThat(mVibratorProviders.get(2).getAmplitudes())
+ .containsExactlyElementsIn(expectedAmplitudes(200)).inOrder();
}
@Test
public void vibrate_multipleSyncedTriggerFailed_cancelPreparedVibrationAndSkipSetAmplitude() {
int[] vibratorIds = new int[]{1, 2};
mockVibrators(vibratorIds);
- mVibratorProviders.get(2).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+ mVibratorProviders.get(2).setSupportedEffects(EFFECT_CLICK);
when(mManagerHooks.prepareSyncedVibration(anyLong(), any())).thenReturn(true);
CombinedVibration effect = CombinedVibration.startParallel()
.addVibrator(1, VibrationEffect.createOneShot(10, 100))
- .addVibrator(2, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
+ .addVibrator(2, VibrationEffect.get(EFFECT_CLICK))
.combine();
// We create the HalVibration here to obtain the vibration id and use it to mock the
// required response when calling triggerSyncedVibration.
@@ -1451,7 +1476,7 @@ public class VibrationThreadTest {
verify(mManagerHooks).prepareSyncedVibration(eq(expectedCap), eq(vibratorIds));
verify(mManagerHooks).triggerSyncedVibration(eq(vibration.id));
verify(mManagerHooks).cancelSyncedVibration();
- assertTrue(mVibratorProviders.get(1).getAmplitudes().isEmpty());
+ assertThat(mVibratorProviders.get(1).getAmplitudes()).isEmpty();
}
@Test
@@ -1472,11 +1497,11 @@ public class VibrationThreadTest {
HalVibration vibration = startThreadAndDispatcher(effect);
// All vibrators are turned on in parallel.
- assertTrue(waitUntil(
+ assertThat(waitUntil(
() -> mControllers.get(1).isVibrating()
&& mControllers.get(2).isVibrating()
&& mControllers.get(3).isVibrating(),
- TEST_TIMEOUT_MILLIS));
+ TEST_TIMEOUT_MILLIS)).isTrue();
waitForCompletion();
@@ -1486,19 +1511,23 @@ public class VibrationThreadTest {
verify(mControllerCallbacks).onComplete(eq(2), eq(vibration.id), anyLong());
verify(mControllerCallbacks).onComplete(eq(3), eq(vibration.id), anyLong());
verifyCallbacksTriggered(vibration, Status.FINISHED);
- assertFalse(mControllers.get(1).isVibrating());
- assertFalse(mControllers.get(2).isVibrating());
- assertFalse(mControllers.get(3).isVibrating());
+ assertThat(mControllers.get(1).isVibrating()).isFalse();
+ assertThat(mControllers.get(2).isVibrating()).isFalse();
+ assertThat(mControllers.get(3).isVibrating()).isFalse();
+
+ assertThat(mVibratorProviders.get(1).getEffectSegments(vibration.id))
+ .containsExactly(expectedOneShot(25)).inOrder();
+ assertThat(mVibratorProviders.get(2).getEffectSegments(vibration.id))
+ .containsExactly(expectedOneShot(80)).inOrder();
+ assertThat(mVibratorProviders.get(3).getEffectSegments(vibration.id))
+ .containsExactly(expectedOneShot(60)).inOrder();
+ assertThat(mVibratorProviders.get(1).getAmplitudes())
+ .containsExactlyElementsIn(expectedAmplitudes(1, 2, 3)).inOrder();
+ assertThat(mVibratorProviders.get(2).getAmplitudes())
+ .containsExactlyElementsIn(expectedAmplitudes(4, 5)).inOrder();
+ assertThat(mVibratorProviders.get(3).getAmplitudes())
+ .containsExactlyElementsIn(expectedAmplitudes(6)).inOrder();
- assertEquals(Arrays.asList(expectedOneShot(25)),
- mVibratorProviders.get(1).getEffectSegments(vibration.id));
- assertEquals(Arrays.asList(expectedOneShot(80)),
- mVibratorProviders.get(2).getEffectSegments(vibration.id));
- assertEquals(Arrays.asList(expectedOneShot(60)),
- mVibratorProviders.get(3).getEffectSegments(vibration.id));
- assertEquals(expectedAmplitudes(1, 2, 3), mVibratorProviders.get(1).getAmplitudes());
- assertEquals(expectedAmplitudes(4, 5), mVibratorProviders.get(2).getAmplitudes());
- assertEquals(expectedAmplitudes(6), mVibratorProviders.get(3).getAmplitudes());
}
@Test
@@ -1545,8 +1574,8 @@ public class VibrationThreadTest {
VibrationEffect.createOneShot(
expectedDuration, VibrationEffect.DEFAULT_AMPLITUDE)));
- startThreadAndDispatcher(vibration);
long startTime = SystemClock.elapsedRealtime();
+ startThreadAndDispatcher(vibration);
vibration.waitForEnd();
long vibrationEndTime = SystemClock.elapsedRealtime();
@@ -1616,26 +1645,24 @@ public class VibrationThreadTest {
// Allow some delay for thread scheduling and callback triggering.
int maxDelay = (int) (0.05 * totalDuration); // < 5% of total duration
- assertTrue("Waveform with perceived delay of " + delay + "ms,"
- + " expected less than " + maxDelay + "ms",
- delay < maxDelay);
+ assertThat(delay).isLessThan(maxDelay);
}
@LargeTest
@Test
public void vibrate_cancelSlowVibrator_cancelIsNotBlockedByVibrationThread() throws Exception {
FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
- fakeVibrator.setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+ fakeVibrator.setSupportedEffects(EFFECT_CLICK);
long latency = 5_000; // 5s
fakeVibrator.setOnLatency(latency);
- VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
+ VibrationEffect effect = VibrationEffect.get(EFFECT_CLICK);
HalVibration vibration = startThreadAndDispatcher(effect);
- assertTrue(waitUntil(() -> !fakeVibrator.getEffectSegments(vibration.id).isEmpty(),
- TEST_TIMEOUT_MILLIS));
- assertTrue(mThread.isRunningVibrationId(vibration.id));
+ assertThat(waitUntil(() -> !fakeVibrator.getEffectSegments(vibration.id).isEmpty(),
+ TEST_TIMEOUT_MILLIS)).isTrue();
+ assertThat(mThread.isRunningVibrationId(vibration.id)).isTrue();
// Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
// fail at waitForCompletion(cancellingThread).
@@ -1651,18 +1678,18 @@ public class VibrationThreadTest {
// After the vibrator call ends the vibration is cancelled and the vibrator is turned off.
waitForCompletion(/* timeout= */ latency + TEST_TIMEOUT_MILLIS);
verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_USER);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
}
@Test
public void vibrate_multiplePredefinedCancel_cancelsVibrationImmediately() throws Exception {
mockVibrators(1, 2);
- mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+ mVibratorProviders.get(1).setSupportedEffects(EFFECT_CLICK);
mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
mVibratorProviders.get(2).setSupportedPrimitives(PRIMITIVE_CLICK);
CombinedVibration effect = CombinedVibration.startParallel()
- .addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
+ .addVibrator(1, VibrationEffect.get(EFFECT_CLICK))
.addVibrator(2, VibrationEffect.startComposition()
.addPrimitive(PRIMITIVE_CLICK, 1f, 100)
.addPrimitive(PRIMITIVE_CLICK, 1f, 100)
@@ -1671,8 +1698,9 @@ public class VibrationThreadTest {
.combine();
HalVibration vibration = startThreadAndDispatcher(effect);
- assertTrue(waitUntil(() -> mControllers.get(2).isVibrating(), TEST_TIMEOUT_MILLIS));
- assertTrue(mThread.isRunningVibrationId(vibration.id));
+ assertThat(waitUntil(() -> mControllers.get(2).isVibrating(), TEST_TIMEOUT_MILLIS))
+ .isTrue();
+ assertThat(mThread.isRunningVibrationId(vibration.id)).isTrue();
// Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
// fail at waitForCompletion(vibrationThread) if the vibration not cancelled immediately.
@@ -1686,8 +1714,8 @@ public class VibrationThreadTest {
cancellingThread.join();
verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_SCREEN_OFF);
- assertFalse(mControllers.get(1).isVibrating());
- assertFalse(mControllers.get(2).isVibrating());
+ assertThat(mControllers.get(1).isVibrating()).isFalse();
+ assertThat(mControllers.get(2).isVibrating()).isFalse();
}
@Test
@@ -1705,8 +1733,9 @@ public class VibrationThreadTest {
.combine();
HalVibration vibration = startThreadAndDispatcher(effect);
- assertTrue(waitUntil(() -> mControllers.get(2).isVibrating(), TEST_TIMEOUT_MILLIS));
- assertTrue(mThread.isRunningVibrationId(vibration.id));
+ assertThat(waitUntil(() -> mControllers.get(2).isVibrating(), TEST_TIMEOUT_MILLIS))
+ .isTrue();
+ assertThat(mThread.isRunningVibrationId(vibration.id)).isTrue();
// Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
// fail at waitForCompletion(vibrationThread) if the vibration not cancelled immediately.
@@ -1720,8 +1749,8 @@ public class VibrationThreadTest {
cancellingThread.join();
verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_SCREEN_OFF);
- assertFalse(mControllers.get(1).isVibrating());
- assertFalse(mControllers.get(2).isVibrating());
+ assertThat(mControllers.get(1).isVibrating()).isFalse();
+ assertThat(mControllers.get(2).isVibrating()).isFalse();
}
@Test
@@ -1737,10 +1766,10 @@ public class VibrationThreadTest {
.combine();
HalVibration vibration = startThreadAndDispatcher(effect);
- assertTrue(waitUntil(() -> mControllers.get(1).isVibrating()
+ assertThat(waitUntil(() -> mControllers.get(1).isVibrating()
&& mControllers.get(2).isVibrating(),
- TEST_TIMEOUT_MILLIS));
- assertTrue(mThread.isRunningVibrationId(vibration.id));
+ TEST_TIMEOUT_MILLIS)).isTrue();
+ assertThat(mThread.isRunningVibrationId(vibration.id)).isTrue();
// Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
// fail at waitForCompletion(vibrationThread) if the vibration not cancelled immediately.
@@ -1754,8 +1783,8 @@ public class VibrationThreadTest {
cancellingThread.join();
verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_SCREEN_OFF);
- assertFalse(mControllers.get(1).isVibrating());
- assertFalse(mControllers.get(2).isVibrating());
+ assertThat(mControllers.get(1).isVibrating()).isFalse();
+ assertThat(mControllers.get(2).isVibrating()).isFalse();
}
@Test
@@ -1763,17 +1792,18 @@ public class VibrationThreadTest {
VibrationEffect effect = VibrationEffect.createWaveform(new long[]{5}, new int[]{100}, 0);
HalVibration vibration = startThreadAndDispatcher(effect);
- assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
- TEST_TIMEOUT_MILLIS));
- assertTrue(mThread.isRunningVibrationId(vibration.id));
+ assertThat(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
+ TEST_TIMEOUT_MILLIS)).isTrue();
+ assertThat(mThread.isRunningVibrationId(vibration.id)).isTrue();
mVibrationConductor.notifyCancelled(
new Vibration.EndInfo(Status.CANCELLED_BINDER_DIED), /* immediate= */ false);
waitForCompletion();
verifyCallbacksTriggered(vibration, Status.CANCELLED_BINDER_DIED);
- assertFalse(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id).isEmpty());
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id))
+ .isNotEmpty();
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
}
@Test
@@ -1790,13 +1820,16 @@ public class VibrationThreadTest {
verifyCallbacksTriggered(vibration, Status.FINISHED);
// Duration extended for 5 + 5 + 5 + 15.
- assertEquals(Arrays.asList(expectedOneShot(30)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id))
+ .containsExactly(expectedOneShot(30)).inOrder();
List<Float> amplitudes = mVibratorProviders.get(VIBRATOR_ID).getAmplitudes();
- assertTrue(amplitudes.size() > 3);
- assertEquals(expectedAmplitudes(60, 120, 240), amplitudes.subList(0, 3));
+ assertThat(amplitudes.size()).isGreaterThan(3);
+ assertThat(amplitudes.subList(0, 3))
+ .containsExactlyElementsIn(expectedAmplitudes(60, 120, 240))
+ .inOrder();
for (int i = 3; i < amplitudes.size(); i++) {
- assertTrue(amplitudes.get(i) < amplitudes.get(i - 1));
+ assertWithMessage("For amplitude index %s", i)
+ .that(amplitudes.get(i)).isLessThan(amplitudes.get(i - 1));
}
}
@@ -1814,11 +1847,11 @@ public class VibrationThreadTest {
verify(mManagerHooks, never()).onVibrationThreadReleased(anyLong());
// Thread still running ramp down.
- assertTrue(mThread.isRunningVibrationId(vibration.id));
+ assertThat(mThread.isRunningVibrationId(vibration.id)).isTrue();
// Duration extended for 10 + 10000.
- assertEquals(Arrays.asList(expectedOneShot(10_010)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id))
+ .containsExactly(expectedOneShot(10_010)).inOrder();
// Will stop the ramp down right away.
mVibrationConductor.notifyCancelled(
@@ -1838,8 +1871,8 @@ public class VibrationThreadTest {
VibrationEffect effect = VibrationEffect.createOneShot(10_000, 240);
HalVibration vibration = startThreadAndDispatcher(effect);
- assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
- TEST_TIMEOUT_MILLIS));
+ assertThat(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
+ TEST_TIMEOUT_MILLIS)).isTrue();
mVibrationConductor.notifyCancelled(
new Vibration.EndInfo(Status.CANCELLED_BY_USER), /* immediate= */ false);
waitForCompletion();
@@ -1847,12 +1880,13 @@ public class VibrationThreadTest {
verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_USER);
// Duration extended for 10000 + 15.
- assertEquals(Arrays.asList(expectedOneShot(10_015)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id))
+ .containsExactly(expectedOneShot(10_015)).inOrder();
List<Float> amplitudes = mVibratorProviders.get(VIBRATOR_ID).getAmplitudes();
- assertTrue(amplitudes.size() > 1);
+ assertThat(amplitudes.size()).isGreaterThan(1);
for (int i = 1; i < amplitudes.size(); i++) {
- assertTrue(amplitudes.get(i) < amplitudes.get(i - 1));
+ assertWithMessage("For amplitude index %s", i)
+ .that(amplitudes.get(i)).isLessThan(amplitudes.get(i - 1));
}
}
@@ -1860,18 +1894,18 @@ public class VibrationThreadTest {
public void vibrate_predefinedWithRampDown_doesNotAddRampDown() {
when(mVibrationConfigMock.getRampDownDurationMs()).thenReturn(15);
mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
- mVibratorProviders.get(VIBRATOR_ID).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+ mVibratorProviders.get(VIBRATOR_ID).setSupportedEffects(EFFECT_CLICK);
- VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
+ VibrationEffect effect = VibrationEffect.get(EFFECT_CLICK);
HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id), anyLong());
verifyCallbacksTriggered(vibration, Status.FINISHED);
- assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
- assertTrue(mVibratorProviders.get(VIBRATOR_ID).getAmplitudes().isEmpty());
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id))
+ .containsExactly(expectedPrebaked(EFFECT_CLICK)).inOrder();
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getAmplitudes()).isEmpty();
}
@Test
@@ -1888,8 +1922,7 @@ public class VibrationThreadTest {
verifyCallbacksTriggered(vibration, Status.FINISHED);
assertThat(mVibratorProviders.get(VIBRATOR_ID).getVendorEffects(vibration.id))
- .containsExactly(effect)
- .inOrder();
+ .containsExactly(effect).inOrder();
assertThat(mVibratorProviders.get(VIBRATOR_ID).getAmplitudes()).isEmpty();
}
@@ -1909,9 +1942,9 @@ public class VibrationThreadTest {
verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id), anyLong());
verifyCallbacksTriggered(vibration, Status.FINISHED);
- assertEquals(Arrays.asList(expectedPrimitive(PRIMITIVE_CLICK, 1, 0)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
- assertTrue(mVibratorProviders.get(VIBRATOR_ID).getAmplitudes().isEmpty());
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id))
+ .containsExactly(expectedPrimitive(PRIMITIVE_CLICK, 1, 0)).inOrder();
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getAmplitudes()).isEmpty();
}
@Test
@@ -1936,30 +1969,29 @@ public class VibrationThreadTest {
verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id), anyLong());
verifyCallbacksTriggered(vibration, Status.FINISHED);
- assertEquals(Arrays.asList(expectedRamp(0, 1, 150, 150, 1)),
- fakeVibrator.getEffectSegments(vibration.id));
- assertTrue(fakeVibrator.getAmplitudes().isEmpty());
+ assertThat(fakeVibrator.getEffectSegments(vibration.id))
+ .containsExactly(expectedRamp(0, 1, 150, 150, 1)).inOrder();
+ assertThat(fakeVibrator.getAmplitudes()).isEmpty();
}
@Test
public void vibrate_multipleVibrations_withCancel() throws Exception {
- mVibratorProviders.get(VIBRATOR_ID).setSupportedEffects(
- VibrationEffect.EFFECT_CLICK, VibrationEffect.EFFECT_TICK);
+ mVibratorProviders.get(VIBRATOR_ID).setSupportedEffects(EFFECT_CLICK, EFFECT_TICK);
mVibratorProviders.get(VIBRATOR_ID).setSupportedPrimitives(PRIMITIVE_CLICK);
mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL,
IVibrator.CAP_COMPOSE_EFFECTS);
// A simple effect, followed by a repeating effect that gets cancelled, followed by another
// simple effect.
- VibrationEffect effect1 = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
+ VibrationEffect effect1 = VibrationEffect.get(EFFECT_CLICK);
VibrationEffect effect2 = VibrationEffect.startComposition()
- .repeatEffectIndefinitely(VibrationEffect.get(VibrationEffect.EFFECT_TICK))
+ .repeatEffectIndefinitely(VibrationEffect.get(EFFECT_TICK))
.compose();
VibrationEffect effect3 = VibrationEffect.startComposition()
.addPrimitive(PRIMITIVE_CLICK)
.compose();
VibrationEffect effect4 = VibrationEffect.createOneShot(8000, 100);
- VibrationEffect effect5 = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
+ VibrationEffect effect5 = VibrationEffect.get(EFFECT_CLICK);
HalVibration vibration1 = startThreadAndDispatcher(effect1);
waitForCompletion();
@@ -1987,14 +2019,14 @@ public class VibrationThreadTest {
waitForCompletion();
FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
- assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+ assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
// Effect1
verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration1.id), anyLong());
verifyCallbacksTriggered(vibration1, Status.FINISHED);
- assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
- fakeVibrator.getEffectSegments(vibration1.id));
+ assertThat(fakeVibrator.getEffectSegments(vibration1.id))
+ .containsExactly(expectedPrebaked(EFFECT_CLICK)).inOrder();
// Effect2: repeating, cancelled.
verify(mControllerCallbacks, atLeast(2))
@@ -2005,24 +2037,24 @@ public class VibrationThreadTest {
// all elements are the same segment.
List<VibrationEffectSegment> actualSegments2 =
fakeVibrator.getEffectSegments(vibration2.id);
- assertTrue(actualSegments2.size() + " > 2", actualSegments2.size() > 2);
+ assertThat(actualSegments2.size()).isGreaterThan(2);
for (VibrationEffectSegment segment : actualSegments2) {
- assertEquals(expectedPrebaked(VibrationEffect.EFFECT_TICK), segment);
+ assertThat(segment).isEqualTo(expectedPrebaked(EFFECT_TICK));
}
// Effect3
verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration3.id), anyLong());
verifyCallbacksTriggered(vibration3, Status.FINISHED);
- assertEquals(Arrays.asList(expectedPrimitive(PRIMITIVE_CLICK, 1, 0)),
- fakeVibrator.getEffectSegments(vibration3.id));
+ assertThat(fakeVibrator.getEffectSegments(vibration3.id))
+ .containsExactly(expectedPrimitive(PRIMITIVE_CLICK, 1, 0)).inOrder();
// Effect4: cancelled quickly.
verifyCallbacksTriggered(vibration4, Status.CANCELLED_BY_SCREEN_OFF);
- assertTrue("Tested duration=" + duration4, duration4 < 2000);
+ assertThat(duration4).isLessThan(2000);
// Effect5: played normally after effect4, which may or may not have played.
- assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
- fakeVibrator.getEffectSegments(vibration5.id));
+ assertThat(fakeVibrator.getEffectSegments(vibration5.id))
+ .containsExactly(expectedPrebaked(EFFECT_CLICK)).inOrder();
}
@Test
@@ -2031,16 +2063,13 @@ public class VibrationThreadTest {
mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
mVibratorProviders.get(2).setSupportedPrimitives(PRIMITIVE_CLICK);
- mVibratorProviders.get(3).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+ mVibratorProviders.get(3).setSupportedEffects(EFFECT_CLICK);
CombinedVibration effect = CombinedVibration.startSequential()
- .addNext(3,
- VibrationEffect.get(VibrationEffect.EFFECT_CLICK),
- /* delay= */ TEST_TIMEOUT_MILLIS)
+ .addNext(3, VibrationEffect.get(EFFECT_CLICK), /* delay= */ TEST_TIMEOUT_MILLIS)
.addNext(1,
VibrationEffect.createWaveform(
- new long[] {TEST_TIMEOUT_MILLIS, TEST_TIMEOUT_MILLIS},
- /* repeat= */ -1),
+ new long[] {TEST_TIMEOUT_MILLIS, TEST_TIMEOUT_MILLIS}, -1),
/* delay= */ TEST_TIMEOUT_MILLIS)
.addNext(2,
VibrationEffect.startComposition()
@@ -2055,20 +2084,22 @@ public class VibrationThreadTest {
// Vibrating state remains ON until session resets it.
verifyCallbacksTriggered(vibration, Status.FINISHED);
- assertTrue(mControllers.get(1).isVibrating());
- assertTrue(mControllers.get(2).isVibrating());
- assertTrue(mControllers.get(3).isVibrating());
-
- assertEquals(0, mVibratorProviders.get(1).getOffCount());
- assertEquals(0, mVibratorProviders.get(2).getOffCount());
- assertEquals(0, mVibratorProviders.get(3).getOffCount());
- assertEquals(Arrays.asList(expectedOneShot(TEST_TIMEOUT_MILLIS)),
- mVibratorProviders.get(1).getEffectSegments(vibration.id));
- assertEquals(expectedAmplitudes(255), mVibratorProviders.get(1).getAmplitudes());
- assertEquals(Arrays.asList(expectedPrimitive(PRIMITIVE_CLICK, 1, TEST_TIMEOUT_MILLIS)),
- mVibratorProviders.get(2).getEffectSegments(vibration.id));
- assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
- mVibratorProviders.get(3).getEffectSegments(vibration.id));
+ assertThat(mControllers.get(1).isVibrating()).isTrue();
+ assertThat(mControllers.get(2).isVibrating()).isTrue();
+ assertThat(mControllers.get(3).isVibrating()).isTrue();
+
+ assertThat(mVibratorProviders.get(1).getOffCount()).isEqualTo(0);
+ assertThat(mVibratorProviders.get(2).getOffCount()).isEqualTo(0);
+ assertThat(mVibratorProviders.get(3).getOffCount()).isEqualTo(0);
+ assertThat(mVibratorProviders.get(1).getEffectSegments(vibration.id))
+ .containsExactly(expectedOneShot(TEST_TIMEOUT_MILLIS)).inOrder();
+ assertThat(mVibratorProviders.get(1).getAmplitudes())
+ .containsExactlyElementsIn(expectedAmplitudes(255)).inOrder();
+ assertThat(mVibratorProviders.get(2).getEffectSegments(vibration.id))
+ .containsExactly(expectedPrimitive(PRIMITIVE_CLICK, 1, TEST_TIMEOUT_MILLIS))
+ .inOrder();
+ assertThat(mVibratorProviders.get(3).getEffectSegments(vibration.id))
+ .containsExactly(expectedPrebaked(EFFECT_CLICK)).inOrder();
}
private void mockVibrators(int... vibratorIds) {
@@ -2122,7 +2153,7 @@ public class VibrationThreadTest {
mVibrationConductor = new VibrationStepConductor(vib, isInSession, mVibrationSettings,
deviceAdapter, mVibrationScaler, mStatsLoggerMock, requestVibrationParamsFuture,
mManagerHooks);
- assertTrue(mThread.runVibrationOnVibrationThread(mVibrationConductor));
+ assertThat(mThread.runVibrationOnVibrationThread(mVibrationConductor)).isTrue();
return mVibrationConductor.getVibration();
}
@@ -2142,8 +2173,8 @@ public class VibrationThreadTest {
}
private void waitForCompletion(long timeout) {
- assertTrue("Timed out waiting for VibrationThread to become idle",
- mThread.waitForThreadIdle(timeout));
+ assertWithMessage("Timed out waiting for VibrationThread to become idle")
+ .that(mThread.waitForThreadIdle(timeout)).isTrue();
mTestLooper.dispatchAll(); // Flush callbacks
}