summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/os/GraphicsEnvironment.java34
-rw-r--r--core/java/android/os/TEST_MAPPING7
-rw-r--r--core/java/android/view/ViewRootImpl.java5
-rw-r--r--core/java/android/window/IWindowOrganizerController.aidl7
-rw-r--r--core/java/android/window/WindowOrganizer.java10
-rw-r--r--core/java/com/android/internal/accessibility/AccessibilityShortcutController.java31
-rw-r--r--core/java/com/android/internal/os/TEST_MAPPING11
-rw-r--r--core/java/com/android/internal/power/TEST_MAPPING6
-rw-r--r--core/jni/android_media_AudioSystem.cpp9
-rw-r--r--core/tests/coretests/Android.bp1
-rw-r--r--core/tests/coretests/AndroidTest.xml1
-rw-r--r--core/tests/coretests/BstatsTestApp/OWNERS1
-rw-r--r--core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java195
-rw-r--r--core/tests/coretests/src/com/android/internal/content/OWNERS2
-rw-r--r--core/tests/packagemonitortests/Android.bp41
-rw-r--r--core/tests/packagemonitortests/AndroidManifest.xml30
-rw-r--r--core/tests/packagemonitortests/AndroidTest.xml44
-rw-r--r--core/tests/packagemonitortests/OWNERS1
-rw-r--r--core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorTest.java (renamed from core/tests/coretests/src/com/android/internal/content/PackageMonitorTest.java)2
-rw-r--r--core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorVisibilityTest.java121
-rw-r--r--core/tests/packagemonitortests/testapp/TestVisibilityApp/Android.bp27
-rw-r--r--core/tests/packagemonitortests/testapp/TestVisibilityApp/AndroidManifest.xml27
-rw-r--r--core/tests/packagemonitortests/testapp/TestVisibilityApp/res/layout/dummy_activity.xml25
-rw-r--r--core/tests/packagemonitortests/testapp/TestVisibilityApp/res/values/strings.xml21
-rw-r--r--core/tests/packagemonitortests/testapp/TestVisibilityApp/src/com/example/android/testvisibilityapp/DummyActivity.java31
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionHandler.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java21
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java20
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java29
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java40
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/SleepHandler.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java25
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingControllerTests.java12
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java41
-rw-r--r--media/java/android/media/AudioManager.java108
-rw-r--r--media/java/android/media/IAudioService.aidl6
-rw-r--r--media/tests/mediatestutils/Android.bp49
-rw-r--r--media/tests/mediatestutils/OWNERS4
-rw-r--r--media/tests/mediatestutils/java/com/android/media/mediatestutils/CancelAllFuturesRule.java51
-rw-r--r--media/tests/mediatestutils/javatests/com/android/media/mediatestutils/CancelAllFuturesRuleTest.java120
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java10
-rw-r--r--packages/SystemUI/compose/core/src/com/android/compose/activity/EdgeToEdgeActivitContent.kt61
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt12
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt12
-rw-r--r--packages/SystemUI/res/layout/log_access_user_consent_dialog_permission.xml96
-rw-r--r--packages/SystemUI/res/values/ids.xml1
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java57
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java34
-rw-r--r--packages/SystemUI/src/com/android/systemui/authentication/data/model/AuthenticationMethodModel.kt37
-rw-r--r--packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt99
-rw-r--r--packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt100
-rw-r--r--packages/SystemUI/src/com/android/systemui/authentication/domain/model/AuthenticationMethodModel.kt (renamed from packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt)9
-rw-r--r--packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationPatternCoordinate.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/controller/UdfpsKeyguardViewController.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt85
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt34
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractor.kt68
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardRootView.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/ShortcutsBesideUdfpsKeyguardBlueprint.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeGuidelines.kt45
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt48
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java98
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.kt99
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/ui/view/PeopleViewBinder.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt34
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java68
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionRepository.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepository.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepository.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt11
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java14
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt49
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt137
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt22
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt18
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt52
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt172
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt14
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSectionTest.kt1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt20
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt105
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt25
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt21
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt23
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt10
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt16
-rw-r--r--services/core/java/com/android/server/am/TEST_MAPPING7
-rw-r--r--services/core/java/com/android/server/audio/AdiDeviceState.java51
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceBroker.java29
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceInventory.java116
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java71
-rw-r--r--services/core/java/com/android/server/audio/SoundDoseHelper.java54
-rw-r--r--services/core/java/com/android/server/audio/SpatializerHelper.java4
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java15
-rw-r--r--services/core/java/com/android/server/display/DisplayDeviceConfig.java33
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java3
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController2.java14
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java3
-rw-r--r--services/core/java/com/android/server/power/TEST_MAPPING13
-rw-r--r--services/core/java/com/android/server/wm/TaskDisplayArea.java14
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java15
-rw-r--r--services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java18
-rw-r--r--services/tests/powerstatstests/Android.bp52
-rw-r--r--services/tests/powerstatstests/AndroidManifest.xml32
-rw-r--r--services/tests/powerstatstests/AndroidTest.xml35
-rw-r--r--services/tests/powerstatstests/BstatsTestApp/Android.bp (renamed from core/tests/coretests/BstatsTestApp/Android.bp)0
-rw-r--r--services/tests/powerstatstests/BstatsTestApp/AndroidManifest.xml (renamed from core/tests/coretests/BstatsTestApp/AndroidManifest.xml)0
-rw-r--r--services/tests/powerstatstests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/BaseCmdReceiver.java (renamed from core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/BaseCmdReceiver.java)0
-rw-r--r--services/tests/powerstatstests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/Common.java (renamed from core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/Common.java)4
-rw-r--r--services/tests/powerstatstests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/IsolatedTestService.java (renamed from core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/IsolatedTestService.java)0
-rw-r--r--services/tests/powerstatstests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/TestActivity.java (renamed from core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/TestActivity.java)0
-rw-r--r--services/tests/powerstatstests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/TestService.java (renamed from core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/TestService.java)0
-rw-r--r--services/tests/powerstatstests/OWNERS (renamed from services/tests/servicestests/src/com/android/server/powerstats/OWNERS)3
-rw-r--r--services/tests/powerstatstests/TEST_MAPPING22
-rw-r--r--services/tests/powerstatstests/res/xml/irq_device_map_1.xml (renamed from services/tests/servicestests/res/xml/irq_device_map_1.xml)0
-rw-r--r--services/tests/powerstatstests/res/xml/irq_device_map_2.xml (renamed from services/tests/servicestests/res/xml/irq_device_map_2.xml)0
-rw-r--r--services/tests/powerstatstests/res/xml/irq_device_map_3.xml (renamed from services/tests/servicestests/res/xml/irq_device_map_3.xml)0
-rw-r--r--services/tests/powerstatstests/res/xml/power_profile_test_legacy_modem.xml (renamed from services/tests/servicestests/res/xml/power_profile_test_legacy_modem.xml)0
-rw-r--r--services/tests/powerstatstests/res/xml/power_profile_test_modem_calculator.xml (renamed from services/tests/servicestests/res/xml/power_profile_test_modem_calculator.xml)0
-rw-r--r--services/tests/powerstatstests/res/xml/power_profile_test_modem_calculator_multiactive.xml (renamed from services/tests/servicestests/res/xml/power_profile_test_modem_calculator_multiactive.xml)0
-rw-r--r--services/tests/powerstatstests/res/xml/power_profile_test_modem_default.xml (renamed from services/tests/servicestests/res/xml/power_profile_test_modem_default.xml)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/AmbientDisplayPowerCalculatorTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/AmbientDisplayPowerCalculatorTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/AudioPowerCalculatorTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/AudioPowerCalculatorTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryChargeCalculatorTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryChargeCalculatorTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryExternalStatsWorkerTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryExternalStatsWorkerTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsBackgroundStatsTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsBackgroundStatsTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsBinderCallStatsTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsBinderCallStatsTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsCounterTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsCounterTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsCpuTimesTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsCpuTimesTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsDualTimerTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsDualTimerTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsDurationTimerTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsDurationTimerTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryIteratorTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsHistoryIteratorTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsImplTest.java)2
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsManagerTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsManagerTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsNoteTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsResetTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsResetTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsSamplingTimerTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsSamplingTimerTest.java)16
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsSensorTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsSensorTest.java)16
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsServTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsServTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsStopwatchTimerTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsStopwatchTimerTest.java)16
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsTimeBaseTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsTimeBaseTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsTimerTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsTimerTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsUserLifecycleTests.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsUserLifecycleTests.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryUsageStatsRule.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsStoreTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryUsageStatsStoreTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BatteryUsageStatsTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerCalculatorTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BluetoothPowerCalculatorTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BstatsCpuTimesValidationTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/BstatsCpuTimesValidationTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerCalculatorTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/CameraPowerCalculatorTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerCalculatorTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/CpuPowerCalculatorTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/CustomEnergyConsumerPowerCalculatorTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/CustomEnergyConsumerPowerCalculatorTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/EnergyConsumerSnapshotTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/EnergyConsumerSnapshotTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/FlashlightPowerCalculatorTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/FlashlightPowerCalculatorTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerCalculatorTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/GnssPowerCalculatorTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/IdlePowerCalculatorTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/IdlePowerCalculatorTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/KernelWakelockReaderTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/KernelWakelockReaderTest.java)16
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/LongSamplingCounterArrayTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/LongSamplingCounterArrayTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/LongSamplingCounterTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/LongSamplingCounterTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/MemoryPowerCalculatorTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/MemoryPowerCalculatorTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerCalculatorTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/MobileRadioPowerCalculatorTest.java)2
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/MockBatteryStatsImpl.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/MockClock.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/MockClock.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/OWNERS (renamed from services/tests/servicestests/src/com/android/server/power/stats/OWNERS)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerCalculatorTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/ScreenPowerCalculatorTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/SensorPowerCalculatorTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/SensorPowerCalculatorTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/SystemServerCpuThreadReaderTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/SystemServerCpuThreadReaderTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/SystemServicePowerCalculatorTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/SystemServicePowerCalculatorTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/UserPowerCalculatorTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/UserPowerCalculatorTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/VideoPowerCalculatorTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/VideoPowerCalculatorTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/WakelockPowerCalculatorTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/WakelockPowerCalculatorTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerCalculatorTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/WifiPowerCalculatorTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/wakeups/CpuWakeupStatsTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/wakeups/CpuWakeupStatsTest.java)2
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/wakeups/IrqDeviceMapTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/wakeups/IrqDeviceMapTest.java)2
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/wakeups/WakingActivityHistoryTest.java (renamed from services/tests/servicestests/src/com/android/server/power/stats/wakeups/WakingActivityHistoryTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/powerstats/IntervalRandomNoiseGeneratorTest.java (renamed from services/tests/servicestests/src/com/android/server/powerstats/IntervalRandomNoiseGeneratorTest.java)0
-rw-r--r--services/tests/powerstatstests/src/com/android/server/powerstats/PowerStatsServiceTest.java (renamed from services/tests/servicestests/src/com/android/server/powerstats/PowerStatsServiceTest.java)0
-rw-r--r--services/tests/servicestests/Android.bp2
-rw-r--r--services/tests/servicestests/AndroidTest.xml1
-rw-r--r--services/tests/servicestests/src/com/android/server/display/TestUtils.java94
-rw-r--r--services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsTests.java72
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayApp3ButtonNavLandscape.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayApp3ButtonNavPortrait.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayAppGesturalNavLandscape.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayAppGesturalNavPortrait.kt2
236 files changed, 2901 insertions, 1440 deletions
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index 538ed423626f..a07735e7540e 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -178,23 +178,6 @@ public class GraphicsEnvironment {
}
/**
- * Query to determine if the Game Mode has enabled ANGLE.
- */
- private boolean isAngleEnabledByGameMode(Context context, String packageName) {
- try {
- final boolean gameModeEnabledAngle =
- (mGameManager != null) && mGameManager.isAngleEnabled(packageName);
- Log.v(TAG, "ANGLE GameManagerService for " + packageName + ": " + gameModeEnabledAngle);
- return gameModeEnabledAngle;
- } catch (SecurityException e) {
- Log.e(TAG, "Caught exception while querying GameManagerService if ANGLE is enabled "
- + "for package: " + packageName);
- }
-
- return false;
- }
-
- /**
* Query to determine the ANGLE driver choice.
*/
private String queryAngleChoice(Context context, Bundle coreSettings,
@@ -422,8 +405,7 @@ public class GraphicsEnvironment {
* 2) The per-application switch (i.e. Settings.Global.ANGLE_GL_DRIVER_SELECTION_PKGS and
* Settings.Global.ANGLE_GL_DRIVER_SELECTION_VALUES; which corresponds to the
* “angle_gl_driver_selection_pkgs” and “angle_gl_driver_selection_values” settings); if it
- * forces a choice;
- * 3) Use ANGLE if isAngleEnabledByGameMode() returns true;
+ * forces a choice.
*/
private String queryAngleChoiceInternal(Context context, Bundle bundle,
String packageName) {
@@ -457,10 +439,6 @@ public class GraphicsEnvironment {
Log.v(TAG, " angle_gl_driver_selection_pkgs=" + optInPackages);
Log.v(TAG, " angle_gl_driver_selection_values=" + optInValues);
- final String gameModeChoice = isAngleEnabledByGameMode(context, packageName)
- ? ANGLE_GL_DRIVER_CHOICE_ANGLE
- : ANGLE_GL_DRIVER_CHOICE_DEFAULT;
-
// Make sure we have good settings to use
if (optInPackages.size() == 0 || optInPackages.size() != optInValues.size()) {
Log.v(TAG,
@@ -469,7 +447,7 @@ public class GraphicsEnvironment {
+ optInPackages.size() + ", "
+ "number of values: "
+ optInValues.size());
- return gameModeChoice;
+ return ANGLE_GL_DRIVER_CHOICE_DEFAULT;
}
// See if this application is listed in the per-application settings list
@@ -477,7 +455,7 @@ public class GraphicsEnvironment {
if (pkgIndex < 0) {
Log.v(TAG, packageName + " is not listed in per-application setting");
- return gameModeChoice;
+ return ANGLE_GL_DRIVER_CHOICE_DEFAULT;
}
mAngleOptInIndex = pkgIndex;
@@ -491,11 +469,9 @@ public class GraphicsEnvironment {
return ANGLE_GL_DRIVER_CHOICE_ANGLE;
} else if (optInValue.equals(ANGLE_GL_DRIVER_CHOICE_NATIVE)) {
return ANGLE_GL_DRIVER_CHOICE_NATIVE;
- } else {
- // The user either chose default or an invalid value; go with the default driver or what
- // the game mode indicates
- return gameModeChoice;
}
+ // The user either chose default or an invalid value; go with the default driver.
+ return ANGLE_GL_DRIVER_CHOICE_DEFAULT;
}
/**
diff --git a/core/java/android/os/TEST_MAPPING b/core/java/android/os/TEST_MAPPING
index dae9b5ea6a43..60622f18fe3b 100644
--- a/core/java/android/os/TEST_MAPPING
+++ b/core/java/android/os/TEST_MAPPING
@@ -99,13 +99,10 @@
"BatteryStats[^/]*\\.java",
"BatteryUsageStats[^/]*\\.java",
"PowerComponents\\.java",
+ "PowerMonitor[^/]*\\.java",
"[^/]*BatteryConsumer[^/]*\\.java"
],
- "name": "FrameworksServicesTests",
- "options": [
- { "include-filter": "com.android.server.power.stats" },
- { "exclude-filter": "com.android.server.power.stats.BatteryStatsTests" }
- ]
+ "name": "PowerStatsTests"
},
{
"file_patterns": [
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 21ee0e783fbc..c8c3bd3f4ac9 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -3792,6 +3792,11 @@ public final class ViewRootImpl implements ViewParent,
boolean cancelDueToPreDrawListener = mAttachInfo.mTreeObserver.dispatchOnPreDraw();
boolean cancelAndRedraw = cancelDueToPreDrawListener
|| (cancelDraw && mDrewOnceForSync);
+ if (cancelAndRedraw) {
+ Log.d(mTag, "Cancelling draw."
+ + " cancelDueToPreDrawListener=" + cancelDueToPreDrawListener
+ + " cancelDueToSync=" + (cancelDraw && mDrewOnceForSync));
+ }
if (!cancelAndRedraw) {
// A sync was already requested before the WMS requested sync. This means we need to
// sync the buffer, regardless if WMS wants to sync the buffer.
diff --git a/core/java/android/window/IWindowOrganizerController.aidl b/core/java/android/window/IWindowOrganizerController.aidl
index 534c9de8102c..5ba2f6caac2d 100644
--- a/core/java/android/window/IWindowOrganizerController.aidl
+++ b/core/java/android/window/IWindowOrganizerController.aidl
@@ -80,13 +80,8 @@ interface IWindowOrganizerController {
* Finishes a transition. This must be called for all created transitions.
* @param transitionToken Which transition to finish
* @param t Changes to make before finishing but in the same SF Transaction. Can be null.
- * @param callback Called when t is finished applying.
- * @return An ID for the sync operation (see {@link #applySyncTransaction}. This will be
- * negative if no sync transaction was attached (null t or callback)
*/
- int finishTransition(in IBinder transitionToken,
- in @nullable WindowContainerTransaction t,
- in IWindowContainerTransactionCallback callback);
+ void finishTransition(in IBinder transitionToken, in @nullable WindowContainerTransaction t);
/** @return An interface enabling the management of task organizers. */
ITaskOrganizerController getTaskOrganizerController();
diff --git a/core/java/android/window/WindowOrganizer.java b/core/java/android/window/WindowOrganizer.java
index 695d01e92316..2dc2cbca0548 100644
--- a/core/java/android/window/WindowOrganizer.java
+++ b/core/java/android/window/WindowOrganizer.java
@@ -115,19 +115,15 @@ public class WindowOrganizer {
* Finishes a running transition.
* @param transitionToken The transition to finish. Can't be null.
* @param t A set of window operations to apply before finishing.
- * @param callback A sync callback (if provided). See {@link #applySyncTransaction}.
- * @return An ID for the sync operation if performed. See {@link #applySyncTransaction}.
*
* @hide
*/
@SuppressLint("ExecutorRegistration")
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
- public int finishTransition(@NonNull IBinder transitionToken,
- @Nullable WindowContainerTransaction t,
- @Nullable WindowContainerTransactionCallback callback) {
+ public void finishTransition(@NonNull IBinder transitionToken,
+ @Nullable WindowContainerTransaction t) {
try {
- return getWindowOrganizerController().finishTransition(transitionToken, t,
- callback != null ? callback.mInterface : null);
+ getWindowOrganizerController().finishTransition(transitionToken, t);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
index f19f6c7949d2..2efe44544f37 100644
--- a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
+++ b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
@@ -128,7 +128,7 @@ public class AccessibilityShortcutController {
DialogStatus.SHOWN,
})
/** Denotes the user shortcut type. */
- private @interface DialogStatus {
+ @interface DialogStatus {
int NOT_SHOWN = 0;
int SHOWN = 1;
}
@@ -333,12 +333,35 @@ public class AccessibilityShortcutController {
// Avoid non-a11y users accidentally turning shortcut on without reading this carefully.
// Put "don't turn on" as the primary action.
final AlertDialog alertDialog = mFrameworkObjectProvider.getAlertDialogBuilder(
- // Use SystemUI context so we pick up any theme set in a vendor overlay
- mFrameworkObjectProvider.getSystemUiContext())
+ // Use SystemUI context so we pick up any theme set in a vendor overlay
+ mFrameworkObjectProvider.getSystemUiContext())
.setTitle(getShortcutWarningTitle(targets))
.setMessage(getShortcutWarningMessage(targets))
.setCancelable(false)
- .setNegativeButton(R.string.accessibility_shortcut_on, null)
+ .setNegativeButton(R.string.accessibility_shortcut_on,
+ (DialogInterface d, int which) -> {
+ String targetServices = Settings.Secure.getStringForUser(
+ mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, userId);
+ String defaultService = mContext.getString(
+ R.string.config_defaultAccessibilityService);
+ // If the targetServices is null, means the user enables a
+ // shortcut for the default service by triggering the volume keys
+ // shortcut in the SUW instead of intentionally configuring the
+ // shortcut on UI.
+ if (targetServices == null && !TextUtils.isEmpty(defaultService)) {
+ // The defaultService in the string resource could be a shorten
+ // form like com.google.android.marvin.talkback/.TalkBackService.
+ // Converts it to the componentName for consistency before saving
+ // to the Settings.
+ final ComponentName configDefaultService =
+ ComponentName.unflattenFromString(defaultService);
+ Settings.Secure.putStringForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
+ configDefaultService.flattenToString(),
+ userId);
+ }
+ })
.setPositiveButton(R.string.accessibility_shortcut_off,
(DialogInterface d, int which) -> {
Settings.Secure.putStringForUser(mContext.getContentResolver(),
diff --git a/core/java/com/android/internal/os/TEST_MAPPING b/core/java/com/android/internal/os/TEST_MAPPING
index 60b160ad18c2..d552e0b8c643 100644
--- a/core/java/com/android/internal/os/TEST_MAPPING
+++ b/core/java/com/android/internal/os/TEST_MAPPING
@@ -38,11 +38,18 @@
],
"name": "FrameworksServicesTests",
"options": [
- { "include-filter": "com.android.server.am.BatteryStatsServiceTest" },
- { "include-filter": "com.android.server.power.stats.BatteryStatsTests" }
+ { "include-filter": "com.android.server.am.BatteryStatsServiceTest" }
]
},
{
+ "file_patterns": [
+ "Battery[^/]*\\.java",
+ "Kernel[^/]*\\.java",
+ "[^/]*Power[^/]*\\.java"
+ ],
+ "name": "PowerStatsTests"
+ },
+ {
"name": "FrameworksCoreTests",
"options": [
{
diff --git a/core/java/com/android/internal/power/TEST_MAPPING b/core/java/com/android/internal/power/TEST_MAPPING
index c6cab183d970..1946f5cc99eb 100644
--- a/core/java/com/android/internal/power/TEST_MAPPING
+++ b/core/java/com/android/internal/power/TEST_MAPPING
@@ -8,11 +8,7 @@
]
},
{
- "name": "FrameworksServicesTests",
- "options": [
- { "include-filter": "com.android.server.am.BatteryStatsServiceTest" },
- { "include-filter": "com.android.server.power.stats.BatteryStatsTests" }
- ]
+ "name": "PowerStatsTests"
}
]
}
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 4cf17b78f489..199854818989 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -523,13 +523,14 @@ android_media_AudioSystem_dyn_policy_callback(int event, String8 regId, int val)
}
jclass clazz = env->FindClass(kClassPathName);
- const char* zechars = regId.string();
- jstring zestring = env->NewStringUTF(zechars);
+ const char *regIdString = regId.string();
+ jstring regIdJString = env->NewStringUTF(regIdString);
env->CallStaticVoidMethod(clazz, gAudioPolicyEventHandlerMethods.postDynPolicyEventFromNative,
- event, zestring, val);
+ event, regIdJString, val);
- env->ReleaseStringUTFChars(zestring, zechars);
+ const char *regIdJChars = env->GetStringUTFChars(regIdJString, NULL);
+ env->ReleaseStringUTFChars(regIdJString, regIdJChars);
env->DeleteLocalRef(clazz);
}
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index c7aaeb0339bd..c14da299c6ef 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -91,7 +91,6 @@ android_test {
java_resources: [":ApkVerityTestCertDer"],
data: [
- ":BstatsTestApp",
":BinderDeathRecipientHelperApp1",
":BinderDeathRecipientHelperApp2",
":com.android.cts.helpers.aosp",
diff --git a/core/tests/coretests/AndroidTest.xml b/core/tests/coretests/AndroidTest.xml
index 3e4c47b36ed9..05b309b2cd52 100644
--- a/core/tests/coretests/AndroidTest.xml
+++ b/core/tests/coretests/AndroidTest.xml
@@ -20,7 +20,6 @@
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="FrameworksCoreTests.apk" />
- <option name="test-file-name" value="BstatsTestApp.apk" />
<option name="test-file-name" value="BinderDeathRecipientHelperApp1.apk" />
<option name="test-file-name" value="BinderDeathRecipientHelperApp2.apk" />
</target_preparer>
diff --git a/core/tests/coretests/BstatsTestApp/OWNERS b/core/tests/coretests/BstatsTestApp/OWNERS
deleted file mode 100644
index 4068e2bc03b7..000000000000
--- a/core/tests/coretests/BstatsTestApp/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include /BATTERY_STATS_OWNERS
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
index 2de1230cf706..cd5ec851e9eb 100644
--- a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
+++ b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
@@ -27,9 +27,7 @@ import static com.android.internal.accessibility.AccessibilityShortcutController
import static com.android.internal.accessibility.AccessibilityShortcutController.ONE_HANDED_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.REDUCE_BRIGHT_COLORS_COMPONENT_NAME;
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
+import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.AdditionalMatchers.aryEq;
@@ -68,7 +66,6 @@ import android.provider.Settings;
import android.speech.tts.TextToSpeech;
import android.speech.tts.Voice;
import android.test.mock.MockContentResolver;
-import android.text.TextUtils;
import android.view.Window;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
@@ -76,7 +73,7 @@ import android.view.accessibility.IAccessibilityManager;
import android.widget.Toast;
import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.internal.R;
import com.android.internal.accessibility.AccessibilityShortcutController.FrameworkObjectProvider;
@@ -232,7 +229,7 @@ public class AccessibilityShortcutControllerTest {
throws Exception {
configureNoShortcutService();
configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
- assertFalse(getController().isAccessibilityShortcutAvailable(false));
+ assertThat(getController().isAccessibilityShortcutAvailable(false)).isFalse();
}
@Test
@@ -240,7 +237,7 @@ public class AccessibilityShortcutControllerTest {
throws Exception {
configureValidShortcutService();
configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
- assertTrue(getController().isAccessibilityShortcutAvailable(false));
+ assertThat(getController().isAccessibilityShortcutAvailable(false)).isTrue();
}
@Test
@@ -248,7 +245,7 @@ public class AccessibilityShortcutControllerTest {
throws Exception {
configureValidShortcutService();
configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
- assertFalse(getController().isAccessibilityShortcutAvailable(true));
+ assertThat(getController().isAccessibilityShortcutAvailable(true)).isFalse();
}
@Test
@@ -256,7 +253,7 @@ public class AccessibilityShortcutControllerTest {
throws Exception {
configureValidShortcutService();
configureShortcutEnabled(ENABLED_INCLUDING_LOCK_SCREEN);
- assertTrue(getController().isAccessibilityShortcutAvailable(true));
+ assertThat(getController().isAccessibilityShortcutAvailable(true)).isTrue();
}
@Test
@@ -267,10 +264,14 @@ public class AccessibilityShortcutControllerTest {
configureShortcutEnabled(ENABLED_INCLUDING_LOCK_SCREEN);
Settings.Secure.putString(
mContentResolver, ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, null);
- Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 0);
- assertFalse(getController().isAccessibilityShortcutAvailable(true));
- Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 1);
- assertTrue(getController().isAccessibilityShortcutAvailable(true));
+ Settings.Secure.putInt(
+ mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ AccessibilityShortcutController.DialogStatus.NOT_SHOWN);
+ assertThat(getController().isAccessibilityShortcutAvailable(true)).isFalse();
+ Settings.Secure.putInt(
+ mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ AccessibilityShortcutController.DialogStatus.SHOWN);
+ assertThat(getController().isAccessibilityShortcutAvailable(true)).isTrue();
}
@Test
@@ -281,7 +282,9 @@ public class AccessibilityShortcutControllerTest {
AccessibilityShortcutController accessibilityShortcutController = getController();
configureNoShortcutService();
accessibilityShortcutController.onSettingsChanged();
- assertFalse(accessibilityShortcutController.isAccessibilityShortcutAvailable(false));
+ assertThat(
+ accessibilityShortcutController.isAccessibilityShortcutAvailable(false)
+ ).isFalse();
}
@Test
@@ -292,7 +295,9 @@ public class AccessibilityShortcutControllerTest {
AccessibilityShortcutController accessibilityShortcutController = getController();
configureValidShortcutService();
accessibilityShortcutController.onSettingsChanged();
- assertTrue(accessibilityShortcutController.isAccessibilityShortcutAvailable(false));
+ assertThat(
+ accessibilityShortcutController.isAccessibilityShortcutAvailable(false)
+ ).isTrue();
}
@Test
@@ -302,7 +307,9 @@ public class AccessibilityShortcutControllerTest {
AccessibilityShortcutController accessibilityShortcutController = getController();
configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
accessibilityShortcutController.onSettingsChanged();
- assertTrue(accessibilityShortcutController.isAccessibilityShortcutAvailable(false));
+ assertThat(
+ accessibilityShortcutController.isAccessibilityShortcutAvailable(false)
+ ).isTrue();
}
@Test
@@ -313,7 +320,9 @@ public class AccessibilityShortcutControllerTest {
AccessibilityShortcutController accessibilityShortcutController = getController();
configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
accessibilityShortcutController.onSettingsChanged();
- assertFalse(accessibilityShortcutController.isAccessibilityShortcutAvailable(true));
+ assertThat(
+ accessibilityShortcutController.isAccessibilityShortcutAvailable(true)
+ ).isFalse();
}
@Test
@@ -324,7 +333,9 @@ public class AccessibilityShortcutControllerTest {
AccessibilityShortcutController accessibilityShortcutController = getController();
configureShortcutEnabled(ENABLED_INCLUDING_LOCK_SCREEN);
accessibilityShortcutController.onSettingsChanged();
- assertTrue(accessibilityShortcutController.isAccessibilityShortcutAvailable(true));
+ assertThat(
+ accessibilityShortcutController.isAccessibilityShortcutAvailable(true)
+ ).isTrue();
}
@Test
@@ -341,11 +352,15 @@ public class AccessibilityShortcutControllerTest {
configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
configureValidShortcutService();
AccessibilityShortcutController accessibilityShortcutController = getController();
- Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 0);
+ Settings.Secure.putInt(
+ mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ AccessibilityShortcutController.DialogStatus.NOT_SHOWN);
accessibilityShortcutController.performAccessibilityShortcut();
- assertEquals(1, Settings.Secure.getInt(
- mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 0));
+ assertThat(Settings.Secure.getInt(
+ mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ AccessibilityShortcutController.DialogStatus.NOT_SHOWN)).isEqualTo(
+ AccessibilityShortcutController.DialogStatus.SHOWN);
verify(mResources).getString(
R.string.accessibility_shortcut_single_service_warning_title, PACKAGE_NAME_STRING);
verify(mAlertDialog).show();
@@ -357,11 +372,12 @@ public class AccessibilityShortcutControllerTest {
@Test
public void testOnAccessibilityShortcut_withDialogShowing_callsServer()
- throws Exception {
+ throws Exception {
configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
configureValidShortcutService();
AccessibilityShortcutController accessibilityShortcutController = getController();
- Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 0);
+ Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ AccessibilityShortcutController.DialogStatus.NOT_SHOWN);
accessibilityShortcutController.performAccessibilityShortcut();
accessibilityShortcutController.performAccessibilityShortcut();
verify(mToast).show();
@@ -374,11 +390,12 @@ public class AccessibilityShortcutControllerTest {
@Test
public void testOnAccessibilityShortcut_ifCanceledFirstTime_showsWarningDialog()
- throws Exception {
+ throws Exception {
configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
configureValidShortcutService();
AccessibilityShortcutController accessibilityShortcutController = getController();
- Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 0);
+ Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ AccessibilityShortcutController.DialogStatus.NOT_SHOWN);
accessibilityShortcutController.performAccessibilityShortcut();
ArgumentCaptor<AlertDialog.OnCancelListener> cancelListenerCaptor =
ArgumentCaptor.forClass(AlertDialog.OnCancelListener.class);
@@ -394,49 +411,98 @@ public class AccessibilityShortcutControllerTest {
public void testClickingDisableButtonInDialog_shouldClearShortcutId() throws Exception {
configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
configureValidShortcutService();
- Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 0);
+ Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ AccessibilityShortcutController.DialogStatus.NOT_SHOWN);
getController().performAccessibilityShortcut();
ArgumentCaptor<DialogInterface.OnClickListener> captor =
ArgumentCaptor.forClass(DialogInterface.OnClickListener.class);
verify(mAlertDialogBuilder).setPositiveButton(eq(R.string.accessibility_shortcut_off),
captor.capture());
- // Call the button callback, if one exists
- if (captor.getValue() != null) {
- captor.getValue().onClick(null, 0);
- }
- assertTrue(TextUtils.isEmpty(
- Settings.Secure.getString(mContentResolver, ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)));
- assertEquals(0, Settings.Secure.getInt(
- mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN));
+ captor.getValue().onClick(null, DialogInterface.BUTTON_POSITIVE);
+
+ assertThat(
+ Settings.Secure.getString(mContentResolver, ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)
+ ).isEmpty();
+ assertThat(Settings.Secure.getInt(
+ mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN)).isEqualTo(
+ AccessibilityShortcutController.DialogStatus.NOT_SHOWN);
}
@Test
public void testClickingTurnOnButtonInDialog_shouldLeaveShortcutReady() throws Exception {
configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
configureValidShortcutService();
- Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 0);
+ Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ AccessibilityShortcutController.DialogStatus.NOT_SHOWN);
getController().performAccessibilityShortcut();
ArgumentCaptor<DialogInterface.OnClickListener> captor =
- ArgumentCaptor.forClass(DialogInterface.OnClickListener.class);
+ ArgumentCaptor.forClass(DialogInterface.OnClickListener.class);
verify(mAlertDialogBuilder).setNegativeButton(eq(R.string.accessibility_shortcut_on),
captor.capture());
- // Call the button callback, if one exists
- if (captor.getValue() != null) {
- captor.getValue().onClick(null, 0);
- }
- assertEquals(SERVICE_NAME_STRING,
- Settings.Secure.getString(mContentResolver, ACCESSIBILITY_SHORTCUT_TARGET_SERVICE));
- assertEquals(1, Settings.Secure.getInt(
- mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN));
+ captor.getValue().onClick(null, DialogInterface.BUTTON_NEGATIVE);
+
+ assertThat(
+ Settings.Secure.getString(mContentResolver, ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)
+ ).isEqualTo(SERVICE_NAME_STRING);
+ assertThat(Settings.Secure.getInt(
+ mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN)).isEqualTo(
+ AccessibilityShortcutController.DialogStatus.SHOWN);
+ }
+
+ @Test
+ public void testTurnOnDefaultA11yServiceInDialog_defaultServiceShortcutTurnsOn()
+ throws Exception {
+ configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
+ configureDefaultAccessibilityService();
+ Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ AccessibilityShortcutController.DialogStatus.NOT_SHOWN);
+ getController().performAccessibilityShortcut();
+
+ ArgumentCaptor<DialogInterface.OnClickListener> captor =
+ ArgumentCaptor.forClass(DialogInterface.OnClickListener.class);
+ verify(mAlertDialogBuilder).setNegativeButton(eq(R.string.accessibility_shortcut_on),
+ captor.capture());
+ captor.getValue().onClick(null, DialogInterface.BUTTON_NEGATIVE);
+
+ assertThat(
+ Settings.Secure.getString(mContentResolver,
+ ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)).isEqualTo(SERVICE_NAME_STRING);
+ assertThat(Settings.Secure.getInt(
+ mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN)).isEqualTo(
+ AccessibilityShortcutController.DialogStatus.SHOWN);
+ }
+
+ @Test
+ public void testTurnOffDefaultA11yServiceInDialog_defaultServiceShortcutTurnsOff()
+ throws Exception {
+ configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
+ configureDefaultAccessibilityService();
+ Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ AccessibilityShortcutController.DialogStatus.NOT_SHOWN);
+ getController().performAccessibilityShortcut();
+
+ ArgumentCaptor<DialogInterface.OnClickListener> captor =
+ ArgumentCaptor.forClass(DialogInterface.OnClickListener.class);
+ verify(mAlertDialogBuilder).setPositiveButton(eq(R.string.accessibility_shortcut_off),
+ captor.capture());
+ captor.getValue().onClick(null, DialogInterface.BUTTON_POSITIVE);
+
+ assertThat(
+ Settings.Secure.getString(mContentResolver,
+ ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)).isEmpty();
+ assertThat(Settings.Secure.getInt(
+ mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN)).isEqualTo(
+ AccessibilityShortcutController.DialogStatus.NOT_SHOWN);
}
@Test
public void testOnAccessibilityShortcut_afterDialogShown_shouldCallServer() throws Exception {
configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
configureValidShortcutService();
- Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 1);
+ Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ AccessibilityShortcutController.DialogStatus.SHOWN);
getController().performAccessibilityShortcut();
verifyZeroInteractions(mAlertDialogBuilder, mAlertDialog);
@@ -464,10 +530,10 @@ public class AccessibilityShortcutControllerTest {
frameworkFeatureMap =
AccessibilityShortcutController.getFrameworkShortcutFeaturesMap();
- assertTrue(frameworkFeatureMap.containsKey(COLOR_INVERSION_COMPONENT_NAME));
- assertTrue(frameworkFeatureMap.containsKey(DALTONIZER_COMPONENT_NAME));
- assertTrue(frameworkFeatureMap.containsKey(REDUCE_BRIGHT_COLORS_COMPONENT_NAME));
- assertTrue(frameworkFeatureMap.containsKey(ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME));
+ assertThat(frameworkFeatureMap).containsKey(COLOR_INVERSION_COMPONENT_NAME);
+ assertThat(frameworkFeatureMap).containsKey(DALTONIZER_COMPONENT_NAME);
+ assertThat(frameworkFeatureMap).containsKey(REDUCE_BRIGHT_COLORS_COMPONENT_NAME);
+ assertThat(frameworkFeatureMap).containsKey(ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME);
}
@Test
@@ -478,7 +544,7 @@ public class AccessibilityShortcutControllerTest {
frameworkFeatureMap =
AccessibilityShortcutController.getFrameworkShortcutFeaturesMap();
- assertTrue(frameworkFeatureMap.containsKey(ONE_HANDED_COMPONENT_NAME));
+ assertThat(frameworkFeatureMap).containsKey(ONE_HANDED_COMPONENT_NAME);
}
@Test
@@ -489,7 +555,7 @@ public class AccessibilityShortcutControllerTest {
frameworkFeatureMap =
AccessibilityShortcutController.getFrameworkShortcutFeaturesMap();
- assertFalse(frameworkFeatureMap.containsKey(ONE_HANDED_COMPONENT_NAME));
+ assertThat(frameworkFeatureMap).doesNotContainKey(ONE_HANDED_COMPONENT_NAME);
}
@Test
@@ -498,7 +564,8 @@ public class AccessibilityShortcutControllerTest {
configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
configureValidShortcutService();
when(mServiceInfo.loadSummary(any())).thenReturn(null);
- Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 1);
+ Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ AccessibilityShortcutController.DialogStatus.SHOWN);
getController().performAccessibilityShortcut();
verify(mAccessibilityManagerService).performAccessibilityShortcut(null);
}
@@ -508,7 +575,8 @@ public class AccessibilityShortcutControllerTest {
throws Exception {
configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
configureFirstFrameworkFeature();
- Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 1);
+ Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ AccessibilityShortcutController.DialogStatus.SHOWN);
getController().performAccessibilityShortcut();
verifyZeroInteractions(mToast);
@@ -523,7 +591,8 @@ public class AccessibilityShortcutControllerTest {
configureApplicationTargetSdkVersion(Build.VERSION_CODES.R);
configureRequestAccessibilityButton();
configureEnabledService();
- Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 1);
+ Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ AccessibilityShortcutController.DialogStatus.SHOWN);
getController().performAccessibilityShortcut();
verifyZeroInteractions(mToast);
@@ -538,7 +607,8 @@ public class AccessibilityShortcutControllerTest {
configureTtsSpokenPromptEnabled();
configureHandlerCallbackInvocation();
AccessibilityShortcutController accessibilityShortcutController = getController();
- Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 0);
+ Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ AccessibilityShortcutController.DialogStatus.NOT_SHOWN);
accessibilityShortcutController.performAccessibilityShortcut();
verify(mAlertDialog).show();
@@ -563,7 +633,8 @@ public class AccessibilityShortcutControllerTest {
configureTtsSpokenPromptEnabled();
configureHandlerCallbackInvocation();
AccessibilityShortcutController accessibilityShortcutController = getController();
- Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 0);
+ Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ AccessibilityShortcutController.DialogStatus.NOT_SHOWN);
accessibilityShortcutController.performAccessibilityShortcut();
verify(mAlertDialog).show();
@@ -583,7 +654,8 @@ public class AccessibilityShortcutControllerTest {
configureTtsSpokenPromptEnabled();
configureHandlerCallbackInvocation();
AccessibilityShortcutController accessibilityShortcutController = getController();
- Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 0);
+ Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ AccessibilityShortcutController.DialogStatus.NOT_SHOWN);
Set<String> features = new HashSet<>();
features.add(TextToSpeech.Engine.KEY_FEATURE_NOT_INSTALLED);
doReturn(features, Collections.emptySet()).when(mVoice).getFeatures();
@@ -682,4 +754,13 @@ public class AccessibilityShortcutControllerTest {
accessibilityShortcutController.mFrameworkObjectProvider = mFrameworkObjectProvider;
return accessibilityShortcutController;
}
+
+ private void configureDefaultAccessibilityService() throws Exception {
+ when(mAccessibilityManagerService
+ .getAccessibilityShortcutTargets(ACCESSIBILITY_SHORTCUT_KEY))
+ .thenReturn(Collections.singletonList(SERVICE_NAME_STRING));
+
+ when(mResources.getString(R.string.config_defaultAccessibilityService)).thenReturn(
+ SERVICE_NAME_STRING);
+ }
}
diff --git a/core/tests/coretests/src/com/android/internal/content/OWNERS b/core/tests/coretests/src/com/android/internal/content/OWNERS
index dd9ede53239c..4bb83438b193 100644
--- a/core/tests/coretests/src/com/android/internal/content/OWNERS
+++ b/core/tests/coretests/src/com/android/internal/content/OWNERS
@@ -1,4 +1,2 @@
-per-file PackageMonitorTest.java = file:/core/java/android/content/pm/OWNERS
-
per-file Overlay* = file:/core/java/android/content/res/OWNERS
diff --git a/core/tests/packagemonitortests/Android.bp b/core/tests/packagemonitortests/Android.bp
new file mode 100644
index 000000000000..453b476edbc0
--- /dev/null
+++ b/core/tests/packagemonitortests/Android.bp
@@ -0,0 +1,41 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_test {
+ name: "FrameworksCorePackageMonitorTests",
+ srcs: ["src/**/*.java"],
+ static_libs: [
+ "androidx.test.runner",
+ "compatibility-device-util-axt",
+ "frameworks-base-testutils",
+ "mockito-target-minus-junit4",
+ "truth-prebuilt",
+ ],
+ libs: ["android.test.runner"],
+ platform_apis: true,
+ certificate: "platform",
+ test_suites: ["device-tests"],
+ data: [
+ ":TestVisibilityApp",
+ ],
+}
diff --git a/core/tests/packagemonitortests/AndroidManifest.xml b/core/tests/packagemonitortests/AndroidManifest.xml
new file mode 100644
index 000000000000..500a3e192077
--- /dev/null
+++ b/core/tests/packagemonitortests/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.frameworks.packagemonitor">
+
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.frameworks.packagemonitor"
+ android:label="Frameworks PackageMonitor Core Tests" />
+</manifest>
diff --git a/core/tests/packagemonitortests/AndroidTest.xml b/core/tests/packagemonitortests/AndroidTest.xml
new file mode 100644
index 000000000000..898dc1877b4b
--- /dev/null
+++ b/core/tests/packagemonitortests/AndroidTest.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<configuration description="Runs Frameworks Core Tests.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-instrumentation" />
+
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="test-file-name" value="FrameworksCorePackageMonitorTests.apk" />
+ </target_preparer>
+
+ <!-- Create place to store apks -->
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command" value="mkdir -p /data/local/tmp/contenttests" />
+ <option name="teardown-command" value="rm -rf /data/local/tmp/contenttests"/>
+ </target_preparer>
+ <!-- Load additional APKs onto device -->
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="push" value="TestVisibilityApp.apk->/data/local/tmp/contenttests/TestVisibilityApp.apk" />
+ <option name="cleanup" value="true" />
+ </target_preparer>
+
+ <option name="test-tag" value="FrameworksCorePackageMonitorTests" />
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="com.android.frameworks.packagemonitor" />
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+ <option name="hidden-api-checks" value="false"/>
+ </test>
+</configuration>
diff --git a/core/tests/packagemonitortests/OWNERS b/core/tests/packagemonitortests/OWNERS
new file mode 100644
index 000000000000..d825dfd7cf00
--- /dev/null
+++ b/core/tests/packagemonitortests/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/pm/OWNERS
diff --git a/core/tests/coretests/src/com/android/internal/content/PackageMonitorTest.java b/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorTest.java
index 7ccbf1d25674..e082c25fa499 100644
--- a/core/tests/coretests/src/com/android/internal/content/PackageMonitorTest.java
+++ b/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorTest.java
@@ -44,10 +44,10 @@ import org.mockito.MockitoAnnotations;
*/
@RunWith(AndroidJUnit4.class)
public class PackageMonitorTest {
-
private static final String FAKE_PACKAGE_NAME = "com.android.internal.content.fakeapp";
private static final int FAKE_PACKAGE_UID = 123;
private static final int FAKE_USER_ID = 0;
+ private static final int WAIT_CALLBACK_CALLED_IN_MS = 300;
@Mock
Context mMockContext;
diff --git a/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorVisibilityTest.java b/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorVisibilityTest.java
new file mode 100644
index 000000000000..a310edceb3b3
--- /dev/null
+++ b/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorVisibilityTest.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.content;
+
+import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.UserHandle;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A test to verify PackageMonitor implementation respects the app visibility.
+ */
+@RunWith(AndroidJUnit4.class)
+public class PackageMonitorVisibilityTest {
+ private static final String TEST_DATA_PATH = "/data/local/tmp/contenttests/";
+ private static final String TEAT_APK_PATH =
+ TEST_DATA_PATH + "TestVisibilityApp.apk";
+ private static final String TEAT_APK_PACKAGE_NAME = "com.example.android.testvisibilityapp";
+ private static final int WAIT_CALLBACK_CALLED_IN_SECONDS = 1;
+ @Test
+ public void testPackageMonitorPackageVisible() throws Exception {
+ TestVisibilityPackageMonitor testPackageMonitor = new TestVisibilityPackageMonitor();
+
+ try {
+ Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ testPackageMonitor.register(context, UserHandle.ALL,
+ new Handler(Looper.getMainLooper()));
+
+ installTestPackage(true /* forceQueryable */);
+ boolean result = testPackageMonitor.mCallbackCountDownLatch.await(
+ WAIT_CALLBACK_CALLED_IN_SECONDS, TimeUnit.SECONDS);
+
+ int expectedUid = context.getPackageManager().getPackageUid(TEAT_APK_PACKAGE_NAME,
+ PackageManager.PackageInfoFlags.of(0));
+ assertThat(result).isTrue();
+ assertThat(testPackageMonitor.mAddedPackageName).isEqualTo(TEAT_APK_PACKAGE_NAME);
+ assertThat(testPackageMonitor.mAddedPackageUid).isEqualTo(expectedUid);
+ } finally {
+ testPackageMonitor.unregister();
+ uninstallTestPackage();
+ }
+ }
+
+ @Test
+ public void testPackageMonitorPackageNotVisible() throws Exception {
+ TestVisibilityPackageMonitor testPackageMonitor = new TestVisibilityPackageMonitor();
+
+ try {
+ Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ testPackageMonitor.register(context, UserHandle.ALL,
+ new Handler(Looper.getMainLooper()));
+
+ installTestPackage(false /* forceQueryable */);
+ boolean result = testPackageMonitor.mCallbackCountDownLatch.await(
+ WAIT_CALLBACK_CALLED_IN_SECONDS, TimeUnit.SECONDS);
+
+ assertThat(result).isFalse();
+ } finally {
+ testPackageMonitor.unregister();
+ uninstallTestPackage();
+ }
+ }
+
+ private static void installTestPackage(boolean forceQueryable) {
+ final StringBuilder cmd = new StringBuilder("pm install ");
+ if (forceQueryable) {
+ cmd.append("--force-queryable ");
+ }
+ cmd.append(TEAT_APK_PATH);
+ final String result = runShellCommand(cmd.toString());
+ assertThat(result.trim()).contains("Success");
+ }
+
+ private static void uninstallTestPackage() {
+ runShellCommand("pm uninstall " + TEAT_APK_PACKAGE_NAME);
+ }
+
+ private static class TestVisibilityPackageMonitor extends PackageMonitor {
+ String mAddedPackageName;
+ int mAddedPackageUid;
+ CountDownLatch mCallbackCountDownLatch = new CountDownLatch(1);
+
+ @Override
+ public void onPackageAdded(String packageName, int uid) {
+ if (!TEAT_APK_PACKAGE_NAME.equals(packageName)) {
+ return;
+ }
+ mAddedPackageName = packageName;
+ mAddedPackageUid = uid;
+ mCallbackCountDownLatch.countDown();
+ }
+ }
+}
diff --git a/core/tests/packagemonitortests/testapp/TestVisibilityApp/Android.bp b/core/tests/packagemonitortests/testapp/TestVisibilityApp/Android.bp
new file mode 100644
index 000000000000..c0e98fcc595d
--- /dev/null
+++ b/core/tests/packagemonitortests/testapp/TestVisibilityApp/Android.bp
@@ -0,0 +1,27 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+ name: "TestVisibilityApp",
+ srcs: ["src/**/*.java"],
+ sdk_version: "current",
+ dex_preopt: {
+ enabled: false,
+ },
+ test_suites: ["device-tests"],
+}
diff --git a/core/tests/packagemonitortests/testapp/TestVisibilityApp/AndroidManifest.xml b/core/tests/packagemonitortests/testapp/TestVisibilityApp/AndroidManifest.xml
new file mode 100644
index 000000000000..0ba5058be979
--- /dev/null
+++ b/core/tests/packagemonitortests/testapp/TestVisibilityApp/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.testvisibilityapp">
+ <application android:label="testvisibilityapp">
+ <activity android:name="DummyActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/core/tests/packagemonitortests/testapp/TestVisibilityApp/res/layout/dummy_activity.xml b/core/tests/packagemonitortests/testapp/TestVisibilityApp/res/layout/dummy_activity.xml
new file mode 100644
index 000000000000..9887dc7117d1
--- /dev/null
+++ b/core/tests/packagemonitortests/testapp/TestVisibilityApp/res/layout/dummy_activity.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<EditText xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/text"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:textSize="18sp"
+ android:autoText="true"
+ android:capitalize="sentences"
+ android:text="@string/activity_text_text" />
+
diff --git a/core/tests/packagemonitortests/testapp/TestVisibilityApp/res/values/strings.xml b/core/tests/packagemonitortests/testapp/TestVisibilityApp/res/values/strings.xml
new file mode 100644
index 000000000000..5771bd50cfe7
--- /dev/null
+++ b/core/tests/packagemonitortests/testapp/TestVisibilityApp/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+
+ <string name="activity_text_text">Hello</string>
+
+</resources>
diff --git a/core/tests/packagemonitortests/testapp/TestVisibilityApp/src/com/example/android/testvisibilityapp/DummyActivity.java b/core/tests/packagemonitortests/testapp/TestVisibilityApp/src/com/example/android/testvisibilityapp/DummyActivity.java
new file mode 100644
index 000000000000..e74454e938b9
--- /dev/null
+++ b/core/tests/packagemonitortests/testapp/TestVisibilityApp/src/com/example/android/testvisibilityapp/DummyActivity.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.testvisibilityapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+
+public class DummyActivity extends Activity {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ View view = getLayoutInflater().inflate(R.layout.dummy_activity, null);
+ setContentView(view);
+ }
+}
+
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java
index 57d374b2b8f5..06ce37148eaf 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java
@@ -186,6 +186,6 @@ public class ActivityEmbeddingController implements Transitions.TransitionHandle
if (callback == null) {
throw new IllegalStateException("No finish callback found");
}
- callback.onTransitionFinished(null /* wct */, null /* wctCB */);
+ callback.onTransitionFinished(null /* wct */);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index e8fa638bea31..d3fada37a685 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -722,10 +722,6 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
return bounds.width() > bounds.height();
}
- public boolean isDensityChanged(int densityDpi) {
- return mDensity != densityDpi;
- }
-
/**
* Return if this layout is landscape.
*/
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java
index 16b23935559c..024465b281b8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java
@@ -241,7 +241,7 @@ public class EnterDesktopTaskTransitionHandler implements Transitions.Transition
public void onAnimationEnd(Animator animation) {
mDesktopModeWindowDecoration.hideResizeVeil();
mTransitions.getMainExecutor().execute(
- () -> finishCallback.onTransitionFinished(null, null));
+ () -> finishCallback.onTransitionFinished(null));
}
});
animator.start();
@@ -271,8 +271,7 @@ public class EnterDesktopTaskTransitionHandler implements Transitions.Transition
startT.apply();
- mTransitions.getMainExecutor().execute(
- () -> finishCallback.onTransitionFinished(null, null));
+ mTransitions.getMainExecutor().execute(() -> finishCallback.onTransitionFinished(null));
return true;
}
@@ -324,7 +323,7 @@ public class EnterDesktopTaskTransitionHandler implements Transitions.Transition
mOnAnimationFinishedCallback.accept(finishT);
}
mTransitions.getMainExecutor().execute(
- () -> finishCallback.onTransitionFinished(null, null));
+ () -> finishCallback.onTransitionFinished(null));
}
});
@@ -378,7 +377,7 @@ public class EnterDesktopTaskTransitionHandler implements Transitions.Transition
mOnAnimationFinishedCallback.accept(finishT);
}
mTransitions.getMainExecutor().execute(
- () -> finishCallback.onTransitionFinished(null, null));
+ () -> finishCallback.onTransitionFinished(null));
}
});
animator.start();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
index 3ad5edf0e604..7342bd1ae5de 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
@@ -168,7 +168,7 @@ public class ExitDesktopTaskTransitionHandler implements Transitions.TransitionH
mOnAnimationFinishedCallback.accept(finishT);
}
mTransitions.getMainExecutor().execute(
- () -> finishCallback.onTransitionFinished(null, null));
+ () -> finishCallback.onTransitionFinished(null));
}
});
animator.start();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
index 94788e45e2b6..b9cb5c75aaf0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
@@ -104,7 +104,7 @@ class ToggleResizeDesktopTaskTransitionHandler(
.setWindowCrop(leash, endBounds.width(), endBounds.height())
.show(leash)
windowDecor.hideResizeVeil()
- finishCallback.onTransitionFinished(null, null)
+ finishCallback.onTransitionFinished(null)
boundsAnimator = null
}
)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionHandler.java
index 55e34fe3d836..84027753435b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionHandler.java
@@ -130,7 +130,7 @@ public class FreeformTaskTransitionHandler
if (!animations.isEmpty()) return;
mMainExecutor.execute(() -> {
mAnimations.remove(transition);
- finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
+ finishCallback.onTransitionFinished(null /* wct */);
});
};
for (TransitionInfo.Change change : info.getChanges()) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
index 56bd188a0d7d..2ef92adb90f5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
@@ -19,7 +19,6 @@ package com.android.wm.shell.keyguard;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
import static android.view.WindowManager.KEYGUARD_VISIBILITY_TRANSIT_FLAGS;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
-import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_APPEARING;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_OCCLUDING;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_UNOCCLUDING;
import static android.view.WindowManager.TRANSIT_SLEEP;
@@ -169,7 +168,7 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler
// Post our finish callback to let startAnimation finish first.
mMainExecutor.executeDelayed(() -> {
mStartedTransitions.remove(transition);
- finishCallback.onTransitionFinished(wct, null);
+ finishCallback.onTransitionFinished(wct);
}, 0);
}
});
@@ -206,7 +205,7 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler
// implementing an AIDL interface.
Log.wtf(TAG, "RemoteException thrown from KeyguardService transition", e);
}
- nextFinishCallback.onTransitionFinished(null, null);
+ nextFinishCallback.onTransitionFinished(null);
} else if (nextInfo.getType() == TRANSIT_SLEEP) {
// An empty SLEEP transition comes in as a signal to abort transitions whenever a sleep
// token is held. In cases where keyguard is showing, we are running the animation for
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index 208f9b7432bf..0d55018ba580 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -592,7 +592,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
SplitScreenController split = mSplitScreenOptional.get();
if (split.isTaskInSplitScreen(mTaskInfo.lastParentTaskIdBeforePip)) {
split.prepareExitSplitScreen(wct, split.getStageOfTask(
- mTaskInfo.lastParentTaskIdBeforePip));
+ mTaskInfo.lastParentTaskIdBeforePip),
+ SplitScreenController.EXIT_REASON_APP_FINISHED);
}
}
mPipTransitionController.startExitTransition(TRANSIT_EXIT_PIP, wct, destinationBounds);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index e3d53fc415db..2563d984b793 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -447,7 +447,7 @@ public class PipTransition extends PipTransitionController {
// handler if there is a pending PiP animation.
final Transitions.TransitionFinishCallback finishCallback = mFinishCallback;
mFinishCallback = null;
- finishCallback.onTransitionFinished(wct, null /* callback */);
+ finishCallback.onTransitionFinished(wct);
}
@Override
@@ -456,7 +456,7 @@ public class PipTransition extends PipTransitionController {
// for example, when app crashes while in PiP and exit transition has not started
mCurrentPipTaskToken = null;
if (mFinishCallback == null) return;
- mFinishCallback.onTransitionFinished(null /* wct */, null /* callback */);
+ mFinishCallback.onTransitionFinished(null /* wct */);
mFinishCallback = null;
mFinishTransaction = null;
}
@@ -586,7 +586,7 @@ public class PipTransition extends PipTransitionController {
final boolean useLocalLeash = activitySc != null;
final boolean toFullscreen = pipChange.getEndAbsBounds().equals(
mPipBoundsState.getDisplayBounds());
- mFinishCallback = (wct, wctCB) -> {
+ mFinishCallback = (wct) -> {
mPipOrganizer.onExitPipFinished(taskInfo);
// TODO(b/286346098): remove the OPEN app flicker completely
@@ -610,7 +610,7 @@ public class PipTransition extends PipTransitionController {
mPipAnimationController.resetAnimatorState();
finishTransaction.remove(pipLeash);
}
- finishCallback.onTransitionFinished(wct, wctCB);
+ finishCallback.onTransitionFinished(wct);
};
mFinishTransaction = finishTransaction;
@@ -750,7 +750,7 @@ public class PipTransition extends PipTransitionController {
finishTransaction.setWindowCrop(info.getChanges().get(0).getLeash(),
mPipDisplayLayoutState.getDisplayBounds());
mPipOrganizer.onExitPipFinished(taskInfo);
- finishCallback.onTransitionFinished(null, null);
+ finishCallback.onTransitionFinished(null);
}
/** Whether we should handle the given {@link TransitionInfo} animation as entering PIP. */
@@ -1045,7 +1045,7 @@ public class PipTransition extends PipTransitionController {
startTransaction.apply();
mPipOrganizer.onExitPipFinished(taskInfo);
- finishCallback.onTransitionFinished(null, null);
+ finishCallback.onTransitionFinished(null);
}
private void resetPrevPip(@NonNull TransitionInfo.Change prevPipTaskChange,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index 7d82dc17ae72..26b7b684e1d8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -799,6 +799,14 @@ public class PipController implements PipTransitionController.PipTransitionCallb
}
private void onDisplayChangedUncheck(DisplayLayout layout, boolean saveRestoreSnapFraction) {
+ if (mPipTransitionState.getInSwipePipToHomeTransition()) {
+ // If orientation is changed when performing swipe-pip animation, DisplayLayout has
+ // been updated in startSwipePipToHome. So it is unnecessary to update again when
+ // receiving onDisplayConfigurationChanged. This also avoids TouchHandler.userResizeTo
+ // update surface position in different orientation by the intermediate state. The
+ // desired resize will be done by the end of transition.
+ return;
+ }
Runnable updateDisplayLayout = () -> {
final boolean fromRotation = Transitions.ENABLE_SHELL_TRANSITIONS
&& mPipDisplayLayoutState.getDisplayLayout().rotation() != layout.rotation();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index 88a81fc291b2..a11d9528a170 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -771,7 +771,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
Slog.e(TAG, "Error sending appeared tasks to recents animation", e);
}
}
- finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
+ finishCallback.onTransitionFinished(null /* wct */);
}
/** For now, just set-up a jump-cut to the new activity. */
@@ -937,7 +937,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
}
}
cleanUp();
- finishCB.onTransitionFinished(wct.isEmpty() ? null : wct, null /* wctCB */);
+ finishCB.onTransitionFinished(wct.isEmpty() ? null : wct);
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index 7699b4bfd13a..5fa26542ee07 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -423,8 +423,9 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
* transition.
*/
public void prepareExitSplitScreen(WindowContainerTransaction wct,
- @StageType int stageToTop) {
+ @StageType int stageToTop, @ExitReason int reason) {
mStageCoordinator.prepareExitSplitScreen(stageToTop, wct);
+ mStageCoordinator.clearSplitPairedInRecents(reason);
}
public void enterSplitScreen(int taskId, boolean leftOrTop) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
index d21f8a48e62a..99be5b8ee861 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
@@ -43,7 +43,6 @@ import android.window.RemoteTransition;
import android.window.TransitionInfo;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
-import android.window.WindowContainerTransactionCallback;
import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.common.TransactionPool;
@@ -109,7 +108,7 @@ class SplitScreenTransitions {
if (pendingTransition.mCanceled) {
// The pending transition was canceled, so skip playing animation.
startTransaction.apply();
- onFinish(null /* wct */, null /* wctCB */);
+ onFinish(null /* wct */);
return;
}
@@ -211,7 +210,7 @@ class SplitScreenTransitions {
}
}
t.apply();
- onFinish(null /* wct */, null /* wctCB */);
+ onFinish(null /* wct */);
}
/** Play animation for drag divider dismiss transition. */
@@ -238,7 +237,7 @@ class SplitScreenTransitions {
mAnimations.remove(va);
if (animated) {
mTransitions.getMainExecutor().execute(() -> {
- onFinish(null /* wct */, null /* wctCB */);
+ onFinish(null /* wct */);
});
}
});
@@ -250,7 +249,7 @@ class SplitScreenTransitions {
}
}
startTransaction.apply();
- onFinish(null /* wct */, null /* wctCB */);
+ onFinish(null /* wct */);
}
/** Play animation for resize transition. */
@@ -283,7 +282,7 @@ class SplitScreenTransitions {
mAnimations.remove(va);
if (animated) {
mTransitions.getMainExecutor().execute(() -> {
- onFinish(null /* wct */, null /* wctCB */);
+ onFinish(null /* wct */);
});
}
});
@@ -291,7 +290,7 @@ class SplitScreenTransitions {
}
startTransaction.apply();
- onFinish(null /* wct */, null /* wctCB */);
+ onFinish(null /* wct */);
}
boolean isPendingTransition(IBinder transition) {
@@ -391,7 +390,7 @@ class SplitScreenTransitions {
if (mPendingResize != null) {
mPendingResize.cancel(null);
mAnimations.clear();
- onFinish(null /* wct */, null /* wctCB */);
+ onFinish(null /* wct */);
}
IBinder transition = mTransitions.startTransition(TRANSIT_CHANGE, wct, handler);
@@ -450,7 +449,7 @@ class SplitScreenTransitions {
}
}
- void onFinish(WindowContainerTransaction wct, WindowContainerTransactionCallback wctCB) {
+ void onFinish(WindowContainerTransaction wct) {
if (!mAnimations.isEmpty()) return;
if (wct == null) wct = new WindowContainerTransaction();
@@ -470,7 +469,7 @@ class SplitScreenTransitions {
mOnFinish.run();
if (mFinishCallback != null) {
- mFinishCallback.onTransitionFinished(wct /* wct */, wctCB /* wctCB */);
+ mFinishCallback.onTransitionFinished(wct /* wct */);
mFinishCallback = null;
}
}
@@ -495,7 +494,7 @@ class SplitScreenTransitions {
mTransactionPool.release(transaction);
mTransitions.getMainExecutor().execute(() -> {
mAnimations.remove(va);
- onFinish(null /* wct */, null /* wctCB */);
+ onFinish(null /* wct */);
});
}
});
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 7d62f58014f0..69609ac6b752 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -83,7 +83,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.LauncherApps;
import android.content.pm.ShortcutInfo;
-import android.content.res.Configuration;
import android.graphics.Rect;
import android.hardware.devicestate.DeviceStateManager;
import android.os.Bundle;
@@ -1494,7 +1493,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
}
- private void clearSplitPairedInRecents(@ExitReason int exitReason) {
+ void clearSplitPairedInRecents(@ExitReason int exitReason) {
if (!shouldBreakPairedTaskInRecents(exitReason) || !mShouldUpdateRecents) return;
mRecentTasks.ifPresent(recentTasks -> {
@@ -1779,8 +1778,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mRootTaskInfo = taskInfo;
if (mSplitLayout != null
&& mSplitLayout.updateConfiguration(mRootTaskInfo.configuration)
- && mMainStage.isActive()
- && !ENABLE_SHELL_TRANSITIONS) {
+ && mMainStage.isActive()) {
// Clear the divider remote animating flag as the divider will be re-rendered to apply
// the new rotation config.
mIsDividerRemoteAnimating = false;
@@ -2218,20 +2216,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mDisplayController.addDisplayChangingController(this::onDisplayChange);
}
- @Override
- public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
- if (displayId != DEFAULT_DISPLAY) {
- return;
- }
- if (mSplitLayout != null && mSplitLayout.isDensityChanged(newConfig.densityDpi)
- && mMainStage.isActive()
- && mSplitLayout.updateConfiguration(newConfig)
- && ENABLE_SHELL_TRANSITIONS) {
- mSplitLayout.update(null /* t */);
- onLayoutSizeChanged(mSplitLayout);
- }
- }
-
/**
* Update surfaces of the split screen layout based on the current state
* @param transaction to write the updates to
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
index a743e99d6954..adae21b20b3c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
@@ -94,9 +94,11 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener {
mShellExecutor = organizer.getExecutor();
mSyncQueue = syncQueue;
mTaskViewTransitions = taskViewTransitions;
- if (mTaskViewTransitions != null) {
- mTaskViewTransitions.addTaskView(this);
- }
+ mShellExecutor.execute(() -> {
+ if (mTaskViewTransitions != null) {
+ mTaskViewTransitions.addTaskView(this);
+ }
+ });
mGuard.open("release");
}
@@ -225,10 +227,10 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener {
}
private void performRelease() {
- if (mTaskViewTransitions != null) {
- mTaskViewTransitions.removeTaskView(this);
- }
mShellExecutor.execute(() -> {
+ if (mTaskViewTransitions != null) {
+ mTaskViewTransitions.removeTaskView(this);
+ }
mTaskOrganizer.removeListener(this);
resetTaskInfo();
});
@@ -410,9 +412,12 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener {
if (mTaskToken == null) {
return;
}
- // Sync Transactions can't operate simultaneously with shell transition collection.
+
if (isUsingShellTransitions()) {
- mTaskViewTransitions.setTaskBounds(this, boundsOnScreen);
+ mShellExecutor.execute(() -> {
+ // Sync Transactions can't operate simultaneously with shell transition collection.
+ mTaskViewTransitions.setTaskBounds(this, boundsOnScreen);
+ });
return;
}
@@ -430,9 +435,11 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener {
Slog.w(TAG, "Trying to remove a task that was never added? (no taskToken)");
return;
}
- WindowContainerTransaction wct = new WindowContainerTransaction();
- wct.removeTask(mTaskToken);
- mTaskViewTransitions.closeTaskView(wct, this);
+ mShellExecutor.execute(() -> {
+ WindowContainerTransaction wct = new WindowContainerTransaction();
+ wct.removeTask(mTaskToken);
+ mTaskViewTransitions.closeTaskView(wct, this);
+ });
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
index daf8be60651a..e03f82526bdb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
@@ -390,7 +390,7 @@ public class TaskViewTransitions implements Transitions.TransitionHandler {
}
// No animation, just show it immediately.
startTransaction.apply();
- finishCallback.onTransitionFinished(wct, null /* wctCB */);
+ finishCallback.onTransitionFinished(wct);
startNextTransition();
return true;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
index 052af3af98cc..986560bd6053 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
@@ -40,7 +40,6 @@ import android.view.WindowManager;
import android.window.TransitionInfo;
import android.window.TransitionRequestInfo;
import android.window.WindowContainerTransaction;
-import android.window.WindowContainerTransactionCallback;
import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.common.split.SplitScreenUtils;
@@ -124,14 +123,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
mTransition = transition;
}
- void joinFinishArgs(WindowContainerTransaction wct,
- WindowContainerTransactionCallback wctCB) {
- if (wctCB != null) {
- // Technically can probably support 1, but don't want to encourage CB usage since
- // it creates instabliity, so just throw.
- throw new IllegalArgumentException("Can't mix transitions that require finish"
- + " sync callback");
- }
+ void joinFinishArgs(WindowContainerTransaction wct) {
if (wct != null) {
if (mFinishWCT == null) {
mFinishWCT = wct;
@@ -389,12 +381,12 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
info.getChanges().remove(i);
}
}
- Transitions.TransitionFinishCallback finishCB = (wct, wctCB) -> {
+ Transitions.TransitionFinishCallback finishCB = (wct) -> {
--mixed.mInFlightSubAnimations;
- mixed.joinFinishArgs(wct, wctCB);
+ mixed.joinFinishArgs(wct);
if (mixed.mInFlightSubAnimations > 0) return;
mActiveTransitions.remove(mixed);
- finishCallback.onTransitionFinished(mixed.mFinishWCT, wctCB);
+ finishCallback.onTransitionFinished(mixed.mFinishWCT);
};
if (pipChange == null) {
if (mixed.mLeftoversHandler != null) {
@@ -461,15 +453,15 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
return false;
}
final boolean isGoingHome = homeIsOpening;
- Transitions.TransitionFinishCallback finishCB = (wct, wctCB) -> {
+ Transitions.TransitionFinishCallback finishCB = (wct) -> {
--mixed.mInFlightSubAnimations;
- mixed.joinFinishArgs(wct, wctCB);
+ mixed.joinFinishArgs(wct);
if (mixed.mInFlightSubAnimations > 0) return;
mActiveTransitions.remove(mixed);
if (isGoingHome) {
mSplitHandler.onTransitionAnimationComplete();
}
- finishCallback.onTransitionFinished(mixed.mFinishWCT, wctCB);
+ finishCallback.onTransitionFinished(mixed.mFinishWCT);
};
if (isGoingHome || mSplitHandler.getSplitItemPosition(pipChange.getLastParent())
!= SPLIT_POSITION_UNDEFINED) {
@@ -586,12 +578,12 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
// We need to split the transition into 2 parts: the split part and the display part.
mixed.mInFlightSubAnimations = 2;
- Transitions.TransitionFinishCallback finishCB = (wct, wctCB) -> {
+ Transitions.TransitionFinishCallback finishCB = (wct) -> {
--mixed.mInFlightSubAnimations;
- mixed.joinFinishArgs(wct, wctCB);
+ mixed.joinFinishArgs(wct);
if (mixed.mInFlightSubAnimations > 0) return;
mActiveTransitions.remove(mixed);
- finishCallback.onTransitionFinished(mixed.mFinishWCT, null /* wctCB */);
+ finishCallback.onTransitionFinished(mixed.mFinishWCT);
};
// Dispatch the display change. This will most-likely be taken by the default handler.
@@ -614,7 +606,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
// Split-screen is only interested in the recents transition finishing (and merging), so
// just wrap finish and start recents animation directly.
- Transitions.TransitionFinishCallback finishCB = (wct, wctCB) -> {
+ Transitions.TransitionFinishCallback finishCB = (wct) -> {
mixed.mInFlightSubAnimations = 0;
mActiveTransitions.remove(mixed);
// If pair-to-pair switching, the post-recents clean-up isn't needed.
@@ -626,7 +618,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
mSplitHandler.onRecentsPairToPairAnimationFinish(wct);
}
mSplitHandler.onTransitionAnimationComplete();
- finishCallback.onTransitionFinished(wct, wctCB);
+ finishCallback.onTransitionFinished(wct);
};
mixed.mInFlightSubAnimations = 1;
mSplitHandler.onRecentsInSplitAnimationStart(info);
@@ -644,11 +636,11 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
- final Transitions.TransitionFinishCallback finishCB = (wct, wctCB) -> {
+ final Transitions.TransitionFinishCallback finishCB = (wct) -> {
mixed.mInFlightSubAnimations--;
if (mixed.mInFlightSubAnimations == 0) {
mActiveTransitions.remove(mixed);
- finishCallback.onTransitionFinished(wct, wctCB);
+ finishCallback.onTransitionFinished(wct);
}
};
mixed.mInFlightSubAnimations++;
@@ -693,11 +685,11 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
- final Transitions.TransitionFinishCallback finishCB = (wct, wctCB) -> {
+ final Transitions.TransitionFinishCallback finishCB = (wct) -> {
mixed.mInFlightSubAnimations--;
if (mixed.mInFlightSubAnimations > 0) return;
mActiveTransitions.remove(mixed);
- finishCallback.onTransitionFinished(wct, wctCB);
+ finishCallback.onTransitionFinished(wct);
};
mixed.mInFlightSubAnimations = 1;
// Sync pip state.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
index dc78c9b139f9..7df658e6c9db 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
@@ -300,7 +300,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
// immediately finishes since there is no animation for screen-wake.
if (info.getType() == WindowManager.TRANSIT_WAKE && !info.isKeyguardGoingAway()) {
startTransaction.apply();
- finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
+ finishCallback.onTransitionFinished(null /* wct */);
return true;
}
@@ -309,7 +309,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
|| (info.getFlags() & WindowManager.TRANSIT_FLAG_INVISIBLE) != 0) {
startTransaction.apply();
finishTransaction.apply();
- finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
+ finishCallback.onTransitionFinished(null /* wct */);
return true;
}
@@ -323,7 +323,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
final Runnable onAnimFinish = () -> {
if (!animations.isEmpty()) return;
mAnimations.remove(transition);
- finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
+ finishCallback.onTransitionFinished(null /* wct */);
};
final List<Consumer<SurfaceControl.Transaction>> postStartTransactionCallbacks =
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java
index 4e3d220f1ea2..fab2dd2bf3e1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java
@@ -68,7 +68,7 @@ public class OneShotRemoteHandler implements Transitions.TransitionHandler {
final IBinder.DeathRecipient remoteDied = () -> {
Log.e(Transitions.TAG, "Remote transition died, finishing");
mMainExecutor.execute(
- () -> finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */));
+ () -> finishCallback.onTransitionFinished(null /* wct */));
};
IRemoteTransitionFinishedCallback cb = new IRemoteTransitionFinishedCallback.Stub() {
@Override
@@ -81,7 +81,7 @@ public class OneShotRemoteHandler implements Transitions.TransitionHandler {
finishTransaction.merge(sct);
}
mMainExecutor.execute(() -> {
- finishCallback.onTransitionFinished(wct, null /* wctCB */);
+ finishCallback.onTransitionFinished(wct);
});
}
};
@@ -104,7 +104,7 @@ public class OneShotRemoteHandler implements Transitions.TransitionHandler {
if (mRemote.asBinder() != null) {
mRemote.asBinder().unlinkToDeath(remoteDied, 0 /* flags */);
}
- finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
+ finishCallback.onTransitionFinished(null /* wct */);
}
return true;
}
@@ -122,8 +122,7 @@ public class OneShotRemoteHandler implements Transitions.TransitionHandler {
// remote applied the transaction, but applying twice will break surfaceflinger
// so just assume the worst-case and clear the local transaction.
t.clear();
- mMainExecutor.execute(
- () -> finishCallback.onTransitionFinished(wct, null /* wctCB */));
+ mMainExecutor.execute(() -> finishCallback.onTransitionFinished(wct));
}
};
try {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java
index c22cc6fbea8f..bbf67a6155d7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java
@@ -133,7 +133,7 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler {
}
mMainExecutor.execute(() -> {
mRequestedRemotes.remove(transition);
- finishCallback.onTransitionFinished(wct, null /* wctCB */);
+ finishCallback.onTransitionFinished(wct);
});
}
};
@@ -153,8 +153,7 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler {
Log.e(Transitions.TAG, "Error running remote transition.", e);
unhandleDeath(remote.asBinder(), finishCallback);
mRequestedRemotes.remove(transition);
- mMainExecutor.execute(
- () -> finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */));
+ mMainExecutor.execute(() -> finishCallback.onTransitionFinished(null /* wct */));
}
return true;
}
@@ -210,7 +209,7 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler {
+ "that the mergeTarget's RemoteTransition impl erroneously "
+ "accepted/ran the merge request after finishing the mergeTarget");
}
- finishCallback.onTransitionFinished(wct, null /* wctCB */);
+ finishCallback.onTransitionFinished(wct);
});
}
};
@@ -316,8 +315,7 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler {
}
}
for (int i = mPendingFinishCallbacks.size() - 1; i >= 0; --i) {
- mPendingFinishCallbacks.get(i).onTransitionFinished(
- null /* wct */, null /* wctCB */);
+ mPendingFinishCallbacks.get(i).onTransitionFinished(null /* wct */);
}
mPendingFinishCallbacks.clear();
});
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/SleepHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/SleepHandler.java
index d2795959494a..87c438a5b37d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/SleepHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/SleepHandler.java
@@ -43,7 +43,7 @@ class SleepHandler implements Transitions.TransitionHandler {
@NonNull Transitions.TransitionFinishCallback finishCallback) {
mSleepTransitions.remove(transition);
startTransaction.apply();
- finishCallback.onTransitionFinished(null, null);
+ finishCallback.onTransitionFinished(null);
return true;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index e2dce88d5958..b4d0a31dc8c1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -62,7 +62,6 @@ import android.window.TransitionInfo;
import android.window.TransitionMetrics;
import android.window.TransitionRequestInfo;
import android.window.WindowContainerTransaction;
-import android.window.WindowContainerTransactionCallback;
import android.window.WindowOrganizer;
import androidx.annotation.BinderThread;
@@ -829,7 +828,7 @@ public class Transitions implements RemoteCallable<Transitions>,
ready.mStartT.apply();
}
// finish now since there's nothing to animate. Calls back into processReadyQueue
- onFinish(ready, null, null);
+ onFinish(ready, null);
return;
}
playTransition(ready);
@@ -849,7 +848,7 @@ public class Transitions implements RemoteCallable<Transitions>,
+ " in case they can be merged", ready, playing);
mTracer.logMergeRequested(ready.mInfo.getDebugId(), playing.mInfo.getDebugId());
playing.mHandler.mergeAnimation(ready.mToken, ready.mInfo, ready.mStartT,
- playing.mToken, (wct, cb) -> onMerged(playing, ready));
+ playing.mToken, (wct) -> onMerged(playing, ready));
}
private void onMerged(@NonNull ActiveTransition playing, @NonNull ActiveTransition merged) {
@@ -899,7 +898,7 @@ public class Transitions implements RemoteCallable<Transitions>,
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " try firstHandler %s",
active.mHandler);
boolean consumed = active.mHandler.startAnimation(active.mToken, active.mInfo,
- active.mStartT, active.mFinishT, (wct, cb) -> onFinish(active, wct, cb));
+ active.mStartT, active.mFinishT, (wct) -> onFinish(active, wct));
if (consumed) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " animated by firstHandler");
mTracer.logDispatched(active.mInfo.getDebugId(), active.mHandler);
@@ -908,7 +907,7 @@ public class Transitions implements RemoteCallable<Transitions>,
}
// Otherwise give every other handler a chance
active.mHandler = dispatchTransition(active.mToken, active.mInfo, active.mStartT,
- active.mFinishT, (wct, cb) -> onFinish(active, wct, cb), active.mHandler);
+ active.mFinishT, (wct) -> onFinish(active, wct), active.mHandler);
}
/**
@@ -985,8 +984,7 @@ public class Transitions implements RemoteCallable<Transitions>,
}
private void onFinish(ActiveTransition active,
- @Nullable WindowContainerTransaction wct,
- @Nullable WindowContainerTransactionCallback wctCB) {
+ @Nullable WindowContainerTransaction wct) {
final Track track = mTracks.get(active.getTrack());
if (track.mActiveTransition != active) {
Log.e(TAG, "Trying to finish a non-running transition. Either remote crashed or "
@@ -1035,11 +1033,11 @@ public class Transitions implements RemoteCallable<Transitions>,
// Now perform all the finish callbacks (starting with the playing one and then all the
// transitions merged into it).
releaseSurfaces(active.mInfo);
- mOrganizer.finishTransition(active.mToken, wct, wctCB);
+ mOrganizer.finishTransition(active.mToken, wct);
if (active.mMerged != null) {
for (int iM = 0; iM < active.mMerged.size(); ++iM) {
ActiveTransition merged = active.mMerged.get(iM);
- mOrganizer.finishTransition(merged.mToken, null /* wct */, null /* wctCB */);
+ mOrganizer.finishTransition(merged.mToken, null /* wct */);
releaseSurfaces(merged.mInfo);
}
active.mMerged.clear();
@@ -1178,7 +1176,7 @@ public class Transitions implements RemoteCallable<Transitions>,
forceFinish.mHandler.onTransitionConsumed(
forceFinish.mToken, true /* aborted */, null /* finishTransaction */);
}
- onFinish(forceFinish, null, null);
+ onFinish(forceFinish, null);
}
}
if (track.isIdle() || mReadyDuringSync.isEmpty()) {
@@ -1198,7 +1196,7 @@ public class Transitions implements RemoteCallable<Transitions>,
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Attempt to merge sync %s"
+ " into %s via a SLEEP proxy", nextSync, playing);
playing.mHandler.mergeAnimation(nextSync.mToken, dummyInfo, dummyT,
- playing.mToken, (wct, cb) -> {});
+ playing.mToken, (wct) -> {});
// it's possible to complete immediately. If that happens, just repeat the signal
// loop until we either finish everything or start playing an animation that isn't
// finishing immediately.
@@ -1226,11 +1224,8 @@ public class Transitions implements RemoteCallable<Transitions>,
* The transition must not touch the surfaces after this has been called.
*
* @param wct A WindowContainerTransaction to run along with the transition clean-up.
- * @param wctCB A sync callback that will be run when the transition clean-up is done and
- * wct has been applied.
*/
- void onTransitionFinished(@Nullable WindowContainerTransaction wct,
- @Nullable WindowContainerTransactionCallback wctCB);
+ void onTransitionFinished(@Nullable WindowContainerTransaction wct);
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
index f148412205bf..2eb6e71456db 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
@@ -169,7 +169,7 @@ public class UnfoldTransitionHandler implements TransitionHandler, UnfoldListene
animator.stop();
}
- mFinishCallback.onTransitionFinished(null, null);
+ mFinishCallback.onTransitionFinished(null);
mFinishCallback = null;
mTransition = null;
}
@@ -193,7 +193,7 @@ public class UnfoldTransitionHandler implements TransitionHandler, UnfoldListene
}
// Apply changes happening during the unfold animation immediately
t.apply();
- finishCallback.onTransitionFinished(null, null);
+ finishCallback.onTransitionFinished(null);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
index fb05c696af82..c9c58de6e82a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
@@ -168,7 +168,7 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback,
startTransaction.apply();
mDesktopWindowDecoration.hideResizeVeil();
mCtrlType = CTRL_TYPE_UNDEFINED;
- finishCallback.onTransitionFinished(null, null);
+ finishCallback.onTransitionFinished(null);
return true;
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java
index 4fca8b46a069..2d9304705738 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java
@@ -92,7 +92,7 @@ public class ActivityEmbeddingAnimationRunnerTests extends ActivityEmbeddingAnim
.build();
final Animator animator = mAnimRunner.createAnimator(
info, mStartTransaction, mFinishTransaction,
- () -> mFinishCallback.onTransitionFinished(null /* wct */, null /* wctCB */),
+ () -> mFinishCallback.onTransitionFinished(null /* wct */),
new ArrayList());
// The animation should be empty when it is behind starting window.
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java
index ab1ccd4599a2..0b2265d4ce9c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java
@@ -75,7 +75,7 @@ abstract class ActivityEmbeddingAnimationTestBase extends ShellTestCase {
assertNotNull(mAnimRunner);
mAnimSpec = mAnimRunner.mAnimationSpec;
assertNotNull(mAnimSpec);
- mFinishCallback = (wct, wctCB) -> {};
+ mFinishCallback = (wct) -> {};
spyOn(mController);
spyOn(mAnimRunner);
spyOn(mAnimSpec);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingControllerTests.java
index ba34f1f74cd3..270dbc49835f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingControllerTests.java
@@ -217,12 +217,10 @@ public class ActivityEmbeddingControllerTests extends ActivityEmbeddingAnimation
doReturn(animator).when(mAnimRunner).createAnimator(any(), any(), any(), any(), any());
mController.startAnimation(mTransition, info, mStartTransaction,
mFinishTransaction, mFinishCallback);
- verify(mFinishCallback, never()).onTransitionFinished(any(), any());
+ verify(mFinishCallback, never()).onTransitionFinished(any());
mController.mergeAnimation(mTransition, info, new SurfaceControl.Transaction(),
- mTransition,
- (wct, cb) -> {
- });
- verify(mFinishCallback).onTransitionFinished(any(), any());
+ mTransition, (wct) -> {});
+ verify(mFinishCallback).onTransitionFinished(any());
}
@Test
@@ -238,9 +236,9 @@ public class ActivityEmbeddingControllerTests extends ActivityEmbeddingAnimation
mController.startAnimation(mTransition, info, mStartTransaction,
mFinishTransaction, mFinishCallback);
- verify(mFinishCallback, never()).onTransitionFinished(any(), any());
+ verify(mFinishCallback, never()).onTransitionFinished(any());
mController.onAnimationFinished(mTransition);
- verify(mFinishCallback).onTransitionFinished(any(), any());
+ verify(mFinishCallback).onTransitionFinished(any());
// Should not call finish when the finish has already been called.
assertThrows(IllegalStateException.class,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
index ff380e92322d..99a1ac663286 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
@@ -176,7 +176,7 @@ public class ShellTransitionTests extends ShellTestCase {
assertEquals(1, mDefaultHandler.activeCount());
mDefaultHandler.finishAll();
mMainExecutor.flushAll();
- verify(mOrganizer, times(1)).finishTransition(eq(transitToken), any(), any());
+ verify(mOrganizer, times(1)).finishTransition(eq(transitToken), any());
}
@Test
@@ -299,7 +299,7 @@ public class ShellTransitionTests extends ShellTestCase {
assertTrue(remoteCalled[0]);
mDefaultHandler.finishAll();
mMainExecutor.flushAll();
- verify(mOrganizer, times(1)).finishTransition(eq(transitToken), eq(remoteFinishWCT), any());
+ verify(mOrganizer, times(1)).finishTransition(eq(transitToken), eq(remoteFinishWCT));
}
@Test
@@ -449,7 +449,7 @@ public class ShellTransitionTests extends ShellTestCase {
assertTrue(remoteCalled[0]);
mDefaultHandler.finishAll();
mMainExecutor.flushAll();
- verify(mOrganizer, times(1)).finishTransition(eq(transitToken), any(), any());
+ verify(mOrganizer, times(1)).finishTransition(eq(transitToken), any());
}
@Test
@@ -524,20 +524,20 @@ public class ShellTransitionTests extends ShellTestCase {
// default handler doesn't merge by default, so it shouldn't increment active count.
assertEquals(1, mDefaultHandler.activeCount());
assertEquals(0, mDefaultHandler.mergeCount());
- verify(mOrganizer, times(0)).finishTransition(eq(transitToken1), any(), any());
- verify(mOrganizer, times(0)).finishTransition(eq(transitToken2), any(), any());
+ verify(mOrganizer, times(0)).finishTransition(eq(transitToken1), any());
+ verify(mOrganizer, times(0)).finishTransition(eq(transitToken2), any());
mDefaultHandler.finishAll();
mMainExecutor.flushAll();
// first transition finished
- verify(mOrganizer, times(1)).finishTransition(eq(transitToken1), any(), any());
- verify(mOrganizer, times(0)).finishTransition(eq(transitToken2), any(), any());
+ verify(mOrganizer, times(1)).finishTransition(eq(transitToken1), any());
+ verify(mOrganizer, times(0)).finishTransition(eq(transitToken2), any());
// But now the "queued" transition is running
assertEquals(1, mDefaultHandler.activeCount());
mDefaultHandler.finishAll();
mMainExecutor.flushAll();
- verify(mOrganizer, times(1)).finishTransition(eq(transitToken2), any(), any());
+ verify(mOrganizer, times(1)).finishTransition(eq(transitToken2), any());
}
@Test
@@ -565,15 +565,15 @@ public class ShellTransitionTests extends ShellTestCase {
// it should still only have 1 active, but then show 1 merged
assertEquals(1, mDefaultHandler.activeCount());
assertEquals(1, mDefaultHandler.mergeCount());
- verify(mOrganizer, times(0)).finishTransition(eq(transitToken1), any(), any());
+ verify(mOrganizer, times(0)).finishTransition(eq(transitToken1), any());
// We don't tell organizer it is finished yet (since we still want to maintain ordering)
- verify(mOrganizer, times(0)).finishTransition(eq(transitToken2), any(), any());
+ verify(mOrganizer, times(0)).finishTransition(eq(transitToken2), any());
mDefaultHandler.finishAll();
mMainExecutor.flushAll();
// transition + merged all finished.
- verify(mOrganizer, times(1)).finishTransition(eq(transitToken1), any(), any());
- verify(mOrganizer, times(1)).finishTransition(eq(transitToken2), any(), any());
+ verify(mOrganizer, times(1)).finishTransition(eq(transitToken1), any());
+ verify(mOrganizer, times(1)).finishTransition(eq(transitToken2), any());
// Make sure nothing was queued
assertEquals(0, mDefaultHandler.activeCount());
}
@@ -599,8 +599,7 @@ public class ShellTransitionTests extends ShellTestCase {
requestStartTransition(transitions, transitTokenNotReady);
mDefaultHandler.setSimulateMerge(true);
- mDefaultHandler.mFinishes.get(0).second.onTransitionFinished(
- null /* wct */, null /* wctCB */);
+ mDefaultHandler.mFinishes.get(0).second.onTransitionFinished(null /* wct */);
// Make sure that the non-ready transition is not merged.
assertEquals(0, mDefaultHandler.mergeCount());
@@ -823,8 +822,8 @@ public class ShellTransitionTests extends ShellTestCase {
mDefaultHandler.finishAll();
mMainExecutor.flushAll();
// first transition finished
- verify(mOrganizer, times(1)).finishTransition(eq(transitToken1), any(), any());
- verify(mOrganizer, times(0)).finishTransition(eq(transitToken2), any(), any());
+ verify(mOrganizer, times(1)).finishTransition(eq(transitToken1), any());
+ verify(mOrganizer, times(0)).finishTransition(eq(transitToken2), any());
// But now the "queued" transition is running
assertEquals(1, mDefaultHandler.activeCount());
@@ -835,7 +834,7 @@ public class ShellTransitionTests extends ShellTestCase {
mDefaultHandler.finishAll();
mMainExecutor.flushAll();
- verify(mOrganizer, times(1)).finishTransition(eq(transitToken2), any(), any());
+ verify(mOrganizer, times(1)).finishTransition(eq(transitToken2), any());
// runnable2 and runnable3 are executed after the second transition finishes because there
// are no other active transitions, runnable1 isn't executed again.
@@ -1449,13 +1448,13 @@ public class ShellTransitionTests extends ShellTestCase {
if (mFinishOnSync && info.getType() == TRANSIT_SLEEP) {
for (int i = 0; i < mFinishes.size(); ++i) {
if (mFinishes.get(i).first != mergeTarget) continue;
- mFinishes.remove(i).second.onTransitionFinished(null, null);
+ mFinishes.remove(i).second.onTransitionFinished(null);
return;
}
}
if (!(mSimulateMerge || mShouldMerge.contains(transition))) return;
mMerged.add(transition);
- finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
+ finishCallback.onTransitionFinished(null /* wct */);
}
@Nullable
@@ -1478,7 +1477,7 @@ public class ShellTransitionTests extends ShellTestCase {
mFinishes;
mFinishes = new ArrayList<>();
for (int i = finishes.size() - 1; i >= 0; --i) {
- finishes.get(i).second.onTransitionFinished(null /* wct */, null /* wctCB */);
+ finishes.get(i).second.onTransitionFinished(null /* wct */);
}
mShouldMerge.clear();
}
@@ -1486,7 +1485,7 @@ public class ShellTransitionTests extends ShellTestCase {
void finishOne() {
Pair<IBinder, Transitions.TransitionFinishCallback> fin = mFinishes.remove(0);
mMerged.clear();
- fin.second.onTransitionFinished(null /* wct */, null /* wctCB */);
+ fin.second.onTransitionFinished(null /* wct */);
}
int activeCount() {
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 4759689335e9..e8c9d0dbd884 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -6929,6 +6929,114 @@ public class AudioManager {
/**
* @hide
+ * Describes an audio device that has not been categorized with a specific
+ * audio type.
+ */
+ public static final int AUDIO_DEVICE_CATEGORY_UNKNOWN = 0;
+
+ /**
+ * @hide
+ * Describes an audio device which is categorized as something different.
+ */
+ public static final int AUDIO_DEVICE_CATEGORY_OTHER = 1;
+
+ /**
+ * @hide
+ * Describes an audio device which was categorized as speakers.
+ */
+ public static final int AUDIO_DEVICE_CATEGORY_SPEAKER = 2;
+
+ /**
+ * @hide
+ * Describes an audio device which was categorized as headphones.
+ */
+ public static final int AUDIO_DEVICE_CATEGORY_HEADPHONES = 3;
+
+ /**
+ * @hide
+ * Describes an audio device which was categorized as car-kit.
+ */
+ public static final int AUDIO_DEVICE_CATEGORY_CARKIT = 4;
+
+ /**
+ * @hide
+ * Describes an audio device which was categorized as watch.
+ */
+ public static final int AUDIO_DEVICE_CATEGORY_WATCH = 5;
+
+ /**
+ * @hide
+ * Describes an audio device which was categorized as hearing aid.
+ */
+ public static final int AUDIO_DEVICE_CATEGORY_HEARING_AID = 6;
+
+ /**
+ * @hide
+ * Describes an audio device which was categorized as receiver.
+ */
+ public static final int AUDIO_DEVICE_CATEGORY_RECEIVER = 7;
+
+ /** @hide */
+ @IntDef(flag = false, prefix = "AUDIO_DEVICE_CATEGORY", value = {
+ AUDIO_DEVICE_CATEGORY_UNKNOWN,
+ AUDIO_DEVICE_CATEGORY_OTHER,
+ AUDIO_DEVICE_CATEGORY_SPEAKER,
+ AUDIO_DEVICE_CATEGORY_HEADPHONES,
+ AUDIO_DEVICE_CATEGORY_CARKIT,
+ AUDIO_DEVICE_CATEGORY_WATCH,
+ AUDIO_DEVICE_CATEGORY_HEARING_AID,
+ AUDIO_DEVICE_CATEGORY_RECEIVER }
+ )
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface AudioDeviceCategory {}
+
+ /** @hide */
+ public static String audioDeviceCategoryToString(int audioDeviceCategory) {
+ switch (audioDeviceCategory) {
+ case AUDIO_DEVICE_CATEGORY_UNKNOWN: return "AUDIO_DEVICE_CATEGORY_UNKNOWN";
+ case AUDIO_DEVICE_CATEGORY_OTHER: return "AUDIO_DEVICE_CATEGORY_OTHER";
+ case AUDIO_DEVICE_CATEGORY_SPEAKER: return "AUDIO_DEVICE_CATEGORY_SPEAKER";
+ case AUDIO_DEVICE_CATEGORY_HEADPHONES: return "AUDIO_DEVICE_CATEGORY_HEADPHONES";
+ case AUDIO_DEVICE_CATEGORY_CARKIT: return "AUDIO_DEVICE_CATEGORY_CARKIT";
+ case AUDIO_DEVICE_CATEGORY_WATCH: return "AUDIO_DEVICE_CATEGORY_WATCH";
+ case AUDIO_DEVICE_CATEGORY_HEARING_AID: return "AUDIO_DEVICE_CATEGORY_HEARING_AID";
+ case AUDIO_DEVICE_CATEGORY_RECEIVER: return "AUDIO_DEVICE_CATEGORY_RECEIVER";
+ default:
+ return new StringBuilder("unknown AudioDeviceCategory ").append(
+ audioDeviceCategory).toString();
+ }
+ }
+
+ /**
+ * @hide
+ * Sets the audio device type of a Bluetooth device given its MAC address
+ */
+ @RequiresPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+ public void setBluetoothAudioDeviceCategory(@NonNull String address, boolean isBle,
+ @AudioDeviceCategory int btAudioDeviceType) {
+ try {
+ getService().setBluetoothAudioDeviceCategory(address, isBle, btAudioDeviceType);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @hide
+ * Gets the audio device type of a Bluetooth device given its MAC address
+ */
+ @RequiresPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+ @AudioDeviceCategory
+ public int getBluetoothAudioDeviceCategory(@NonNull String address, boolean isBle) {
+ try {
+ return getService().getBluetoothAudioDeviceCategory(address, isBle);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @hide
* Sound dose warning at every 100% of dose during integration window
*/
public static final int CSD_WARNING_DOSE_REACHED_1X = 1;
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 02f765a3dab9..b2466e990b8f 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -324,6 +324,12 @@ interface IAudioService {
@EnforcePermission("MODIFY_AUDIO_SETTINGS_PRIVILEGED")
boolean isCsdEnabled();
+ @EnforcePermission("MODIFY_AUDIO_SETTINGS_PRIVILEGED")
+ oneway void setBluetoothAudioDeviceCategory(in String address, boolean isBle, int deviceType);
+
+ @EnforcePermission("MODIFY_AUDIO_SETTINGS_PRIVILEGED")
+ int getBluetoothAudioDeviceCategory(in String address, boolean isBle);
+
int setHdmiSystemAudioSupported(boolean on);
boolean isHdmiSystemAudioSupported();
diff --git a/media/tests/mediatestutils/Android.bp b/media/tests/mediatestutils/Android.bp
new file mode 100644
index 000000000000..e50e69ac6f4f
--- /dev/null
+++ b/media/tests/mediatestutils/Android.bp
@@ -0,0 +1,49 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+// TODO audio build defaults
+java_library {
+ name: "mediatestutils_host",
+ host_supported: true,
+ srcs: [
+ "java/com/android/media/mediatestutils/CancelAllFuturesRule.java",
+ ],
+ static_libs: [
+ "junit",
+ ],
+ visibility: [
+ ":__subpackages__",
+ ],
+}
+
+java_library {
+ name: "mediatestutils",
+ static_libs: [
+ "mediatestutils_host",
+ "junit",
+ ],
+ visibility: [
+ "//cts/tests/tests/media:__subpackages__",
+ ":__subpackages__",
+ ],
+}
+
+java_test_host {
+ name: "mediatestutilshosttests",
+ srcs: ["javatests/**/*.java"],
+ static_libs: [
+ "mediatestutils_host",
+ "junit",
+ "truth",
+ ],
+ test_suites: ["general-tests"],
+ test_options: {
+ unit_test: true,
+ },
+}
diff --git a/media/tests/mediatestutils/OWNERS b/media/tests/mediatestutils/OWNERS
new file mode 100644
index 000000000000..b9eb1f82663f
--- /dev/null
+++ b/media/tests/mediatestutils/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 48436
+atneya@google.com
+jmtrivi@google.com
+elaurent@google.com
diff --git a/media/tests/mediatestutils/java/com/android/media/mediatestutils/CancelAllFuturesRule.java b/media/tests/mediatestutils/java/com/android/media/mediatestutils/CancelAllFuturesRule.java
new file mode 100644
index 000000000000..14e261c40d9f
--- /dev/null
+++ b/media/tests/mediatestutils/java/com/android/media/mediatestutils/CancelAllFuturesRule.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.media.mediatestutils;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Future;
+
+/**
+ *
+ */
+public class CancelAllFuturesRule implements TestRule {
+ private List<Future> mRegisteredFutures = new ArrayList<>();
+
+ public <T extends Future<?>> T registerFuture(T future) {
+ mRegisteredFutures.add(future);
+ return future;
+ }
+
+ @Override
+ public Statement apply(Statement base, Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ try {
+ base.evaluate();
+ } finally {
+ mRegisteredFutures.forEach(f -> f.cancel(false /* shouldInterrupt */));
+ }
+ }
+ };
+ }
+}
diff --git a/media/tests/mediatestutils/javatests/com/android/media/mediatestutils/CancelAllFuturesRuleTest.java b/media/tests/mediatestutils/javatests/com/android/media/mediatestutils/CancelAllFuturesRuleTest.java
new file mode 100644
index 000000000000..94fa3d7847eb
--- /dev/null
+++ b/media/tests/mediatestutils/javatests/com/android/media/mediatestutils/CancelAllFuturesRuleTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.media.mediatestutils;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Future;
+
+
+@RunWith(JUnit4.class)
+public class CancelAllFuturesRuleTest {
+
+ public static class TestException extends Throwable { }
+
+ public static class CheckFutureStatusRule implements TestRule {
+ private final List<CompletableFuture> mFutures = Arrays.asList(new CompletableFuture<>(),
+ new CompletableFuture<>());
+
+ private boolean mCompleted;
+
+ @Override
+ public Statement apply(Statement base, Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ try {
+ base.evaluate();
+ } finally {
+ // Intentionally suppresses original exception
+ if (mCompleted) {
+ assertThat(mFutures.get(0).isDone())
+ .isTrue();
+ assertThat(mFutures.get(0).isCancelled())
+ .isFalse();
+ } else {
+ assertThat(mFutures.get(0).isCancelled())
+ .isTrue();
+ }
+ assertThat(mFutures.get(1).isCancelled())
+ .isTrue();
+ }
+ }
+ };
+ }
+
+ Future getFuture(int idx) {
+ return mFutures.get(idx);
+ }
+
+ void completeFirstFuture(boolean exceptionally) {
+ assertThat(mFutures.get(0).complete(null))
+ .isTrue();
+ mCompleted = true;
+ }
+ }
+
+ @Rule(order = 0)
+ public ExpectedException mExpectedThrownRule = ExpectedException.none();
+
+ @Rule(order = 1)
+ public CheckFutureStatusRule mRuleVerifyerRule = new CheckFutureStatusRule();
+
+ @Rule(order = 2)
+ public CancelAllFuturesRule mCancelRule = new CancelAllFuturesRule();
+
+ @Test
+ public void testRuleCancelsFutures_whenFinishesNormally() {
+ mCancelRule.registerFuture(mRuleVerifyerRule.getFuture(0));
+ mCancelRule.registerFuture(mRuleVerifyerRule.getFuture(1));
+ // return normally
+ }
+
+ @Test
+ public void testRuleCancelsFutures_whenFinishesExceptionally() throws TestException {
+ mExpectedThrownRule.expect(TestException.class);
+ mCancelRule.registerFuture(mRuleVerifyerRule.getFuture(0));
+ mCancelRule.registerFuture(mRuleVerifyerRule.getFuture(1));
+ throw new TestException();
+ }
+
+ @Test
+ public void testRuleDoesNotThrow_whenCompletesNormally() {
+ mCancelRule.registerFuture(mRuleVerifyerRule.getFuture(0));
+ mCancelRule.registerFuture(mRuleVerifyerRule.getFuture(1));
+ mRuleVerifyerRule.completeFirstFuture(false);
+ }
+
+ @Test
+ public void testRuleDoesNotThrow_whenCompletesExceptionally() {
+ mCancelRule.registerFuture(mRuleVerifyerRule.getFuture(0));
+ mCancelRule.registerFuture(mRuleVerifyerRule.getFuture(1));
+ mRuleVerifyerRule.completeFirstFuture(false);
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
index b66679af3fe3..2d6cc699fc11 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
@@ -16,9 +16,7 @@
*/
package com.android.packageinstaller;
-import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
import static android.content.Intent.FLAG_ACTIVITY_NO_HISTORY;
-import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
import android.Manifest;
@@ -808,8 +806,12 @@ public class PackageInstallerActivity extends AlertActivity {
}
new Handler(Looper.getMainLooper()).postDelayed(() -> {
if (!isDestroyed()) {
- startActivity(getIntent().addFlags(
- FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP));
+ // The start flag (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP) doesn't
+ // work for the multiple user case, i.e. the caller task user and started
+ // Activity user are not the same. To avoid having multiple PIAs in the task,
+ // finish the current PackageInstallerActivity
+ finish();
+ startActivity(getIntent());
}
}, 500);
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/activity/EdgeToEdgeActivitContent.kt b/packages/SystemUI/compose/core/src/com/android/compose/activity/EdgeToEdgeActivitContent.kt
new file mode 100644
index 000000000000..97c8076e910b
--- /dev/null
+++ b/packages/SystemUI/compose/core/src/com/android/compose/activity/EdgeToEdgeActivitContent.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compose.activity
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.material3.LocalContentColor
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.contentColorFor
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.DisposableEffect
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import com.android.compose.rememberSystemUiController
+import com.android.compose.theme.PlatformTheme
+
+/** Scaffolding for an edge-to-edge activity content. */
+@Composable
+fun EdgeToEdgeActivityContent(
+ modifier: Modifier = Modifier,
+ content: @Composable () -> Unit,
+) {
+ // Make the status and navigation bars transparent, ensuring that the status bar icons are dark
+ // when the theme is light and vice-versa.
+ val systemUiController = rememberSystemUiController()
+ val isDarkTheme = isSystemInDarkTheme()
+ val useDarkIcons = !isDarkTheme
+ DisposableEffect(systemUiController, useDarkIcons) {
+ systemUiController.setSystemBarsColor(
+ color = Color.Transparent,
+ darkIcons = useDarkIcons,
+ )
+ onDispose {}
+ }
+
+ PlatformTheme(isDarkTheme) {
+ val backgroundColor = MaterialTheme.colorScheme.background
+ Box(modifier.fillMaxSize().background(backgroundColor)) {
+ CompositionLocalProvider(LocalContentColor provides contentColorFor(backgroundColor)) {
+ content()
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
index ca7352ef2501..da48762e1960 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
@@ -63,7 +63,7 @@ constructor(
.stateIn(
scope = applicationScope,
started = SharingStarted.Eagerly,
- initialValue = destinationScenes(up = viewModel.upDestinationSceneKey.value)
+ initialValue = destinationScenes(up = null)
)
@Composable
@@ -77,12 +77,12 @@ constructor(
}
private fun destinationScenes(
- up: SceneKey,
+ up: SceneKey?,
): Map<UserAction, SceneModel> {
- return mapOf(
- UserAction.Swipe(Direction.UP) to SceneModel(up),
- UserAction.Swipe(Direction.DOWN) to SceneModel(SceneKey.Shade)
- )
+ return buildMap {
+ up?.let { this[UserAction.Swipe(Direction.UP)] = SceneModel(up) }
+ this[UserAction.Swipe(Direction.DOWN)] = SceneModel(SceneKey.Shade)
+ }
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt
index d84e67620177..68f010e1c50d 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt
@@ -42,13 +42,10 @@ import androidx.compose.runtime.key
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.asImageBitmap
-import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.repeatOnLifecycle
import com.android.compose.theme.LocalAndroidColorScheme
import com.android.systemui.R
import com.android.systemui.compose.modifiers.sysuiResTag
@@ -70,15 +67,6 @@ fun PeopleScreen(
val priorityTiles by viewModel.priorityTiles.collectAsState()
val recentTiles by viewModel.recentTiles.collectAsState()
- // Make sure to refresh the tiles/conversations when the lifecycle is resumed, so that it
- // updates them when going back to the Activity after leaving it.
- val lifecycleOwner = LocalLifecycleOwner.current
- LaunchedEffect(lifecycleOwner, viewModel) {
- lifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
- viewModel.onTileRefreshRequested()
- }
- }
-
// Call [onResult] this activity when the ViewModel tells us so.
LaunchedEffect(viewModel.result) {
viewModel.result.collect { result ->
diff --git a/packages/SystemUI/res/layout/log_access_user_consent_dialog_permission.xml b/packages/SystemUI/res/layout/log_access_user_consent_dialog_permission.xml
index 89e36ac93387..d647c9b9f2ee 100644
--- a/packages/SystemUI/res/layout/log_access_user_consent_dialog_permission.xml
+++ b/packages/SystemUI/res/layout/log_access_user_consent_dialog_permission.xml
@@ -16,22 +16,29 @@
** limitations under the License.
*/
-->
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="380dp"
- android:layout_height="match_parent"
- android:clipToPadding="false">
- <LinearLayout
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="380dp"
+ android:layout_height="match_parent"
+ android:clipToPadding="false"
+ android:orientation="vertical">
+
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1">
+
+ <LinearLayout
android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
android:orientation="vertical"
- android:gravity="center"
android:paddingLeft="24dp"
android:paddingRight="24dp"
android:paddingTop="24dp"
- android:paddingBottom="24dp">
+ android:paddingBottom="24dp"
+ android:gravity="center">
- <ImageView
+ <ImageView
android:id="@+id/log_access_image_view"
android:layout_width="32dp"
android:layout_height="32dp"
@@ -41,7 +48,7 @@
tools:layout_editor_absoluteY="35dp"
android:gravity="center" />
- <TextView
+ <TextView
android:id="@+id/log_access_dialog_title"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
@@ -51,7 +58,7 @@
android:textColor="?android:attr/textColorPrimary"
android:gravity="center" />
- <TextView
+ <TextView
android:id="@+id/log_access_dialog_body"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
@@ -60,42 +67,37 @@
android:textAppearance="@style/PrimaryAllowLogAccess"
android:textColor="?android:attr/textColorPrimary"
android:gravity="center" />
+ </LinearLayout>
+ </ScrollView>
- <Space
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1" />
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="24dp"
+ android:paddingRight="24dp"
+ android:paddingTop="24dp"
+ android:paddingBottom="24dp">
- <LinearLayout
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <Button
- android:id="@+id/log_access_dialog_allow_button"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/log_access_confirmation_allow"
- style="?permissionGrantButtonTopStyle"
- android:textAppearance="@style/PermissionGrantButtonTextAppearance"
- android:layout_marginBottom="5dp"
- android:layout_centerHorizontal="true"
- android:layout_alignParentTop="true"
- android:layout_alignParentBottom="true"
- android:clipToOutline="true"
- android:gravity="center" />
+ <Button
+ android:id="@+id/log_access_dialog_allow_button"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/log_access_confirmation_allow"
+ style="?permissionGrantButtonTopStyle"
+ android:textAppearance="@style/PermissionGrantButtonTextAppearance"
+ android:layout_marginBottom="5dp"
+ android:clipToOutline="true"
+ android:gravity="center" />
- <Button
- android:id="@+id/log_access_dialog_deny_button"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/log_access_confirmation_deny"
- style="?permissionGrantButtonBottomStyle"
- android:textAppearance="@style/PermissionGrantButtonTextAppearance"
- android:layout_centerHorizontal="true"
- android:layout_alignParentTop="true"
- android:layout_alignParentBottom="true"
- android:clipToOutline="true"
- android:gravity="center" />
- </LinearLayout>
+ <Button
+ android:id="@+id/log_access_dialog_deny_button"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/log_access_confirmation_deny"
+ style="?permissionGrantButtonBottomStyle"
+ android:textAppearance="@style/PermissionGrantButtonTextAppearance"
+ android:clipToOutline="true"
+ android:gravity="center" />
</LinearLayout>
-</ScrollView>
+</LinearLayout> \ No newline at end of file
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 15ca9d48c62a..d2cb475ad2b0 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -212,6 +212,7 @@
<item type="id" name="keyguard_indication_text" />
<item type="id" name="keyguard_indication_text_bottom" />
<item type="id" name="nssl_guideline" />
+ <item type="id" name="split_shade_guideline" />
<item type="id" name="lock_icon" />
<item type="id" name="lock_icon_bg" />
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 2c224f62dac7..3d48f3cc5359 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -244,24 +244,8 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
return;
}
updateAodIcons();
-
mStatusArea = mView.findViewById(R.id.keyguard_status_area);
- if (mSmartspaceController.isEnabled()) {
- View ksv = mView.findViewById(R.id.keyguard_slice_view);
- int viewIndex = mStatusArea.indexOfChild(ksv);
- ksv.setVisibility(View.GONE);
-
- // TODO(b/261757708): add content observer for the Settings toggle and add/remove
- // weather according to the Settings.
- if (mSmartspaceController.isDateWeatherDecoupled()) {
- addDateWeatherView(viewIndex);
- viewIndex += 1;
- }
-
- addSmartspaceView(viewIndex);
- }
-
mSecureSettings.registerContentObserverForUser(
Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK,
false, /* notifyForDescendants */
@@ -275,13 +259,27 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
mShowWeatherObserver,
UserHandle.USER_ALL
);
-
updateDoubleLineClock();
- setDateWeatherVisibility();
- setWeatherVisibility();
mKeyguardUnlockAnimationController.addKeyguardUnlockAnimationListener(
mKeyguardUnlockAnimationListener);
+
+ if (mSmartspaceController.isEnabled()) {
+ View ksv = mView.findViewById(R.id.keyguard_slice_view);
+ int viewIndex = mStatusArea.indexOfChild(ksv);
+ ksv.setVisibility(View.GONE);
+
+ mSmartspaceController.removeViewsFromParent(mStatusArea);
+ addSmartspaceView();
+ // TODO(b/261757708): add content observer for the Settings toggle and add/remove
+ // weather according to the Settings.
+ if (mSmartspaceController.isDateWeatherDecoupled()) {
+ addDateWeatherView();
+ }
+ }
+
+ setDateWeatherVisibility();
+ setWeatherVisibility();
}
int getNotificationIconAreaHeight() {
@@ -302,29 +300,22 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
void onLocaleListChanged() {
if (mSmartspaceController.isEnabled()) {
+ mSmartspaceController.removeViewsFromParent(mStatusArea);
+ addSmartspaceView();
if (mSmartspaceController.isDateWeatherDecoupled()) {
mDateWeatherView.removeView(mWeatherView);
- int index = mStatusArea.indexOfChild(mDateWeatherView);
- if (index >= 0) {
- mStatusArea.removeView(mDateWeatherView);
- addDateWeatherView(index);
- }
+ addDateWeatherView();
setDateWeatherVisibility();
setWeatherVisibility();
}
- int index = mStatusArea.indexOfChild(mSmartspaceView);
- if (index >= 0) {
- mStatusArea.removeView(mSmartspaceView);
- addSmartspaceView(index);
- }
}
}
- private void addDateWeatherView(int index) {
+ private void addDateWeatherView() {
mDateWeatherView = (ViewGroup) mSmartspaceController.buildAndConnectDateView(mView);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
MATCH_PARENT, WRAP_CONTENT);
- mStatusArea.addView(mDateWeatherView, index, lp);
+ mStatusArea.addView(mDateWeatherView, 0, lp);
int startPadding = getContext().getResources().getDimensionPixelSize(
R.dimen.below_clock_padding_start);
int endPadding = getContext().getResources().getDimensionPixelSize(
@@ -344,11 +335,11 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
mWeatherView.setPaddingRelative(0, 0, 4, 0);
}
- private void addSmartspaceView(int index) {
+ private void addSmartspaceView() {
mSmartspaceView = mSmartspaceController.buildAndConnectView(mView);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
MATCH_PARENT, WRAP_CONTENT);
- mStatusArea.addView(mSmartspaceView, index, lp);
+ mStatusArea.addView(mSmartspaceView, 0, lp);
int startPadding = getContext().getResources().getDimensionPixelSize(
R.dimen.below_clock_padding_start);
int endPadding = getContext().getResources().getDimensionPixelSize(
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index 8e92941c79fa..73b4c5f47cde 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -150,7 +150,8 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
@Override
public void onInit() {
mKeyguardClockSwitchController.init();
- mDumpManager.registerDumpable(this);
+
+ mDumpManager.registerDumpable(getInstanceName(), this);
if (mFeatureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) {
startCoroutines(EmptyCoroutineContext.INSTANCE);
}
@@ -190,7 +191,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
* Called in notificationPanelViewController to avoid leak
*/
public void onDestroy() {
- mDumpManager.unregisterDumpable(TAG);
+ mDumpManager.unregisterDumpable(getInstanceName());
}
/**
@@ -385,7 +386,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
* Updates the alignment of the KeyguardStatusView and animates the transition if requested.
*/
public void updateAlignment(
- ConstraintLayout notifContainerParent,
+ ConstraintLayout layout,
boolean splitShadeEnabled,
boolean shouldBeCentered,
boolean animate) {
@@ -395,16 +396,23 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
}
mStatusViewCentered = shouldBeCentered;
- if (notifContainerParent == null) {
+ if (layout == null) {
return;
}
ConstraintSet constraintSet = new ConstraintSet();
- constraintSet.clone(notifContainerParent);
- int statusConstraint = shouldBeCentered ? PARENT_ID : R.id.qs_edge_guideline;
+ constraintSet.clone(layout);
+ int guideline;
+ if (mFeatureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) {
+ guideline = R.id.split_shade_guideline;
+ } else {
+ guideline = R.id.qs_edge_guideline;
+ }
+
+ int statusConstraint = shouldBeCentered ? PARENT_ID : guideline;
constraintSet.connect(R.id.keyguard_status_view, END, statusConstraint, END);
if (!animate) {
- constraintSet.applyTo(notifContainerParent);
+ constraintSet.applyTo(layout);
return;
}
@@ -447,7 +455,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
// old animation rather than setting up the custom animations.
if (clockContainerView == null || clockContainerView.getChildCount() == 0) {
transition.addListener(mKeyguardStatusAlignmentTransitionListener);
- TransitionManager.beginDelayedTransition(notifContainerParent, transition);
+ TransitionManager.beginDelayedTransition(layout, transition);
} else {
View clockView = clockContainerView.getChildAt(0);
@@ -481,14 +489,14 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
}
set.addListener(mKeyguardStatusAlignmentTransitionListener);
- TransitionManager.beginDelayedTransition(notifContainerParent, set);
+ TransitionManager.beginDelayedTransition(layout, set);
}
} else {
transition.addListener(mKeyguardStatusAlignmentTransitionListener);
- TransitionManager.beginDelayedTransition(notifContainerParent, transition);
+ TransitionManager.beginDelayedTransition(layout, transition);
}
- constraintSet.applyTo(notifContainerParent);
+ constraintSet.applyTo(layout);
}
@Override
@@ -496,6 +504,10 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
mView.dump(pw, args);
}
+ String getInstanceName() {
+ return TAG + "#" + hashCode();
+ }
+
@VisibleForTesting
static class SplitShadeTransitionAdapter extends Transition {
private static final String PROP_BOUNDS_LEFT = "splitShadeTransitionAdapter:boundsLeft";
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/data/model/AuthenticationMethodModel.kt b/packages/SystemUI/src/com/android/systemui/authentication/data/model/AuthenticationMethodModel.kt
new file mode 100644
index 000000000000..6d23b11e5d66
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/authentication/data/model/AuthenticationMethodModel.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.authentication.data.model
+
+/** Enumerates all known authentication methods. */
+sealed class AuthenticationMethodModel(
+ /**
+ * Whether the authentication method is considered to be "secure".
+ *
+ * "Secure" authentication methods require authentication to unlock the device. Non-secure auth
+ * methods simply require user dismissal.
+ */
+ open val isSecure: Boolean,
+) {
+ /** There is no authentication method on the device. We shouldn't even show the lock screen. */
+ object None : AuthenticationMethodModel(isSecure = false)
+
+ object Pin : AuthenticationMethodModel(isSecure = true)
+
+ object Password : AuthenticationMethodModel(isSecure = true)
+
+ object Pattern : AuthenticationMethodModel(isSecure = true)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt b/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
index deb3d035d753..8d1fc5d9d558 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
@@ -14,15 +14,21 @@
* limitations under the License.
*/
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
package com.android.systemui.authentication.data.repository
+import android.app.admin.DevicePolicyManager
+import android.content.IntentFilter
+import android.os.UserHandle
import com.android.internal.widget.LockPatternChecker
import com.android.internal.widget.LockPatternUtils
import com.android.internal.widget.LockscreenCredential
import com.android.keyguard.KeyguardSecurityModel
-import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.authentication.data.model.AuthenticationMethodModel
import com.android.systemui.authentication.shared.model.AuthenticationResultModel
import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel
+import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.keyguard.data.repository.KeyguardRepository
@@ -37,13 +43,17 @@ import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@@ -54,9 +64,10 @@ interface AuthenticationRepository {
* Whether the device is unlocked.
*
* A device that is not yet unlocked requires unlocking by completing an authentication
- * challenge according to the current authentication method.
- *
- * Note that this state has no real bearing on whether the lockscreen is showing or dismissed.
+ * challenge according to the current authentication method, unless in cases when the current
+ * authentication method is not "secure" (for example, None); in such cases, the value of this
+ * flow will always be `true`, even if the lockscreen is showing and still needs to be dismissed
+ * by the user to proceed.
*/
val isUnlocked: StateFlow<Boolean>
@@ -86,8 +97,29 @@ interface AuthenticationRepository {
val throttling: StateFlow<AuthenticationThrottlingModel>
/**
+ * The currently-configured authentication method. This determines how the authentication
+ * challenge needs to be completed in order to unlock an otherwise locked device.
+ *
+ * Note: there may be other ways to unlock the device that "bypass" the need for this
+ * authentication challenge (notably, biometrics like fingerprint or face unlock).
+ *
+ * Note: by design, this is a [Flow] and not a [StateFlow]; a consumer who wishes to get a
+ * snapshot of the current authentication method without establishing a collector of the flow
+ * can do so by invoking [getAuthenticationMethod].
+ */
+ val authenticationMethod: Flow<AuthenticationMethodModel>
+
+ /**
* Returns the currently-configured authentication method. This determines how the
- * authentication challenge is completed in order to unlock an otherwise locked device.
+ * authentication challenge needs to be completed in order to unlock an otherwise locked device.
+ *
+ * Note: there may be other ways to unlock the device that "bypass" the need for this
+ * authentication challenge (notably, biometrics like fingerprint or face unlock).
+ *
+ * Note: by design, this is offered as a convenience method alongside [authenticationMethod].
+ * The flow should be used for code that wishes to stay up-to-date its logic as the
+ * authentication changes over time and this method should be used for simple code that only
+ * needs to check the current value.
*/
suspend fun getAuthenticationMethod(): AuthenticationMethodModel
@@ -141,6 +173,7 @@ constructor(
private val userRepository: UserRepository,
keyguardRepository: KeyguardRepository,
private val lockPatternUtils: LockPatternUtils,
+ broadcastDispatcher: BroadcastDispatcher,
) : AuthenticationRepository {
override val isUnlocked = keyguardRepository.isKeyguardUnlocked
@@ -148,7 +181,7 @@ constructor(
override suspend fun isLockscreenEnabled(): Boolean {
return withContext(backgroundDispatcher) {
val selectedUserId = userRepository.selectedUserId
- !lockPatternUtils.isLockPatternEnabled(selectedUserId)
+ !lockPatternUtils.isLockScreenDisabled(selectedUserId)
}
}
@@ -172,18 +205,31 @@ constructor(
private val UserRepository.selectedUserId: Int
get() = getSelectedUserInfo().id
+ override val authenticationMethod: Flow<AuthenticationMethodModel> =
+ userRepository.selectedUserInfo
+ .map { it.id }
+ .distinctUntilChanged()
+ .flatMapLatest { selectedUserId ->
+ broadcastDispatcher
+ .broadcastFlow(
+ filter =
+ IntentFilter(
+ DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
+ ),
+ user = UserHandle.of(selectedUserId),
+ )
+ .onStart { emit(Unit) }
+ .map { selectedUserId }
+ }
+ .map { selectedUserId ->
+ withContext(backgroundDispatcher) {
+ blockingAuthenticationMethodInternal(selectedUserId)
+ }
+ }
+
override suspend fun getAuthenticationMethod(): AuthenticationMethodModel {
return withContext(backgroundDispatcher) {
- val selectedUserId = userRepository.selectedUserId
- when (getSecurityMode.apply(selectedUserId)) {
- KeyguardSecurityModel.SecurityMode.PIN,
- KeyguardSecurityModel.SecurityMode.SimPin,
- KeyguardSecurityModel.SecurityMode.SimPuk -> AuthenticationMethodModel.Pin
- KeyguardSecurityModel.SecurityMode.Password -> AuthenticationMethodModel.Password
- KeyguardSecurityModel.SecurityMode.Pattern -> AuthenticationMethodModel.Pattern
- KeyguardSecurityModel.SecurityMode.None -> AuthenticationMethodModel.None
- KeyguardSecurityModel.SecurityMode.Invalid -> error("Invalid security mode!")
- }
+ blockingAuthenticationMethodInternal(userRepository.selectedUserId)
}
}
@@ -301,6 +347,27 @@ constructor(
return flow.asStateFlow()
}
+
+ /**
+ * Returns the authentication method for the given user ID.
+ *
+ * WARNING: this is actually a blocking IPC/"binder" call that's expensive to do on the main
+ * thread. We keep it not marked as `suspend` because we want to be able to run this without a
+ * `runBlocking` which has a ton of performance/blocking problems.
+ */
+ private fun blockingAuthenticationMethodInternal(
+ userId: Int,
+ ): AuthenticationMethodModel {
+ return when (getSecurityMode.apply(userId)) {
+ KeyguardSecurityModel.SecurityMode.PIN,
+ KeyguardSecurityModel.SecurityMode.SimPin,
+ KeyguardSecurityModel.SecurityMode.SimPuk -> AuthenticationMethodModel.Pin
+ KeyguardSecurityModel.SecurityMode.Password -> AuthenticationMethodModel.Password
+ KeyguardSecurityModel.SecurityMode.Pattern -> AuthenticationMethodModel.Pattern
+ KeyguardSecurityModel.SecurityMode.None -> AuthenticationMethodModel.None
+ KeyguardSecurityModel.SecurityMode.Invalid -> error("Invalid security mode!")
+ }
+ }
}
@Module
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
index d4371bf30e0e..75192021dab6 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
@@ -18,8 +18,10 @@ package com.android.systemui.authentication.domain.interactor
import com.android.internal.widget.LockPatternView
import com.android.internal.widget.LockscreenCredential
+import com.android.systemui.authentication.data.model.AuthenticationMethodModel as DataLayerAuthenticationMethodModel
import com.android.systemui.authentication.data.repository.AuthenticationRepository
-import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.authentication.domain.model.AuthenticationMethodModel as DomainLayerAuthenticationMethodModel
+import com.android.systemui.authentication.shared.model.AuthenticationPatternCoordinate
import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
@@ -35,8 +37,10 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
@@ -56,21 +60,40 @@ constructor(
private val clock: SystemClock,
) {
/**
+ * The currently-configured authentication method. This determines how the authentication
+ * challenge needs to be completed in order to unlock an otherwise locked device.
+ *
+ * Note: there may be other ways to unlock the device that "bypass" the need for this
+ * authentication challenge (notably, biometrics like fingerprint or face unlock).
+ *
+ * Note: by design, this is a [Flow] and not a [StateFlow]; a consumer who wishes to get a
+ * snapshot of the current authentication method without establishing a collector of the flow
+ * can do so by invoking [getAuthenticationMethod].
+ *
+ * Note: this layer adds the synthetic authentication method of "swipe" which is special. When
+ * the current authentication method is "swipe", the user does not need to complete any
+ * authentication challenge to unlock the device; they just need to dismiss the lockscreen to
+ * get past it. This also means that the value of [isUnlocked] remains `false` even when the
+ * lockscreen is showing and still needs to be dismissed by the user to proceed.
+ */
+ val authenticationMethod: Flow<DomainLayerAuthenticationMethodModel> =
+ repository.authenticationMethod.map { rawModel -> rawModel.toDomainLayer() }
+
+ /**
* Whether the device is unlocked.
*
* A device that is not yet unlocked requires unlocking by completing an authentication
- * challenge according to the current authentication method.
- *
- * Note that this state has no real bearing on whether the lock screen is showing or dismissed.
+ * challenge according to the current authentication method, unless in cases when the current
+ * authentication method is not "secure" (for example, None and Swipe); in such cases, the value
+ * of this flow will always be `true`, even if the lockscreen is showing and still needs to be
+ * dismissed by the user to proceed.
*/
val isUnlocked: StateFlow<Boolean> =
- repository.isUnlocked
- .map { isUnlocked ->
- if (getAuthenticationMethod() is AuthenticationMethodModel.None) {
- true
- } else {
- isUnlocked
- }
+ combine(
+ repository.isUnlocked,
+ authenticationMethod,
+ ) { isUnlocked, authenticationMethod ->
+ authenticationMethod is DomainLayerAuthenticationMethodModel.None || isUnlocked
}
.stateIn(
scope = applicationScope,
@@ -129,18 +152,24 @@ constructor(
/**
* Returns the currently-configured authentication method. This determines how the
- * authentication challenge is completed in order to unlock an otherwise locked device.
+ * authentication challenge needs to be completed in order to unlock an otherwise locked device.
+ *
+ * Note: there may be other ways to unlock the device that "bypass" the need for this
+ * authentication challenge (notably, biometrics like fingerprint or face unlock).
+ *
+ * Note: by design, this is offered as a convenience method alongside [authenticationMethod].
+ * The flow should be used for code that wishes to stay up-to-date its logic as the
+ * authentication changes over time and this method should be used for simple code that only
+ * needs to check the current value.
+ *
+ * Note: this layer adds the synthetic authentication method of "swipe" which is special. When
+ * the current authentication method is "swipe", the user does not need to complete any
+ * authentication challenge to unlock the device; they just need to dismiss the lockscreen to
+ * get past it. This also means that the value of [isUnlocked] remains `false` even when the
+ * lockscreen is showing and still needs to be dismissed by the user to proceed.
*/
- suspend fun getAuthenticationMethod(): AuthenticationMethodModel {
- val authMethod = repository.getAuthenticationMethod()
- return if (
- authMethod is AuthenticationMethodModel.None && repository.isLockscreenEnabled()
- ) {
- // We treat "None" as "Swipe" when the lockscreen is enabled.
- AuthenticationMethodModel.Swipe
- } else {
- authMethod
- }
+ suspend fun getAuthenticationMethod(): DomainLayerAuthenticationMethodModel {
+ return repository.getAuthenticationMethod().toDomainLayer()
}
/**
@@ -270,21 +299,38 @@ constructor(
}
}
- private fun AuthenticationMethodModel.createCredential(
+ private fun DomainLayerAuthenticationMethodModel.createCredential(
input: List<Any>
): LockscreenCredential? {
return when (this) {
- is AuthenticationMethodModel.Pin ->
+ is DomainLayerAuthenticationMethodModel.Pin ->
LockscreenCredential.createPin(input.joinToString(""))
- is AuthenticationMethodModel.Password ->
+ is DomainLayerAuthenticationMethodModel.Password ->
LockscreenCredential.createPassword(input.joinToString(""))
- is AuthenticationMethodModel.Pattern ->
+ is DomainLayerAuthenticationMethodModel.Pattern ->
LockscreenCredential.createPattern(
input
- .map { it as AuthenticationMethodModel.Pattern.PatternCoordinate }
+ .map { it as AuthenticationPatternCoordinate }
.map { LockPatternView.Cell.of(it.y, it.x) }
)
else -> null
}
}
+
+ private suspend fun DataLayerAuthenticationMethodModel.toDomainLayer():
+ DomainLayerAuthenticationMethodModel {
+ return when (this) {
+ is DataLayerAuthenticationMethodModel.None ->
+ if (repository.isLockscreenEnabled()) {
+ DomainLayerAuthenticationMethodModel.Swipe
+ } else {
+ DomainLayerAuthenticationMethodModel.None
+ }
+ is DataLayerAuthenticationMethodModel.Pin -> DomainLayerAuthenticationMethodModel.Pin
+ is DataLayerAuthenticationMethodModel.Password ->
+ DomainLayerAuthenticationMethodModel.Password
+ is DataLayerAuthenticationMethodModel.Pattern ->
+ DomainLayerAuthenticationMethodModel.Pattern
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt b/packages/SystemUI/src/com/android/systemui/authentication/domain/model/AuthenticationMethodModel.kt
index 97c6697f10a5..d7e6099a8908 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/domain/model/AuthenticationMethodModel.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.authentication.shared.model
+package com.android.systemui.authentication.domain.model
/** Enumerates all known authentication methods. */
sealed class AuthenticationMethodModel(
@@ -36,10 +36,5 @@ sealed class AuthenticationMethodModel(
object Password : AuthenticationMethodModel(isSecure = true)
- object Pattern : AuthenticationMethodModel(isSecure = true) {
- data class PatternCoordinate(
- val x: Int,
- val y: Int,
- )
- }
+ object Pattern : AuthenticationMethodModel(isSecure = true)
}
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationPatternCoordinate.kt b/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationPatternCoordinate.kt
new file mode 100644
index 000000000000..8a3f780b3e54
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationPatternCoordinate.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.authentication.shared.model
+
+data class AuthenticationPatternCoordinate(
+ val x: Int,
+ val y: Int,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
index 063f62e19686..869d0846e0ae 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
@@ -186,7 +186,7 @@ constructor(
}
private fun listenForAlternateBouncerVisibility() {
- alternateBouncerInteractor.setAlternateBouncerUIAvailable(true)
+ alternateBouncerInteractor.setAlternateBouncerUIAvailable(true, "SideFpsController")
scope.launch {
alternateBouncerInteractor.isVisible.collect { isVisible: Boolean ->
if (isVisible) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt
index 15bd73193687..db30a55ea1e1 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt
@@ -83,6 +83,7 @@ constructor(
dumpManager,
),
UdfpsKeyguardViewControllerAdapter {
+ private val uniqueIdentifier = this.toString()
private val useExpandedOverlay: Boolean =
featureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)
private var showingUdfpsBouncer = false
@@ -282,7 +283,7 @@ constructor(
public override fun onViewAttached() {
super.onViewAttached()
- alternateBouncerInteractor.setAlternateBouncerUIAvailable(true)
+ alternateBouncerInteractor.setAlternateBouncerUIAvailable(true, uniqueIdentifier)
val dozeAmount = statusBarStateController.dozeAmount
lastDozeAmount = dozeAmount
stateListener.onDozeAmountChanged(dozeAmount, dozeAmount)
@@ -312,7 +313,7 @@ constructor(
override fun onViewDetached() {
super.onViewDetached()
- alternateBouncerInteractor.setAlternateBouncerUIAvailable(false)
+ alternateBouncerInteractor.setAlternateBouncerUIAvailable(false, uniqueIdentifier)
faceDetectRunning = false
keyguardStateController.removeCallback(keyguardStateControllerCallback)
statusBarStateController.removeCallback(stateListener)
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/controller/UdfpsKeyguardViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/controller/UdfpsKeyguardViewController.kt
index 2a9f3eafc776..c9b1624d4d50 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/controller/UdfpsKeyguardViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/controller/UdfpsKeyguardViewController.kt
@@ -46,6 +46,7 @@ open class UdfpsKeyguardViewController(
dumpManager,
),
UdfpsKeyguardViewControllerAdapter {
+ private val uniqueIdentifier = this.toString()
override val tag: String
get() = TAG
@@ -55,12 +56,12 @@ open class UdfpsKeyguardViewController(
public override fun onViewAttached() {
super.onViewAttached()
- alternateBouncerInteractor.setAlternateBouncerUIAvailable(true)
+ alternateBouncerInteractor.setAlternateBouncerUIAvailable(true, uniqueIdentifier)
}
public override fun onViewDetached() {
super.onViewDetached()
- alternateBouncerInteractor.setAlternateBouncerUIAvailable(false)
+ alternateBouncerInteractor.setAlternateBouncerUIAvailable(false, uniqueIdentifier)
}
override fun shouldPauseAuth(): Boolean {
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt
index e3e9b3a3754a..98ae54b1340e 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt
@@ -40,6 +40,7 @@ constructor(
) {
var receivedDownTouch = false
val isVisible: Flow<Boolean> = bouncerRepository.alternateBouncerVisible
+ private val alternateBouncerUiAvailableFromSource: HashSet<String> = HashSet()
/**
* Sets the correct bouncer states to show the alternate bouncer if it can show.
@@ -69,8 +70,15 @@ constructor(
return bouncerRepository.alternateBouncerVisible.value
}
- fun setAlternateBouncerUIAvailable(isAvailable: Boolean) {
- bouncerRepository.setAlternateBouncerUIAvailable(isAvailable)
+ fun setAlternateBouncerUIAvailable(isAvailable: Boolean, token: String) {
+ if (isAvailable) {
+ alternateBouncerUiAvailableFromSource.add(token)
+ } else {
+ alternateBouncerUiAvailableFromSource.remove(token)
+ }
+ bouncerRepository.setAlternateBouncerUIAvailable(
+ alternateBouncerUiAvailableFromSource.isNotEmpty()
+ )
}
fun canShowAlternateBouncerForFingerprint(): Boolean {
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 8ed964d4af22..ffcae1cacb00 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
@@ -14,14 +14,12 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.bouncer.domain.interactor
import android.content.Context
import com.android.systemui.R
import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
-import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.authentication.domain.model.AuthenticationMethodModel
import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel
import com.android.systemui.bouncer.data.repository.BouncerRepository
import com.android.systemui.dagger.SysUISingleton
@@ -35,7 +33,6 @@ import com.android.systemui.util.kotlin.pairwise
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
@@ -107,14 +104,6 @@ constructor(
}
/**
- * Returns the currently-configured authentication method. This determines how the
- * authentication challenge is completed in order to unlock an otherwise locked device.
- */
- suspend fun getAuthenticationMethod(): AuthenticationMethodModel {
- return authenticationInteractor.getAuthenticationMethod()
- }
-
- /**
* Either shows the bouncer or unlocks the device, if the bouncer doesn't need to be shown.
*
* @param message An optional message to show to the user in the bouncer.
@@ -124,7 +113,9 @@ constructor(
) {
applicationScope.launch {
if (authenticationInteractor.isAuthenticationRequired()) {
- repository.setMessage(message ?: promptMessage(getAuthenticationMethod()))
+ repository.setMessage(
+ message ?: promptMessage(authenticationInteractor.getAuthenticationMethod())
+ )
sceneInteractor.setCurrentScene(
scene = SceneModel(SceneKey.Bouncer),
loggingReason = "request to unlock device while authentication required",
@@ -143,7 +134,9 @@ constructor(
* method.
*/
fun resetMessage() {
- applicationScope.launch { repository.setMessage(promptMessage(getAuthenticationMethod())) }
+ applicationScope.launch {
+ repository.setMessage(promptMessage(authenticationInteractor.getAuthenticationMethod()))
+ }
}
/** Removes the user-facing message. */
@@ -181,7 +174,7 @@ constructor(
loggingReason = "successful authentication",
)
} else {
- repository.setMessage(errorMessage(getAuthenticationMethod()))
+ repository.setMessage(errorMessage(authenticationInteractor.getAuthenticationMethod()))
}
return isAuthenticated
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
index 68e1a29bc609..5b1998d1e5f6 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
@@ -14,25 +14,20 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.bouncer.ui.viewmodel
import android.content.Context
import com.android.systemui.R
-import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
+import com.android.systemui.authentication.domain.model.AuthenticationMethodModel
import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
-import com.android.systemui.util.kotlin.pairwise
import javax.inject.Inject
import kotlin.math.ceil
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.channels.BufferOverflow
-import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
@@ -50,23 +45,24 @@ class BouncerViewModel
constructor(
@Application private val applicationContext: Context,
@Application private val applicationScope: CoroutineScope,
- private val interactor: BouncerInteractor,
+ private val bouncerInteractor: BouncerInteractor,
+ private val authenticationInteractor: AuthenticationInteractor,
featureFlags: FeatureFlags,
) {
private val isInputEnabled: StateFlow<Boolean> =
- interactor.isThrottled
+ bouncerInteractor.isThrottled
.map { !it }
.stateIn(
scope = applicationScope,
started = SharingStarted.WhileSubscribed(),
- initialValue = !interactor.isThrottled.value,
+ initialValue = !bouncerInteractor.isThrottled.value,
)
private val pin: PinBouncerViewModel by lazy {
PinBouncerViewModel(
applicationContext = applicationContext,
applicationScope = applicationScope,
- interactor = interactor,
+ interactor = bouncerInteractor,
isInputEnabled = isInputEnabled,
)
}
@@ -74,7 +70,7 @@ constructor(
private val password: PasswordBouncerViewModel by lazy {
PasswordBouncerViewModel(
applicationScope = applicationScope,
- interactor = interactor,
+ interactor = bouncerInteractor,
isInputEnabled = isInputEnabled,
)
}
@@ -83,31 +79,35 @@ constructor(
PatternBouncerViewModel(
applicationContext = applicationContext,
applicationScope = applicationScope,
- interactor = interactor,
+ interactor = bouncerInteractor,
isInputEnabled = isInputEnabled,
)
}
/** View-model for the current UI, based on the current authentication method. */
- private val _authMethod =
- MutableSharedFlow<AuthMethodBouncerViewModel?>(
- replay = 1,
- onBufferOverflow = BufferOverflow.DROP_OLDEST,
- )
val authMethod: StateFlow<AuthMethodBouncerViewModel?> =
- _authMethod.stateIn(
- scope = applicationScope,
- started = SharingStarted.WhileSubscribed(),
- initialValue = null,
- )
+ authenticationInteractor.authenticationMethod
+ .map { authenticationMethod ->
+ when (authenticationMethod) {
+ is AuthenticationMethodModel.Pin -> pin
+ is AuthenticationMethodModel.Password -> password
+ is AuthenticationMethodModel.Pattern -> pattern
+ else -> null
+ }
+ }
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = null,
+ )
init {
if (featureFlags.isEnabled(Flags.SCENE_CONTAINER)) {
applicationScope.launch {
- interactor.isThrottled
+ bouncerInteractor.isThrottled
.map { isThrottled ->
if (isThrottled) {
- when (interactor.getAuthenticationMethod()) {
+ when (authenticationInteractor.getAuthenticationMethod()) {
is AuthenticationMethodModel.Pin ->
R.string.kg_too_many_failed_pin_attempts_dialog_message
is AuthenticationMethodModel.Password ->
@@ -118,8 +118,9 @@ constructor(
}?.let { stringResourceId ->
applicationContext.getString(
stringResourceId,
- interactor.throttling.value.failedAttemptCount,
- ceil(interactor.throttling.value.remainingMs / 1000f).toInt(),
+ bouncerInteractor.throttling.value.failedAttemptCount,
+ ceil(bouncerInteractor.throttling.value.remainingMs / 1000f)
+ .toInt(),
)
}
} else {
@@ -133,25 +134,14 @@ constructor(
}
}
}
-
- applicationScope.launch {
- _authMethod.subscriptionCount
- .pairwise()
- .map { (previousCount, currentCount) -> currentCount > previousCount }
- .collect { subscriberAdded ->
- if (subscriberAdded) {
- reloadAuthMethod()
- }
- }
- }
}
}
/** The user-facing message to show in the bouncer. */
val message: StateFlow<MessageViewModel> =
combine(
- interactor.message,
- interactor.isThrottled,
+ bouncerInteractor.message,
+ bouncerInteractor.isThrottled,
) { message, isThrottled ->
toMessageViewModel(message, isThrottled)
}
@@ -160,8 +150,8 @@ constructor(
started = SharingStarted.WhileSubscribed(),
initialValue =
toMessageViewModel(
- message = interactor.message.value,
- isThrottled = interactor.isThrottled.value,
+ message = bouncerInteractor.message.value,
+ isThrottled = bouncerInteractor.isThrottled.value,
),
)
@@ -197,17 +187,6 @@ constructor(
)
}
- private suspend fun reloadAuthMethod() {
- _authMethod.tryEmit(
- when (interactor.getAuthenticationMethod()) {
- is AuthenticationMethodModel.Pin -> pin
- is AuthenticationMethodModel.Password -> password
- is AuthenticationMethodModel.Pattern -> pattern
- else -> null
- }
- )
- }
-
data class MessageViewModel(
val text: String,
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt
index 4be539d9396d..4425f9ffcb5e 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt
@@ -18,7 +18,7 @@ package com.android.systemui.bouncer.ui.viewmodel
import android.content.Context
import android.util.TypedValue
-import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.authentication.shared.model.AuthenticationPatternCoordinate
import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
import kotlin.math.max
import kotlin.math.min
@@ -193,8 +193,8 @@ data class PatternDotViewModel(
val x: Int,
val y: Int,
) {
- fun toCoordinate(): AuthenticationMethodModel.Pattern.PatternCoordinate {
- return AuthenticationMethodModel.Pattern.PatternCoordinate(
+ fun toCoordinate(): AuthenticationPatternCoordinate {
+ return AuthenticationPatternCoordinate(
x = x,
y = y,
)
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index cc371618ddfe..a30a3e1f855c 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -290,7 +290,8 @@ object Flags {
val WALLPAPER_PICKER_PREVIEW_ANIMATION =
unreleasedFlag(
244,
- "wallpaper_picker_preview_animation"
+ "wallpaper_picker_preview_animation",
+ teamfood = true
)
// 300 - power menu
@@ -369,6 +370,10 @@ object Flags {
val WIFI_TRACKER_LIB_FOR_WIFI_ICON =
unreleasedFlag(613, "wifi_tracker_lib_for_wifi_icon")
+ // TODO(b/293863612): Tracking Bug
+ @JvmField val INCOMPATIBLE_CHARGING_BATTERY_ICON =
+ unreleasedFlag(614, "incompatible_charging_battery_icon")
+
// 700 - dialer/calls
// TODO(b/254512734): Tracking Bug
val ONGOING_CALL_STATUS_BAR_CHIP = releasedFlag(700, "ongoing_call_status_bar_chip")
@@ -716,6 +721,11 @@ object Flags {
val BIGPICTURE_NOTIFICATION_LAZY_LOADING =
unreleasedFlag(283447257, "bigpicture_notification_lazy_loading")
+ // TODO(b/292062937): Tracking bug
+ @JvmField
+ val NOTIFICATION_CLEARABLE_REFACTOR =
+ unreleasedFlag(292062937, "notification_clearable_refactor")
+
// TODO(b/283740863): Tracking Bug
@JvmField
val ENABLE_NEW_PRIVACY_DIALOG =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
index 6213265cb66e..dffc19d566ff 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
@@ -20,6 +20,8 @@ package com.android.systemui.keyguard
import android.content.res.Configuration
import android.view.View
import android.view.ViewGroup
+import com.android.keyguard.KeyguardStatusViewController
+import com.android.keyguard.dagger.KeyguardStatusViewComponent
import com.android.systemui.CoreStartable
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
@@ -80,6 +82,7 @@ constructor(
private val chipbarCoordinator: ChipbarCoordinator,
private val keyguardBlueprintCommandListener: KeyguardBlueprintCommandListener,
private val keyguardBlueprintViewModel: KeyguardBlueprintViewModel,
+ private val keyguardStatusViewComponentFactory: KeyguardStatusViewComponent.Factory,
) : CoreStartable {
private var rootViewHandle: DisposableHandle? = null
@@ -88,6 +91,7 @@ constructor(
private var rightShortcutHandle: KeyguardQuickAffordanceViewBinder.Binding? = null
private var ambientIndicationAreaHandle: KeyguardAmbientIndicationAreaViewBinder.Binding? = null
private var settingsPopupMenuHandle: DisposableHandle? = null
+ private var keyguardStatusViewController: KeyguardStatusViewController? = null
override fun start() {
bindKeyguardRootView()
@@ -96,6 +100,7 @@ constructor(
unbindKeyguardBottomArea(notificationPanel)
bindIndicationArea()
bindLockIconView(notificationPanel)
+ bindKeyguardStatusView(notificationPanel)
setupNotificationStackScrollLayout(notificationPanel)
bindLeftShortcut()
bindRightShortcut()
@@ -117,7 +122,7 @@ constructor(
sharedNotificationContainer.addNotificationStackScrollLayout(nssl)
SharedNotificationContainerBinder.bind(
sharedNotificationContainer,
- sharedNotificationContainerViewModel
+ sharedNotificationContainerViewModel,
)
}
}
@@ -255,4 +260,31 @@ constructor(
}
}
}
+
+ fun bindKeyguardStatusView(legacyParent: ViewGroup) {
+ // At startup, 2 views with the ID `R.id.keyguard_status_view` will be available.
+ // Disable one of them
+ if (featureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) {
+ legacyParent.findViewById<View>(R.id.keyguard_status_view)?.let {
+ legacyParent.removeView(it)
+ }
+
+ val keyguardStatusView = keyguardRootView.addStatusView()
+ val statusViewComponent = keyguardStatusViewComponentFactory.build(keyguardStatusView)
+ val controller = statusViewComponent.getKeyguardStatusViewController()
+ controller.init()
+ keyguardStatusViewController = controller
+ } else {
+ keyguardRootView.findViewById<View?>(R.id.keyguard_status_view)?.let {
+ keyguardRootView.removeView(it)
+ }
+ }
+ }
+
+ /**
+ * Temporary, to allow NotificationPanelViewController to use the same instance while code is
+ * migrated: b/288242803
+ */
+ fun getKeyguardStatusViewController() = keyguardStatusViewController
+ fun getKeyguardRootView() = keyguardRootView
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
index f1b344199516..e35c3699aabf 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
@@ -199,13 +199,16 @@ interface KeyguardRepository {
fun setAnimateDozingTransitions(animate: Boolean)
/** Sets the current amount of alpha that should be used for rendering the bottom area. */
- @Deprecated("Deprecated as part of b/278057014")
- fun setBottomAreaAlpha(alpha: Float)
+ @Deprecated("Deprecated as part of b/278057014") fun setBottomAreaAlpha(alpha: Float)
/** Sets the current amount of alpha that should be used for rendering the keyguard. */
fun setKeyguardAlpha(alpha: Float)
- fun setKeyguardVisibility(statusBarState: Int, goingToFullShade: Boolean, occlusionTransitionRunning: Boolean)
+ fun setKeyguardVisibility(
+ statusBarState: Int,
+ goingToFullShade: Boolean,
+ occlusionTransitionRunning: Boolean
+ )
/**
* Sets the relative offset of the lock-screen clock from its natural position on the screen.
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractor.kt
deleted file mode 100644
index 278c68d3c55b..000000000000
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractor.kt
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.keyguard.domain.interactor
-
-import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
-import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
-import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
-import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.stateIn
-
-/** Hosts business and application state accessing logic for the lockscreen scene. */
-@SysUISingleton
-class LockscreenSceneInteractor
-@Inject
-constructor(
- @Application applicationScope: CoroutineScope,
- private val authenticationInteractor: AuthenticationInteractor,
- private val bouncerInteractor: BouncerInteractor,
-) {
- /** Whether the device is currently locked. */
- val isDeviceLocked: StateFlow<Boolean> =
- authenticationInteractor.isUnlocked
- .map { !it }
- .stateIn(
- scope = applicationScope,
- started = SharingStarted.WhileSubscribed(),
- initialValue = !authenticationInteractor.isUnlocked.value,
- )
-
- /** Whether it's currently possible to swipe up to dismiss the lockscreen. */
- val isSwipeToDismissEnabled: StateFlow<Boolean> =
- authenticationInteractor.isUnlocked
- .map { isUnlocked ->
- !isUnlocked &&
- authenticationInteractor.getAuthenticationMethod() is
- AuthenticationMethodModel.Swipe
- }
- .stateIn(
- scope = applicationScope,
- started = SharingStarted.WhileSubscribed(),
- initialValue = false,
- )
-
- /** Attempts to dismiss the lockscreen. This will cause the bouncer to show, if needed. */
- fun dismissLockscreen() {
- bouncerInteractor.showOrUnlockDevice()
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardRootView.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardRootView.kt
index e60901f922c3..a94874176a34 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardRootView.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardRootView.kt
@@ -24,6 +24,7 @@ import android.view.View
import android.widget.ImageView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.res.ResourcesCompat
+import com.android.keyguard.KeyguardStatusView
import com.android.keyguard.LockIconView
import com.android.systemui.R
import com.android.systemui.animation.view.LaunchableImageView
@@ -38,6 +39,8 @@ class KeyguardRootView(
attrs,
) {
+ private var statusView: KeyguardStatusView? = null
+
init {
addIndicationTextArea()
addLockIconView()
@@ -45,6 +48,7 @@ class KeyguardRootView(
addLeftShortcut()
addRightShortcut()
addSettingsPopupMenu()
+ addStatusView()
}
private fun addIndicationTextArea() {
@@ -119,4 +123,19 @@ class KeyguardRootView(
}
addView(view)
}
+
+ fun addStatusView(): KeyguardStatusView {
+ // StatusView may need to be rebuilt on config changes. Remove and reinflate
+ statusView?.let { removeView(it) }
+ val view =
+ (LayoutInflater.from(context).inflate(R.layout.keyguard_status_view, this, false)
+ as KeyguardStatusView)
+ .apply {
+ setClipChildren(false)
+ statusView = this
+ }
+
+ addView(view)
+ return view
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt
index 5538fe7e7006..518df0719aaa 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt
@@ -25,6 +25,8 @@ import com.android.systemui.keyguard.ui.view.layout.sections.DefaultIndicationAr
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultLockIconSection
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultSettingsPopupMenuSection
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultShortcutsSection
+import com.android.systemui.keyguard.ui.view.layout.sections.DefaultStatusViewSection
+import com.android.systemui.keyguard.ui.view.layout.sections.SplitShadeGuidelines
import javax.inject.Inject
/**
@@ -42,6 +44,8 @@ constructor(
private val defaultShortcutsSection: DefaultShortcutsSection,
private val defaultAmbientIndicationAreaSection: DefaultAmbientIndicationAreaSection,
private val defaultSettingsPopupMenuSection: DefaultSettingsPopupMenuSection,
+ private val defaultStatusViewSection: DefaultStatusViewSection,
+ private val splitShadeGuidelines: SplitShadeGuidelines,
) : KeyguardBlueprint {
override val id: String = DEFAULT
@@ -51,6 +55,8 @@ constructor(
defaultShortcutsSection.apply(constraintSet)
defaultAmbientIndicationAreaSection.apply(constraintSet)
defaultSettingsPopupMenuSection.apply(constraintSet)
+ defaultStatusViewSection.apply(constraintSet)
+ splitShadeGuidelines.apply(constraintSet)
}
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/ShortcutsBesideUdfpsKeyguardBlueprint.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/ShortcutsBesideUdfpsKeyguardBlueprint.kt
index 19410e4ba89d..54c27960db3c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/ShortcutsBesideUdfpsKeyguardBlueprint.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/ShortcutsBesideUdfpsKeyguardBlueprint.kt
@@ -27,6 +27,8 @@ import com.android.systemui.keyguard.ui.view.layout.sections.DefaultIndicationAr
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultLockIconSection
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultSettingsPopupMenuSection
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultShortcutsSection
+import com.android.systemui.keyguard.ui.view.layout.sections.DefaultStatusViewSection
+import com.android.systemui.keyguard.ui.view.layout.sections.SplitShadeGuidelines
import javax.inject.Inject
/** Vertically aligns the shortcuts with the udfps. */
@@ -41,6 +43,8 @@ constructor(
private val defaultSettingsPopupMenuSection: DefaultSettingsPopupMenuSection,
private val alignShortcutsToUdfpsSection: AlignShortcutsToUdfpsSection,
private val defaultShortcutsSection: DefaultShortcutsSection,
+ private val defaultStatusViewSection: DefaultStatusViewSection,
+ private val splitShadeGuidelines: SplitShadeGuidelines,
) : KeyguardBlueprint {
override val id: String = SHORTCUTS_BESIDE_UDFPS
@@ -54,6 +58,8 @@ constructor(
} else {
defaultShortcutsSection.apply(constraintSet)
}
+ defaultStatusViewSection.apply(constraintSet)
+ splitShadeGuidelines.apply(constraintSet)
}
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt
new file mode 100644
index 000000000000..3f319ba2d0e4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyguard.ui.view.layout.sections
+
+import android.content.Context
+import android.view.ViewGroup
+import androidx.constraintlayout.widget.ConstraintSet
+import com.android.systemui.R
+import com.android.systemui.keyguard.data.repository.KeyguardSection
+import javax.inject.Inject
+import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
+import androidx.constraintlayout.widget.ConstraintSet.MATCH_CONSTRAINT
+import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
+import androidx.constraintlayout.widget.ConstraintSet.START
+import androidx.constraintlayout.widget.ConstraintSet.TOP
+import androidx.constraintlayout.widget.ConstraintSet.END
+
+class DefaultStatusViewSection @Inject constructor(private val context: Context) :
+ KeyguardSection {
+ private val statusViewId = R.id.keyguard_status_view
+
+ override fun apply(constraintSet: ConstraintSet) {
+ constraintSet.apply {
+ constrainWidth(statusViewId, MATCH_CONSTRAINT)
+ constrainHeight(statusViewId, WRAP_CONTENT)
+ connect(statusViewId, TOP, PARENT_ID, TOP)
+ connect(statusViewId, START, PARENT_ID, START)
+ connect(statusViewId, END, PARENT_ID, END)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeGuidelines.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeGuidelines.kt
new file mode 100644
index 000000000000..668b17ffeba0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeGuidelines.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyguard.ui.view.layout.sections
+
+import android.content.Context
+import android.view.ViewGroup
+import androidx.constraintlayout.widget.ConstraintSet
+import com.android.systemui.R
+import com.android.systemui.keyguard.data.repository.KeyguardSection
+import javax.inject.Inject
+import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
+import androidx.constraintlayout.widget.ConstraintSet.MATCH_CONSTRAINT
+import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
+import androidx.constraintlayout.widget.ConstraintSet.START
+import androidx.constraintlayout.widget.ConstraintSet.TOP
+import androidx.constraintlayout.widget.ConstraintSet.END
+import androidx.constraintlayout.widget.ConstraintSet.VERTICAL
+
+class SplitShadeGuidelines @Inject constructor(private val context: Context) :
+ KeyguardSection {
+
+ override fun apply(constraintSet: ConstraintSet) {
+ constraintSet.apply {
+ // For use on large screens, it will provide a guideline vertically in the center to
+ // enable items to be aligned on the left or right sides
+ create(R.id.split_shade_guideline, VERTICAL)
+ setGuidelinePercent(R.id.split_shade_guideline, 0.5f)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
index abd178ca6c1d..f46d0eb449a0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
@@ -17,14 +17,17 @@
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.R
+import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
+import com.android.systemui.authentication.domain.model.AuthenticationMethodModel
+import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
import com.android.systemui.scene.shared.model.SceneKey
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
@@ -36,36 +39,37 @@ class LockscreenSceneViewModel
@Inject
constructor(
@Application applicationScope: CoroutineScope,
- private val interactor: LockscreenSceneInteractor,
+ authenticationInteractor: AuthenticationInteractor,
+ private val bouncerInteractor: BouncerInteractor,
) {
/** The icon for the "lock" button on the lockscreen. */
val lockButtonIcon: StateFlow<Icon> =
- interactor.isDeviceLocked
- .map { isLocked -> lockIcon(isLocked = isLocked) }
+ authenticationInteractor.isUnlocked
+ .map { isUnlocked -> lockIcon(isUnlocked = isUnlocked) }
.stateIn(
scope = applicationScope,
started = SharingStarted.WhileSubscribed(),
- initialValue = lockIcon(isLocked = interactor.isDeviceLocked.value),
+ initialValue = lockIcon(isUnlocked = authenticationInteractor.isUnlocked.value),
)
/** The key of the scene we should switch to when swiping up. */
- val upDestinationSceneKey: StateFlow<SceneKey> =
- interactor.isSwipeToDismissEnabled
- .map { isSwipeToUnlockEnabled -> upDestinationSceneKey(isSwipeToUnlockEnabled) }
- .stateIn(
- scope = applicationScope,
- started = SharingStarted.WhileSubscribed(),
- initialValue = upDestinationSceneKey(interactor.isSwipeToDismissEnabled.value),
- )
+ val upDestinationSceneKey: Flow<SceneKey> =
+ authenticationInteractor.authenticationMethod.map { authenticationMethod ->
+ if (authenticationMethod is AuthenticationMethodModel.Swipe) {
+ SceneKey.Gone
+ } else {
+ SceneKey.Bouncer
+ }
+ }
/** Notifies that the lock button on the lock screen was clicked. */
fun onLockButtonClicked() {
- interactor.dismissLockscreen()
+ bouncerInteractor.showOrUnlockDevice()
}
/** Notifies that some content on the lock screen was clicked. */
fun onContentClicked() {
- interactor.dismissLockscreen()
+ bouncerInteractor.showOrUnlockDevice()
}
private fun upDestinationSceneKey(
@@ -75,22 +79,22 @@ constructor(
}
private fun lockIcon(
- isLocked: Boolean,
+ isUnlocked: Boolean,
): Icon {
return Icon.Resource(
res =
- if (isLocked) {
- R.drawable.ic_device_lock_on
- } else {
+ if (isUnlocked) {
R.drawable.ic_device_lock_off
+ } else {
+ R.drawable.ic_device_lock_on
},
contentDescription =
ContentDescription.Resource(
res =
- if (isLocked) {
- R.string.accessibility_lock_icon
- } else {
+ if (isUnlocked) {
R.string.accessibility_unlock_button
+ } else {
+ R.string.accessibility_lock_icon
}
)
)
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
deleted file mode 100644
index d1d3e3de39f0..000000000000
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2020 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.people;
-
-import static android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID;
-import static android.appwidget.AppWidgetManager.INVALID_APPWIDGET_ID;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.ViewGroup;
-
-import androidx.activity.ComponentActivity;
-import androidx.lifecycle.ViewModelProvider;
-
-import com.android.systemui.compose.ComposeFacade;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
-import com.android.systemui.people.ui.view.PeopleViewBinder;
-import com.android.systemui.people.ui.viewmodel.PeopleViewModel;
-
-import javax.inject.Inject;
-
-import kotlin.Unit;
-import kotlin.jvm.functions.Function1;
-
-/** People Tile Widget configuration activity that shows the user their conversation tiles. */
-public class PeopleSpaceActivity extends ComponentActivity {
-
- private static final String TAG = "PeopleSpaceActivity";
- private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;
-
- private final PeopleViewModel.Factory mViewModelFactory;
- private final FeatureFlags mFeatureFlags;
-
- @Inject
- public PeopleSpaceActivity(PeopleViewModel.Factory viewModelFactory,
- FeatureFlags featureFlags) {
- super();
- mViewModelFactory = viewModelFactory;
- mFeatureFlags = featureFlags;
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setResult(RESULT_CANCELED);
-
- PeopleViewModel viewModel = new ViewModelProvider(this, mViewModelFactory).get(
- PeopleViewModel.class);
-
- // Update the widget ID coming from the intent.
- int widgetId = getIntent().getIntExtra(EXTRA_APPWIDGET_ID, INVALID_APPWIDGET_ID);
- viewModel.onWidgetIdChanged(widgetId);
-
- Function1<PeopleViewModel.Result, Unit> onResult = (result) -> {
- finishActivity(result);
- return null;
- };
-
- if (mFeatureFlags.isEnabled(Flags.COMPOSE_PEOPLE_SPACE)
- && ComposeFacade.INSTANCE.isComposeAvailable()) {
- Log.d(TAG, "Using the Compose implementation of the PeopleSpaceActivity");
- ComposeFacade.INSTANCE.setPeopleSpaceActivityContent(this, viewModel, onResult);
- } else {
- Log.d(TAG, "Using the View implementation of the PeopleSpaceActivity");
- ViewGroup view = PeopleViewBinder.create(this);
- PeopleViewBinder.bind(view, viewModel, /* lifecycleOwner= */ this, onResult);
- setContentView(view);
- }
- }
-
- private void finishActivity(PeopleViewModel.Result result) {
- if (result instanceof PeopleViewModel.Result.Success) {
- if (DEBUG) Log.d(TAG, "Widget added!");
- Intent data = ((PeopleViewModel.Result.Success) result).getData();
- setResult(RESULT_OK, data);
- } else {
- if (DEBUG) Log.d(TAG, "Activity dismissed with no widgets added!");
- setResult(RESULT_CANCELED);
- }
- finish();
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.kt b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.kt
new file mode 100644
index 000000000000..5b7eb454597c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.kt
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.people
+
+import android.appwidget.AppWidgetManager
+import android.os.Bundle
+import android.util.Log
+import androidx.activity.ComponentActivity
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.systemui.compose.ComposeFacade.isComposeAvailable
+import com.android.systemui.compose.ComposeFacade.setPeopleSpaceActivityContent
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.people.ui.view.PeopleViewBinder
+import com.android.systemui.people.ui.view.PeopleViewBinder.bind
+import com.android.systemui.people.ui.viewmodel.PeopleViewModel
+import javax.inject.Inject
+import kotlinx.coroutines.launch
+
+/** People Tile Widget configuration activity that shows the user their conversation tiles. */
+class PeopleSpaceActivity
+@Inject
+constructor(
+ private val viewModelFactory: PeopleViewModel.Factory,
+ private val featureFlags: FeatureFlags,
+) : ComponentActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setResult(RESULT_CANCELED)
+
+ // Update the widget ID coming from the intent.
+ val viewModel = ViewModelProvider(this, viewModelFactory)[PeopleViewModel::class.java]
+ val widgetId =
+ intent.getIntExtra(
+ AppWidgetManager.EXTRA_APPWIDGET_ID,
+ AppWidgetManager.INVALID_APPWIDGET_ID,
+ )
+ viewModel.onWidgetIdChanged(widgetId)
+
+ // Make sure to refresh the tiles/conversations when the lifecycle is resumed, so that it
+ // updates them when going back to the Activity after leaving it.
+ // Note that we do this here instead of inside an effect in the PeopleScreen() composable
+ // because otherwise onTileRefreshRequested() will be called after the first composition,
+ // which will trigger a new recomposition and redraw, affecting the GPU memory (see
+ // b/276871425).
+ lifecycleScope.launch {
+ repeatOnLifecycle(Lifecycle.State.RESUMED) { viewModel.onTileRefreshRequested() }
+ }
+
+ // Set the content of the activity, using either the View or Compose implementation.
+ if (featureFlags.isEnabled(Flags.COMPOSE_PEOPLE_SPACE) && isComposeAvailable()) {
+ Log.d(TAG, "Using the Compose implementation of the PeopleSpaceActivity")
+ setPeopleSpaceActivityContent(
+ activity = this,
+ viewModel,
+ onResult = { finishActivity(it) },
+ )
+ } else {
+ Log.d(TAG, "Using the View implementation of the PeopleSpaceActivity")
+ val view = PeopleViewBinder.create(this)
+ bind(view, viewModel, lifecycleOwner = this, onResult = { finishActivity(it) })
+ setContentView(view)
+ }
+ }
+
+ private fun finishActivity(result: PeopleViewModel.Result) {
+ if (result is PeopleViewModel.Result.Success) {
+ if (DEBUG) Log.d(TAG, "Widget added!")
+ setResult(RESULT_OK, result.data)
+ } else {
+ if (DEBUG) Log.d(TAG, "Activity dismissed with no widgets added!")
+ setResult(RESULT_CANCELED)
+ }
+
+ finish()
+ }
+
+ companion object {
+ private const val TAG = "PeopleSpaceActivity"
+ private const val DEBUG = PeopleSpaceUtils.DEBUG
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/people/ui/view/PeopleViewBinder.kt b/packages/SystemUI/src/com/android/systemui/people/ui/view/PeopleViewBinder.kt
index d8a429e5bb1a..5f338c30c966 100644
--- a/packages/SystemUI/src/com/android/systemui/people/ui/view/PeopleViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/people/ui/view/PeopleViewBinder.kt
@@ -109,14 +109,6 @@ object PeopleViewBinder {
}
}
}
-
- // Make sure to refresh the tiles/conversations when the Activity is resumed, so that it
- // updates them when going back to the Activity after leaving it.
- lifecycleOwner.lifecycleScope.launch {
- lifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
- viewModel.onTileRefreshRequested()
- }
- }
}
private fun setNoConversationsContent(view: ViewGroup, onGotItClicked: () -> Unit) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
index 5e6a44bf8130..4c6281e1cdb0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
@@ -16,19 +16,17 @@
package com.android.systemui.qs.ui.viewmodel
+import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
import javax.inject.Inject
/** Models UI state and handles user input for the quick settings scene. */
@SysUISingleton
class QuickSettingsSceneViewModel
@Inject
-constructor(
- private val lockscreenSceneInteractor: LockscreenSceneInteractor,
-) {
+constructor(private val bouncerInteractor: BouncerInteractor) {
/** Notifies that some content in quick settings was clicked. */
fun onContentClicked() {
- lockscreenSceneInteractor.dismissLockscreen()
+ bouncerInteractor.showOrUnlockDevice()
}
}
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 20ee393e8dac..bd233f80b47b 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 com.android.systemui.CoreStartable
import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
+import com.android.systemui.authentication.domain.model.AuthenticationMethodModel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.DisplayId
@@ -135,22 +136,27 @@ constructor(
applicationScope.launch {
keyguardInteractor.wakefulnessModel
- .map { it.state == WakefulnessState.ASLEEP }
+ .map { wakefulnessModel -> wakefulnessModel.state }
.distinctUntilChanged()
- .collect { isAsleep ->
- if (isAsleep) {
- // When the device goes to sleep, reset the current scene.
- val isUnlocked = authenticationInteractor.isUnlocked.value
- val (targetSceneKey, loggingReason) =
- if (isUnlocked) {
- SceneKey.Gone to "device is asleep while unlocked"
- } else {
- SceneKey.Lockscreen to "device is asleep while locked"
+ .collect { wakefulnessState ->
+ when (wakefulnessState) {
+ WakefulnessState.STARTING_TO_SLEEP -> {
+ switchToScene(
+ targetSceneKey = SceneKey.Lockscreen,
+ loggingReason = "device is asleep",
+ )
+ }
+ WakefulnessState.STARTING_TO_WAKE -> {
+ val authMethod = authenticationInteractor.getAuthenticationMethod()
+ if (authMethod == AuthenticationMethodModel.None) {
+ switchToScene(
+ targetSceneKey = SceneKey.Gone,
+ loggingReason =
+ "device is starting to wake up while auth method is None",
+ )
}
- switchToScene(
- targetSceneKey = targetSceneKey,
- loggingReason = loggingReason,
- )
+ }
+ else -> Unit
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 416f147b7429..35fd98cf34c6 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -90,6 +90,8 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
+import androidx.constraintlayout.widget.ConstraintLayout;
+
import com.android.app.animation.Interpolators;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
@@ -1053,10 +1055,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mKeyguardStatusBarViewController.init();
mNotificationContainerParent = mView.findViewById(R.id.notification_container_parent);
- updateViewControllers(
- mView.findViewById(R.id.keyguard_status_view),
- userAvatarContainer,
- keyguardUserSwitcherView);
+ updateViewControllers(userAvatarContainer, keyguardUserSwitcherView);
mNotificationStackScrollLayoutController.setOnHeightChangedListener(
new NsslHeightChangedListener());
@@ -1218,18 +1217,31 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mQsController.loadDimens();
}
- private void updateViewControllers(KeyguardStatusView keyguardStatusView,
+ private void updateViewControllers(
FrameLayout userAvatarView,
KeyguardUserSwitcherView keyguardUserSwitcherView) {
+ // Re-associate the KeyguardStatusViewController
if (mKeyguardStatusViewController != null) {
mKeyguardStatusViewController.onDestroy();
}
- // Re-associate the KeyguardStatusViewController
- KeyguardStatusViewComponent statusViewComponent =
+
+ if (mFeatureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) {
+ // Need a shared controller until mKeyguardStatusViewController can be removed from
+ // here, due to important state being set in that controller. Rebind in order to pick
+ // up config changes
+ mKeyguardViewConfigurator.bindKeyguardStatusView(mView);
+ mKeyguardStatusViewController =
+ mKeyguardViewConfigurator.getKeyguardStatusViewController();
+ } else {
+ KeyguardStatusView keyguardStatusView = mView.getRootView().findViewById(
+ R.id.keyguard_status_view);
+ KeyguardStatusViewComponent statusViewComponent =
mKeyguardStatusViewComponentFactory.build(keyguardStatusView);
- mKeyguardStatusViewController = statusViewComponent.getKeyguardStatusViewController();
- mKeyguardStatusViewController.init();
+ mKeyguardStatusViewController = statusViewComponent.getKeyguardStatusViewController();
+ mKeyguardStatusViewController.init();
+ }
mKeyguardStatusViewController.setSplitShadeEnabled(mSplitShadeEnabled);
+
updateClockAppearance();
if (mKeyguardUserSwitcherController != null) {
@@ -1335,15 +1347,22 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
void reInflateViews() {
debugLog("reInflateViews");
// Re-inflate the status view group.
- KeyguardStatusView keyguardStatusView =
- mNotificationContainerParent.findViewById(R.id.keyguard_status_view);
- int statusIndex = mNotificationContainerParent.indexOfChild(keyguardStatusView);
- mNotificationContainerParent.removeView(keyguardStatusView);
- keyguardStatusView = (KeyguardStatusView) mLayoutInflater.inflate(
- R.layout.keyguard_status_view, mNotificationContainerParent, false);
- mNotificationContainerParent.addView(keyguardStatusView, statusIndex);
- attachSplitShadeMediaPlayerContainer(
- keyguardStatusView.findViewById(R.id.status_view_media_container));
+ if (!mFeatureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) {
+ KeyguardStatusView keyguardStatusView =
+ mNotificationContainerParent.findViewById(R.id.keyguard_status_view);
+ int statusIndex = mNotificationContainerParent.indexOfChild(keyguardStatusView);
+ mNotificationContainerParent.removeView(keyguardStatusView);
+ keyguardStatusView = (KeyguardStatusView) mLayoutInflater.inflate(
+ R.layout.keyguard_status_view, mNotificationContainerParent, false);
+ mNotificationContainerParent.addView(keyguardStatusView, statusIndex);
+
+ attachSplitShadeMediaPlayerContainer(
+ keyguardStatusView.findViewById(R.id.status_view_media_container));
+ } else {
+ attachSplitShadeMediaPlayerContainer(
+ mKeyguardViewConfigurator.getKeyguardRootView()
+ .findViewById(R.id.status_view_media_container));
+ }
// we need to update KeyguardStatusView constraints after reinflating it
updateResources();
@@ -1369,8 +1388,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
R.layout.keyguard_user_switcher /* layoutId */,
showKeyguardUserSwitcher /* enabled */);
- updateViewControllers(mView.findViewById(R.id.keyguard_status_view), userAvatarView,
- keyguardUserSwitcherView);
+ updateViewControllers(userAvatarView, keyguardUserSwitcherView);
if (!mFeatureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) {
// Update keyguard bottom area
@@ -1666,8 +1684,14 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
private void updateKeyguardStatusViewAlignment(boolean animate) {
boolean shouldBeCentered = shouldKeyguardStatusViewBeCentered();
+ ConstraintLayout layout;
+ if (mFeatureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) {
+ layout = mKeyguardViewConfigurator.getKeyguardRootView();
+ } else {
+ layout = mNotificationContainerParent;
+ }
mKeyguardStatusViewController.updateAlignment(
- mNotificationContainerParent, mSplitShadeEnabled, shouldBeCentered, animate);
+ layout, mSplitShadeEnabled, shouldBeCentered, animate);
mKeyguardUnfoldTransition.ifPresent(t -> t.setStatusViewCentered(shouldBeCentered));
}
@@ -3390,7 +3414,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
ipw.print("mPanelFlingOvershootAmount="); ipw.println(mPanelFlingOvershootAmount);
ipw.print("mLastGesturedOverExpansion="); ipw.println(mLastGesturedOverExpansion);
ipw.print("mIsSpringBackAnimation="); ipw.println(mIsSpringBackAnimation);
- ipw.print("mSplitShadeEnabled="); ipw.println(mSplitShadeEnabled);
ipw.print("mHintDistance="); ipw.println(mHintDistance);
ipw.print("mInitialOffsetOnTouch="); ipw.println(mInitialOffsetOnTouch);
ipw.print("mCollapsedAndHeadsUpOnDown="); ipw.println(mCollapsedAndHeadsUpOnDown);
@@ -3423,7 +3446,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
ipw.print("mGestureWaitForTouchSlop="); ipw.println(mGestureWaitForTouchSlop);
ipw.print("mIgnoreXTouchSlop="); ipw.println(mIgnoreXTouchSlop);
ipw.print("mExpandLatencyTracking="); ipw.println(mExpandLatencyTracking);
- ipw.print("mExpandLatencyTracking="); ipw.println(mExpandLatencyTracking);
ipw.println("gestureExclusionRect:" + calculateGestureExclusionRect());
new DumpsysTableLogger(
TAG,
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
index 0b3ed5601c2e..87abc9208d45 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
@@ -16,9 +16,10 @@
package com.android.systemui.shade.ui.viewmodel
+import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
+import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
import com.android.systemui.scene.shared.model.SceneKey
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -33,29 +34,30 @@ class ShadeSceneViewModel
@Inject
constructor(
@Application private val applicationScope: CoroutineScope,
- private val lockscreenSceneInteractor: LockscreenSceneInteractor,
+ authenticationInteractor: AuthenticationInteractor,
+ private val bouncerInteractor: BouncerInteractor,
) {
/** The key of the scene we should switch to when swiping up. */
val upDestinationSceneKey: StateFlow<SceneKey> =
- lockscreenSceneInteractor.isDeviceLocked
- .map { isLocked -> upDestinationSceneKey(isLocked = isLocked) }
+ authenticationInteractor.isUnlocked
+ .map { isUnlocked -> upDestinationSceneKey(isUnlocked = isUnlocked) }
.stateIn(
scope = applicationScope,
started = SharingStarted.WhileSubscribed(),
initialValue =
upDestinationSceneKey(
- isLocked = lockscreenSceneInteractor.isDeviceLocked.value,
+ isUnlocked = authenticationInteractor.isUnlocked.value,
),
)
/** Notifies that some content in the shade was clicked. */
fun onContentClicked() {
- lockscreenSceneInteractor.dismissLockscreen()
+ bouncerInteractor.showOrUnlockDevice()
}
private fun upDestinationSceneKey(
- isLocked: Boolean,
+ isUnlocked: Boolean,
): SceneKey {
- return if (isLocked) SceneKey.Lockscreen else SceneKey.Gone
+ return if (isUnlocked) SceneKey.Gone else SceneKey.Lockscreen
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
index 94251ffc74c8..efd7d2ef2718 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
@@ -446,6 +446,12 @@ constructor(
session?.requestSmartspaceUpdate()
}
+ fun removeViewsFromParent(viewGroup: ViewGroup) {
+ smartspaceViews.toList().forEach {
+ viewGroup.removeView(it as View)
+ }
+ }
+
/**
* Disconnects the smartspace view from the smartspace service and cleans up any resources.
*/
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 5e7e4be60104..1b790fdc35c1 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
@@ -321,7 +321,8 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
protected void setBackgroundTintColor(int color) {
if (color != mCurrentBackgroundTint) {
mCurrentBackgroundTint = color;
- if (color == mNormalColor) {
+ // TODO(282173943): re-enable this tinting optimization when Resources are thread-safe
+ if (false && color == mNormalColor) {
// We don't need to tint a normal notification
color = 0;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
index 6bbeebfdb431..0989df61a5e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
@@ -16,11 +16,15 @@
package com.android.systemui.statusbar.notification.row;
+import static android.graphics.PorterDuff.Mode.SRC_ATOP;
+
import android.annotation.ColorInt;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.ColorFilter;
+import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.IndentingPrintWriter;
@@ -157,10 +161,20 @@ public class FooterView extends StackScrollerDecorView {
*/
public void updateColors() {
Resources.Theme theme = mContext.getTheme();
- int textColor = getResources().getColor(R.color.notif_pill_text, theme);
- mClearAllButton.setBackground(theme.getDrawable(R.drawable.notif_footer_btn_background));
+ final @ColorInt int textColor = getResources().getColor(R.color.notif_pill_text, theme);
+ final Drawable clearAllBg = theme.getDrawable(R.drawable.notif_footer_btn_background);
+ final Drawable manageBg = theme.getDrawable(R.drawable.notif_footer_btn_background);
+ // TODO(b/282173943): Remove redundant tinting once Resources are thread-safe
+ final @ColorInt int buttonBgColor =
+ Utils.getColorAttrDefaultColor(mContext, com.android.internal.R.attr.colorSurface);
+ final ColorFilter bgColorFilter = new PorterDuffColorFilter(buttonBgColor, SRC_ATOP);
+ if (buttonBgColor != 0) {
+ clearAllBg.setColorFilter(bgColorFilter);
+ manageBg.setColorFilter(bgColorFilter);
+ }
+ mClearAllButton.setBackground(clearAllBg);
mClearAllButton.setTextColor(textColor);
- mManageButton.setBackground(theme.getDrawable(R.drawable.notif_footer_btn_background));
+ mManageButton.setBackground(manageBg);
mManageButton.setTextColor(textColor);
final @ColorInt int labelTextColor =
Utils.getColorAttrDefaultColor(mContext, android.R.attr.textColorPrimary);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
index dcd18dd7d1bf..2ccbc9f2f017 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
@@ -401,7 +401,7 @@ constructor(
isActivityIntent: Boolean,
showOverLockscreen: Boolean,
): Boolean {
- // TODO(b/184121838): Support launch animations when occluded.
+ // TODO(b/294418322): Support launch animations when occluded.
if (keyguardStateController.isOccluded) {
return false
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt
index 3a11635f75c3..c1af6df12bd1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt
@@ -118,6 +118,11 @@ interface MobileConnectionRepository {
/** The service provider name for this network connection, or the default name */
val networkName: StateFlow<NetworkNameModel>
+ /**
+ * True if this type of connection is allowed while airplane mode is on, and false otherwise.
+ */
+ val isAllowedDuringAirplaneMode: StateFlow<Boolean>
+
companion object {
/** The default number of levels to use for [numberOfLevels]. */
const val DEFAULT_NUM_LEVELS = 4
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionRepository.kt
index 6b86432b8171..17d20c297861 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionRepository.kt
@@ -186,6 +186,8 @@ class DemoMobileConnectionRepository(
override val networkName = MutableStateFlow(NetworkNameModel.IntentDerived("demo network"))
+ override val isAllowedDuringAirplaneMode = MutableStateFlow(false)
+
/**
* Process a new demo mobile event. Note that [resolvedNetworkType] must be passed in separately
* from the event, due to the requirement to reverse the mobile mappings lookup in the top-level
@@ -217,6 +219,8 @@ class DemoMobileConnectionRepository(
(event.activity ?: TelephonyManager.DATA_ACTIVITY_NONE).toMobileDataActivityModel()
_carrierNetworkChangeActive.value = event.carrierNetworkChange
_resolvedNetworkType.value = resolvedNetworkType
+
+ isAllowedDuringAirplaneMode.value = false
}
fun processCarrierMergedEvent(event: FakeWifiEventModel.CarrierMerged) {
@@ -240,6 +244,7 @@ class DemoMobileConnectionRepository(
_isInService.value = true
_isGsm.value = false
_carrierNetworkChangeActive.value = false
+ isAllowedDuringAirplaneMode.value = true
}
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepository.kt
index a609917351d9..65f486683837 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepository.kt
@@ -165,6 +165,13 @@ class CarrierMergedConnectionRepository(
override val isGsm = MutableStateFlow(false).asStateFlow()
override val carrierNetworkChangeActive = MutableStateFlow(false).asStateFlow()
+ /**
+ * Carrier merged connections happen over wifi but are displayed as a mobile triangle. Because
+ * they occur over wifi, it's possible to have a valid carrier merged connection even during
+ * airplane mode. See b/291993542.
+ */
+ override val isAllowedDuringAirplaneMode = MutableStateFlow(true).asStateFlow()
+
override val dataEnabled: StateFlow<Boolean> = wifiRepository.isWifiEnabled
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepository.kt
index 8869dfe02697..8ba7d2197c14 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepository.kt
@@ -287,6 +287,15 @@ class FullMobileConnectionRepository(
)
.stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.networkName.value)
+ override val isAllowedDuringAirplaneMode =
+ activeRepo
+ .flatMapLatest { it.isAllowedDuringAirplaneMode }
+ .stateIn(
+ scope,
+ SharingStarted.WhileSubscribed(),
+ activeRepo.value.isAllowedDuringAirplaneMode.value,
+ )
+
class Factory
@Inject
constructor(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
index b475183d98c6..aadc975a10de 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
@@ -59,8 +59,10 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.asExecutor
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
@@ -331,6 +333,9 @@ class MobileConnectionRepositoryImpl(
.stateIn(scope, SharingStarted.WhileSubscribed(), initial)
}
+ /** Typical mobile connections aren't available during airplane mode. */
+ override val isAllowedDuringAirplaneMode = MutableStateFlow(false).asStateFlow()
+
class Factory
@Inject
constructor(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
index d42e30c9b1b9..1a138272d67c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
@@ -111,6 +111,9 @@ interface MobileIconInteractor {
/** See [MobileIconsInteractor.isForceHidden]. */
val isForceHidden: Flow<Boolean>
+ /** See [MobileConnectionRepository.isAllowedDuringAirplaneMode]. */
+ val isAllowedDuringAirplaneMode: StateFlow<Boolean>
+
/** True when in carrier network change mode */
val carrierNetworkChangeActive: StateFlow<Boolean>
}
@@ -267,4 +270,6 @@ class MobileIconInteractorImpl(
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
override val isInService = connectionRepository.isInService
+
+ override val isAllowedDuringAirplaneMode = connectionRepository.isAllowedDuringAirplaneMode
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
index 35f4f9aa4622..fe2481595ff4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
@@ -102,9 +102,16 @@ constructor(
} else {
combine(
airplaneModeInteractor.isAirplaneMode,
+ iconInteractor.isAllowedDuringAirplaneMode,
iconInteractor.isForceHidden,
- ) { isAirplaneMode, isForceHidden ->
- !isAirplaneMode && !isForceHidden
+ ) { isAirplaneMode, isAllowedDuringAirplaneMode, isForceHidden ->
+ if (isForceHidden) {
+ false
+ } else if (isAirplaneMode) {
+ isAllowedDuringAirplaneMode
+ } else {
+ true
+ }
}
}
.distinctUntilChanged()
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java
index ac04bc4356ac..98d4d22d59b4 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java
@@ -23,6 +23,7 @@ import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLE
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -157,6 +158,12 @@ public class KeyguardClockSwitchControllerBaseTest extends SysuiTestCase {
when(mSmartspaceController.buildAndConnectDateView(any())).thenReturn(mFakeDateView);
when(mSmartspaceController.buildAndConnectWeatherView(any())).thenReturn(mFakeWeatherView);
when(mSmartspaceController.buildAndConnectView(any())).thenReturn(mFakeSmartspaceView);
+ doAnswer(invocation -> {
+ removeView(mFakeDateView);
+ removeView(mFakeWeatherView);
+ removeView(mFakeSmartspaceView);
+ return null;
+ }).when(mSmartspaceController).removeViewsFromParent(any());
mExecutor = new FakeExecutor(new FakeSystemClock());
mFakeFeatureFlags = new FakeFeatureFlags();
mFakeFeatureFlags.set(FACE_AUTH_REFACTOR, false);
@@ -201,6 +208,13 @@ public class KeyguardClockSwitchControllerBaseTest extends SysuiTestCase {
when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(mStatusArea);
}
+ private void removeView(View v) {
+ ViewGroup group = ((ViewGroup) v.getParent());
+ if (group != null) {
+ group.removeView(v);
+ }
+ }
+
protected void init() {
mController.init();
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
index 20d9ef1e86b1..7d23c800321a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
@@ -16,6 +16,7 @@
package com.android.keyguard;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -119,8 +120,8 @@ public class KeyguardStatusViewControllerTest extends KeyguardStatusViewControll
@Test
public void correctlyDump() {
mController.onInit();
- verify(mDumpManager).registerDumpable(mController);
+ verify(mDumpManager).registerDumpable(eq(mController.getInstanceName()), eq(mController));
mController.onDestroy();
- verify(mDumpManager, times(1)).unregisterDumpable(KeyguardStatusViewController.TAG);
+ verify(mDumpManager, times(1)).unregisterDumpable(eq(mController.getInstanceName()));
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt
index 005697044c0f..d3a2a73959dd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt
@@ -18,23 +18,30 @@
package com.android.systemui.authentication.data.repository
+import android.app.admin.DevicePolicyManager
+import android.content.Intent
import android.content.pm.UserInfo
import androidx.test.filters.SmallTest
import com.android.internal.widget.LockPatternUtils
import com.android.keyguard.KeyguardSecurityModel
import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.data.model.AuthenticationMethodModel
+import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.user.data.repository.FakeUserRepository
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
+import java.util.function.Function
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
+import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.MockitoAnnotations
@@ -43,6 +50,7 @@ import org.mockito.MockitoAnnotations
class AuthenticationRepositoryTest : SysuiTestCase() {
@Mock private lateinit var lockPatternUtils: LockPatternUtils
+ @Mock private lateinit var getSecurityMode: Function<Int, KeyguardSecurityModel.SecurityMode>
private val testUtils = SceneTestUtils(this)
private val testScope = testUtils.testScope
@@ -50,24 +58,49 @@ class AuthenticationRepositoryTest : SysuiTestCase() {
private lateinit var underTest: AuthenticationRepository
+ private var currentSecurityMode: KeyguardSecurityModel.SecurityMode =
+ KeyguardSecurityModel.SecurityMode.PIN
+
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
userRepository.setUserInfos(USER_INFOS)
runBlocking { userRepository.setSelectedUserInfo(USER_INFOS[0]) }
+ whenever(getSecurityMode.apply(anyInt())).thenAnswer { currentSecurityMode }
underTest =
AuthenticationRepositoryImpl(
applicationScope = testScope.backgroundScope,
- getSecurityMode = { KeyguardSecurityModel.SecurityMode.PIN },
+ getSecurityMode = getSecurityMode,
backgroundDispatcher = testUtils.testDispatcher,
userRepository = userRepository,
keyguardRepository = testUtils.keyguardRepository,
lockPatternUtils = lockPatternUtils,
+ broadcastDispatcher = fakeBroadcastDispatcher,
)
}
@Test
+ fun authenticationMethod() =
+ testScope.runTest {
+ val authMethod by collectLastValue(underTest.authenticationMethod)
+ runCurrent()
+ dispatchBroadcast()
+ assertThat(authMethod).isEqualTo(AuthenticationMethodModel.Pin)
+ assertThat(underTest.getAuthenticationMethod()).isEqualTo(AuthenticationMethodModel.Pin)
+
+ setSecurityModeAndDispatchBroadcast(KeyguardSecurityModel.SecurityMode.Pattern)
+ assertThat(authMethod).isEqualTo(AuthenticationMethodModel.Pattern)
+ assertThat(underTest.getAuthenticationMethod())
+ .isEqualTo(AuthenticationMethodModel.Pattern)
+
+ setSecurityModeAndDispatchBroadcast(KeyguardSecurityModel.SecurityMode.None)
+ assertThat(authMethod).isEqualTo(AuthenticationMethodModel.None)
+ assertThat(underTest.getAuthenticationMethod())
+ .isEqualTo(AuthenticationMethodModel.None)
+ }
+
+ @Test
fun isAutoConfirmEnabled() =
testScope.runTest {
whenever(lockPatternUtils.isAutoPinConfirmEnabled(USER_INFOS[0].id)).thenReturn(true)
@@ -95,6 +128,20 @@ class AuthenticationRepositoryTest : SysuiTestCase() {
assertThat(values.last()).isTrue()
}
+ private fun setSecurityModeAndDispatchBroadcast(
+ securityMode: KeyguardSecurityModel.SecurityMode,
+ ) {
+ currentSecurityMode = securityMode
+ dispatchBroadcast()
+ }
+
+ private fun dispatchBroadcast() {
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ context,
+ Intent(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED)
+ )
+ }
+
companion object {
private val USER_INFOS =
listOf(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
index a86937fcad3c..d848cd46e509 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
@@ -19,9 +19,11 @@ package com.android.systemui.authentication.domain.interactor
import android.app.admin.DevicePolicyManager
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.data.model.AuthenticationMethodModel as DataLayerAuthenticationMethodModel
import com.android.systemui.authentication.data.repository.AuthenticationRepository
import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
-import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.authentication.domain.model.AuthenticationMethodModel as DomainLayerAuthenticationMethodModel
+import com.android.systemui.authentication.shared.model.AuthenticationPatternCoordinate
import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.scene.SceneTestUtils
@@ -50,42 +52,61 @@ class AuthenticationInteractorTest : SysuiTestCase() {
)
@Test
- fun getAuthenticationMethod() =
+ fun authenticationMethod() =
testScope.runTest {
- assertThat(underTest.getAuthenticationMethod()).isEqualTo(AuthenticationMethodModel.Pin)
+ val authMethod by collectLastValue(underTest.authenticationMethod)
+ runCurrent()
+ assertThat(authMethod).isEqualTo(DomainLayerAuthenticationMethodModel.Pin)
+ assertThat(underTest.getAuthenticationMethod())
+ .isEqualTo(DomainLayerAuthenticationMethodModel.Pin)
utils.authenticationRepository.setAuthenticationMethod(
- AuthenticationMethodModel.Password
+ DataLayerAuthenticationMethodModel.Password
)
+ assertThat(authMethod).isEqualTo(DomainLayerAuthenticationMethodModel.Password)
assertThat(underTest.getAuthenticationMethod())
- .isEqualTo(AuthenticationMethodModel.Password)
+ .isEqualTo(DomainLayerAuthenticationMethodModel.Password)
}
@Test
- fun getAuthenticationMethod_noneTreatedAsSwipe_whenLockscreenEnabled() =
+ fun authenticationMethod_noneTreatedAsSwipe_whenLockscreenEnabled() =
testScope.runTest {
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.None)
+ val authMethod by collectLastValue(underTest.authenticationMethod)
+ runCurrent()
+
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.None
+ )
utils.authenticationRepository.setLockscreenEnabled(true)
+ assertThat(authMethod).isEqualTo(DomainLayerAuthenticationMethodModel.Swipe)
assertThat(underTest.getAuthenticationMethod())
- .isEqualTo(AuthenticationMethodModel.Swipe)
+ .isEqualTo(DomainLayerAuthenticationMethodModel.Swipe)
}
@Test
- fun getAuthenticationMethod_none_whenLockscreenDisabled() =
+ fun authenticationMethod_none_whenLockscreenDisabled() =
testScope.runTest {
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.None)
+ val authMethod by collectLastValue(underTest.authenticationMethod)
+ runCurrent()
+
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.None
+ )
utils.authenticationRepository.setLockscreenEnabled(false)
+ assertThat(authMethod).isEqualTo(DomainLayerAuthenticationMethodModel.None)
assertThat(underTest.getAuthenticationMethod())
- .isEqualTo(AuthenticationMethodModel.None)
+ .isEqualTo(DomainLayerAuthenticationMethodModel.None)
}
@Test
fun isUnlocked_whenAuthMethodIsNoneAndLockscreenDisabled_isTrue() =
testScope.runTest {
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.None)
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.None
+ )
utils.authenticationRepository.setLockscreenEnabled(false)
val isUnlocked by collectLastValue(underTest.isUnlocked)
@@ -111,7 +132,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
@Test
fun isUnlocked_whenAuthMethodIsNoneAndLockscreenEnabled_isFalse() =
testScope.runTest {
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.None)
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.None
+ )
utils.authenticationRepository.setLockscreenEnabled(true)
val isUnlocked by collectLastValue(underTest.isUnlocked)
@@ -124,7 +147,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
utils.authenticationRepository.setUnlocked(false)
runCurrent()
utils.authenticationRepository.setAuthenticationMethod(
- AuthenticationMethodModel.Password
+ DataLayerAuthenticationMethodModel.Password
)
assertThat(underTest.isAuthenticationRequired()).isTrue()
@@ -135,7 +158,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
testScope.runTest {
utils.authenticationRepository.setUnlocked(false)
runCurrent()
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.None
+ )
assertThat(underTest.isAuthenticationRequired()).isFalse()
}
@@ -146,7 +171,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
utils.authenticationRepository.setUnlocked(true)
runCurrent()
utils.authenticationRepository.setAuthenticationMethod(
- AuthenticationMethodModel.Password
+ DataLayerAuthenticationMethodModel.Password
)
assertThat(underTest.isAuthenticationRequired()).isFalse()
@@ -157,7 +182,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
testScope.runTest {
utils.authenticationRepository.setUnlocked(true)
runCurrent()
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.None
+ )
assertThat(underTest.isAuthenticationRequired()).isFalse()
}
@@ -166,7 +193,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
fun authenticate_withCorrectPin_returnsTrue() =
testScope.runTest {
val isThrottled by collectLastValue(underTest.isThrottled)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.Pin
+ )
assertThat(underTest.authenticate(FakeAuthenticationRepository.DEFAULT_PIN)).isTrue()
assertThat(isThrottled).isFalse()
}
@@ -174,21 +203,27 @@ class AuthenticationInteractorTest : SysuiTestCase() {
@Test
fun authenticate_withIncorrectPin_returnsFalse() =
testScope.runTest {
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.Pin
+ )
assertThat(underTest.authenticate(listOf(9, 8, 7, 6, 5, 4))).isFalse()
}
@Test(expected = IllegalArgumentException::class)
fun authenticate_withEmptyPin_throwsException() =
testScope.runTest {
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.Pin
+ )
underTest.authenticate(listOf())
}
@Test
fun authenticate_withCorrectMaxLengthPin_returnsTrue() =
testScope.runTest {
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.Pin
+ )
val pin = List(16) { 9 }
utils.authenticationRepository.overrideCredential(pin)
assertThat(underTest.authenticate(pin)).isTrue()
@@ -203,7 +238,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
// If the policy changes, there is work to do in SysUI.
assertThat(DevicePolicyManager.MAX_PASSWORD_LENGTH).isLessThan(17)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.Pin
+ )
assertThat(underTest.authenticate(List(17) { 9 })).isFalse()
}
@@ -212,7 +249,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
testScope.runTest {
val isThrottled by collectLastValue(underTest.isThrottled)
utils.authenticationRepository.setAuthenticationMethod(
- AuthenticationMethodModel.Password
+ DataLayerAuthenticationMethodModel.Password
)
assertThat(underTest.authenticate("password".toList())).isTrue()
@@ -223,7 +260,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
fun authenticate_withIncorrectPassword_returnsFalse() =
testScope.runTest {
utils.authenticationRepository.setAuthenticationMethod(
- AuthenticationMethodModel.Password
+ DataLayerAuthenticationMethodModel.Password
)
assertThat(underTest.authenticate("alohomora".toList())).isFalse()
@@ -233,7 +270,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
fun authenticate_withCorrectPattern_returnsTrue() =
testScope.runTest {
utils.authenticationRepository.setAuthenticationMethod(
- AuthenticationMethodModel.Pattern
+ DataLayerAuthenticationMethodModel.Pattern
)
assertThat(underTest.authenticate(FakeAuthenticationRepository.PATTERN)).isTrue()
@@ -243,21 +280,21 @@ class AuthenticationInteractorTest : SysuiTestCase() {
fun authenticate_withIncorrectPattern_returnsFalse() =
testScope.runTest {
utils.authenticationRepository.setAuthenticationMethod(
- AuthenticationMethodModel.Pattern
+ DataLayerAuthenticationMethodModel.Pattern
)
assertThat(
underTest.authenticate(
listOf(
- AuthenticationMethodModel.Pattern.PatternCoordinate(
+ AuthenticationPatternCoordinate(
x = 2,
y = 0,
),
- AuthenticationMethodModel.Pattern.PatternCoordinate(
+ AuthenticationPatternCoordinate(
x = 2,
y = 1,
),
- AuthenticationMethodModel.Pattern.PatternCoordinate(
+ AuthenticationPatternCoordinate(
x = 2,
y = 2,
),
@@ -271,7 +308,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
fun tryAutoConfirm_withAutoConfirmPinAndShorterPin_returnsNullAndHasNoEffect() =
testScope.runTest {
val isThrottled by collectLastValue(underTest.isThrottled)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.Pin
+ )
utils.authenticationRepository.setAutoConfirmEnabled(true)
assertThat(
underTest.authenticate(
@@ -289,7 +328,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
fun tryAutoConfirm_withAutoConfirmWrongPinCorrectLength_returnsFalseAndDoesNotUnlockDevice() =
testScope.runTest {
val isUnlocked by collectLastValue(underTest.isUnlocked)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.Pin
+ )
utils.authenticationRepository.setAutoConfirmEnabled(true)
assertThat(
underTest.authenticate(
@@ -305,7 +346,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
fun tryAutoConfirm_withAutoConfirmLongerPin_returnsFalseAndDoesNotUnlockDevice() =
testScope.runTest {
val isUnlocked by collectLastValue(underTest.isUnlocked)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.Pin
+ )
utils.authenticationRepository.setAutoConfirmEnabled(true)
assertThat(
underTest.authenticate(
@@ -321,7 +364,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
fun tryAutoConfirm_withAutoConfirmCorrectPin_returnsTrueAndUnlocksDevice() =
testScope.runTest {
val isUnlocked by collectLastValue(underTest.isUnlocked)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.Pin
+ )
utils.authenticationRepository.setAutoConfirmEnabled(true)
assertThat(
underTest.authenticate(
@@ -337,7 +382,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
fun tryAutoConfirm_withoutAutoConfirmButCorrectPin_returnsNullAndHasNoEffects() =
testScope.runTest {
val isUnlocked by collectLastValue(underTest.isUnlocked)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.Pin
+ )
utils.authenticationRepository.setAutoConfirmEnabled(false)
assertThat(
underTest.authenticate(
@@ -354,7 +401,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
testScope.runTest {
val isUnlocked by collectLastValue(underTest.isUnlocked)
utils.authenticationRepository.setAuthenticationMethod(
- AuthenticationMethodModel.Password
+ DataLayerAuthenticationMethodModel.Password
)
assertThat(underTest.authenticate("password".toList(), tryAutoConfirm = true)).isNull()
@@ -367,7 +414,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
val isUnlocked by collectLastValue(underTest.isUnlocked)
val throttling by collectLastValue(underTest.throttling)
val isThrottled by collectLastValue(underTest.isThrottled)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.Pin
+ )
underTest.authenticate(FakeAuthenticationRepository.DEFAULT_PIN)
assertThat(isUnlocked).isTrue()
assertThat(isThrottled).isFalse()
@@ -456,7 +505,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
fun hintedPinLength_withoutAutoConfirm_isNull() =
testScope.runTest {
val hintedPinLength by collectLastValue(underTest.hintedPinLength)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.Pin
+ )
utils.authenticationRepository.setAutoConfirmEnabled(false)
assertThat(hintedPinLength).isNull()
@@ -466,7 +517,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
fun hintedPinLength_withAutoConfirmPinTooShort_isNull() =
testScope.runTest {
val hintedPinLength by collectLastValue(underTest.hintedPinLength)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.Pin
+ )
utils.authenticationRepository.overrideCredential(
buildList {
repeat(utils.authenticationRepository.hintedPinLength - 1) { add(it + 1) }
@@ -481,7 +534,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
fun hintedPinLength_withAutoConfirmPinAtRightLength_isSameLength() =
testScope.runTest {
val hintedPinLength by collectLastValue(underTest.hintedPinLength)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.Pin
+ )
utils.authenticationRepository.setAutoConfirmEnabled(true)
utils.authenticationRepository.overrideCredential(
buildList { repeat(utils.authenticationRepository.hintedPinLength) { add(it + 1) } }
@@ -494,7 +549,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
fun hintedPinLength_withAutoConfirmPinTooLong_isNull() =
testScope.runTest {
val hintedPinLength by collectLastValue(underTest.hintedPinLength)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.Pin
+ )
utils.authenticationRepository.overrideCredential(
buildList {
repeat(utils.authenticationRepository.hintedPinLength + 1) { add(it + 1) }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt
index 186df02536ea..38e5728f6e70 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt
@@ -165,6 +165,28 @@ class AlternateBouncerInteractorTest : SysuiTestCase() {
assertFalse(bouncerRepository.alternateBouncerVisible.value)
}
+ @Test
+ fun alternateBouncerUiAvailable_fromMultipleSources() {
+ assertFalse(bouncerRepository.alternateBouncerUIAvailable.value)
+
+ // GIVEN there are two different sources indicating the alternate bouncer is available
+ underTest.setAlternateBouncerUIAvailable(true, "source1")
+ underTest.setAlternateBouncerUIAvailable(true, "source2")
+ assertTrue(bouncerRepository.alternateBouncerUIAvailable.value)
+
+ // WHEN one of the sources no longer says the UI is available
+ underTest.setAlternateBouncerUIAvailable(false, "source1")
+
+ // THEN alternate bouncer UI is still available (from the other source)
+ assertTrue(bouncerRepository.alternateBouncerUIAvailable.value)
+
+ // WHEN all sources say the UI is not available
+ underTest.setAlternateBouncerUIAvailable(false, "source2")
+
+ // THEN alternate boucer UI is not available
+ assertFalse(bouncerRepository.alternateBouncerUIAvailable.value)
+ }
+
private fun givenCanShowAlternateBouncer() {
bouncerRepository.setAlternateBouncerUIAvailable(true)
biometricSettingsRepository.setFingerprintEnrolled(true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
index 14fc931522a4..df4d2225f459 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
@@ -19,8 +19,9 @@ package com.android.systemui.bouncer.domain.interactor
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.data.model.AuthenticationMethodModel
import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
-import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.authentication.shared.model.AuthenticationPatternCoordinate
import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.scene.SceneTestUtils
@@ -73,6 +74,7 @@ class BouncerInteractorTest : SysuiTestCase() {
val message by collectLastValue(underTest.message)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+ runCurrent()
utils.authenticationRepository.setUnlocked(false)
underTest.showOrUnlockDevice()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
@@ -104,6 +106,7 @@ class BouncerInteractorTest : SysuiTestCase() {
val message by collectLastValue(underTest.message)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+ runCurrent()
utils.authenticationRepository.setAutoConfirmEnabled(true)
utils.authenticationRepository.setUnlocked(false)
underTest.showOrUnlockDevice()
@@ -140,6 +143,7 @@ class BouncerInteractorTest : SysuiTestCase() {
val message by collectLastValue(underTest.message)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+ runCurrent()
utils.authenticationRepository.setUnlocked(false)
underTest.showOrUnlockDevice()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
@@ -170,6 +174,7 @@ class BouncerInteractorTest : SysuiTestCase() {
utils.authenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Password
)
+ runCurrent()
utils.authenticationRepository.setUnlocked(false)
underTest.showOrUnlockDevice()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
@@ -202,6 +207,7 @@ class BouncerInteractorTest : SysuiTestCase() {
utils.authenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Pattern
)
+ runCurrent()
utils.authenticationRepository.setUnlocked(false)
underTest.showOrUnlockDevice()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
@@ -214,11 +220,7 @@ class BouncerInteractorTest : SysuiTestCase() {
assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PATTERN)
// Wrong input.
- assertThat(
- underTest.authenticate(
- listOf(AuthenticationMethodModel.Pattern.PatternCoordinate(1, 2))
- )
- )
+ assertThat(underTest.authenticate(listOf(AuthenticationPatternCoordinate(1, 2))))
.isFalse()
assertThat(message).isEqualTo(MESSAGE_WRONG_PATTERN)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
@@ -248,7 +250,8 @@ class BouncerInteractorTest : SysuiTestCase() {
fun showOrUnlockDevice_authMethodNotSecure_switchesToGoneScene() =
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
+ utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.None)
+ utils.authenticationRepository.setLockscreenEnabled(true)
utils.authenticationRepository.setUnlocked(false)
underTest.showOrUnlockDevice()
@@ -264,6 +267,7 @@ class BouncerInteractorTest : SysuiTestCase() {
utils.authenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Password
)
+ runCurrent()
utils.authenticationRepository.setUnlocked(false)
val customMessage = "Hello there!"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
index 2cc949326fa0..7af8a0425402 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
@@ -18,19 +18,17 @@ package com.android.systemui.bouncer.ui.viewmodel
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.data.model.AuthenticationMethodModel
import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
-import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.scene.SceneTestUtils
import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(JUnit4::class)
class AuthMethodBouncerViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
index 0df0a17931f4..2c96bcc9dd33 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
@@ -18,8 +18,9 @@ package com.android.systemui.bouncer.ui.viewmodel
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.data.model.AuthenticationMethodModel as DataLayerAuthenticationMethodModel
import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
-import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.authentication.domain.model.AuthenticationMethodModel as DomainLayerAuthenticationMethodModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.scene.SceneTestUtils
import com.google.common.truth.Truth.assertThat
@@ -55,6 +56,7 @@ class BouncerViewModelTest : SysuiTestCase() {
private val underTest =
utils.bouncerViewModel(
bouncerInteractor = bouncerInteractor,
+ authenticationInteractor = authenticationInteractor,
)
@Test
@@ -86,7 +88,8 @@ class BouncerViewModelTest : SysuiTestCase() {
@Test
fun authMethod_reusesInstances() =
testScope.runTest {
- val seen = mutableMapOf<AuthenticationMethodModel, AuthMethodBouncerViewModel>()
+ val seen =
+ mutableMapOf<DomainLayerAuthenticationMethodModel, AuthMethodBouncerViewModel>()
val authMethodViewModel: AuthMethodBouncerViewModel? by
collectLastValue(underTest.authMethod)
// First pass, populate our "seen" map:
@@ -105,7 +108,7 @@ class BouncerViewModelTest : SysuiTestCase() {
@Test
fun authMethodsToTest_returnsCompleteSampleOfAllAuthMethodTypes() {
assertThat(authMethodsToTest().map { it::class }.toSet())
- .isEqualTo(AuthenticationMethodModel::class.sealedSubclasses.toSet())
+ .isEqualTo(DomainLayerAuthenticationMethodModel::class.sealedSubclasses.toSet())
}
@Test
@@ -113,7 +116,9 @@ class BouncerViewModelTest : SysuiTestCase() {
testScope.runTest {
val message by collectLastValue(underTest.message)
val throttling by collectLastValue(bouncerInteractor.throttling)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.Pin
+ )
assertThat(message?.isUpdateAnimated).isTrue()
repeat(FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING) {
@@ -136,7 +141,9 @@ class BouncerViewModelTest : SysuiTestCase() {
}
)
val throttling by collectLastValue(bouncerInteractor.throttling)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.Pin
+ )
assertThat(isInputEnabled).isTrue()
repeat(FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING) {
@@ -153,7 +160,9 @@ class BouncerViewModelTest : SysuiTestCase() {
fun throttlingDialogMessage() =
testScope.runTest {
val throttlingDialogMessage by collectLastValue(underTest.throttlingDialogMessage)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+ utils.authenticationRepository.setAuthenticationMethod(
+ DataLayerAuthenticationMethodModel.Pin
+ )
repeat(FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING) {
// Wrong PIN.
@@ -166,13 +175,32 @@ class BouncerViewModelTest : SysuiTestCase() {
assertThat(throttlingDialogMessage).isNull()
}
- private fun authMethodsToTest(): List<AuthenticationMethodModel> {
+ private fun authMethodsToTest(): List<DomainLayerAuthenticationMethodModel> {
return listOf(
- AuthenticationMethodModel.None,
- AuthenticationMethodModel.Swipe,
- AuthenticationMethodModel.Pin,
- AuthenticationMethodModel.Password,
- AuthenticationMethodModel.Pattern,
+ DomainLayerAuthenticationMethodModel.None,
+ DomainLayerAuthenticationMethodModel.Swipe,
+ DomainLayerAuthenticationMethodModel.Pin,
+ DomainLayerAuthenticationMethodModel.Password,
+ DomainLayerAuthenticationMethodModel.Pattern,
+ )
+ }
+
+ private fun FakeAuthenticationRepository.setAuthenticationMethod(
+ model: DomainLayerAuthenticationMethodModel,
+ ) {
+ setAuthenticationMethod(
+ when (model) {
+ is DomainLayerAuthenticationMethodModel.None,
+ is DomainLayerAuthenticationMethodModel.Swipe ->
+ DataLayerAuthenticationMethodModel.None
+ is DomainLayerAuthenticationMethodModel.Pin ->
+ DataLayerAuthenticationMethodModel.Pin
+ is DomainLayerAuthenticationMethodModel.Password ->
+ DataLayerAuthenticationMethodModel.Password
+ is DomainLayerAuthenticationMethodModel.Pattern ->
+ DataLayerAuthenticationMethodModel.Pattern
+ }
)
+ setLockscreenEnabled(model !is DomainLayerAuthenticationMethodModel.None)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
index 7f8d54c43387..4e9fe8d91da1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
@@ -19,7 +19,7 @@ package com.android.systemui.bouncer.ui.viewmodel
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
-import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.authentication.data.model.AuthenticationMethodModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.shared.model.SceneKey
@@ -55,6 +55,7 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
private val bouncerViewModel =
utils.bouncerViewModel(
bouncerInteractor = bouncerInteractor,
+ authenticationInteractor = authenticationInteractor,
)
private val underTest =
PasswordBouncerViewModel(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
index 57fcbe595fa6..000200c606b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
@@ -19,8 +19,8 @@ package com.android.systemui.bouncer.ui.viewmodel
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.data.model.AuthenticationMethodModel
import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
-import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.shared.model.SceneKey
@@ -57,6 +57,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
private val bouncerViewModel =
utils.bouncerViewModel(
bouncerInteractor = bouncerInteractor,
+ authenticationInteractor = authenticationInteractor,
)
private val underTest =
PatternBouncerViewModel(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
index 81c68ed2320f..4b667c393b62 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
@@ -19,8 +19,8 @@ package com.android.systemui.bouncer.ui.viewmodel
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.data.model.AuthenticationMethodModel
import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
-import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.shared.model.SceneKey
@@ -57,6 +57,7 @@ class PinBouncerViewModelTest : SysuiTestCase() {
private val bouncerViewModel =
utils.bouncerViewModel(
bouncerInteractor = bouncerInteractor,
+ authenticationInteractor = authenticationInteractor,
)
private val underTest =
PinBouncerViewModel(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt
deleted file mode 100644
index 86e56bf1e131..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.keyguard.domain.interactor
-
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.scene.SceneTestUtils
-import com.android.systemui.scene.shared.model.SceneKey
-import com.android.systemui.scene.shared.model.SceneModel
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.runCurrent
-import kotlinx.coroutines.test.runTest
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-@OptIn(ExperimentalCoroutinesApi::class)
-@SmallTest
-@RunWith(JUnit4::class)
-class LockscreenSceneInteractorTest : SysuiTestCase() {
-
- private val utils = SceneTestUtils(this)
- private val testScope = utils.testScope
- private val sceneInteractor = utils.sceneInteractor()
- private val authenticationInteractor =
- utils.authenticationInteractor(
- repository = utils.authenticationRepository(),
- )
- private val underTest =
- utils.lockScreenSceneInteractor(
- authenticationInteractor = authenticationInteractor,
- bouncerInteractor =
- utils.bouncerInteractor(
- authenticationInteractor = authenticationInteractor,
- sceneInteractor = sceneInteractor,
- ),
- )
-
- @Test
- fun isDeviceLocked() =
- testScope.runTest {
- val isDeviceLocked by collectLastValue(underTest.isDeviceLocked)
-
- utils.authenticationRepository.setUnlocked(false)
- assertThat(isDeviceLocked).isTrue()
-
- utils.authenticationRepository.setUnlocked(true)
- assertThat(isDeviceLocked).isFalse()
- }
-
- @Test
- fun isSwipeToDismissEnabled_deviceLockedAndAuthMethodSwipe_true() =
- testScope.runTest {
- val isSwipeToDismissEnabled by collectLastValue(underTest.isSwipeToDismissEnabled)
-
- utils.authenticationRepository.setUnlocked(false)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
-
- assertThat(isSwipeToDismissEnabled).isTrue()
- }
-
- @Test
- fun isSwipeToDismissEnabled_deviceUnlockedAndAuthMethodSwipe_false() =
- testScope.runTest {
- val isSwipeToDismissEnabled by collectLastValue(underTest.isSwipeToDismissEnabled)
-
- utils.authenticationRepository.setUnlocked(true)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
-
- assertThat(isSwipeToDismissEnabled).isFalse()
- }
-
- @Test
- fun dismissLockScreen_deviceLockedWithSecureAuthMethod_switchesToBouncer() =
- testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene)
- utils.authenticationRepository.setUnlocked(false)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
-
- underTest.dismissLockscreen()
-
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
- }
-
- @Test
- fun dismissLockScreen_deviceUnlocked_switchesToGone() =
- testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene)
- utils.authenticationRepository.setUnlocked(true)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
-
- underTest.dismissLockscreen()
-
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
- }
-
- @Test
- fun dismissLockScreen_deviceLockedWithInsecureAuthMethod_switchesToGone() =
- testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene)
- utils.authenticationRepository.setUnlocked(false)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
-
- underTest.dismissLockscreen()
-
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
- }
-
- @Test
- fun switchFromLockScreenToGone_authMethodNotSwipe_doesNotUnlockDevice() =
- testScope.runTest {
- val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
- sceneInteractor.setCurrentScene(SceneModel(SceneKey.Lockscreen), "reason")
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
- assertThat(isUnlocked).isFalse()
-
- sceneInteractor.setCurrentScene(SceneModel(SceneKey.Gone), "reason")
-
- assertThat(isUnlocked).isFalse()
- }
-
- @Test
- fun switchFromNonLockScreenToGone_authMethodSwipe_doesNotUnlockDevice() =
- testScope.runTest {
- val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
- runCurrent()
- sceneInteractor.setCurrentScene(SceneModel(SceneKey.Shade), "reason")
- runCurrent()
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
- runCurrent()
- assertThat(isUnlocked).isFalse()
-
- sceneInteractor.setCurrentScene(SceneModel(SceneKey.Gone), "reason")
-
- assertThat(isUnlocked).isFalse()
- }
-
- @Test
- fun authMethodChangedToNone_notOnLockScreenScene_doesNotDismissLockScreen() =
- testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
- runCurrent()
- sceneInteractor.setCurrentScene(SceneModel(SceneKey.QuickSettings), "reason")
- runCurrent()
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.QuickSettings))
-
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.None)
-
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.QuickSettings))
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt
index 66631dc9977b..addb1815cead 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt
@@ -17,6 +17,8 @@
package com.android.systemui.keyguard.ui.view.layout.blueprints
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
import androidx.constraintlayout.widget.ConstraintSet
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -26,15 +28,17 @@ import com.android.systemui.keyguard.ui.view.layout.sections.DefaultIndicationAr
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultLockIconSection
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultSettingsPopupMenuSection
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultShortcutsSection
+import com.android.systemui.keyguard.ui.view.layout.sections.DefaultStatusViewSection
+import com.android.systemui.keyguard.ui.view.layout.sections.SplitShadeGuidelines
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
-@RunWith(JUnit4::class)
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper(setAsMainLooper = true)
@SmallTest
class DefaultKeyguardBlueprintTest : SysuiTestCase() {
private lateinit var underTest: DefaultKeyguardBlueprint
@@ -45,6 +49,8 @@ class DefaultKeyguardBlueprintTest : SysuiTestCase() {
@Mock
private lateinit var defaultAmbientIndicationAreaSection: DefaultAmbientIndicationAreaSection
@Mock private lateinit var defaultSettingsPopupMenuSection: DefaultSettingsPopupMenuSection
+ @Mock private lateinit var defaultStatusViewSection: DefaultStatusViewSection
+ @Mock private lateinit var splitShadeGuidelines: SplitShadeGuidelines
@Before
fun setup() {
@@ -57,6 +63,8 @@ class DefaultKeyguardBlueprintTest : SysuiTestCase() {
defaultShortcutsSection,
defaultAmbientIndicationAreaSection,
defaultSettingsPopupMenuSection,
+ defaultStatusViewSection,
+ splitShadeGuidelines,
)
}
@@ -69,5 +77,7 @@ class DefaultKeyguardBlueprintTest : SysuiTestCase() {
verify(defaultShortcutsSection).apply(cs)
verify(defaultAmbientIndicationAreaSection).apply(cs)
verify(defaultSettingsPopupMenuSection).apply(cs)
+ verify(defaultStatusViewSection).apply(cs)
+ verify(splitShadeGuidelines).apply(cs)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSectionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSectionTest.kt
index 1444f8df4e4c..379c03c4353d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSectionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSectionTest.kt
@@ -25,6 +25,7 @@ import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.AuthController
+import com.android.systemui.keyguard.ui.view.KeyguardRootView
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
index 63ee240fd2c6..834b9c526669 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
@@ -19,7 +19,7 @@ package com.android.systemui.keyguard.ui.viewmodel
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
-import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.authentication.data.model.AuthenticationMethodModel
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.scene.SceneTestUtils
@@ -49,14 +49,11 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
private val underTest =
LockscreenSceneViewModel(
applicationScope = testScope.backgroundScope,
- interactor =
- utils.lockScreenSceneInteractor(
+ authenticationInteractor = authenticationInteractor,
+ bouncerInteractor =
+ utils.bouncerInteractor(
authenticationInteractor = authenticationInteractor,
- bouncerInteractor =
- utils.bouncerInteractor(
- authenticationInteractor = authenticationInteractor,
- sceneInteractor = sceneInteractor,
- ),
+ sceneInteractor = sceneInteractor,
),
)
@@ -87,17 +84,18 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
}
@Test
- fun upTransitionSceneKey_swipeToUnlockedEnabled_gone() =
+ fun upTransitionSceneKey_swipeToUnlockEnabled_gone() =
testScope.runTest {
val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey)
- utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
+ utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.None)
+ utils.authenticationRepository.setLockscreenEnabled(true)
utils.authenticationRepository.setUnlocked(false)
assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Gone)
}
@Test
- fun upTransitionSceneKey_swipeToUnlockedNotEnabled_bouncer() =
+ fun upTransitionSceneKey_swipeToUnlockNotEnabled_bouncer() =
testScope.runTest {
val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
index ee42a7011264..bb365d05e9e2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
@@ -18,7 +18,7 @@ package com.android.systemui.qs.ui.viewmodel
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.authentication.data.model.AuthenticationMethodModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.shared.model.SceneKey
@@ -46,14 +46,10 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() {
private val underTest =
QuickSettingsSceneViewModel(
- lockscreenSceneInteractor =
- utils.lockScreenSceneInteractor(
+ bouncerInteractor =
+ utils.bouncerInteractor(
authenticationInteractor = authenticationInteractor,
- bouncerInteractor =
- utils.bouncerInteractor(
- authenticationInteractor = authenticationInteractor,
- sceneInteractor = sceneInteractor,
- ),
+ sceneInteractor = sceneInteractor,
),
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
index 6be19b99dd3b..bec0b77e6480 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
@@ -21,6 +21,7 @@ package com.android.systemui.scene.domain.startable
import android.view.Display
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.data.model.AuthenticationMethodModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.shared.model.WakeSleepReason
@@ -245,93 +246,110 @@ class SceneContainerStartableTest : SysuiTestCase() {
}
@Test
- fun switchToGoneWhenDeviceSleepsUnlocked_featureEnabled() =
+ fun switchToLockscreenWhenDeviceSleepsLocked_featureEnabled() =
testScope.runTest {
val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
prepareState(
isFeatureEnabled = true,
- isDeviceUnlocked = true,
+ isDeviceUnlocked = false,
initialSceneKey = SceneKey.Shade,
)
assertThat(currentSceneKey).isEqualTo(SceneKey.Shade)
underTest.start()
- keyguardRepository.setWakefulnessModel(ASLEEP)
+ keyguardRepository.setWakefulnessModel(STARTING_TO_SLEEP)
- assertThat(currentSceneKey).isEqualTo(SceneKey.Gone)
+ assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen)
}
@Test
- fun switchToGoneWhenDeviceSleepsUnlocked_featureDisabled() =
+ fun switchToLockscreenWhenDeviceSleepsLocked_featureDisabled() =
testScope.runTest {
val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
prepareState(
isFeatureEnabled = false,
- isDeviceUnlocked = true,
+ isDeviceUnlocked = false,
initialSceneKey = SceneKey.Shade,
)
assertThat(currentSceneKey).isEqualTo(SceneKey.Shade)
underTest.start()
- keyguardRepository.setWakefulnessModel(ASLEEP)
+ keyguardRepository.setWakefulnessModel(STARTING_TO_SLEEP)
assertThat(currentSceneKey).isEqualTo(SceneKey.Shade)
}
@Test
- fun switchToLockscreenWhenDeviceSleepsLocked_featureEnabled() =
+ fun hydrateSystemUiState() =
+ testScope.runTest {
+ underTest.start()
+ runCurrent()
+ clearInvocations(sysUiState)
+
+ listOf(
+ SceneKey.Gone,
+ SceneKey.Lockscreen,
+ SceneKey.Bouncer,
+ SceneKey.Shade,
+ SceneKey.QuickSettings,
+ )
+ .forEachIndexed { index, sceneKey ->
+ sceneInteractor.setCurrentScene(SceneModel(sceneKey), "reason")
+ runCurrent()
+
+ verify(sysUiState, times(index + 1)).commitUpdate(Display.DEFAULT_DISPLAY)
+ }
+ }
+
+ @Test
+ fun switchToGoneWhenDeviceStartsToWakeUp_authMethodNone_featureEnabled() =
testScope.runTest {
val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
prepareState(
isFeatureEnabled = true,
- isDeviceUnlocked = false,
- initialSceneKey = SceneKey.Shade,
+ initialSceneKey = SceneKey.Lockscreen,
+ authenticationMethod = AuthenticationMethodModel.None,
)
- assertThat(currentSceneKey).isEqualTo(SceneKey.Shade)
+ assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen)
underTest.start()
- keyguardRepository.setWakefulnessModel(ASLEEP)
+ keyguardRepository.setWakefulnessModel(STARTING_TO_WAKE)
- assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen)
+ assertThat(currentSceneKey).isEqualTo(SceneKey.Gone)
}
@Test
- fun switchToLockscreenWhenDeviceSleepsLocked_featureDisabled() =
+ fun switchToGoneWhenDeviceStartsToWakeUp_authMethodNotNone_featureEnabled() =
testScope.runTest {
val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
prepareState(
- isFeatureEnabled = false,
- isDeviceUnlocked = false,
- initialSceneKey = SceneKey.Shade,
+ isFeatureEnabled = true,
+ initialSceneKey = SceneKey.Lockscreen,
+ authenticationMethod = AuthenticationMethodModel.Pin,
)
- assertThat(currentSceneKey).isEqualTo(SceneKey.Shade)
+ assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen)
underTest.start()
- keyguardRepository.setWakefulnessModel(ASLEEP)
+ keyguardRepository.setWakefulnessModel(STARTING_TO_WAKE)
- assertThat(currentSceneKey).isEqualTo(SceneKey.Shade)
+ assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen)
}
@Test
- fun hydrateSystemUiState() =
+ fun switchToGoneWhenDeviceStartsToWakeUp_authMethodNone_featureDisabled() =
testScope.runTest {
+ val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
+ prepareState(
+ isFeatureEnabled = false,
+ initialSceneKey = SceneKey.Lockscreen,
+ authenticationMethod = AuthenticationMethodModel.None,
+ )
+ assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen)
underTest.start()
- runCurrent()
- clearInvocations(sysUiState)
- listOf(
- SceneKey.Gone,
- SceneKey.Lockscreen,
- SceneKey.Bouncer,
- SceneKey.Shade,
- SceneKey.QuickSettings,
- )
- .forEachIndexed { index, sceneKey ->
- sceneInteractor.setCurrentScene(SceneModel(sceneKey), "reason")
- runCurrent()
+ keyguardRepository.setWakefulnessModel(STARTING_TO_WAKE)
- verify(sysUiState, times(index + 1)).commitUpdate(Display.DEFAULT_DISPLAY)
- }
+ assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen)
}
private fun prepareState(
@@ -339,17 +357,30 @@ class SceneContainerStartableTest : SysuiTestCase() {
isDeviceUnlocked: Boolean = false,
isBypassEnabled: Boolean = false,
initialSceneKey: SceneKey? = null,
+ authenticationMethod: AuthenticationMethodModel? = null,
) {
featureFlags.set(Flags.SCENE_CONTAINER, isFeatureEnabled)
authenticationRepository.setUnlocked(isDeviceUnlocked)
keyguardRepository.setBypassEnabled(isBypassEnabled)
initialSceneKey?.let { sceneInteractor.setCurrentScene(SceneModel(it), "reason") }
+ authenticationMethod?.let {
+ authenticationRepository.setAuthenticationMethod(authenticationMethod)
+ authenticationRepository.setLockscreenEnabled(
+ authenticationMethod != AuthenticationMethodModel.None
+ )
+ }
}
companion object {
- private val ASLEEP =
+ private val STARTING_TO_SLEEP =
+ WakefulnessModel(
+ state = WakefulnessState.STARTING_TO_SLEEP,
+ lastWakeReason = WakeSleepReason.POWER_BUTTON,
+ lastSleepReason = WakeSleepReason.POWER_BUTTON
+ )
+ private val STARTING_TO_WAKE =
WakefulnessModel(
- state = WakefulnessState.ASLEEP,
+ state = WakefulnessState.STARTING_TO_WAKE,
lastWakeReason = WakeSleepReason.POWER_BUTTON,
lastSleepReason = WakeSleepReason.POWER_BUTTON
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index c3540cfec72d..981e44bea846 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -424,6 +424,10 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
when(mView.findViewById(R.id.qs_frame)).thenReturn(mQsFrame);
when(mView.findViewById(R.id.keyguard_status_view))
.thenReturn(mock(KeyguardStatusView.class));
+ View rootView = mock(View.class);
+ when(mView.getRootView()).thenReturn(rootView);
+ when(rootView.findViewById(R.id.keyguard_status_view))
+ .thenReturn(mock(KeyguardStatusView.class));
mNotificationContainerParent = new NotificationsQuickSettingsContainer(getContext(), null);
mNotificationContainerParent.addView(keyguardStatusView);
mNotificationContainerParent.onFinishInflate();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
index 8739b28c940e..d9301604c67f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
@@ -18,7 +18,7 @@ package com.android.systemui.shade.ui.viewmodel
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.authentication.data.model.AuthenticationMethodModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.shared.model.SceneKey
@@ -47,14 +47,11 @@ class ShadeSceneViewModelTest : SysuiTestCase() {
private val underTest =
ShadeSceneViewModel(
applicationScope = testScope.backgroundScope,
- lockscreenSceneInteractor =
- utils.lockScreenSceneInteractor(
+ authenticationInteractor = authenticationInteractor,
+ bouncerInteractor =
+ utils.bouncerInteractor(
authenticationInteractor = authenticationInteractor,
- bouncerInteractor =
- utils.bouncerInteractor(
- authenticationInteractor = authenticationInteractor,
- sceneInteractor = sceneInteractor,
- ),
+ sceneInteractor = sceneInteractor,
),
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt
index 6306a36d9730..50ee6a31d389 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt
@@ -55,6 +55,8 @@ class FakeMobileConnectionRepository(
override val networkName =
MutableStateFlow<NetworkNameModel>(NetworkNameModel.Default("default"))
+ override val isAllowedDuringAirplaneMode = MutableStateFlow(false)
+
fun setDataEnabled(enabled: Boolean) {
_dataEnabled.value = enabled
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt
index 441186acb6b7..a251c2850d41 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt
@@ -20,6 +20,7 @@ import android.telephony.TelephonyManager
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
@@ -319,6 +320,14 @@ class CarrierMergedConnectionRepositoryTest : SysuiTestCase() {
job.cancel()
}
+ @Test
+ fun isAllowedDuringAirplaneMode_alwaysTrue() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.isAllowedDuringAirplaneMode)
+
+ assertThat(latest).isTrue()
+ }
+
private companion object {
const val SUB_ID = 123
const val NET_ID = 456
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt
index b701fbd66937..3dd2eaff7bce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt
@@ -22,6 +22,7 @@ import android.telephony.TelephonyCallback
import android.telephony.TelephonyManager
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.log.table.TableLogBufferFactory
import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
@@ -84,7 +85,11 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() {
@Before
fun setUp() {
mobileRepo = FakeMobileConnectionRepository(SUB_ID, tableLogBuffer)
- carrierMergedRepo = FakeMobileConnectionRepository(SUB_ID, tableLogBuffer)
+ carrierMergedRepo =
+ FakeMobileConnectionRepository(SUB_ID, tableLogBuffer).apply {
+ // Mimicks the real carrier merged repository
+ this.isAllowedDuringAirplaneMode.value = true
+ }
whenever(
mobileFactory.build(
@@ -300,6 +305,24 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() {
}
@Test
+ fun isAllowedDuringAirplaneMode_updatesWhenCarrierMergedUpdates() =
+ testScope.runTest {
+ initializeRepo(startingIsCarrierMerged = false)
+
+ val latest by collectLastValue(underTest.isAllowedDuringAirplaneMode)
+
+ assertThat(latest).isFalse()
+
+ underTest.setIsCarrierMerged(true)
+
+ assertThat(latest).isTrue()
+
+ underTest.setIsCarrierMerged(false)
+
+ assertThat(latest).isFalse()
+ }
+
+ @Test
fun factory_reusesLogBuffersForSameConnection() =
testScope.runTest {
val realLoggerFactory =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
index cf832b4ab059..1ff737bfc137 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
@@ -53,6 +53,7 @@ import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
import androidx.test.filters.SmallTest
import com.android.settingslib.mobile.MobileMappings
import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.statusbar.pipeline.mobile.data.MobileInputLogger
import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
@@ -812,6 +813,14 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
job.cancel()
}
+ @Test
+ fun isAllowedDuringAirplaneMode_alwaysFalse() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.isAllowedDuringAirplaneMode)
+
+ assertThat(latest).isFalse()
+ }
+
private inline fun <reified T> getTelephonyCallbackForType(): T {
return MobileTelephonyHelpers.getTelephonyCallbackForType(telephonyManager)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
index c4e419366759..8d1da69d6877 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
@@ -77,6 +77,8 @@ class FakeMobileIconInteractor(
override val isForceHidden = MutableStateFlow(false)
+ override val isAllowedDuringAirplaneMode = MutableStateFlow(false)
+
fun setIsEmergencyOnly(emergency: Boolean) {
_isEmergencyOnly.value = emergency
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
index c2768654809b..58d3804b7155 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
@@ -23,6 +23,7 @@ import com.android.settingslib.mobile.MobileIconCarrierIdOverrides
import com.android.settingslib.mobile.MobileIconCarrierIdOverridesImpl
import com.android.settingslib.mobile.TelephonyIcons
import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.CarrierMergedNetworkType
@@ -473,6 +474,18 @@ class MobileIconInteractorTest : SysuiTestCase() {
job.cancel()
}
+ @Test
+ fun isAllowedDuringAirplaneMode_matchesRepo() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.isAllowedDuringAirplaneMode)
+
+ connectionRepository.isAllowedDuringAirplaneMode.value = true
+ assertThat(latest).isTrue()
+
+ connectionRepository.isAllowedDuringAirplaneMode.value = false
+ assertThat(latest).isFalse()
+ }
+
private fun createInteractor(
overrides: MobileIconCarrierIdOverrides = MobileIconCarrierIdOverridesImpl()
) =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
index b5ab29d6217e..72feec78a979 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
@@ -116,12 +116,13 @@ class MobileIconViewModelTest : SysuiTestCase() {
}
@Test
- fun isVisible_airplane_false() =
+ fun isVisible_airplaneAndNotAllowed_false() =
testScope.runTest {
var latest: Boolean? = null
val job = underTest.isVisible.onEach { latest = it }.launchIn(this)
airplaneModeRepository.setIsAirplaneMode(true)
+ interactor.isAllowedDuringAirplaneMode.value = false
interactor.isForceHidden.value = false
assertThat(latest).isFalse()
@@ -129,6 +130,22 @@ class MobileIconViewModelTest : SysuiTestCase() {
job.cancel()
}
+ /** Regression test for b/291993542. */
+ @Test
+ fun isVisible_airplaneButAllowed_true() =
+ testScope.runTest {
+ var latest: Boolean? = null
+ val job = underTest.isVisible.onEach { latest = it }.launchIn(this)
+
+ airplaneModeRepository.setIsAirplaneMode(true)
+ interactor.isAllowedDuringAirplaneMode.value = true
+ interactor.isForceHidden.value = false
+
+ assertThat(latest).isTrue()
+
+ job.cancel()
+ }
+
@Test
fun isVisible_forceHidden_false() =
testScope.runTest {
@@ -157,7 +174,7 @@ class MobileIconViewModelTest : SysuiTestCase() {
airplaneModeRepository.setIsAirplaneMode(true)
assertThat(latest).isFalse()
- airplaneModeRepository.setIsAirplaneMode(false)
+ interactor.isAllowedDuringAirplaneMode.value = true
assertThat(latest).isTrue()
interactor.isForceHidden.value = true
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt
index c2e1ac70af80..7c98df6c6317 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt
@@ -20,7 +20,8 @@ import com.android.internal.widget.LockPatternUtils
import com.android.internal.widget.LockPatternView
import com.android.internal.widget.LockscreenCredential
import com.android.keyguard.KeyguardSecurityModel.SecurityMode
-import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.authentication.data.model.AuthenticationMethodModel
+import com.android.systemui.authentication.shared.model.AuthenticationPatternCoordinate
import com.android.systemui.authentication.shared.model.AuthenticationResultModel
import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel
import kotlinx.coroutines.flow.MutableStateFlow
@@ -47,7 +48,7 @@ class FakeAuthenticationRepository(
private val _authenticationMethod =
MutableStateFlow<AuthenticationMethodModel>(DEFAULT_AUTHENTICATION_METHOD)
- val authenticationMethod: StateFlow<AuthenticationMethodModel> =
+ override val authenticationMethod: StateFlow<AuthenticationMethodModel> =
_authenticationMethod.asStateFlow()
private var isLockscreenEnabled = true
@@ -154,13 +155,13 @@ class FakeAuthenticationRepository(
val DEFAULT_AUTHENTICATION_METHOD = AuthenticationMethodModel.Pin
val PATTERN =
listOf(
- AuthenticationMethodModel.Pattern.PatternCoordinate(2, 0),
- AuthenticationMethodModel.Pattern.PatternCoordinate(2, 1),
- AuthenticationMethodModel.Pattern.PatternCoordinate(2, 2),
- AuthenticationMethodModel.Pattern.PatternCoordinate(1, 1),
- AuthenticationMethodModel.Pattern.PatternCoordinate(0, 0),
- AuthenticationMethodModel.Pattern.PatternCoordinate(0, 1),
- AuthenticationMethodModel.Pattern.PatternCoordinate(0, 2),
+ AuthenticationPatternCoordinate(2, 0),
+ AuthenticationPatternCoordinate(2, 1),
+ AuthenticationPatternCoordinate(2, 2),
+ AuthenticationPatternCoordinate(1, 1),
+ AuthenticationPatternCoordinate(0, 0),
+ AuthenticationPatternCoordinate(0, 1),
+ AuthenticationPatternCoordinate(0, 2),
)
const val MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING = 5
const val THROTTLE_DURATION_MS = 30000
@@ -172,7 +173,6 @@ class FakeAuthenticationRepository(
is AuthenticationMethodModel.Pin -> SecurityMode.PIN
is AuthenticationMethodModel.Password -> SecurityMode.Password
is AuthenticationMethodModel.Pattern -> SecurityMode.Pattern
- is AuthenticationMethodModel.Swipe,
is AuthenticationMethodModel.None -> SecurityMode.None
}
}
@@ -208,8 +208,7 @@ class FakeAuthenticationRepository(
}
}
- private fun List<AuthenticationMethodModel.Pattern.PatternCoordinate>.toCells():
- List<LockPatternView.Cell> {
+ private fun List<AuthenticationPatternCoordinate>.toCells(): List<LockPatternView.Cell> {
return map { coordinate -> LockPatternView.Cell.of(coordinate.y, coordinate.x) }
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
index 15ce055bcc63..faebcaac1be3 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
@@ -146,7 +146,6 @@ class FakeKeyguardRepository : KeyguardRepository {
_animateBottomAreaDozingTransitions.tryEmit(animate)
}
-
@Deprecated("Deprecated as part of b/278057014")
override fun setBottomAreaAlpha(alpha: Float) {
_bottomAreaAlpha.value = alpha
@@ -257,8 +256,11 @@ class FakeKeyguardRepository : KeyguardRepository {
goingToFullShade: Boolean,
occlusionTransitionRunning: Boolean
) {
- _keyguardRootViewVisibility.value = KeyguardRootViewVisibilityState(
- statusBarState, goingToFullShade, occlusionTransitionRunning
- )
+ _keyguardRootViewVisibility.value =
+ KeyguardRootViewVisibilityState(
+ statusBarState,
+ goingToFullShade,
+ occlusionTransitionRunning
+ )
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt
index 6cffb669d466..62087df8c238 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt
@@ -32,7 +32,6 @@ import com.android.systemui.keyguard.data.repository.FakeCommandQueue
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
-import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
import com.android.systemui.keyguard.shared.model.WakeSleepReason
import com.android.systemui.keyguard.shared.model.WakefulnessModel
import com.android.systemui.keyguard.shared.model.WakefulnessState
@@ -176,23 +175,14 @@ class SceneTestUtils(
fun bouncerViewModel(
bouncerInteractor: BouncerInteractor,
+ authenticationInteractor: AuthenticationInteractor,
): BouncerViewModel {
return BouncerViewModel(
applicationContext = context,
applicationScope = applicationScope(),
- interactor = bouncerInteractor,
- featureFlags = featureFlags,
- )
- }
-
- fun lockScreenSceneInteractor(
- authenticationInteractor: AuthenticationInteractor,
- bouncerInteractor: BouncerInteractor,
- ): LockscreenSceneInteractor {
- return LockscreenSceneInteractor(
- applicationScope = applicationScope(),
- authenticationInteractor = authenticationInteractor,
bouncerInteractor = bouncerInteractor,
+ authenticationInteractor = authenticationInteractor,
+ featureFlags = featureFlags,
)
}
diff --git a/services/core/java/com/android/server/am/TEST_MAPPING b/services/core/java/com/android/server/am/TEST_MAPPING
index 0af9b2b4c26a..08a2c8561bd7 100644
--- a/services/core/java/com/android/server/am/TEST_MAPPING
+++ b/services/core/java/com/android/server/am/TEST_MAPPING
@@ -88,11 +88,14 @@
"file_patterns": ["Battery[^/]*\\.java", "MeasuredEnergy[^/]*\\.java"],
"name": "FrameworksServicesTests",
"options": [
- { "include-filter": "com.android.server.am.BatteryStatsServiceTest" },
- { "include-filter": "com.android.server.power.stats.BatteryStatsTests" }
+ { "include-filter": "com.android.server.am.BatteryStatsServiceTest" }
]
},
{
+ "file_patterns": ["Battery[^/]*\\.java", "MeasuredEnergy[^/]*\\.java"],
+ "name": "PowerStatsTests"
+ },
+ {
"file_patterns": ["Broadcast.*"],
"name": "FrameworksMockingServicesTests",
"options": [
diff --git a/services/core/java/com/android/server/audio/AdiDeviceState.java b/services/core/java/com/android/server/audio/AdiDeviceState.java
index 683b3eb7a92e..247094f2f796 100644
--- a/services/core/java/com/android/server/audio/AdiDeviceState.java
+++ b/services/core/java/com/android/server/audio/AdiDeviceState.java
@@ -16,6 +16,7 @@
package com.android.server.audio;
+import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_UNKNOWN;
import static android.media.AudioSystem.DEVICE_NONE;
import static android.media.AudioSystem.isBluetoothDevice;
@@ -23,8 +24,10 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.media.AudioDeviceAttributes;
import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Pair;
import java.util.Objects;
@@ -41,8 +44,16 @@ import java.util.Objects;
private final int mDeviceType;
private final int mInternalDeviceType;
+
@NonNull
private final String mDeviceAddress;
+
+ /** Unique device id from internal device type and address. */
+ private final Pair<Integer, String> mDeviceId;
+
+ @AudioManager.AudioDeviceCategory
+ private int mAudioDeviceCategory = AUDIO_DEVICE_CATEGORY_UNKNOWN;
+
private boolean mSAEnabled;
private boolean mHasHeadTracker = false;
private boolean mHeadTrackerEnabled;
@@ -68,6 +79,12 @@ import java.util.Objects;
}
mDeviceAddress = isBluetoothDevice(mInternalDeviceType) ? Objects.requireNonNull(
address) : "";
+
+ mDeviceId = new Pair<>(mInternalDeviceType, mDeviceAddress);
+ }
+
+ public Pair<Integer, String> getDeviceId() {
+ return mDeviceId;
}
@AudioDeviceInfo.AudioDeviceType
@@ -109,6 +126,15 @@ import java.util.Objects;
return mHasHeadTracker;
}
+ @AudioDeviceInfo.AudioDeviceType
+ public int getAudioDeviceCategory() {
+ return mAudioDeviceCategory;
+ }
+
+ public void setAudioDeviceCategory(@AudioDeviceInfo.AudioDeviceType int audioDeviceCategory) {
+ mAudioDeviceCategory = audioDeviceCategory;
+ }
+
@Override
public boolean equals(Object obj) {
if (this == obj) {
@@ -127,20 +153,23 @@ import java.util.Objects;
&& mDeviceAddress.equals(sads.mDeviceAddress) // NonNull
&& mSAEnabled == sads.mSAEnabled
&& mHasHeadTracker == sads.mHasHeadTracker
- && mHeadTrackerEnabled == sads.mHeadTrackerEnabled;
+ && mHeadTrackerEnabled == sads.mHeadTrackerEnabled
+ && mAudioDeviceCategory == sads.mAudioDeviceCategory;
}
@Override
public int hashCode() {
return Objects.hash(mDeviceType, mInternalDeviceType, mDeviceAddress, mSAEnabled,
- mHasHeadTracker, mHeadTrackerEnabled);
+ mHasHeadTracker, mHeadTrackerEnabled, mAudioDeviceCategory);
}
@Override
public String toString() {
return "type: " + mDeviceType + "internal type: " + mInternalDeviceType
- + " addr: " + mDeviceAddress + " enabled: " + mSAEnabled
- + " HT: " + mHasHeadTracker + " HTenabled: " + mHeadTrackerEnabled;
+ + " addr: " + mDeviceAddress + " bt audio type: "
+ + AudioManager.audioDeviceCategoryToString(mAudioDeviceCategory)
+ + " enabled: " + mSAEnabled + " HT: " + mHasHeadTracker
+ + " HTenabled: " + mHeadTrackerEnabled;
}
public String toPersistableString() {
@@ -150,6 +179,7 @@ import java.util.Objects;
.append(SETTING_FIELD_SEPARATOR).append(mHasHeadTracker ? "1" : "0")
.append(SETTING_FIELD_SEPARATOR).append(mHeadTrackerEnabled ? "1" : "0")
.append(SETTING_FIELD_SEPARATOR).append(mInternalDeviceType)
+ .append(SETTING_FIELD_SEPARATOR).append(mAudioDeviceCategory)
.toString());
}
@@ -174,21 +204,27 @@ import java.util.Objects;
String[] fields = TextUtils.split(persistedString, SETTING_FIELD_SEPARATOR);
// we may have 5 fields for the legacy AdiDeviceState and 6 containing the internal
// device type
- if (fields.length != 5 && fields.length != 6) {
- // expecting all fields, fewer may mean corruption, ignore those settings
+ if (fields.length < 5 || fields.length > 7) {
+ // different number of fields may mean corruption, ignore those settings
+ // newly added fields are optional (mInternalDeviceType, mBtAudioDeviceCategory)
return null;
}
try {
final int deviceType = Integer.parseInt(fields[0]);
int internalDeviceType = -1;
- if (fields.length == 6) {
+ if (fields.length >= 6) {
internalDeviceType = Integer.parseInt(fields[5]);
}
+ int audioDeviceCategory = AUDIO_DEVICE_CATEGORY_UNKNOWN;
+ if (fields.length == 7) {
+ audioDeviceCategory = Integer.parseInt(fields[6]);
+ }
final AdiDeviceState deviceState = new AdiDeviceState(deviceType,
internalDeviceType, fields[1]);
deviceState.setHasHeadTracker(Integer.parseInt(fields[2]) == 1);
deviceState.setHasHeadTracker(Integer.parseInt(fields[3]) == 1);
deviceState.setHeadTrackerEnabled(Integer.parseInt(fields[4]) == 1);
+ deviceState.setAudioDeviceCategory(audioDeviceCategory);
return deviceState;
} catch (NumberFormatException e) {
Log.e(TAG, "unable to parse setting for AdiDeviceState: " + persistedString, e);
@@ -200,5 +236,4 @@ import java.util.Objects;
return new AudioDeviceAttributes(AudioDeviceAttributes.ROLE_OUTPUT,
mDeviceType, mDeviceAddress);
}
-
}
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 946f01688e66..af8aa9167217 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -63,6 +63,7 @@ import com.android.server.utils.EventLogger;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
@@ -2493,13 +2494,13 @@ public class AudioDeviceBroker {
void onPersistAudioDeviceSettings() {
final String deviceSettings = mDeviceInventory.getDeviceSettings();
- Log.v(TAG, "saving audio device settings: " + deviceSettings);
+ Log.v(TAG, "saving AdiDeviceState: " + deviceSettings);
final SettingsAdapter settings = mAudioService.getSettings();
boolean res = settings.putSecureStringForUser(mAudioService.getContentResolver(),
Settings.Secure.AUDIO_DEVICE_INVENTORY,
deviceSettings, UserHandle.USER_CURRENT);
if (!res) {
- Log.e(TAG, "error saving audio device settings: " + deviceSettings);
+ Log.e(TAG, "error saving AdiDeviceState: " + deviceSettings);
}
}
@@ -2509,7 +2510,7 @@ public class AudioDeviceBroker {
String settings = settingsAdapter.getSecureStringForUser(contentResolver,
Settings.Secure.AUDIO_DEVICE_INVENTORY, UserHandle.USER_CURRENT);
if (settings == null) {
- Log.i(TAG, "reading spatial audio device settings from legacy key"
+ Log.i(TAG, "reading AdiDeviceState from legacy key"
+ Settings.Secure.SPATIAL_AUDIO_ENABLED);
// legacy string format for key SPATIAL_AUDIO_ENABLED has the same order of fields like
// the strings for key AUDIO_DEVICE_INVENTORY. This will ensure to construct valid
@@ -2517,21 +2518,21 @@ public class AudioDeviceBroker {
settings = settingsAdapter.getSecureStringForUser(contentResolver,
Settings.Secure.SPATIAL_AUDIO_ENABLED, UserHandle.USER_CURRENT);
if (settings == null) {
- Log.i(TAG, "no spatial audio device settings stored with legacy key");
+ Log.i(TAG, "no AdiDeviceState stored with legacy key");
} else if (!settings.equals("")) {
// Delete old key value and update the new key
if (!settingsAdapter.putSecureStringForUser(contentResolver,
Settings.Secure.SPATIAL_AUDIO_ENABLED,
/*value=*/"",
UserHandle.USER_CURRENT)) {
- Log.w(TAG, "cannot erase the legacy audio device settings with key "
+ Log.w(TAG, "cannot erase the legacy AdiDeviceState with key "
+ Settings.Secure.SPATIAL_AUDIO_ENABLED);
}
if (!settingsAdapter.putSecureStringForUser(contentResolver,
Settings.Secure.AUDIO_DEVICE_INVENTORY,
settings,
UserHandle.USER_CURRENT)) {
- Log.e(TAG, "error updating the new audio device settings with key "
+ Log.e(TAG, "error updating the new AdiDeviceState with key "
+ Settings.Secure.AUDIO_DEVICE_INVENTORY);
}
}
@@ -2551,19 +2552,29 @@ public class AudioDeviceBroker {
return mDeviceInventory.getDeviceSettings();
}
- List<AdiDeviceState> getImmutableDeviceInventory() {
+ Collection<AdiDeviceState> getImmutableDeviceInventory() {
return mDeviceInventory.getImmutableDeviceInventory();
}
- void addDeviceStateToInventory(AdiDeviceState deviceState) {
- mDeviceInventory.addDeviceStateToInventory(deviceState);
+ void addOrUpdateDeviceSAStateInInventory(AdiDeviceState deviceState) {
+ mDeviceInventory.addOrUpdateDeviceSAStateInInventory(deviceState);
}
+ void addOrUpdateBtAudioDeviceCategoryInInventory(AdiDeviceState deviceState) {
+ mDeviceInventory.addOrUpdateAudioDeviceCategoryInInventory(deviceState);
+ }
+
+ @Nullable
AdiDeviceState findDeviceStateForAudioDeviceAttributes(AudioDeviceAttributes ada,
int canonicalType) {
return mDeviceInventory.findDeviceStateForAudioDeviceAttributes(ada, canonicalType);
}
+ @Nullable
+ AdiDeviceState findBtDeviceStateForAddress(String address, boolean isBle) {
+ return mDeviceInventory.findBtDeviceStateForAddress(address, isBle);
+ }
+
//------------------------------------------------
// for testing purposes only
void clearDeviceInventory() {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index f5b7ecf5daf4..5a92cb464950 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -15,6 +15,8 @@
*/
package com.android.server.audio;
+import static android.media.AudioSystem.DEVICE_OUT_ALL_A2DP_SET;
+import static android.media.AudioSystem.DEVICE_OUT_ALL_BLE_SET;
import static android.media.AudioSystem.isBluetoothDevice;
import android.annotation.NonNull;
@@ -61,11 +63,13 @@ import com.google.android.collect.Sets;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
-import java.util.Map;
+import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
@@ -90,35 +94,95 @@ public class AudioDeviceInventory {
private static final String mMetricsId = "audio.device.";
private final Object mDeviceInventoryLock = new Object();
- @GuardedBy("mDeviceCatalogLock")
- private final ArrayList<AdiDeviceState> mDeviceInventory = new ArrayList<>(0);
- List<AdiDeviceState> getImmutableDeviceInventory() {
+
+ @GuardedBy("mDeviceInventoryLock")
+ private final HashMap<Pair<Integer, String>, AdiDeviceState> mDeviceInventory = new HashMap<>();
+
+ Collection<AdiDeviceState> getImmutableDeviceInventory() {
+ synchronized (mDeviceInventoryLock) {
+ return mDeviceInventory.values();
+ }
+ }
+
+ /**
+ * Adds a new AdiDeviceState or updates the spatial audio related properties of the matching
+ * AdiDeviceState in the {@link AudioDeviceInventory#mDeviceInventory} list.
+ * @param deviceState the device to update
+ */
+ void addOrUpdateDeviceSAStateInInventory(AdiDeviceState deviceState) {
+ synchronized (mDeviceInventoryLock) {
+ mDeviceInventory.merge(deviceState.getDeviceId(), deviceState, (oldState, newState) -> {
+ oldState.setHasHeadTracker(newState.hasHeadTracker());
+ oldState.setHeadTrackerEnabled(newState.isHeadTrackerEnabled());
+ oldState.setSAEnabled(newState.isSAEnabled());
+ return oldState;
+ });
+ }
+ }
+
+ /**
+ * Adds a new AdiDeviceState or updates the audio device cateogory of the matching
+ * AdiDeviceState in the {@link AudioDeviceInventory#mDeviceInventory} list.
+ * @param deviceState the device to update
+ */
+ void addOrUpdateAudioDeviceCategoryInInventory(AdiDeviceState deviceState) {
synchronized (mDeviceInventoryLock) {
- return List.copyOf(mDeviceInventory);
+ mDeviceInventory.merge(deviceState.getDeviceId(), deviceState, (oldState, newState) -> {
+ oldState.setAudioDeviceCategory(newState.getAudioDeviceCategory());
+ return oldState;
+ });
}
}
- void addDeviceStateToInventory(AdiDeviceState deviceState) {
+ /**
+ * Finds the BT device that matches the passed {@code address}. Currently, this method only
+ * returns a valid device for A2DP and BLE devices.
+ *
+ * @param address MAC address of BT device
+ * @param isBle true if the device is BLE, false for A2DP
+ * @return the found {@link AdiDeviceState} or {@code null} otherwise.
+ */
+ @Nullable
+ AdiDeviceState findBtDeviceStateForAddress(String address, boolean isBle) {
synchronized (mDeviceInventoryLock) {
- mDeviceInventory.add(deviceState);
+ final Set<Integer> deviceSet = isBle ? DEVICE_OUT_ALL_BLE_SET : DEVICE_OUT_ALL_A2DP_SET;
+ for (Integer internalType : deviceSet) {
+ AdiDeviceState deviceState = mDeviceInventory.get(
+ new Pair<>(internalType, address));
+ if (deviceState != null) {
+ return deviceState;
+ }
+ }
}
+ return null;
}
+ /**
+ * Finds the device state that matches the passed {@link AudioDeviceAttributes} and device
+ * type. Note: currently this method only returns a valid device for A2DP and BLE devices.
+ *
+ * @param ada attributes of device to match
+ * @param canonicalDeviceType external device type to match
+ * @return the found {@link AdiDeviceState} matching a cached A2DP or BLE device or
+ * {@code null} otherwise.
+ */
+ @Nullable
AdiDeviceState findDeviceStateForAudioDeviceAttributes(AudioDeviceAttributes ada,
int canonicalDeviceType) {
final boolean isWireless = isBluetoothDevice(ada.getInternalType());
synchronized (mDeviceInventoryLock) {
- for (AdiDeviceState deviceSetting : mDeviceInventory) {
- if (deviceSetting.getDeviceType() == canonicalDeviceType
+ for (AdiDeviceState deviceState : mDeviceInventory.values()) {
+ if (deviceState.getDeviceType() == canonicalDeviceType
&& (!isWireless || ada.getAddress().equals(
- deviceSetting.getDeviceAddress()))) {
- return deviceSetting;
+ deviceState.getDeviceAddress()))) {
+ return deviceState;
}
}
}
return null;
}
+ /** Clears all cached {@link AdiDeviceState}'s. */
void clearDeviceInventory() {
synchronized (mDeviceInventoryLock) {
mDeviceInventory.clear();
@@ -384,7 +448,7 @@ public class AudioDeviceInventory {
+ " role:" + key.second + " devices:" + devices); });
pw.println("\ndevices:\n");
synchronized (mDeviceInventoryLock) {
- for (AdiDeviceState device : mDeviceInventory) {
+ for (AdiDeviceState device : mDeviceInventory.values()) {
pw.println("\t" + device + "\n");
}
}
@@ -1232,11 +1296,11 @@ public class AudioDeviceInventory {
AudioDeviceInfo[] connectedDevices = AudioManager.getDevicesStatic(
AudioManager.GET_DEVICES_ALL);
- Iterator<Map.Entry<Pair<Integer, Integer>, List<AudioDeviceAttributes>>> itRole =
+ Iterator<Entry<Pair<Integer, Integer>, List<AudioDeviceAttributes>>> itRole =
rolesMap.entrySet().iterator();
while (itRole.hasNext()) {
- Map.Entry<Pair<Integer, Integer>, List<AudioDeviceAttributes>> entry =
+ Entry<Pair<Integer, Integer>, List<AudioDeviceAttributes>> entry =
itRole.next();
Pair<Integer, Integer> keyRole = entry.getKey();
Iterator<AudioDeviceAttributes> itDev = rolesMap.get(keyRole).iterator();
@@ -2423,19 +2487,20 @@ public class AudioDeviceInventory {
int deviceCatalogSize = 0;
synchronized (mDeviceInventoryLock) {
deviceCatalogSize = mDeviceInventory.size();
- }
- final StringBuilder settingsBuilder = new StringBuilder(
- deviceCatalogSize * AdiDeviceState.getPeristedMaxSize());
- synchronized (mDeviceInventoryLock) {
- for (int i = 0; i < mDeviceInventory.size(); i++) {
- settingsBuilder.append(mDeviceInventory.get(i).toPersistableString());
- if (i != mDeviceInventory.size() - 1) {
- settingsBuilder.append(SETTING_DEVICE_SEPARATOR_CHAR);
- }
+ final StringBuilder settingsBuilder = new StringBuilder(
+ deviceCatalogSize * AdiDeviceState.getPeristedMaxSize());
+
+ Iterator<AdiDeviceState> iterator = mDeviceInventory.values().iterator();
+ if (iterator.hasNext()) {
+ settingsBuilder.append(iterator.next().toPersistableString());
+ }
+ while (iterator.hasNext()) {
+ settingsBuilder.append(SETTING_DEVICE_SEPARATOR_CHAR);
+ settingsBuilder.append(iterator.next().toPersistableString());
}
+ return settingsBuilder.toString();
}
- return settingsBuilder.toString();
}
/*package*/ void setDeviceSettings(String settings) {
@@ -2448,7 +2513,8 @@ public class AudioDeviceInventory {
// Note if the device is not compatible with spatialization mode or the device
// type is not canonical, it will be ignored in {@link SpatializerHelper}.
if (devState != null) {
- addDeviceStateToInventory(devState);
+ addOrUpdateDeviceSAStateInInventory(devState);
+ addOrUpdateAudioDeviceCategoryInInventory(devState);
}
}
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 3353b9ec538f..76c4cfe929bb 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -18,6 +18,14 @@ package com.android.server.audio;
import static android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED;
import static android.app.BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT;
+import static android.media.AudioDeviceInfo.TYPE_BLE_HEADSET;
+import static android.media.AudioDeviceInfo.TYPE_BLE_SPEAKER;
+import static android.media.AudioDeviceInfo.TYPE_BLUETOOTH_A2DP;
+import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_HEADPHONES;
+import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_UNKNOWN;
+import static android.media.AudioManager.DEVICE_OUT_BLE_HEADSET;
+import static android.media.AudioManager.DEVICE_OUT_BLE_SPEAKER;
+import static android.media.AudioManager.DEVICE_OUT_BLUETOOTH_A2DP;
import static android.media.AudioManager.RINGER_MODE_NORMAL;
import static android.media.AudioManager.RINGER_MODE_SILENT;
import static android.media.AudioManager.RINGER_MODE_VIBRATE;
@@ -92,6 +100,7 @@ import android.media.AudioFocusRequest;
import android.media.AudioFormat;
import android.media.AudioHalVersionInfo;
import android.media.AudioManager;
+import android.media.AudioManager.AudioDeviceCategory;
import android.media.AudioManagerInternal;
import android.media.AudioMixerAttributes;
import android.media.AudioPlaybackConfiguration;
@@ -405,6 +414,7 @@ public class AudioService extends IAudioService.Stub
private static final int MSG_DISABLE_AUDIO_FOR_UID = 100;
private static final int MSG_INIT_STREAMS_VOLUMES = 101;
private static final int MSG_INIT_SPATIALIZER = 102;
+ private static final int MSG_INIT_ADI_DEVICE_STATES = 103;
// end of messages handled under wakelock
@@ -1286,6 +1296,8 @@ public class AudioService extends IAudioService.Stub
// done with service initialization, continue additional work in our Handler thread
queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_STREAMS_VOLUMES,
0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */);
+ queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_ADI_DEVICE_STATES,
+ 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */);
queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_SPATIALIZER,
0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */);
@@ -7377,7 +7389,7 @@ public class AudioService extends IAudioService.Stub
if (pkgName == null) {
pkgName = "";
}
- if (device.getType() == AudioDeviceInfo.TYPE_BLUETOOTH_A2DP) {
+ if (device.getType() == TYPE_BLUETOOTH_A2DP) {
avrcpSupportsAbsoluteVolume(device.getAddress(),
deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
return;
@@ -9253,6 +9265,11 @@ public class AudioService extends IAudioService.Stub
mAudioEventWakeLock.release();
break;
+ case MSG_INIT_ADI_DEVICE_STATES:
+ onInitAdiDeviceStates();
+ mAudioEventWakeLock.release();
+ break;
+
case MSG_INIT_SPATIALIZER:
onInitSpatializer();
mAudioEventWakeLock.release();
@@ -10322,8 +10339,13 @@ public class AudioService extends IAudioService.Stub
/*arg1*/ 0, /*arg2*/ 0, TAG, /*delay*/ 0);
}
- void onInitSpatializer() {
+ void onInitAdiDeviceStates() {
mDeviceBroker.onReadAudioDeviceSettings();
+ mSoundDoseHelper.initCachedAudioDeviceCategories(
+ mDeviceBroker.getImmutableDeviceInventory());
+ }
+
+ void onInitSpatializer() {
mSpatializerHelper.init(/*effectExpected*/ mHasSpatializerEffect);
mSpatializerHelper.setFeatureEnabled(mHasSpatializerEffect);
}
@@ -10718,6 +10740,51 @@ public class AudioService extends IAudioService.Stub
return mSoundDoseHelper.isCsdEnabled();
}
+ @Override
+ @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+ public void setBluetoothAudioDeviceCategory(@NonNull String address, boolean isBle,
+ @AudioDeviceCategory int btAudioDeviceCategory) {
+ super.setBluetoothAudioDeviceCategory_enforcePermission();
+
+ final String addr = Objects.requireNonNull(address);
+
+ AdiDeviceState deviceState = mDeviceBroker.findBtDeviceStateForAddress(addr, isBle);
+
+ int internalType = !isBle ? DEVICE_OUT_BLUETOOTH_A2DP
+ : ((btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES)
+ ? DEVICE_OUT_BLE_HEADSET : DEVICE_OUT_BLE_SPEAKER);
+ int deviceType = !isBle ? TYPE_BLUETOOTH_A2DP
+ : ((btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES) ? TYPE_BLE_HEADSET
+ : TYPE_BLE_SPEAKER);
+
+ if (deviceState == null) {
+ deviceState = new AdiDeviceState(deviceType, internalType, addr);
+ }
+
+ deviceState.setAudioDeviceCategory(btAudioDeviceCategory);
+
+ mDeviceBroker.addOrUpdateBtAudioDeviceCategoryInInventory(deviceState);
+ mDeviceBroker.persistAudioDeviceSettings();
+
+ mSoundDoseHelper.setAudioDeviceCategory(addr, internalType,
+ btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES);
+ }
+
+ @Override
+ @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+ @AudioDeviceCategory
+ public int getBluetoothAudioDeviceCategory(@NonNull String address, boolean isBle) {
+ super.getBluetoothAudioDeviceCategory_enforcePermission();
+
+ final AdiDeviceState deviceState = mDeviceBroker.findBtDeviceStateForAddress(
+ Objects.requireNonNull(address), isBle);
+ if (deviceState == null) {
+ return AUDIO_DEVICE_CATEGORY_UNKNOWN;
+ }
+
+ return deviceState.getAudioDeviceCategory();
+ }
+
//==========================================================================================
// Hdmi CEC:
// - System audio mode:
diff --git a/services/core/java/com/android/server/audio/SoundDoseHelper.java b/services/core/java/com/android/server/audio/SoundDoseHelper.java
index 01af3a838597..851c5c3cb73c 100644
--- a/services/core/java/com/android/server/audio/SoundDoseHelper.java
+++ b/services/core/java/com/android/server/audio/SoundDoseHelper.java
@@ -16,6 +16,9 @@
package com.android.server.audio;
+import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_HEADPHONES;
+import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_UNKNOWN;
+
import static com.android.server.audio.AudioService.MAX_STREAM_VOLUME;
import static com.android.server.audio.AudioService.MIN_STREAM_VOLUME;
import static com.android.server.audio.AudioService.MSG_SET_DEVICE_VOLUME;
@@ -57,6 +60,7 @@ import com.android.server.utils.EventLogger;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -189,6 +193,9 @@ public class SoundDoseHelper {
private final AtomicBoolean mEnableCsd = new AtomicBoolean(false);
+ private ArrayList<ISoundDose.AudioDeviceCategory> mCachedAudioDeviceCategories =
+ new ArrayList<>();
+
private final Object mCsdStateLock = new Object();
private final AtomicReference<ISoundDose> mSoundDose = new AtomicReference<>();
@@ -487,6 +494,43 @@ public class SoundDoseHelper {
return false;
}
+ void setAudioDeviceCategory(String address, int internalAudioType, boolean isHeadphone) {
+ if (!mEnableCsd.get()) {
+ return;
+ }
+
+ final ISoundDose soundDose = mSoundDose.get();
+ if (soundDose == null) {
+ Log.w(TAG, "Sound dose interface not initialized");
+ return;
+ }
+
+ try {
+ final ISoundDose.AudioDeviceCategory audioDeviceCategory =
+ new ISoundDose.AudioDeviceCategory();
+ audioDeviceCategory.address = address;
+ audioDeviceCategory.internalAudioType = internalAudioType;
+ audioDeviceCategory.csdCompatible = isHeadphone;
+ soundDose.setAudioDeviceCategory(audioDeviceCategory);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception while forcing the internal MEL computation", e);
+ }
+ }
+
+ void initCachedAudioDeviceCategories(Collection<AdiDeviceState> deviceStates) {
+ for (final AdiDeviceState state : deviceStates) {
+ if (state.getAudioDeviceCategory() != AUDIO_DEVICE_CATEGORY_UNKNOWN) {
+ final ISoundDose.AudioDeviceCategory audioDeviceCategory =
+ new ISoundDose.AudioDeviceCategory();
+ audioDeviceCategory.address = state.getDeviceAddress();
+ audioDeviceCategory.internalAudioType = state.getInternalDeviceType();
+ audioDeviceCategory.csdCompatible =
+ state.getAudioDeviceCategory() == AUDIO_DEVICE_CATEGORY_HEADPHONES;
+ mCachedAudioDeviceCategories.add(audioDeviceCategory);
+ }
+ }
+ }
+
/*package*/ int safeMediaVolumeIndex(int device) {
final int vol = mSafeMediaVolumeDevices.get(device);
if (vol == SAFE_MEDIA_VOLUME_UNINITIALIZED) {
@@ -810,6 +854,16 @@ public class SoundDoseHelper {
Log.v(TAG, "Initializing sound dose");
+ try {
+ if (mCachedAudioDeviceCategories.size() > 0) {
+ soundDose.initCachedAudioDeviceCategories(mCachedAudioDeviceCategories.toArray(
+ new ISoundDose.AudioDeviceCategory[0]));
+ mCachedAudioDeviceCategories.clear();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception while forcing the internal MEL computation", e);
+ }
+
synchronized (mCsdStateLock) {
if (mGlobalTimeOffsetInSecs == GLOBAL_TIME_OFFSET_UNINITIALIZED) {
mGlobalTimeOffsetInSecs = System.currentTimeMillis() / 1000L;
diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java
index 969dd60a8012..496bdf48b5bf 100644
--- a/services/core/java/com/android/server/audio/SpatializerHelper.java
+++ b/services/core/java/com/android/server/audio/SpatializerHelper.java
@@ -560,7 +560,7 @@ public class SpatializerHelper {
updatedDevice = new AdiDeviceState(canonicalDeviceType, ada.getInternalType(),
ada.getAddress());
initSAState(updatedDevice);
- mDeviceBroker.addDeviceStateToInventory(updatedDevice);
+ mDeviceBroker.addOrUpdateDeviceSAStateInInventory(updatedDevice);
}
if (updatedDevice != null) {
onRoutingUpdated();
@@ -693,7 +693,7 @@ public class SpatializerHelper {
new AdiDeviceState(canonicalDeviceType, ada.getInternalType(),
ada.getAddress());
initSAState(deviceState);
- mDeviceBroker.addDeviceStateToInventory(deviceState);
+ mDeviceBroker.addOrUpdateDeviceSAStateInInventory(deviceState);
mDeviceBroker.persistAudioDeviceSettings();
logDeviceState(deviceState, "addWirelessDeviceIfNew"); // may be updated later.
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
index 3d0ea9d8bef6..54d1faa39be0 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
@@ -260,6 +260,14 @@ class FingerprintAuthenticationClient
final AidlSession session = getFreshDaemon();
final OperationContextExt opContext = getOperationContext();
+ final ICancellationSignal cancel;
+ if (session.hasContextMethods()) {
+ cancel = session.getSession().authenticateWithContext(
+ mOperationId, opContext.toAidlContext(getOptions()));
+ } else {
+ cancel = session.getSession().authenticate(mOperationId);
+ }
+
getBiometricContext().subscribe(opContext, ctx -> {
if (session.hasContextMethods()) {
try {
@@ -281,12 +289,7 @@ class FingerprintAuthenticationClient
mALSProbeCallback.getProbe().enable();
}
- if (session.hasContextMethods()) {
- return session.getSession().authenticateWithContext(
- mOperationId, opContext.toAidlContext(getOptions()));
- } else {
- return session.getSession().authenticate(mOperationId);
- }
+ return cancel;
}
@Override
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index e5965eff7070..51a0ef6af73b 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -1568,37 +1568,40 @@ public class DisplayDeviceConfig {
public String toString() {
return "DisplayDeviceConfig{"
+ "mLoadedFrom=" + mLoadedFrom
- + ", mBacklight=" + Arrays.toString(mBacklight)
+ + "\n"
+ + "mBacklight=" + Arrays.toString(mBacklight)
+ ", mNits=" + Arrays.toString(mNits)
+ ", mRawBacklight=" + Arrays.toString(mRawBacklight)
+ ", mRawNits=" + Arrays.toString(mRawNits)
+ ", mInterpolationType=" + mInterpolationType
- + ", mBrightness=" + Arrays.toString(mBrightness)
- + ", mBrightnessToBacklightSpline=" + mBrightnessToBacklightSpline
+ + "mBrightness=" + Arrays.toString(mBrightness)
+ + "\n"
+ + "mBrightnessToBacklightSpline=" + mBrightnessToBacklightSpline
+ ", mBacklightToBrightnessSpline=" + mBacklightToBrightnessSpline
+ ", mNitsToBacklightSpline=" + mNitsToBacklightSpline
+ ", mBacklightMinimum=" + mBacklightMinimum
+ ", mBacklightMaximum=" + mBacklightMaximum
+ ", mBrightnessDefault=" + mBrightnessDefault
+ ", mQuirks=" + mQuirks
- + ", isHbmEnabled=" + mIsHighBrightnessModeEnabled
- + ", mLuxThrottlingData=" + mLuxThrottlingData
+ + ", mIsHighBrightnessModeEnabled=" + mIsHighBrightnessModeEnabled
+ + "\n"
+ + "mLuxThrottlingData=" + mLuxThrottlingData
+ ", mHbmData=" + mHbmData
+ ", mSdrToHdrRatioSpline=" + mSdrToHdrRatioSpline
+ ", mThermalBrightnessThrottlingDataMapByThrottlingId="
+ mThermalBrightnessThrottlingDataMapByThrottlingId
+ "\n"
- + ", mBrightnessRampFastDecrease=" + mBrightnessRampFastDecrease
+ + "mBrightnessRampFastDecrease=" + mBrightnessRampFastDecrease
+ ", mBrightnessRampFastIncrease=" + mBrightnessRampFastIncrease
+ ", mBrightnessRampSlowDecrease=" + mBrightnessRampSlowDecrease
+ ", mBrightnessRampSlowIncrease=" + mBrightnessRampSlowIncrease
+ ", mBrightnessRampDecreaseMaxMillis=" + mBrightnessRampDecreaseMaxMillis
+ ", mBrightnessRampIncreaseMaxMillis=" + mBrightnessRampIncreaseMaxMillis
+ "\n"
- + ", mAmbientHorizonLong=" + mAmbientHorizonLong
+ + "mAmbientHorizonLong=" + mAmbientHorizonLong
+ ", mAmbientHorizonShort=" + mAmbientHorizonShort
+ "\n"
- + ", mScreenDarkeningMinThreshold=" + mScreenDarkeningMinThreshold
+ + "mScreenDarkeningMinThreshold=" + mScreenDarkeningMinThreshold
+ ", mScreenDarkeningMinThresholdIdle=" + mScreenDarkeningMinThresholdIdle
+ ", mScreenBrighteningMinThreshold=" + mScreenBrighteningMinThreshold
+ ", mScreenBrighteningMinThresholdIdle=" + mScreenBrighteningMinThresholdIdle
@@ -1608,7 +1611,7 @@ public class DisplayDeviceConfig {
+ ", mAmbientLuxBrighteningMinThresholdIdle="
+ mAmbientLuxBrighteningMinThresholdIdle
+ "\n"
- + ", mScreenBrighteningLevels=" + Arrays.toString(
+ + "mScreenBrighteningLevels=" + Arrays.toString(
mScreenBrighteningLevels)
+ ", mScreenBrighteningPercentages=" + Arrays.toString(
mScreenBrighteningPercentages)
@@ -1625,7 +1628,7 @@ public class DisplayDeviceConfig {
+ ", mAmbientDarkeningPercentages=" + Arrays.toString(
mAmbientDarkeningPercentages)
+ "\n"
- + ", mAmbientBrighteningLevelsIdle=" + Arrays.toString(
+ + "mAmbientBrighteningLevelsIdle=" + Arrays.toString(
mAmbientBrighteningLevelsIdle)
+ ", mAmbientBrighteningPercentagesIdle=" + Arrays.toString(
mAmbientBrighteningPercentagesIdle)
@@ -1642,7 +1645,7 @@ public class DisplayDeviceConfig {
+ ", mScreenDarkeningPercentagesIdle=" + Arrays.toString(
mScreenDarkeningPercentagesIdle)
+ "\n"
- + ", mAmbientLightSensor=" + mAmbientLightSensor
+ + "mAmbientLightSensor=" + mAmbientLightSensor
+ ", mScreenOffBrightnessSensor=" + mScreenOffBrightnessSensor
+ ", mProximitySensor=" + mProximitySensor
+ ", mRefreshRateLimitations= " + Arrays.toString(mRefreshRateLimitations.toArray())
@@ -1656,7 +1659,7 @@ public class DisplayDeviceConfig {
+ ", mDdcAutoBrightnessAvailable= " + mDdcAutoBrightnessAvailable
+ ", mAutoBrightnessAvailable= " + mAutoBrightnessAvailable
+ "\n"
- + ", mDefaultLowBlockingZoneRefreshRate= " + mDefaultLowBlockingZoneRefreshRate
+ + "mDefaultLowBlockingZoneRefreshRate= " + mDefaultLowBlockingZoneRefreshRate
+ ", mDefaultHighBlockingZoneRefreshRate= " + mDefaultHighBlockingZoneRefreshRate
+ ", mDefaultPeakRefreshRate= " + mDefaultPeakRefreshRate
+ ", mDefaultRefreshRate= " + mDefaultRefreshRate
@@ -1665,7 +1668,7 @@ public class DisplayDeviceConfig {
+ ", mDefaultRefreshRateInHbmSunlight= " + mDefaultRefreshRateInHbmSunlight
+ ", mRefreshRateThrottlingMap= " + mRefreshRateThrottlingMap
+ "\n"
- + ", mLowDisplayBrightnessThresholds= "
+ + "mLowDisplayBrightnessThresholds= "
+ Arrays.toString(mLowDisplayBrightnessThresholds)
+ ", mLowAmbientBrightnessThresholds= "
+ Arrays.toString(mLowAmbientBrightnessThresholds)
@@ -1674,10 +1677,10 @@ public class DisplayDeviceConfig {
+ ", mHighAmbientBrightnessThresholds= "
+ Arrays.toString(mHighAmbientBrightnessThresholds)
+ "\n"
- + ", mScreenOffBrightnessSensorValueToLux=" + Arrays.toString(
+ + "mScreenOffBrightnessSensorValueToLux=" + Arrays.toString(
mScreenOffBrightnessSensorValueToLux)
+ "\n"
- + ", mUsiVersion= " + mHostUsiVersion
+ + "mUsiVersion= " + mHostUsiVersion
+ "}";
}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 19dffeba868e..58f4d0859c1a 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -39,6 +39,7 @@ import static android.hardware.display.DisplayViewport.VIEWPORT_EXTERNAL;
import static android.hardware.display.DisplayViewport.VIEWPORT_INTERNAL;
import static android.hardware.display.DisplayViewport.VIEWPORT_VIRTUAL;
import static android.hardware.display.HdrConversionMode.HDR_CONVERSION_UNSUPPORTED;
+import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
import static android.os.Process.FIRST_APPLICATION_UID;
import static android.os.Process.ROOT_UID;
@@ -593,7 +594,7 @@ public final class DisplayManagerService extends SystemService {
DisplayManagerGlobal.invalidateLocalDisplayInfoCaches();
publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
- true /*allowIsolated*/);
+ true /*allowIsolated*/, DUMP_FLAG_PRIORITY_CRITICAL);
publishLocalService(DisplayManagerInternal.class, new LocalService());
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java
index b96187f7af77..5213d3179de7 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController2.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController2.java
@@ -613,7 +613,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
setUpAutoBrightness(resources, handler);
- mColorFadeEnabled = mInjector.isColorFadeEnabled(resources);
+ mColorFadeEnabled = mInjector.isColorFadeEnabled()
+ && !resources.getBoolean(
+ com.android.internal.R.bool.config_displayColorFadeDisabled);
mColorFadeFadesConfig = resources.getBoolean(
R.bool.config_animateScreenLights);
@@ -2449,6 +2451,10 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
dumpRbcEvents(pw);
+ if (mScreenOffBrightnessSensorController != null) {
+ mScreenOffBrightnessSensorController.dump(pw);
+ }
+
if (mBrightnessRangeController != null) {
mBrightnessRangeController.dump(pw);
}
@@ -3005,10 +3011,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
sensorManager, resources);
}
- boolean isColorFadeEnabled(Resources resources) {
- return !ActivityManager.isLowRamDeviceStatic()
- && !resources.getBoolean(
- com.android.internal.R.bool.config_displayColorFadeDisabled);
+ boolean isColorFadeEnabled() {
+ return !ActivityManager.isLowRamDeviceStatic();
}
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 75fcca5eec9a..1e6486a17fe7 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -18,7 +18,6 @@ package com.android.server.power;
import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.policyToString;
import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
-import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT;
import static android.os.PowerManager.GO_TO_SLEEP_REASON_DISPLAY_GROUPS_TURNED_OFF;
import static android.os.PowerManager.GO_TO_SLEEP_REASON_DISPLAY_GROUP_REMOVED;
import static android.os.PowerManager.WAKE_REASON_DISPLAY_GROUP_ADDED;
@@ -1280,7 +1279,7 @@ public final class PowerManagerService extends SystemService
@Override
public void onStart() {
publishBinderService(Context.POWER_SERVICE, mBinderService, /* allowIsolated= */ false,
- DUMP_FLAG_PRIORITY_DEFAULT | DUMP_FLAG_PRIORITY_CRITICAL);
+ DUMP_FLAG_PRIORITY_CRITICAL);
publishLocalService(PowerManagerInternal.class, mLocalService);
Watchdog.getInstance().addMonitor(this);
diff --git a/services/core/java/com/android/server/power/TEST_MAPPING b/services/core/java/com/android/server/power/TEST_MAPPING
index 8374997e3fa2..19086a184068 100644
--- a/services/core/java/com/android/server/power/TEST_MAPPING
+++ b/services/core/java/com/android/server/power/TEST_MAPPING
@@ -17,15 +17,6 @@
]
},
{
- "name": "FrameworksServicesTests",
- "options": [
- {"include-filter": "com.android.server.power"},
- {"exclude-filter": "com.android.server.power.BatteryStatsTests"},
- {"exclude-annotation": "android.platform.test.annotations.FlakyTest"},
- {"exclude-annotation": "androidx.test.filters.FlakyTest"}
- ]
- },
- {
"name": "PowerServiceTests",
"options": [
{"include-filter": "com.android.server.power"},
@@ -48,15 +39,13 @@
{
"name": "FrameworksServicesTests",
"options": [
- {"include-filter": "com.android.server.power"},
- {"exclude-filter": "com.android.server.power.BatteryStatsTests"}
+ {"include-filter": "com.android.server.power"}
]
},
{
"name": "PowerServiceTests",
"options": [
{"include-filter": "com.android.server.power"},
- {"exclude-filter": "com.android.server.power.BatteryStatsTests"},
{"exclude-annotation": "org.junit.Ignore"}
]
}
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index e80cbb302424..9af12ad6e766 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -1851,9 +1851,17 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
0 /* launchFlags */);
task.reparent(launchRoot == null ? toDisplayArea : launchRoot, POSITION_TOP);
- // Set the windowing mode to undefined by default to let the root task inherited the
- // windowing mode.
- task.setWindowingMode(WINDOWING_MODE_UNDEFINED);
+ // If the task is going to be reparented to the non-fullscreen root TDA and the task
+ // is set to FULLSCREEN explicitly, we keep the windowing mode as is. Otherwise, the
+ // task will inherit the display windowing mode unexpectedly.
+ final boolean keepWindowingMode = launchRoot == null
+ && task.getRequestedOverrideWindowingMode() == WINDOWING_MODE_FULLSCREEN
+ && toDisplayArea.getWindowingMode() != WINDOWING_MODE_FULLSCREEN;
+ if (!keepWindowingMode) {
+ // Set the windowing mode to undefined to let the root task inherited the
+ // windowing mode.
+ task.setWindowingMode(WINDOWING_MODE_UNDEFINED);
+ }
lastReparentedRootTask = task;
}
// Root task may be removed from this display. Ensure each root task will be processed
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index a84749aa6643..fe7a70a48e8d 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -382,18 +382,13 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
}
@Override
- public int finishTransition(@NonNull IBinder transitionToken,
- @Nullable WindowContainerTransaction t,
- @Nullable IWindowContainerTransactionCallback callback) {
+ public void finishTransition(@NonNull IBinder transitionToken,
+ @Nullable WindowContainerTransaction t) {
enforceTaskPermission("finishTransition()");
final CallerInfo caller = new CallerInfo();
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
- int syncId = -1;
- if (t != null && callback != null) {
- syncId = startSyncWithOrganizer(callback);
- }
final Transition transition = Transition.fromBinder(transitionToken);
// apply the incoming transaction before finish in case it alters the visibility
// of the participants.
@@ -402,14 +397,10 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
// changes of the transition participants will only set visible-requested
// and still let finishTransition handle the participants.
mTransitionController.mFinishingTransition = transition;
- applyTransaction(t, syncId, null /*transition*/, caller, transition);
+ applyTransaction(t, -1 /* syncId */, null /*transition*/, caller, transition);
}
mTransitionController.finishTransition(transition);
mTransitionController.mFinishingTransition = null;
- if (syncId >= 0) {
- setSyncReady(syncId);
- }
- return syncId;
}
} finally {
Binder.restoreCallingIdentity(ident);
diff --git a/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java
index 0b1e3386cbac..d6d5264257e6 100644
--- a/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -141,7 +141,7 @@ import java.util.concurrent.atomic.AtomicReference;
* Tests for {@link com.android.server.power.PowerManagerService}.
*
* Build/Install/Run:
- * atest FrameworksServicesTests:PowerManagerServiceTest
+ * atest PowerServiceTests:PowerManagerServiceTest
*/
@SuppressWarnings("GuardedBy")
@RunWith(TestParameterInjector.class)
@@ -240,6 +240,10 @@ public class PowerManagerServiceTest {
cr.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
when(mContextSpy.getContentResolver()).thenReturn(cr);
+ when(mResourcesSpy.getBoolean(com.android.internal.R.bool.config_dreamsSupported))
+ .thenReturn(true);
+ when(mResourcesSpy.getBoolean(com.android.internal.R.bool.config_dreamsEnabledByDefault))
+ .thenReturn(true);
Settings.Global.putInt(mContextSpy.getContentResolver(),
Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0);
Settings.Secure.putInt(mContextSpy.getContentResolver(),
@@ -1084,13 +1088,9 @@ public class PowerManagerServiceTest {
@SuppressWarnings("GuardedBy")
@Test
public void testScreensaverActivateOnSleepEnabled_powered_afterTimeout_goesToDreaming() {
- when(mResourcesSpy.getBoolean(com.android.internal.R.bool.config_dreamsSupported))
- .thenReturn(true);
when(mBatteryManagerInternalMock.isPowered(anyInt())).thenReturn(true);
Settings.Secure.putInt(mContextSpy.getContentResolver(),
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 1);
- Settings.Secure.putInt(mContextSpy.getContentResolver(),
- Settings.Secure.SCREENSAVER_ENABLED, 1);
doAnswer(inv -> {
when(mDreamManagerInternalMock.isDreaming()).thenReturn(true);
@@ -1112,8 +1112,6 @@ public class PowerManagerServiceTest {
public void testAmbientSuppression_disablesDreamingAndWakesDevice() {
Settings.Secure.putInt(mContextSpy.getContentResolver(),
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 1);
- Settings.Secure.putInt(mContextSpy.getContentResolver(),
- Settings.Secure.SCREENSAVER_ENABLED, 1);
setDreamsDisabledByAmbientModeSuppressionConfig(true);
setMinimumScreenOffTimeoutConfig(10000);
@@ -1141,8 +1139,6 @@ public class PowerManagerServiceTest {
public void testAmbientSuppressionDisabled_shouldNotWakeDevice() {
Settings.Secure.putInt(mContextSpy.getContentResolver(),
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 1);
- Settings.Secure.putInt(mContextSpy.getContentResolver(),
- Settings.Secure.SCREENSAVER_ENABLED, 1);
setDreamsDisabledByAmbientModeSuppressionConfig(false);
setMinimumScreenOffTimeoutConfig(10000);
@@ -1169,8 +1165,6 @@ public class PowerManagerServiceTest {
public void testAmbientSuppression_doesNotAffectDreamForcing() {
Settings.Secure.putInt(mContextSpy.getContentResolver(),
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 1);
- Settings.Secure.putInt(mContextSpy.getContentResolver(),
- Settings.Secure.SCREENSAVER_ENABLED, 1);
setDreamsDisabledByAmbientModeSuppressionConfig(true);
setMinimumScreenOffTimeoutConfig(10000);
@@ -1196,8 +1190,6 @@ public class PowerManagerServiceTest {
public void testBatteryDrainDuringDream() {
Settings.Secure.putInt(mContextSpy.getContentResolver(),
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 1);
- Settings.Secure.putInt(mContextSpy.getContentResolver(),
- Settings.Secure.SCREENSAVER_ENABLED, 1);
setMinimumScreenOffTimeoutConfig(100);
setDreamsBatteryLevelDrainConfig(5);
diff --git a/services/tests/powerstatstests/Android.bp b/services/tests/powerstatstests/Android.bp
new file mode 100644
index 000000000000..05acd9b8eeb1
--- /dev/null
+++ b/services/tests/powerstatstests/Android.bp
@@ -0,0 +1,52 @@
+package {
+ // See: http://go/android-license-faq
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_test {
+ name: "PowerStatsTests",
+
+ // Include all test java files.
+ srcs: [
+ "src/**/*.java",
+ ],
+
+ static_libs: [
+ "services.core",
+ "coretests-aidl",
+ "platformprotosnano",
+ "junit",
+ "truth-prebuilt",
+ "androidx.test.runner",
+ "androidx.test.ext.junit",
+ "androidx.test.ext.truth",
+ "androidx.test.uiautomator_uiautomator",
+ "mockito-target-minus-junit4",
+ "servicestests-utils",
+ ],
+
+ libs: [
+ "android.test.base",
+ ],
+
+ resource_dirs: ["res/"],
+
+ data: [
+ ":BstatsTestApp",
+ ],
+
+ test_suites: [
+ "automotive-tests",
+ "device-tests",
+ ],
+
+ platform_apis: true,
+
+ certificate: "platform",
+
+ dxflags: ["--multi-dex"],
+
+ optimize: {
+ enabled: false,
+ },
+}
diff --git a/services/tests/powerstatstests/AndroidManifest.xml b/services/tests/powerstatstests/AndroidManifest.xml
new file mode 100644
index 000000000000..d3a88d2bc38c
--- /dev/null
+++ b/services/tests/powerstatstests/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.frameworks.powerstatstests">
+
+ <uses-permission android:name="android.permission.BATTERY_STATS" />
+ <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
+ <uses-permission android:name="android.permission.MANAGE_USERS"/>
+
+ <queries>
+ <package android:name="com.android.coretests.apps.bstatstestapp" />
+ </queries>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.frameworks.powerstatstests"
+ android:label="BatteryStats and PowerStats Services Tests"/>
+</manifest>
diff --git a/services/tests/powerstatstests/AndroidTest.xml b/services/tests/powerstatstests/AndroidTest.xml
new file mode 100644
index 000000000000..79b07e812b28
--- /dev/null
+++ b/services/tests/powerstatstests/AndroidTest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Runs Power Stats Tests.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-instrumentation" />
+
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="install-arg" value="-t" />
+ <option name="test-file-name" value="PowerStatsTests.apk" />
+ <option name="test-file-name" value="BstatsTestApp.apk" />
+ </target_preparer>
+
+ <option name="test-tag" value="PowerStatsTests" />
+
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="com.android.frameworks.powerstatstests" />
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+ <option name="hidden-api-checks" value="false"/>
+ <option name="exclude-annotation" value="androidx.test.filters.FlakyTest" />
+ </test>
+</configuration>
diff --git a/core/tests/coretests/BstatsTestApp/Android.bp b/services/tests/powerstatstests/BstatsTestApp/Android.bp
index c82da9e7b449..c82da9e7b449 100644
--- a/core/tests/coretests/BstatsTestApp/Android.bp
+++ b/services/tests/powerstatstests/BstatsTestApp/Android.bp
diff --git a/core/tests/coretests/BstatsTestApp/AndroidManifest.xml b/services/tests/powerstatstests/BstatsTestApp/AndroidManifest.xml
index fcb1e71cc3f5..fcb1e71cc3f5 100644
--- a/core/tests/coretests/BstatsTestApp/AndroidManifest.xml
+++ b/services/tests/powerstatstests/BstatsTestApp/AndroidManifest.xml
diff --git a/core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/BaseCmdReceiver.java b/services/tests/powerstatstests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/BaseCmdReceiver.java
index 2601f3571b98..2601f3571b98 100644
--- a/core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/BaseCmdReceiver.java
+++ b/services/tests/powerstatstests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/BaseCmdReceiver.java
diff --git a/core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/Common.java b/services/tests/powerstatstests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/Common.java
index d192fbd66c89..c731e536d032 100644
--- a/core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/Common.java
+++ b/services/tests/powerstatstests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/Common.java
@@ -15,8 +15,6 @@
*/
package com.android.coretests.apps.bstatstestapp;
-import com.android.frameworks.coretests.aidl.ICmdCallback;
-
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
@@ -24,6 +22,8 @@ import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;
+import com.android.frameworks.coretests.aidl.ICmdCallback;
+
public class Common {
private static final String EXTRA_KEY_CMD_RECEIVER = "cmd_receiver";
diff --git a/core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/IsolatedTestService.java b/services/tests/powerstatstests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/IsolatedTestService.java
index 892f60e8530f..892f60e8530f 100644
--- a/core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/IsolatedTestService.java
+++ b/services/tests/powerstatstests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/IsolatedTestService.java
diff --git a/core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/TestActivity.java b/services/tests/powerstatstests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/TestActivity.java
index 5c551d54b4d5..5c551d54b4d5 100644
--- a/core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/TestActivity.java
+++ b/services/tests/powerstatstests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/TestActivity.java
diff --git a/core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/TestService.java b/services/tests/powerstatstests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/TestService.java
index 0cd0643ee8c0..0cd0643ee8c0 100644
--- a/core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/TestService.java
+++ b/services/tests/powerstatstests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/TestService.java
diff --git a/services/tests/servicestests/src/com/android/server/powerstats/OWNERS b/services/tests/powerstatstests/OWNERS
index 12f13ea63db0..9ed0e051738d 100644
--- a/services/tests/servicestests/src/com/android/server/powerstats/OWNERS
+++ b/services/tests/powerstatstests/OWNERS
@@ -1 +1,4 @@
+# Bug component: 987260
+
+include /BATTERY_STATS_OWNERS
include /services/core/java/com/android/server/powerstats/OWNERS
diff --git a/services/tests/powerstatstests/TEST_MAPPING b/services/tests/powerstatstests/TEST_MAPPING
new file mode 100644
index 000000000000..e1eb1e4fc0db
--- /dev/null
+++ b/services/tests/powerstatstests/TEST_MAPPING
@@ -0,0 +1,22 @@
+{
+ "presubmit": [
+ {
+ "name": "PowerStatsTests",
+ "options": [
+ {"include-filter": "com.android.server.power.stats"},
+ {"exclude-annotation": "android.platform.test.annotations.FlakyTest"},
+ {"exclude-annotation": "androidx.test.filters.FlakyTest"},
+ {"exclude-annotation": "org.junit.Ignore"}
+ ]
+ }
+ ],
+ "postsubmit": [
+ {
+ "name": "PowerStatsTests",
+ "options": [
+ {"include-filter": "com.android.server.power.stats"},
+ {"exclude-annotation": "org.junit.Ignore"}
+ ]
+ }
+ ]
+}
diff --git a/services/tests/servicestests/res/xml/irq_device_map_1.xml b/services/tests/powerstatstests/res/xml/irq_device_map_1.xml
index 1f1a77b437ab..1f1a77b437ab 100644
--- a/services/tests/servicestests/res/xml/irq_device_map_1.xml
+++ b/services/tests/powerstatstests/res/xml/irq_device_map_1.xml
diff --git a/services/tests/servicestests/res/xml/irq_device_map_2.xml b/services/tests/powerstatstests/res/xml/irq_device_map_2.xml
index 508c98d871da..508c98d871da 100644
--- a/services/tests/servicestests/res/xml/irq_device_map_2.xml
+++ b/services/tests/powerstatstests/res/xml/irq_device_map_2.xml
diff --git a/services/tests/servicestests/res/xml/irq_device_map_3.xml b/services/tests/powerstatstests/res/xml/irq_device_map_3.xml
index fd55428c48df..fd55428c48df 100644
--- a/services/tests/servicestests/res/xml/irq_device_map_3.xml
+++ b/services/tests/powerstatstests/res/xml/irq_device_map_3.xml
diff --git a/services/tests/servicestests/res/xml/power_profile_test_legacy_modem.xml b/services/tests/powerstatstests/res/xml/power_profile_test_legacy_modem.xml
index 5335f9640738..5335f9640738 100644
--- a/services/tests/servicestests/res/xml/power_profile_test_legacy_modem.xml
+++ b/services/tests/powerstatstests/res/xml/power_profile_test_legacy_modem.xml
diff --git a/services/tests/servicestests/res/xml/power_profile_test_modem_calculator.xml b/services/tests/powerstatstests/res/xml/power_profile_test_modem_calculator.xml
index f57bc0f70b5d..f57bc0f70b5d 100644
--- a/services/tests/servicestests/res/xml/power_profile_test_modem_calculator.xml
+++ b/services/tests/powerstatstests/res/xml/power_profile_test_modem_calculator.xml
diff --git a/services/tests/servicestests/res/xml/power_profile_test_modem_calculator_multiactive.xml b/services/tests/powerstatstests/res/xml/power_profile_test_modem_calculator_multiactive.xml
index 4f5e674c60f5..4f5e674c60f5 100644
--- a/services/tests/servicestests/res/xml/power_profile_test_modem_calculator_multiactive.xml
+++ b/services/tests/powerstatstests/res/xml/power_profile_test_modem_calculator_multiactive.xml
diff --git a/services/tests/servicestests/res/xml/power_profile_test_modem_default.xml b/services/tests/powerstatstests/res/xml/power_profile_test_modem_default.xml
index ab016fbb1f5d..ab016fbb1f5d 100644
--- a/services/tests/servicestests/res/xml/power_profile_test_modem_default.xml
+++ b/services/tests/powerstatstests/res/xml/power_profile_test_modem_default.xml
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/AmbientDisplayPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/AmbientDisplayPowerCalculatorTest.java
index 319a280d10cc..319a280d10cc 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/AmbientDisplayPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/AmbientDisplayPowerCalculatorTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/AudioPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/AudioPowerCalculatorTest.java
index fb367b24168e..fb367b24168e 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/AudioPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/AudioPowerCalculatorTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryChargeCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryChargeCalculatorTest.java
index 4ea0805ffaa7..4ea0805ffaa7 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryChargeCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryChargeCalculatorTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryExternalStatsWorkerTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryExternalStatsWorkerTest.java
index 5a2d2e3d33fd..5a2d2e3d33fd 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryExternalStatsWorkerTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryExternalStatsWorkerTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsBackgroundStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsBackgroundStatsTest.java
index 4d3fcb611f24..4d3fcb611f24 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsBackgroundStatsTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsBackgroundStatsTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsBinderCallStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsBinderCallStatsTest.java
index 3f101a96d36c..3f101a96d36c 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsBinderCallStatsTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsBinderCallStatsTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsCounterTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsCounterTest.java
index 326639c54495..326639c54495 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsCounterTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsCounterTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsCpuTimesTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsCpuTimesTest.java
index 55ffa1a15a6b..55ffa1a15a6b 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsCpuTimesTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsCpuTimesTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsDualTimerTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsDualTimerTest.java
index d6acf8da7431..d6acf8da7431 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsDualTimerTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsDualTimerTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsDurationTimerTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsDurationTimerTest.java
index 99520cd6fbad..99520cd6fbad 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsDurationTimerTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsDurationTimerTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsHistoryIteratorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryIteratorTest.java
index 4fde73bd8408..4fde73bd8408 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsHistoryIteratorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryIteratorTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java
index 48ba765c3968..48ba765c3968 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsImplTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java
index f20f061230e2..5ebc6ca3f558 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsImplTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java
@@ -267,7 +267,7 @@ public class BatteryStatsImplTest {
final long[][] delta3 = {
{98545, 95768795, 76586, 548945, 57846},
{788876, 586, 578459, 8776984, 9578923},
- {3049509483598l, 4597834, 377654, 94589035, 7854},
+ {3049509483598L, 4597834, 377654, 94589035, 7854},
{9493, 784, 99895, 8974893, 9879843}
};
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsManagerTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsManagerTest.java
index 7ae111711b6b..7ae111711b6b 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsManagerTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsManagerTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsNoteTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java
index 88b9522d4cb1..88b9522d4cb1 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsNoteTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsResetTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsResetTest.java
index a0fb631812f4..a0fb631812f4 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsResetTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsResetTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsSamplingTimerTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsSamplingTimerTest.java
index 784d673ed3f0..ee68bf8ae53c 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsSamplingTimerTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsSamplingTimerTest.java
@@ -1,17 +1,17 @@
/*
* Copyright (C) 2016 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
+ * 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
+ * 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.
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package com.android.server.power.stats;
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsSensorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsSensorTest.java
index b8f0ce3456f8..9c70f376ca14 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsSensorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsSensorTest.java
@@ -1,17 +1,17 @@
/*
* Copyright (C) 2016 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
+ * 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
+ * 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.
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package com.android.server.power.stats;
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsServTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsServTest.java
index 200eb1d0ad15..200eb1d0ad15 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsServTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsServTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsStopwatchTimerTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsStopwatchTimerTest.java
index fcae42a76f1b..18a366c178fd 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsStopwatchTimerTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsStopwatchTimerTest.java
@@ -1,17 +1,17 @@
/*
* Copyright (C) 2017 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
+ * 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
+ * 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.
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package com.android.server.power.stats;
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsTimeBaseTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsTimeBaseTest.java
index 5b47423f0d59..5b47423f0d59 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsTimeBaseTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsTimeBaseTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsTimerTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsTimerTest.java
index 14c5c5db5c1c..14c5c5db5c1c 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsTimerTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsTimerTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsUserLifecycleTests.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsUserLifecycleTests.java
index face849620d7..face849620d7 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsUserLifecycleTests.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsUserLifecycleTests.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java
index 5df0acb65249..5df0acb65249 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryUsageStatsRule.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java
index 534aa89e1699..534aa89e1699 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryUsageStatsRule.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryUsageStatsStoreTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsStoreTest.java
index b846e3a36656..b846e3a36656 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryUsageStatsStoreTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsStoreTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryUsageStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java
index 266a22632a6d..266a22632a6d 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryUsageStatsTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BluetoothPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerCalculatorTest.java
index 4d4337c16757..4d4337c16757 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BluetoothPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerCalculatorTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BstatsCpuTimesValidationTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BstatsCpuTimesValidationTest.java
index ccace40bb056..ccace40bb056 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BstatsCpuTimesValidationTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BstatsCpuTimesValidationTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/CameraPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerCalculatorTest.java
index 5fce32f0598a..5fce32f0598a 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/CameraPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerCalculatorTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/CpuPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerCalculatorTest.java
index 888bc623f669..888bc623f669 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/CpuPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerCalculatorTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/CustomEnergyConsumerPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/CustomEnergyConsumerPowerCalculatorTest.java
index 245faaf15cc8..245faaf15cc8 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/CustomEnergyConsumerPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/CustomEnergyConsumerPowerCalculatorTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/EnergyConsumerSnapshotTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/EnergyConsumerSnapshotTest.java
index 28f4799656b7..28f4799656b7 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/EnergyConsumerSnapshotTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/EnergyConsumerSnapshotTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/FlashlightPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/FlashlightPowerCalculatorTest.java
index 0f85fdc375fb..0f85fdc375fb 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/FlashlightPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/FlashlightPowerCalculatorTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/GnssPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerCalculatorTest.java
index 3f2a6d04c1e6..3f2a6d04c1e6 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/GnssPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerCalculatorTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/IdlePowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/IdlePowerCalculatorTest.java
index 3d150af711f1..3d150af711f1 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/IdlePowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/IdlePowerCalculatorTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/KernelWakelockReaderTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/KernelWakelockReaderTest.java
index c0f3c775ffe5..2edfc8e1e408 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/KernelWakelockReaderTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/KernelWakelockReaderTest.java
@@ -1,17 +1,17 @@
/*
* Copyright (C) 2016 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
+ * 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
+ * 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.
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package com.android.server.power.stats;
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/LongSamplingCounterArrayTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/LongSamplingCounterArrayTest.java
index 2e962c364ed2..2e962c364ed2 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/LongSamplingCounterArrayTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/LongSamplingCounterArrayTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/LongSamplingCounterTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/LongSamplingCounterTest.java
index 0eac625051fc..0eac625051fc 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/LongSamplingCounterTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/LongSamplingCounterTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/MemoryPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/MemoryPowerCalculatorTest.java
index 2cce449c6c05..2cce449c6c05 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/MemoryPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/MemoryPowerCalculatorTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/MobileRadioPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerCalculatorTest.java
index d3ec0d7e3f6e..888a1688c2a1 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/MobileRadioPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerCalculatorTest.java
@@ -46,7 +46,7 @@ import android.telephony.TelephonyManager;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.frameworks.servicestests.R;
+import com.android.frameworks.powerstatstests.R;
import com.google.common.collect.Range;
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/MockBatteryStatsImpl.java b/services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java
index 6d3f1f27b572..6d3f1f27b572 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/MockBatteryStatsImpl.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/MockClock.java b/services/tests/powerstatstests/src/com/android/server/power/stats/MockClock.java
index 5e57cc36797b..5e57cc36797b 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/MockClock.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/MockClock.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/OWNERS b/services/tests/powerstatstests/src/com/android/server/power/stats/OWNERS
index 9a7db1cb4fe4..9a7db1cb4fe4 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/OWNERS
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/ScreenPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerCalculatorTest.java
index 372307985f04..372307985f04 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/ScreenPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerCalculatorTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/SensorPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/SensorPowerCalculatorTest.java
index 474527040839..474527040839 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/SensorPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/SensorPowerCalculatorTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/SystemServerCpuThreadReaderTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/SystemServerCpuThreadReaderTest.java
index 80cbe0da402e..80cbe0da402e 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/SystemServerCpuThreadReaderTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/SystemServerCpuThreadReaderTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/SystemServicePowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/SystemServicePowerCalculatorTest.java
index 4dae2d548057..4dae2d548057 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/SystemServicePowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/SystemServicePowerCalculatorTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/UserPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/UserPowerCalculatorTest.java
index f14745ef2daa..f14745ef2daa 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/UserPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/UserPowerCalculatorTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/VideoPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/VideoPowerCalculatorTest.java
index f578aa3b46be..f578aa3b46be 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/VideoPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/VideoPowerCalculatorTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/WakelockPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/WakelockPowerCalculatorTest.java
index f1961855f12f..f1961855f12f 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/WakelockPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/WakelockPowerCalculatorTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/WifiPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerCalculatorTest.java
index 113be8b19518..113be8b19518 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/WifiPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerCalculatorTest.java
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/wakeups/CpuWakeupStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/wakeups/CpuWakeupStatsTest.java
index b81b776019f9..0dc836ba0400 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/wakeups/CpuWakeupStatsTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/wakeups/CpuWakeupStatsTest.java
@@ -34,7 +34,7 @@ import android.util.SparseIntArray;
import androidx.test.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
-import com.android.frameworks.servicestests.R;
+import com.android.frameworks.powerstatstests.R;
import com.android.server.power.stats.wakeups.CpuWakeupStats.Wakeup;
import org.junit.Test;
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/wakeups/IrqDeviceMapTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/wakeups/IrqDeviceMapTest.java
index 47a8f49e7025..9af288496bb9 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/wakeups/IrqDeviceMapTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/wakeups/IrqDeviceMapTest.java
@@ -23,7 +23,7 @@ import android.content.Context;
import androidx.test.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
-import com.android.frameworks.servicestests.R;
+import com.android.frameworks.powerstatstests.R;
import com.android.internal.util.CollectionUtils;
import org.junit.Test;
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/wakeups/WakingActivityHistoryTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/wakeups/WakingActivityHistoryTest.java
index 99bc25abc4a1..99bc25abc4a1 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/wakeups/WakingActivityHistoryTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/wakeups/WakingActivityHistoryTest.java
diff --git a/services/tests/servicestests/src/com/android/server/powerstats/IntervalRandomNoiseGeneratorTest.java b/services/tests/powerstatstests/src/com/android/server/powerstats/IntervalRandomNoiseGeneratorTest.java
index 99621460f360..99621460f360 100644
--- a/services/tests/servicestests/src/com/android/server/powerstats/IntervalRandomNoiseGeneratorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/powerstats/IntervalRandomNoiseGeneratorTest.java
diff --git a/services/tests/servicestests/src/com/android/server/powerstats/PowerStatsServiceTest.java b/services/tests/powerstatstests/src/com/android/server/powerstats/PowerStatsServiceTest.java
index 2ffe4aacda73..2ffe4aacda73 100644
--- a/services/tests/servicestests/src/com/android/server/powerstats/PowerStatsServiceTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/powerstats/PowerStatsServiceTest.java
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index 173c5f5dd40f..92ff7ab86247 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -112,7 +112,6 @@ android_test {
},
data: [
- ":BstatsTestApp",
":JobTestApp",
":SimpleServiceTestApp1",
":SimpleServiceTestApp2",
@@ -134,7 +133,6 @@ java_library {
name: "servicestests-core-utils",
srcs: [
"src/com/android/server/am/DeviceConfigSession.java",
- "src/com/android/server/display/TestUtils.java",
"src/com/android/server/pm/PackageSettingBuilder.java",
"src/com/android/server/pm/parsing/TestPackageParser2.kt",
],
diff --git a/services/tests/servicestests/AndroidTest.xml b/services/tests/servicestests/AndroidTest.xml
index fbb0ca108ecd..b1d50399416a 100644
--- a/services/tests/servicestests/AndroidTest.xml
+++ b/services/tests/servicestests/AndroidTest.xml
@@ -28,7 +28,6 @@
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="install-arg" value="-t" />
- <option name="test-file-name" value="BstatsTestApp.apk" />
<option name="test-file-name" value="FrameworksServicesTests.apk" />
<option name="test-file-name" value="JobTestApp.apk" />
<option name="test-file-name" value="SuspendTestApp.apk" />
diff --git a/services/tests/servicestests/src/com/android/server/display/TestUtils.java b/services/tests/servicestests/src/com/android/server/display/TestUtils.java
deleted file mode 100644
index 8b45145b160f..000000000000
--- a/services/tests/servicestests/src/com/android/server/display/TestUtils.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.display;
-
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.input.InputSensorInfo;
-import android.os.Parcel;
-import android.os.SystemClock;
-import android.view.DisplayAddress;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-public final class TestUtils {
-
- public static SensorEvent createSensorEvent(Sensor sensor, int value) throws Exception {
- final Constructor<SensorEvent> constructor =
- SensorEvent.class.getDeclaredConstructor(int.class);
- constructor.setAccessible(true);
- final SensorEvent event = constructor.newInstance(1);
- event.sensor = sensor;
- event.values[0] = value;
- event.timestamp = SystemClock.elapsedRealtimeNanos();
- return event;
- }
-
-
- public static void setSensorType(Sensor sensor, int type, String strType) throws Exception {
- Method setter = Sensor.class.getDeclaredMethod("setType", Integer.TYPE);
- setter.setAccessible(true);
- setter.invoke(sensor, type);
- if (strType != null) {
- Field f = sensor.getClass().getDeclaredField("mStringType");
- f.setAccessible(true);
- f.set(sensor, strType);
- }
- }
-
- public static void setMaximumRange(Sensor sensor, float maximumRange) throws Exception {
- Method setter = Sensor.class.getDeclaredMethod("setRange", Float.TYPE, Float.TYPE);
- setter.setAccessible(true);
- setter.invoke(sensor, maximumRange, 1);
- }
-
- public static Sensor createSensor(int type, String strType) throws Exception {
- Constructor<Sensor> constr = Sensor.class.getDeclaredConstructor();
- constr.setAccessible(true);
- Sensor sensor = constr.newInstance();
- setSensorType(sensor, type, strType);
- return sensor;
- }
-
- public static Sensor createSensor(int type, String strType, float maximumRange)
- throws Exception {
- Constructor<Sensor> constr = Sensor.class.getDeclaredConstructor();
- constr.setAccessible(true);
- Sensor sensor = constr.newInstance();
- setSensorType(sensor, type, strType);
- setMaximumRange(sensor, maximumRange);
- return sensor;
- }
-
- public static Sensor createSensor(String type, String name) {
- return new Sensor(new InputSensorInfo(
- name, "vendor", 0, 0, 0, 1f, 1f, 1, 1, 1, 1,
- type, "", 0, 0, 0));
- }
-
- /**
- * Create a custom {@link DisplayAddress} to ensure we're not relying on any specific
- * display-address implementation in our code. Intentionally uses default object (reference)
- * equality rules.
- */
- public static class TestDisplayAddress extends DisplayAddress {
- @Override
- public void writeToParcel(Parcel out, int flags) { }
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsTests.java b/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsTests.java
deleted file mode 100644
index 48290e5ca1ef..000000000000
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsTests.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.power.stats;
-
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
- AmbientDisplayPowerCalculatorTest.class,
- AudioPowerCalculatorTest.class,
- BatteryChargeCalculatorTest.class,
- BatteryExternalStatsWorkerTest.class,
- BatteryStatsCpuTimesTest.class,
- BatteryStatsBackgroundStatsTest.class,
- BatteryStatsBinderCallStatsTest.class,
- BatteryStatsCounterTest.class,
- BatteryStatsDualTimerTest.class,
- BatteryStatsDurationTimerTest.class,
- BatteryStatsHistoryIteratorTest.class,
- BatteryStatsHistoryTest.class,
- BatteryStatsImplTest.class,
- BatteryStatsManagerTest.class,
- BatteryStatsNoteTest.class,
- BatteryStatsSamplingTimerTest.class,
- BatteryStatsSensorTest.class,
- BatteryStatsServTest.class,
- BatteryStatsStopwatchTimerTest.class,
- BatteryStatsTimeBaseTest.class,
- BatteryStatsTimerTest.class,
- BatteryUsageStatsProviderTest.class,
- BatteryUsageStatsTest.class,
- BatteryUsageStatsStoreTest.class,
- BatteryStatsUserLifecycleTests.class,
- BluetoothPowerCalculatorTest.class,
- BstatsCpuTimesValidationTest.class,
- CameraPowerCalculatorTest.class,
- CpuPowerCalculatorTest.class,
- CustomEnergyConsumerPowerCalculatorTest.class,
- FlashlightPowerCalculatorTest.class,
- GnssPowerCalculatorTest.class,
- IdlePowerCalculatorTest.class,
- KernelWakelockReaderTest.class,
- LongSamplingCounterTest.class,
- LongSamplingCounterArrayTest.class,
- EnergyConsumerSnapshotTest.class,
- MobileRadioPowerCalculatorTest.class,
- ScreenPowerCalculatorTest.class,
- SensorPowerCalculatorTest.class,
- SystemServerCpuThreadReaderTest.class,
- SystemServicePowerCalculatorTest.class,
- UserPowerCalculatorTest.class,
- VideoPowerCalculatorTest.class,
- WakelockPowerCalculatorTest.class,
- WifiPowerCalculatorTest.class,
-})
-public class BatteryStatsTests {
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayApp3ButtonNavLandscape.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayApp3ButtonNavLandscape.kt
index b34da72ea5d6..4adcc8bf5f0b 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayApp3ButtonNavLandscape.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayApp3ButtonNavLandscape.kt
@@ -25,10 +25,12 @@ import android.tools.common.flicker.config.FlickerConfig
import android.tools.common.flicker.config.FlickerServiceConfig
import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromLockscreenNotificationWithOverlayApp
+import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(FlickerServiceJUnit4ClassRunner::class)
+@Ignore("b/294418322: no notification launch animation exists when keyguard is occluded")
class OpenAppFromLockscreenNotificationWithOverlayApp3ButtonNavLandscape :
OpenAppFromLockscreenNotificationWithOverlayApp(NavBar.MODE_3BUTTON, Rotation.ROTATION_90) {
@ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayApp3ButtonNavPortrait.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayApp3ButtonNavPortrait.kt
index b1638979cd0d..f7211e7287cf 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayApp3ButtonNavPortrait.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayApp3ButtonNavPortrait.kt
@@ -25,10 +25,12 @@ import android.tools.common.flicker.config.FlickerConfig
import android.tools.common.flicker.config.FlickerServiceConfig
import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromLockscreenNotificationWithOverlayApp
+import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(FlickerServiceJUnit4ClassRunner::class)
+@Ignore("b/294418322: no notification launch animation exists when keyguard is occluded")
class OpenAppFromLockscreenNotificationWithOverlayApp3ButtonNavPortrait :
OpenAppFromLockscreenNotificationWithOverlayApp(NavBar.MODE_3BUTTON, Rotation.ROTATION_0) {
@ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayAppGesturalNavLandscape.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayAppGesturalNavLandscape.kt
index 19b533ed57af..1ade9560d90f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayAppGesturalNavLandscape.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayAppGesturalNavLandscape.kt
@@ -25,10 +25,12 @@ import android.tools.common.flicker.config.FlickerConfig
import android.tools.common.flicker.config.FlickerServiceConfig
import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromLockscreenNotificationWithOverlayApp
+import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(FlickerServiceJUnit4ClassRunner::class)
+@Ignore("b/294418322: no notification launch animation exists when keyguard is occluded")
class OpenAppFromLockscreenNotificationWithOverlayAppGesturalNavLandscape :
OpenAppFromLockscreenNotificationWithOverlayApp(NavBar.MODE_GESTURAL, Rotation.ROTATION_90) {
@ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayAppGesturalNavPortrait.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayAppGesturalNavPortrait.kt
index c9ed4f42af06..ea26f0867c7f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayAppGesturalNavPortrait.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayAppGesturalNavPortrait.kt
@@ -25,10 +25,12 @@ import android.tools.common.flicker.config.FlickerConfig
import android.tools.common.flicker.config.FlickerServiceConfig
import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromLockscreenNotificationWithOverlayApp
+import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(FlickerServiceJUnit4ClassRunner::class)
+@Ignore("b/294418322: no notification launch animation exists when keyguard is occluded")
class OpenAppFromLockscreenNotificationWithOverlayAppGesturalNavPortrait :
OpenAppFromLockscreenNotificationWithOverlayApp(NavBar.MODE_GESTURAL, Rotation.ROTATION_0) {
@ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])