summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp1
-rw-r--r--apex/jobscheduler/service/java/com/android/server/usage/TEST_MAPPING8
-rw-r--r--core/api/current.txt1
-rw-r--r--core/api/system-current.txt8
-rw-r--r--core/java/android/app/Notification.java45
-rw-r--r--core/java/android/app/appfunctions/AppFunctionRuntimeMetadata.java14
-rw-r--r--core/java/android/app/appfunctions/AppFunctionStaticMetadataHelper.java2
-rw-r--r--core/java/android/companion/virtual/flags/flags.aconfig11
-rw-r--r--core/java/android/content/pm/LauncherActivityInfo.java188
-rw-r--r--core/java/android/hardware/fingerprint/FingerprintSensorConfigurations.java42
-rw-r--r--core/java/android/net/vcn/flags.aconfig10
-rw-r--r--core/java/android/os/Build.java25
-rw-r--r--core/java/android/os/SystemClock.java67
-rw-r--r--core/java/android/text/ClientFlags.java21
-rw-r--r--core/java/android/text/MeasuredParagraph.java224
-rw-r--r--core/java/android/text/TextFlags.java6
-rw-r--r--core/java/android/text/flags/24Q3.aconfig54
-rw-r--r--core/java/android/text/flags/flags.aconfig73
-rw-r--r--core/java/android/view/ViewGroup.java5
-rw-r--r--core/java/android/view/WindowManager.java78
-rw-r--r--core/java/android/webkit/UserPackage.java40
-rw-r--r--core/java/android/window/flags/lse_desktop_experience.aconfig7
-rw-r--r--core/java/com/android/internal/jank/flags.aconfig2
-rw-r--r--core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java1
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java46
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java15
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/RadioModuleTest.java7
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java40
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java15
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/RadioModuleHidlTest.java7
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java20
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java46
-rw-r--r--core/tests/coretests/Android.bp38
-rw-r--r--core/tests/coretests/src/android/content/pm/LauncherActivityInfoTest.java218
-rw-r--r--core/tests/coretests/src/android/text/TextLineLetterSpacingTest.kt4
-rw-r--r--graphics/java/android/graphics/OWNERS1
-rw-r--r--graphics/java/android/graphics/Paint.java11
-rw-r--r--graphics/java/android/graphics/fonts/SystemFonts.java16
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionHandler.java21
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitscreenEventLogger.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java3
-rw-r--r--libs/androidfw/AssetManager.cpp32
-rw-r--r--libs/androidfw/include/androidfw/AssetManager.h22
-rw-r--r--libs/androidfw/include/androidfw/Idmap.h5
-rw-r--r--libs/androidfw/include/androidfw/misc.h35
-rw-r--r--libs/androidfw/misc.cpp55
-rw-r--r--libs/androidfw/tests/Idmap_test.cpp11
-rw-r--r--libs/hwui/FeatureFlags.h8
-rw-r--r--libs/hwui/hwui/MinikinUtils.cpp4
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp3
-rw-r--r--packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java79
-rw-r--r--packages/SettingsLib/Android.bp2
-rw-r--r--packages/SettingsLib/Preference/Android.bp1
-rw-r--r--packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceFragment.kt2
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservablePreferenceFragment.java7
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt6
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/volume/domain/interactor/AudioVolumeInteractor.kt2
-rw-r--r--packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioRepositoryTest.kt23
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinInputDisplay.kt6
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/TextExt.kt7
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt22
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt75
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/SideFpsOverlayInteractorTest.kt174
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt255
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt65
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadStatsInteractorTest.kt55
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/IconAndNameCustomRepositoryTest.kt5
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorTest.kt6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt20
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/shared/model/GroupAndSortCategoryAndNameTest.kt87
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractorTest.kt10
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapperTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/RecordingServiceTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegateTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegateTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ActionIntentExecutorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentExecutorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/AnnouncementResolverTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/AnnouncementResolverTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/DraggableConstraintLayoutTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/DraggableConstraintLayoutTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/FakeImageCapture.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeImageCapture.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/FakeScreenshotPolicy.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeScreenshotPolicy.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/RecyclerViewActivity.java (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/RecyclerViewActivity.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ScreenshotActionsControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotActionsControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ScreenshotDataTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDataTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ScreenshotDetectionControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDetectionControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ScreenshotSoundControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotSoundControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/SmartActionsReceiverTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/SmartActionsReceiverTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperServiceTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperServiceTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/appclips/AppClipsServiceTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsServiceTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/data/model/DisplayContentScenarios.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/data/model/DisplayContentScenarios.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/data/repository/ProfileTypeRepositoryKosmos.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/data/repository/ProfileTypeRepositoryKosmos.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/message/ProfileMessageControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/message/ProfileMessageControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/policy/NewRootTaskInfo.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/NewRootTaskInfo.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/policy/PolicyRequestProcessorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/PolicyRequestProcessorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/policy/PrivateProfilePolicyTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/PrivateProfilePolicyTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/policy/TestUserIds.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/TestUserIds.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/policy/WorkProfilePolicyTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/WorkProfilePolicyTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/scroll/FakeSessionTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/scroll/FakeSessionTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/scroll/ScrollCaptureFrameworkSmokeTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/scroll/ScrollCaptureFrameworkSmokeTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/scroll/ScrollViewActivity.java (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/scroll/ScrollViewActivity.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scrim/ScrimViewTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/scrim/ScrimViewTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/BrightnessControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ConstraintChangeTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shade/ConstraintChangeTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ConstraintChangesTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shade/ConstraintChangesTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/LockscreenHostedDreamGestureListenerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shade/LockscreenHostedDreamGestureListenerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationsQuickSettingsContainerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQuickSettingsContainerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/PulsingGestureListenerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shade/PulsingGestureListenerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplWithCoroutinesTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplWithCoroutinesTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/carrier/CellSignalStateTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shade/carrier/CellSignalStateTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/carrier/ShadeCarrierTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/transition/LinearLargeScreenShadeInterpolator.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shade/transition/LinearLargeScreenShadeInterpolator.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shared/animation/DisableSubpixelTextTransitionListenerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shared/animation/DisableSubpixelTextTransitionListenerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shared/animation/UnfoldConstantTranslateAnimatorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldConstantTranslateAnimatorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimatorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimatorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/FakeCondition.java (renamed from packages/SystemUI/tests/src/com/android/systemui/shared/condition/FakeCondition.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shared/plugins/PluginManagerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginManagerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shared/plugins/VersionInfoTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/shared/plugins/VersionInfoTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shared/regionsampling/RegionSamplerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shared/regionsampling/RegionSamplerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shared/rotation/RotationButtonControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shared/rotation/RotationButtonControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/BlurUtilsTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/BlurUtilsTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/DragDownHelperTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/DragDownHelperTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationListenerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilderTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilderTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/VibratorHelperTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/view/ChipBackgroundContainerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/view/ChipBackgroundContainerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/view/ChipChronometerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/view/ChipChronometerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/commandline/ParametersTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ParametersTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/commandline/ParseableCommandTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ParseableCommandTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/commandline/ValueParserTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ValueParserTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/connectivity/MobileIconCarrierIdOverridesFake.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/MobileIconCarrierIdOverridesFake.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/connectivity/NetworkTypeResIdCacheTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkTypeResIdCacheTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/connectivity/ui/MobileContextProviderTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/ui/MobileContextProviderTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/KeyguardStatusBarRepositoryImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/KeyguardStatusBarRepositoryImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/disableflags/DisableFlagsLoggerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/DisableFlagsLoggerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/disableflags/DisableStateTrackerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/DisableStateTrackerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/FakeStatusEvent.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/events/FakeStatusEvent.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLoggerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLoggerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NoManSimulator.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NoManSimulator.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreMocks.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreMocks.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/SectionStyleProviderTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/SectionStyleProviderTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinatorTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinatorTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/DismissibilityCoordinatorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DismissibilityCoordinatorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/DreamCoordinatorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DreamCoordinatorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinatorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinatorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupWhenCoordinatorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupWhenCoordinatorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/MediaCoordinatorTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/MediaCoordinatorTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/NotificationStatsLoggerCoordinatorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/NotificationStatsLoggerCoordinatorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/RemoteInputCoordinatorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RemoteInputCoordinatorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAlertTimeCoordinatorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAlertTimeCoordinatorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinatorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinatorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/listbuilder/SemiStableSortTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/listbuilder/SemiStableSortTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderHelperTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderHelperTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionInconsistencyTrackerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionInconsistencyTrackerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/notifcollection/SelfTrackingLifetimeExtenderTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/SelfTrackingLifetimeExtenderTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProviderTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProviderTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/FakeNodeController.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/FakeNodeController.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationLaunchAnimationInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationLaunchAnimationInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/logging/ExpansionStateLoggerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/ExpansionStateLoggerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLoggerFake.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLoggerFake.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/HeadsUpStyleProviderImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/HeadsUpStyleProviderImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManagerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManagerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotifRemoteViewCacheImplTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifRemoteViewCacheImplTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolverTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolverTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/NotificationViewFlipperViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/NotificationViewFlipperViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shared/TestActiveNotificationModel.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shared/TestActiveNotificationModel.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/DisplaySwitchNotificationsHiderTrackerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/DisplaySwitchNotificationsHiderTrackerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationLoggerViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationLoggerViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ConfigurationControllerImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ConfigurationControllerImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardDismissUtilTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardDismissUtilTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyLightsOutNotifControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LegacyLightsOutNotifControllerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProviderTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProviderTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LightBarTransitionsControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarTransitionsControllerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialogTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialogTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaListenerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaListenerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ui/IconManagerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/IconManagerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconListTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconListTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/AirplaneModeRepositoryImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/AirplaneModeRepositoryImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLoggerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLoggerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModelParameterizedTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModelParameterizedTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/data/demo/DemoDeviceBasedSatelliteRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/demo/DemoDeviceBasedSatelliteRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/FakeDeviceBasedSatelliteRepository.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/FakeDeviceBasedSatelliteRepository.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/FakeDeviceBasedSatelliteViewModel.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/FakeDeviceBasedSatelliteViewModel.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/data/model/DefaultConnectionModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/model/DefaultConnectionModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/SingleBindableStatusBarIconViewTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/SingleBindableStatusBarIconViewTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewBinder.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewBinder.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt18
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt10
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapterTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapterTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BlockingQueueIntentReceiver.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BlockingQueueIntentReceiver.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ClockTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ClockTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/DevicePostureControllerImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DevicePostureControllerImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepositoryImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepositoryImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/bluetooth/FakeBluetoothRepository.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/bluetooth/FakeBluetoothRepository.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/data/repository/DeviceProvisioningRepositoryImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/data/repository/DeviceProvisioningRepositoryImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/stylus/FixedCapacityBatteryState.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/stylus/FixedCapacityBatteryState.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/glowboxeffect/GlowBoxEffectTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/glowboxeffect/GlowBoxEffectTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/loadingeffect/LoadingEffectTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/loadingeffect/LoadingEffectTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/ripple/MultiRippleControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/MultiRippleControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/ripple/RippleShaderTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleShaderTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/ripple/RippleViewTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleViewTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/shaders/SolidColorShaderTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/shaders/SolidColorShaderTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/shaders/SparkleShaderTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/shaders/SparkleShaderTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShaderTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShaderTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseViewTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseViewTest.kt)0
-rw-r--r--packages/SystemUI/res/layout/biometric_prompt_one_pane_layout.xml13
-rw-r--r--packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml13
-rw-r--r--packages/SystemUI/res/values/strings.xml29
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/DisplaySpecific.kt5
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl5
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/battery/BatterySaverModule.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/domain/BiometricsDomainLayerModule.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/SideFpsOverlayInteractor.kt82
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinder.kt111
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModel.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlags.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt39
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduStatsInteractor.kt39
-rw-r--r--packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartable.kt36
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt45
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardDismissActionBinder.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardDismissBinder.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt29
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/SideFpsProgressBarViewModel.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/dagger/BouncerTableLog.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/dagger/MediaDeviceLog.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImpl.kt166
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceLogger.kt116
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceManager.kt60
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/domain/resume/MediaResumeListener.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModel.kt34
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/IconAndNameCustomRepository.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractor.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/EditTileData.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt50
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/model/TileGridCell.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt72
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditTileViewModel.kt37
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/pipeline/dagger/QSTileListLog.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/shared/model/TileCategory.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProvider.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockNewModule.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractor.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/startable/ScrimStartable.kt70
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java37
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt59
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModel.kt150
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartableTest.kt60
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt49
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceManagerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/resume/MediaResumeListenerTest.kt59
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt (renamed from packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt)0
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt18
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt38
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModelTest.kt116
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt42
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/keyguard/TestScopeProvider.kt (renamed from packages/SystemUI/tests/src/com/android/keyguard/TestScopeProvider.kt)0
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/SideFpsOverlayInteractorKosmos.kt32
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderKosmos.kt20
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelKosmos.kt8
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorKosmos.kt9
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt11
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceLoggerKosmos.kt23
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceManagerKosmos.kt1
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigTestBuilder.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/NotificationEntryHelper.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryHelper.java)0
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioRepository.kt8
-rw-r--r--ravenwood/TEST_MAPPING4
-rw-r--r--ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java50
-rw-r--r--ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodMultipleRuleTest.java57
-rw-r--r--ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/listenertests/RavenwoodAfterClassFailureTest.java70
-rw-r--r--ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/listenertests/RavenwoodBeforeClassAssumptionFailureTest.java66
-rw-r--r--ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/listenertests/RavenwoodBeforeClassFailureTest.java71
-rw-r--r--ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/listenertests/RavenwoodClassRuleAssumptionFailureTest.java78
-rw-r--r--ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/listenertests/RavenwoodClassRuleFailureTest.java79
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerHook.java101
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java252
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java (renamed from ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java)96
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java10
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java26
-rw-r--r--ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java101
-rw-r--r--ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java184
-rw-r--r--ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java129
-rw-r--r--ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerHook.java28
-rw-r--r--ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java37
-rw-r--r--ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java13
-rw-r--r--ravenwood/tests/coretest/Android.bp25
-rw-r--r--ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerCallbackTest.java356
-rw-r--r--ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java452
-rw-r--r--ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerTestBase.java220
-rw-r--r--services/accessibility/Android.bp13
-rw-r--r--services/accessibility/TEST_MAPPING32
-rw-r--r--services/accessibility/java/com/android/server/accessibility/a11ychecker/Android.bp31
-rw-r--r--services/appfunctions/TEST_MAPPING3
-rw-r--r--services/appfunctions/java/com/android/server/appfunctions/FutureAppSearchSession.java21
-rw-r--r--services/appfunctions/java/com/android/server/appfunctions/MetadataSyncAdapter.java72
-rw-r--r--services/core/java/com/android/server/BatteryService.java62
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java25
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java10
-rw-r--r--services/core/java/com/android/server/am/SettingsToPropertiesMapper.java4
-rw-r--r--services/core/java/com/android/server/biometrics/AuthService.java4
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java25
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java8
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java27
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java6
-rw-r--r--services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java5
-rw-r--r--services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java5
-rw-r--r--services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java9
-rw-r--r--services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java42
-rw-r--r--services/core/java/com/android/server/broadcastradio/RadioServiceUserControllerImpl.java62
-rw-r--r--services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java10
-rw-r--r--services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java14
-rw-r--r--services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java27
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal1/BroadcastRadioService.java7
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal1/Tuner.java22
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java14
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java16
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java31
-rw-r--r--services/core/java/com/android/server/camera/CameraServiceProxy.java7
-rw-r--r--services/core/java/com/android/server/display/BrightnessRangeController.java3
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java22
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java5
-rw-r--r--services/core/java/com/android/server/display/HighBrightnessModeController.java2
-rw-r--r--services/core/java/com/android/server/flags/services.aconfig11
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java8
-rw-r--r--services/core/java/com/android/server/input/debug/TouchpadDebugView.java76
-rw-r--r--services/core/java/com/android/server/input/debug/TouchpadDebugViewController.java15
-rw-r--r--services/core/java/com/android/server/input/debug/TouchpadVisualisationView.java26
-rw-r--r--services/core/java/com/android/server/logcat/TEST_MAPPING7
-rw-r--r--services/core/java/com/android/server/notification/NotificationRecord.java15
-rw-r--r--services/core/java/com/android/server/notification/VibratorHelper.java31
-rw-r--r--services/core/java/com/android/server/notification/flags.aconfig7
-rw-r--r--services/core/java/com/android/server/om/OverlayManagerService.java13
-rw-r--r--services/core/java/com/android/server/pm/InstallPackageHelper.java87
-rw-r--r--services/core/java/com/android/server/pm/PackageArchiver.java36
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java10
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerService.java149
-rw-r--r--services/core/java/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java4
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java34
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java2
-rw-r--r--services/core/java/com/android/server/wm/BackNavigationController.java83
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java8
-rw-r--r--services/core/java/com/android/server/wm/DisplayRotation.java10
-rw-r--r--services/core/java/com/android/server/wm/LockTaskController.java2
-rw-r--r--services/core/java/com/android/server/wm/Transition.java54
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java21
-rw-r--r--services/tests/appfunctions/src/android/app/appfunctions/AppFunctionRuntimeMetadataTest.kt104
-rw-r--r--services/tests/appfunctions/src/com/android/server/appfunctions/FutureAppSearchSessionTest.kt57
-rw-r--r--services/tests/appfunctions/src/com/android/server/appfunctions/MetadataSyncAdapterTest.kt34
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java40
-rw-r--r--services/tests/mockingservicestests/Android.bp14
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java65
-rw-r--r--services/tests/servicestests/Android.bp61
-rw-r--r--services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java8
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java87
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/VibratorHelperTest.java59
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java34
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TransitionTests.java55
-rw-r--r--tests/Input/src/com/android/server/input/debug/TouchpadDebugViewTest.java30
-rw-r--r--tests/vcn/java/com/android/server/vcn/routeselection/NetworkEvaluationTestBase.java1
-rw-r--r--tools/aapt/Package.cpp11
537 files changed, 6372 insertions, 2978 deletions
diff --git a/Android.bp b/Android.bp
index f8907f3d82e8..258440f24084 100644
--- a/Android.bp
+++ b/Android.bp
@@ -98,6 +98,7 @@ filegroup {
":android.frameworks.location.altitude-V2-java-source",
":android.hardware.biometrics.common-V4-java-source",
":android.hardware.biometrics.fingerprint-V5-java-source",
+ ":android.hardware.biometrics.fingerprint.virtualhal-java-source",
":android.hardware.biometrics.face-V4-java-source",
":android.hardware.gnss-V2-java-source",
":android.hardware.graphics.common-V3-java-source",
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/TEST_MAPPING b/apex/jobscheduler/service/java/com/android/server/usage/TEST_MAPPING
index 52670a2570d3..dd0d1b6285de 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/TEST_MAPPING
+++ b/apex/jobscheduler/service/java/com/android/server/usage/TEST_MAPPING
@@ -10,14 +10,10 @@
]
},
{
- "name": "CtsBRSTestCases",
- "options": [
- {"exclude-annotation": "androidx.test.filters.FlakyTest"},
- {"exclude-annotation": "org.junit.Ignore"}
- ]
+ "name": "CtsBRSTestCases"
},
{
- "name": "FrameworksServicesTests_com_android_server_usage_Presubmit"
+ "name": "FrameworksServicesTests_com_android_server_usage"
}
],
"postsubmit": [
diff --git a/core/api/current.txt b/core/api/current.txt
index 5e8febebee0e..9875c0276bf0 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -32771,6 +32771,7 @@ package android.os {
field @NonNull public static final String RELEASE_OR_PREVIEW_DISPLAY;
field @Deprecated public static final String SDK;
field public static final int SDK_INT;
+ field @FlaggedApi("android.sdk.major_minor_versioning_scheme") public static final int SDK_MINOR_INT;
field public static final String SECURITY_PATCH;
}
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index ede4a8957b6f..fb425a99732a 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -18156,9 +18156,17 @@ package android.view {
field public static final int DISPLAY_IME_POLICY_LOCAL = 0; // 0x0
}
+ @FlaggedApi("android.companion.virtualdevice.flags.status_bar_and_insets") public static class WindowManager.InsetsParams {
+ ctor public WindowManager.InsetsParams(int);
+ method @Nullable public android.graphics.Insets getInsetsSize();
+ method public int getType();
+ method @NonNull public android.view.WindowManager.InsetsParams setInsetsSize(@Nullable android.graphics.Insets);
+ }
+
public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable {
method public final long getUserActivityTimeout();
method public boolean isSystemApplicationOverlay();
+ method @FlaggedApi("android.companion.virtualdevice.flags.status_bar_and_insets") public void setInsetsParams(@NonNull java.util.List<android.view.WindowManager.InsetsParams>);
method @RequiresPermission(android.Manifest.permission.SYSTEM_APPLICATION_OVERLAY) public void setSystemApplicationOverlay(boolean);
method public final void setUserActivityTimeout(long);
field @RequiresPermission(android.Manifest.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS) public static final int SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS = 524288; // 0x80000
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 7a36fbb55dc4..7a33ab748597 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1593,6 +1593,17 @@ public class Notification implements Parcelable
*/
@FlaggedApi(Flags.FLAG_API_RICH_ONGOING)
public static final String EXTRA_ENROUTE_LARGE_ICON_SUBTEXT = "android.enrouteLargeIconSubText";
+
+ /**
+ * {@link #extras} key: {@link Icon} of an image used as a thumb icon on
+ * {@link Notification} progress bar for {@link EnRouteStyle} notifications.
+ * This extra is an {@code Icon}.
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_API_RICH_ONGOING)
+ public static final String EXTRA_ENROUTE_PROGRESS_THUMB_ICON =
+ "android.enrouteProgressThumbIcon";
+
/**
* {@link #extras} key: whether the notification should be colorized as
* supplied to {@link Builder#setColorized(boolean)}.
@@ -3052,6 +3063,8 @@ public class Notification implements Parcelable
if (Flags.apiRichOngoing()) {
visitIconUri(visitor, extras.getParcelable(EXTRA_ENROUTE_OVERLAY_ICON, Icon.class));
+ visitIconUri(visitor, extras.getParcelable(EXTRA_ENROUTE_PROGRESS_THUMB_ICON,
+ Icon.class));
}
if (mBubbleMetadata != null) {
@@ -11015,6 +11028,9 @@ public class Notification implements Parcelable
@Nullable
private CharSequence mLargeIconSubText = null;
+ @Nullable
+ private Icon mProgressThumbIcon = null;
+
public EnRouteStyle() {
}
@@ -11058,6 +11074,25 @@ public class Notification implements Parcelable
return this;
}
+ /**
+ * Returns the progress thumb icon.
+ * @see EnRouteStyle#setProgressThumbIcon
+ */
+ @Nullable
+ public Icon getProgressThumbIcon() {
+ return mProgressThumbIcon;
+ }
+
+ /**
+ * Optional icon to be used as a progress thumb.
+ */
+ @NonNull
+ public EnRouteStyle setProgressThumbIcon(@Nullable Icon progressThumbIcon) {
+ mProgressThumbIcon = progressThumbIcon;
+ return this;
+ }
+
+
/**
* @hide
*/
@@ -11069,7 +11104,8 @@ public class Notification implements Parcelable
final EnRouteStyle enRouteStyle = (EnRouteStyle) other;
return !Objects.equals(mOverlayIcon, enRouteStyle.mOverlayIcon)
- || !Objects.equals(mLargeIconSubText, enRouteStyle.mLargeIconSubText);
+ || !Objects.equals(mLargeIconSubText, enRouteStyle.mLargeIconSubText)
+ || !Objects.equals(mProgressThumbIcon, enRouteStyle.mProgressThumbIcon);
}
/**
@@ -11080,6 +11116,7 @@ public class Notification implements Parcelable
super.addExtras(extras);
extras.putParcelable(EXTRA_ENROUTE_OVERLAY_ICON, mOverlayIcon);
extras.putCharSequence(EXTRA_ENROUTE_LARGE_ICON_SUBTEXT, mLargeIconSubText);
+ extras.putParcelable(EXTRA_ENROUTE_PROGRESS_THUMB_ICON, mProgressThumbIcon);
}
/**
@@ -11090,6 +11127,8 @@ public class Notification implements Parcelable
super.restoreFromExtras(extras);
mOverlayIcon = extras.getParcelable(EXTRA_ENROUTE_OVERLAY_ICON, Icon.class);
mLargeIconSubText = extras.getCharSequence(EXTRA_ENROUTE_LARGE_ICON_SUBTEXT);
+ mProgressThumbIcon =
+ extras.getParcelable(EXTRA_ENROUTE_PROGRESS_THUMB_ICON, Icon.class);
}
/**
@@ -11101,6 +11140,10 @@ public class Notification implements Parcelable
if (mOverlayIcon != null) {
mOverlayIcon.convertToAshmem();
}
+
+ if (mProgressThumbIcon != null) {
+ mProgressThumbIcon.convertToAshmem();
+ }
}
/**
diff --git a/core/java/android/app/appfunctions/AppFunctionRuntimeMetadata.java b/core/java/android/app/appfunctions/AppFunctionRuntimeMetadata.java
index c4bfae98e33d..f5c5a11f45fb 100644
--- a/core/java/android/app/appfunctions/AppFunctionRuntimeMetadata.java
+++ b/core/java/android/app/appfunctions/AppFunctionRuntimeMetadata.java
@@ -61,6 +61,20 @@ public class AppFunctionRuntimeMetadata extends GenericDocument {
return RUNTIME_SCHEMA_TYPE + RUNTIME_SCHEMA_TYPE_SEPARATOR + Objects.requireNonNull(pkg);
}
+ /** Returns the package name from the runtime metadata schema name. */
+ @NonNull
+ public static String getPackageNameFromSchema(String metadataSchemaType) {
+ String[] split = metadataSchemaType.split(RUNTIME_SCHEMA_TYPE_SEPARATOR);
+ if (split.length > 2) {
+ throw new IllegalArgumentException(
+ "Invalid schema type: " + metadataSchemaType + " for app function runtime");
+ }
+ if (split.length < 2) {
+ return APP_FUNCTION_INDEXER_PACKAGE;
+ }
+ return split[1];
+ }
+
/** Returns the document id for an app function's runtime metadata. */
public static String getDocumentIdForAppFunction(
@NonNull String pkg, @NonNull String functionId) {
diff --git a/core/java/android/app/appfunctions/AppFunctionStaticMetadataHelper.java b/core/java/android/app/appfunctions/AppFunctionStaticMetadataHelper.java
index 926cc9a3642c..085e0a47d356 100644
--- a/core/java/android/app/appfunctions/AppFunctionStaticMetadataHelper.java
+++ b/core/java/android/app/appfunctions/AppFunctionStaticMetadataHelper.java
@@ -39,6 +39,8 @@ public class AppFunctionStaticMetadataHelper {
public static final String STATIC_PROPERTY_ENABLED_BY_DEFAULT = "enabledByDefault";
public static final String APP_FUNCTION_STATIC_NAMESPACE = "app_functions";
+ public static final String PROPERTY_FUNCTION_ID = "functionId";
+ public static final String PROPERTY_PACKAGE_NAME = "packageName";
// These are constants that has to be kept the same with {@code
// com.android.server.appsearch.appsindexer.appsearchtypes.AppSearchHelper}.
diff --git a/core/java/android/companion/virtual/flags/flags.aconfig b/core/java/android/companion/virtual/flags/flags.aconfig
index 748260bc8d5f..e9fa3e15fe05 100644
--- a/core/java/android/companion/virtual/flags/flags.aconfig
+++ b/core/java/android/companion/virtual/flags/flags.aconfig
@@ -43,6 +43,7 @@ flag {
name: "virtual_display_insets"
description: "APIs for specifying virtual display insets (via cutout)"
bug: "350007135"
+ is_exported: true
}
flag {
@@ -88,6 +89,7 @@ flag {
name: "virtual_display_rotation_api"
description: "API for on-demand rotation of virtual displays"
bug: "291748430"
+ is_exported: true
}
flag {
@@ -110,6 +112,7 @@ flag {
name: "device_aware_display_power"
description: "Device awareness in power and display APIs"
bug: "285020111"
+ is_exported: true
}
flag {
@@ -125,4 +128,12 @@ flag {
namespace: "virtual_devices"
description: "Allow for status bar and insets on virtual devices"
bug: "350007866"
+ is_exported: true
+}
+
+flag {
+ namespace: "virtual_devices"
+ name: "camera_timestamp_from_surface"
+ description: "Pass the surface timestamp to the capture result"
+ bug: "351341245"
}
diff --git a/core/java/android/content/pm/LauncherActivityInfo.java b/core/java/android/content/pm/LauncherActivityInfo.java
index cb3455b266cd..bb91a37825e6 100644
--- a/core/java/android/content/pm/LauncherActivityInfo.java
+++ b/core/java/android/content/pm/LauncherActivityInfo.java
@@ -43,9 +43,11 @@ public class LauncherActivityInfo {
private final PackageManager mPm;
private final LauncherActivityInfoInternal mInternal;
- private static final UnicodeSet TRIMMABLE_CHARACTERS =
+ private static final UnicodeSet INVISIBLE_CHARACTERS =
new UnicodeSet("[[:White_Space:][:Default_Ignorable_Code_Point:][:gc=Cc:]]",
/* ignoreWhitespace= */ false).freeze();
+ // Only allow 3 consecutive invisible characters in the prefix of the string.
+ private static final int PREFIX_CONSECUTIVE_INVISIBLE_CHARACTERS_MAXIMUM = 3;
/**
* Create a launchable activity object for a given ResolveInfo and user.
@@ -93,17 +95,21 @@ public class LauncherActivityInfo {
return getActivityInfo().loadLabel(mPm);
}
- CharSequence label = trim(getActivityInfo().loadLabel(mPm));
- // If the trimmed label is empty, use application's label instead
- if (TextUtils.isEmpty(label)) {
- label = trim(getApplicationInfo().loadLabel(mPm));
- // If the trimmed label is still empty, use package name instead
- if (TextUtils.isEmpty(label)) {
- label = getComponentName().getPackageName();
- }
+ CharSequence label = getActivityInfo().loadLabel(mPm).toString().trim();
+ // If the activity label is visible to the user, return the original activity label
+ if (isVisible(label)) {
+ return label;
}
- // TODO: Go through LauncherAppsService
- return label;
+
+ // Use application label instead
+ label = getApplicationInfo().loadLabel(mPm).toString().trim();
+ // If the application label is visible to the user, return the original application label
+ if (isVisible(label)) {
+ return label;
+ }
+
+ // Use package name instead
+ return getComponentName().getPackageName();
}
/**
@@ -207,147 +213,75 @@ public class LauncherActivityInfo {
}
/**
- * If the {@code ch} is trimmable, return {@code true}. Otherwise, return
- * {@code false}. If the count of the code points of {@code ch} doesn't
- * equal 1, return {@code false}.
+ * Check whether the {@code sequence} is visible to the user or not.
+ * <p>
+ * Return {@code false} when one of these conditions are satisfied:
+ * 1. The {@code sequence} starts with at least consecutive three invisible characters.
+ * 2. The sequence is composed of the invisible characters and non-glyph characters.
* <p>
- * There are two types of the trimmable characters.
- * 1. The character is one of the Default_Ignorable_Code_Point in
+ * Invisible character is one of the Default_Ignorable_Code_Point in
* <a href="
* https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt">
* DerivedCoreProperties.txt</a>, the White_Space in <a href=
* "https://www.unicode.org/Public/UCD/latest/ucd/PropList.txt">PropList.txt
* </a> or category Cc.
* <p>
- * 2. The character is not supported in the current system font.
+ * Non-glyph character means the character is not supported in the current system font.
* {@link android.graphics.Paint#hasGlyph(String)}
* <p>
*
- */
- private static boolean isTrimmable(@NonNull Paint paint, @NonNull CharSequence ch) {
- Objects.requireNonNull(paint);
- Objects.requireNonNull(ch);
-
- // if ch is empty or it is not a character (i,e, the count of code
- // point doesn't equal one), return false
- if (TextUtils.isEmpty(ch)
- || Character.codePointCount(ch, /* beginIndex= */ 0, ch.length()) != 1) {
- return false;
- }
-
- // Return true for the cases as below:
- // 1. The character is in the TRIMMABLE_CHARACTERS set
- // 2. The character is not supported in the system font
- return TRIMMABLE_CHARACTERS.contains(ch) || !paint.hasGlyph(ch.toString());
- }
-
- /**
- * If the {@code sequence} has some leading trimmable characters, creates a new copy
- * and removes the trimmable characters from the copy. Otherwise the given
- * {@code sequence} is returned as it is. Use {@link #isTrimmable(Paint, CharSequence)}
- * to determine whether the character is trimmable or not.
- *
- * @return the trimmed string or the original string that has no
- * leading trimmable characters.
- * @see #isTrimmable(Paint, CharSequence)
- * @see #trim(CharSequence)
- * @see #trimEnd(CharSequence)
- *
* @hide
*/
@VisibleForTesting
- @NonNull
- public static CharSequence trimStart(@NonNull CharSequence sequence) {
+ public static boolean isVisible(@NonNull CharSequence sequence) {
Objects.requireNonNull(sequence);
-
if (TextUtils.isEmpty(sequence)) {
- return sequence;
+ return false;
}
final Paint paint = new Paint();
- int trimCount = 0;
+ int invisibleCharCount = 0;
+ int notSupportedCharCount = 0;
final int[] codePoints = sequence.codePoints().toArray();
for (int i = 0, length = codePoints.length; i < length; i++) {
String ch = new String(new int[]{codePoints[i]}, /* offset= */ 0, /* count= */ 1);
- if (!isTrimmable(paint, ch)) {
- break;
- }
- trimCount += ch.length();
- }
- if (trimCount == 0) {
- return sequence;
- }
- return sequence.subSequence(trimCount, sequence.length());
- }
- /**
- * If the {@code sequence} has some trailing trimmable characters, creates a new copy
- * and removes the trimmable characters from the copy. Otherwise the given
- * {@code sequence} is returned as it is. Use {@link #isTrimmable(Paint, CharSequence)}
- * to determine whether the character is trimmable or not.
- *
- * @return the trimmed sequence or the original sequence that has no
- * trailing trimmable characters.
- * @see #isTrimmable(Paint, CharSequence)
- * @see #trimStart(CharSequence)
- * @see #trim(CharSequence)
- *
- * @hide
- */
- @VisibleForTesting
- @NonNull
- public static CharSequence trimEnd(@NonNull CharSequence sequence) {
- Objects.requireNonNull(sequence);
-
- if (TextUtils.isEmpty(sequence)) {
- return sequence;
- }
-
- final Paint paint = new Paint();
- int trimCount = 0;
- final int[] codePoints = sequence.codePoints().toArray();
- for (int i = codePoints.length - 1; i >= 0; i--) {
- String ch = new String(new int[]{codePoints[i]}, /* offset= */ 0, /* count= */ 1);
- if (!isTrimmable(paint, ch)) {
- break;
+ // The check steps:
+ // 1. If the character is contained in INVISIBLE_CHARACTERS, invisibleCharCount++.
+ // 1.1 Check whether the invisibleCharCount is larger or equal to
+ // PREFIX_INVISIBLE_CHARACTERS_MAXIMUM when notSupportedCharCount is zero.
+ // It means that there are three consecutive invisible characters at the
+ // start of the string, return false.
+ // Otherwise, continue.
+ // 2. If the character is not supported on the system:
+ // notSupportedCharCount++, continue
+ // 3. If it does not continue or return on the above two cases, it means the
+ // character is visible and supported on the system, break.
+ // After going through the whole string, if the sum of invisibleCharCount
+ // and notSupportedCharCount is smaller than the length of the string, it
+ // means the string has the other visible characters, return true.
+ // Otherwise, return false.
+ if (INVISIBLE_CHARACTERS.contains(ch)) {
+ invisibleCharCount++;
+ // If there are three successive invisible characters at the start of the
+ // string, it is hard to visible to the user.
+ if (notSupportedCharCount == 0
+ && invisibleCharCount >= PREFIX_CONSECUTIVE_INVISIBLE_CHARACTERS_MAXIMUM) {
+ return false;
+ }
+ continue;
}
- trimCount += ch.length();
- }
-
- if (trimCount == 0) {
- return sequence;
- }
- return sequence.subSequence(0, sequence.length() - trimCount);
- }
- /**
- * If the {@code sequence} has some leading or trailing trimmable characters, creates
- * a new copy and removes the trimmable characters from the copy. Otherwise the given
- * {@code sequence} is returned as it is. Use {@link #isTrimmable(Paint, CharSequence)}
- * to determine whether the character is trimmable or not.
- *
- * @return the trimmed sequence or the original sequence that has no leading or
- * trailing trimmable characters.
- * @see #isTrimmable(Paint, CharSequence)
- * @see #trimStart(CharSequence)
- * @see #trimEnd(CharSequence)
- *
- * @hide
- */
- @VisibleForTesting
- @NonNull
- public static CharSequence trim(@NonNull CharSequence sequence) {
- Objects.requireNonNull(sequence);
-
- if (TextUtils.isEmpty(sequence)) {
- return sequence;
- }
-
- CharSequence result = trimStart(sequence);
- if (TextUtils.isEmpty(result)) {
- return result;
+ // The character is not supported on the system, but it may not be an invisible
+ // character. E.g. tofu (a rectangle).
+ if (!paint.hasGlyph(ch)) {
+ notSupportedCharCount++;
+ continue;
+ }
+ // The character is visible and supported on the system, break the for loop
+ break;
}
- return trimEnd(result);
+ return (invisibleCharCount + notSupportedCharCount < codePoints.length);
}
}
diff --git a/core/java/android/hardware/fingerprint/FingerprintSensorConfigurations.java b/core/java/android/hardware/fingerprint/FingerprintSensorConfigurations.java
index 43c0da9bd8ed..48c5887d80d0 100644
--- a/core/java/android/hardware/fingerprint/FingerprintSensorConfigurations.java
+++ b/core/java/android/hardware/fingerprint/FingerprintSensorConfigurations.java
@@ -23,12 +23,14 @@ import android.annotation.Nullable;
import android.content.Context;
import android.hardware.biometrics.fingerprint.IFingerprint;
import android.hardware.biometrics.fingerprint.SensorProps;
+import android.hardware.biometrics.fingerprint.virtualhal.IVirtualHal;
import android.os.Binder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
+import android.util.Slog;
import java.util.ArrayList;
import java.util.HashMap;
@@ -162,6 +164,43 @@ public class FingerprintSensorConfigurations implements Parcelable {
dest.writeMap(mSensorPropsMap);
}
+
+ /**
+ * Remap fqName of VHAL because the `virtual` instance is registered
+ * with IVirtulalHal now (IFingerprint previously)
+ * @param fqName fqName to be translated
+ * @return real fqName
+ */
+ public static String remapFqName(String fqName) {
+ if (!fqName.contains(IFingerprint.DESCRIPTOR + "/virtual")) {
+ return fqName; //no remap needed for real hardware HAL
+ } else {
+ //new Vhal instance name
+ return fqName.replace("IFingerprint", "virtualhal.IVirtualHal");
+ }
+ }
+
+ /**
+ * @param fqName aidl interface instance name
+ * @return aidl interface
+ */
+ public static IFingerprint getIFingerprint(String fqName) {
+ if (fqName.contains("virtual")) {
+ String fqNameMapped = remapFqName(fqName);
+ Slog.i(TAG, "getIFingerprint fqName is mapped: " + fqName + "->" + fqNameMapped);
+ try {
+ IVirtualHal vhal = IVirtualHal.Stub.asInterface(
+ Binder.allowBlocking(ServiceManager.waitForService(fqNameMapped)));
+ return vhal.getFingerprintHal();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception in vhal.getFingerprintHal() call" + fqNameMapped);
+ }
+ }
+
+ return IFingerprint.Stub.asInterface(
+ Binder.allowBlocking(ServiceManager.waitForDeclaredService(fqName)));
+ }
+
/**
* Returns fingerprint sensor props for the HAL {@param instance}.
*/
@@ -176,8 +215,7 @@ public class FingerprintSensorConfigurations implements Parcelable {
try {
final String fqName = IFingerprint.DESCRIPTOR + "/" + instance;
- final IFingerprint fp = IFingerprint.Stub.asInterface(Binder.allowBlocking(
- ServiceManager.waitForDeclaredService(fqName)));
+ final IFingerprint fp = getIFingerprint(fqName);
if (fp != null) {
props = fp.getSensorProps();
} else {
diff --git a/core/java/android/net/vcn/flags.aconfig b/core/java/android/net/vcn/flags.aconfig
index d4d1ed22dd4e..dcb363ccf535 100644
--- a/core/java/android/net/vcn/flags.aconfig
+++ b/core/java/android/net/vcn/flags.aconfig
@@ -55,14 +55,4 @@ flag{
metadata {
purpose: PURPOSE_BUGFIX
}
-}
-
-flag{
- name: "allow_disable_ipsec_loss_detector"
- namespace: "vcn"
- description: "Allow disabling IPsec packet loss detector"
- bug: "336638836"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
} \ No newline at end of file
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 30d2dec8b4c4..a8267d1c9d8c 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -17,6 +17,7 @@
package android.os;
import android.Manifest;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -28,6 +29,7 @@ import android.app.Application;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.ravenwood.annotation.RavenwoodKeepWholeClass;
+import android.sdk.Flags;
import android.sysprop.DeviceProperties;
import android.sysprop.SocProperties;
import android.sysprop.TelephonyProperties;
@@ -399,12 +401,35 @@ public class Build {
* device. This value never changes while a device is booted, but it may
* increase when the hardware manufacturer provides an OTA update.
* <p>
+ * Together with {@link SDK_MINOR_INT}, this constant defines the
+ * <pre>major.minor</pre> version of Android. <pre>SDK_INT</pre> is
+ * increased and <pre>SDK_MINOR_INT</pre> is set to 0 on new Android
+ * dessert releases. Between these, Android may also release so called
+ * minor releases where <pre>SDK_INT</pre> remains unchanged and
+ * <pre>SDK_MINOR_INT</pre> is increased. Minor releases can add new
+ * APIs, and have stricter guarantees around backwards compatibility
+ * (e.g. no changes gated by <pre>targetSdkVersion</pre>) compared to
+ * major releases.
+ * <p>
* Possible values are defined in {@link Build.VERSION_CODES}.
*/
public static final int SDK_INT = SystemProperties.getInt(
"ro.build.version.sdk", 0);
/**
+ * The minor SDK version of the software currently running on this hardware
+ * device. This value never changes while a device is booted, but it may
+ * increase when the hardware manufacturer provides an OTA update.
+ * <p>
+ * Together with {@link SDK_INT}, this constant defines the
+ * <pre>major.minor</pre> version of Android. See {@link SDK_INT} for
+ * more information.
+ */
+ @FlaggedApi(Flags.FLAG_MAJOR_MINOR_VERSIONING_SCHEME)
+ public static final int SDK_MINOR_INT = SystemProperties.getInt(
+ "ro.build.version.sdk_minor", 0);
+
+ /**
* The SDK version of the software that <em>initially</em> shipped on
* this hardware device. It <em>never</em> changes during the lifetime
* of the device, even when {@link #SDK_INT} increases due to an OTA
diff --git a/core/java/android/os/SystemClock.java b/core/java/android/os/SystemClock.java
index 0ed1ab6c8d72..4c9a02c1fc49 100644
--- a/core/java/android/os/SystemClock.java
+++ b/core/java/android/os/SystemClock.java
@@ -109,6 +109,7 @@ public final class SystemClock {
private static final String TAG = "SystemClock";
private static volatile IAlarmManager sIAlarmManager;
+ private static volatile ITimeDetectorService sITimeDetectorService;
/**
* Since {@code nanoTime()} is arbitrary, anchor our Ravenwood clocks against it.
@@ -188,6 +189,14 @@ public final class SystemClock {
return sIAlarmManager;
}
+ private static ITimeDetectorService getITimeDetectorService() {
+ if (sITimeDetectorService == null) {
+ sITimeDetectorService = ITimeDetectorService.Stub
+ .asInterface(ServiceManager.getService(Context.TIME_DETECTOR_SERVICE));
+ }
+ return sITimeDetectorService;
+ }
+
/**
* Returns milliseconds since boot, not counting time spent in deep sleep.
*
@@ -314,15 +323,6 @@ public final class SystemClock {
}
/**
- * @see #currentNetworkTimeMillis(ITimeDetectorService)
- * @hide
- */
- public static long currentNetworkTimeMillis() {
- return currentNetworkTimeMillis(ITimeDetectorService.Stub
- .asInterface(ServiceManager.getService(Context.TIME_DETECTOR_SERVICE)));
- }
-
- /**
* Returns milliseconds since January 1, 1970 00:00:00.0 UTC, synchronized
* using a remote network source outside the device.
* <p>
@@ -346,29 +346,29 @@ public final class SystemClock {
* @throws DateTimeException when no network time can be provided.
* @hide
*/
- public static long currentNetworkTimeMillis(
- ITimeDetectorService timeDetectorService) {
- if (timeDetectorService != null) {
- UnixEpochTime time;
- try {
- time = timeDetectorService.latestNetworkTime();
- } catch (ParcelableException e) {
- e.maybeRethrow(DateTimeException.class);
- throw new RuntimeException(e);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
-
- if (time == null) {
- // This is not expected.
- throw new DateTimeException("Network based time is not available.");
- }
- long currentMillis = elapsedRealtime();
- long deltaMs = currentMillis - time.getElapsedRealtimeMillis();
- return time.getUnixEpochTimeMillis() + deltaMs;
- } else {
+ public static long currentNetworkTimeMillis() {
+ ITimeDetectorService timeDetectorService = getITimeDetectorService();
+ if (timeDetectorService == null) {
throw new RuntimeException(new DeadSystemException());
}
+
+ UnixEpochTime time;
+ try {
+ time = timeDetectorService.latestNetworkTime();
+ } catch (ParcelableException e) {
+ e.maybeRethrow(DateTimeException.class);
+ throw new RuntimeException(e);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ if (time == null) {
+ // This is not expected.
+ throw new DateTimeException("Network based time is not available.");
+ }
+
+ long currentMillis = elapsedRealtime();
+ long deltaMs = currentMillis - time.getElapsedRealtimeMillis();
+ return time.getUnixEpochTimeMillis() + deltaMs;
}
/**
@@ -396,14 +396,9 @@ public final class SystemClock {
*/
public static @NonNull Clock currentNetworkTimeClock() {
return new SimpleClock(ZoneOffset.UTC) {
- private ITimeDetectorService mSvc;
@Override
public long millis() {
- if (mSvc == null) {
- mSvc = ITimeDetectorService.Stub
- .asInterface(ServiceManager.getService(Context.TIME_DETECTOR_SERVICE));
- }
- return SystemClock.currentNetworkTimeMillis(mSvc);
+ return SystemClock.currentNetworkTimeMillis();
}
};
}
diff --git a/core/java/android/text/ClientFlags.java b/core/java/android/text/ClientFlags.java
index bbe9cdbbce9f..c2ad508c2b44 100644
--- a/core/java/android/text/ClientFlags.java
+++ b/core/java/android/text/ClientFlags.java
@@ -28,27 +28,6 @@ import com.android.text.flags.Flags;
*/
public class ClientFlags {
/**
- * @see Flags#noBreakNoHyphenationSpan()
- */
- public static boolean noBreakNoHyphenationSpan() {
- return TextFlags.isFeatureEnabled(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN);
- }
-
- /**
- * @see Flags#fixLineHeightForLocale()
- */
- public static boolean fixLineHeightForLocale() {
- return TextFlags.isFeatureEnabled(Flags.FLAG_FIX_LINE_HEIGHT_FOR_LOCALE);
- }
-
- /**
- * @see Flags#icuBidiMigration()
- */
- public static boolean icuBidiMigration() {
- return TextFlags.isFeatureEnabled(Flags.FLAG_ICU_BIDI_MIGRATION);
- }
-
- /**
* @see Flags#fixMisalignedContextMenu()
*/
public static boolean fixMisalignedContextMenu() {
diff --git a/core/java/android/text/MeasuredParagraph.java b/core/java/android/text/MeasuredParagraph.java
index 896e08726419..31a226341907 100644
--- a/core/java/android/text/MeasuredParagraph.java
+++ b/core/java/android/text/MeasuredParagraph.java
@@ -42,8 +42,6 @@ import android.text.style.MetricAffectingSpan;
import android.text.style.ReplacementSpan;
import android.util.Pools.SynchronizedPool;
-import com.android.text.flags.Flags;
-
import java.util.Arrays;
/**
@@ -201,14 +199,11 @@ public class MeasuredParagraph {
* @hide
*/
public @Layout.Direction int getParagraphDir() {
- if (Flags.icuBidiMigration()) {
- if (mBidi == null) {
- return Layout.DIR_LEFT_TO_RIGHT;
- }
- return (mBidi.getParaLevel() & 0x01) == 0
- ? Layout.DIR_LEFT_TO_RIGHT : Layout.DIR_RIGHT_TO_LEFT;
+ if (mBidi == null) {
+ return Layout.DIR_LEFT_TO_RIGHT;
}
- return mParaDir;
+ return (mBidi.getParaLevel() & 0x01) == 0
+ ? Layout.DIR_LEFT_TO_RIGHT : Layout.DIR_RIGHT_TO_LEFT;
}
/**
@@ -219,71 +214,62 @@ public class MeasuredParagraph {
*/
public Directions getDirections(@IntRange(from = 0) int start, // inclusive
@IntRange(from = 0) int end) { // exclusive
- if (Flags.icuBidiMigration()) {
- // Easy case: mBidi == null means the text is all LTR and no bidi suppot is needed.
- if (mBidi == null) {
- return Layout.DIRS_ALL_LEFT_TO_RIGHT;
- }
+ // Easy case: mBidi == null means the text is all LTR and no bidi suppot is needed.
+ if (mBidi == null) {
+ return Layout.DIRS_ALL_LEFT_TO_RIGHT;
+ }
- // Easy case: If the original text only contains single directionality run, the
- // substring is only single run.
- if (start == end) {
- if ((mBidi.getParaLevel() & 0x01) == 0) {
- return Layout.DIRS_ALL_LEFT_TO_RIGHT;
- } else {
- return Layout.DIRS_ALL_RIGHT_TO_LEFT;
- }
+ // Easy case: If the original text only contains single directionality run, the
+ // substring is only single run.
+ if (start == end) {
+ if ((mBidi.getParaLevel() & 0x01) == 0) {
+ return Layout.DIRS_ALL_LEFT_TO_RIGHT;
+ } else {
+ return Layout.DIRS_ALL_RIGHT_TO_LEFT;
}
+ }
- // Okay, now we need to generate the line instance.
- Bidi bidi = mBidi.createLineBidi(start, end);
-
- // Easy case: If the line instance only contains single directionality run, no need
- // to reorder visually.
- if (bidi.getRunCount() == 1) {
- if (bidi.getRunLevel(0) == 1) {
- return Layout.DIRS_ALL_RIGHT_TO_LEFT;
- } else if (bidi.getRunLevel(0) == 0) {
- return Layout.DIRS_ALL_LEFT_TO_RIGHT;
- } else {
- return new Directions(new int[] {
- 0, bidi.getRunLevel(0) << Layout.RUN_LEVEL_SHIFT | (end - start)});
- }
- }
+ // Okay, now we need to generate the line instance.
+ Bidi bidi = mBidi.createLineBidi(start, end);
- // Reorder directionality run visually.
- byte[] levels = new byte[bidi.getRunCount()];
- for (int i = 0; i < bidi.getRunCount(); ++i) {
- levels[i] = (byte) bidi.getRunLevel(i);
+ // Easy case: If the line instance only contains single directionality run, no need
+ // to reorder visually.
+ if (bidi.getRunCount() == 1) {
+ if (bidi.getRunLevel(0) == 1) {
+ return Layout.DIRS_ALL_RIGHT_TO_LEFT;
+ } else if (bidi.getRunLevel(0) == 0) {
+ return Layout.DIRS_ALL_LEFT_TO_RIGHT;
+ } else {
+ return new Directions(new int[] {
+ 0, bidi.getRunLevel(0) << Layout.RUN_LEVEL_SHIFT | (end - start)});
}
- int[] visualOrders = Bidi.reorderVisual(levels);
-
- int[] dirs = new int[bidi.getRunCount() * 2];
- for (int i = 0; i < bidi.getRunCount(); ++i) {
- int vIndex;
- if ((mBidi.getBaseLevel() & 0x01) == 1) {
- // For the historical reasons, if the base directionality is RTL, the Android
- // draws from the right, i.e. the visually reordered run needs to be reversed.
- vIndex = visualOrders[bidi.getRunCount() - i - 1];
- } else {
- vIndex = visualOrders[i];
- }
+ }
- // Special packing of dire
- dirs[i * 2] = bidi.getRunStart(vIndex);
- dirs[i * 2 + 1] = bidi.getRunLevel(vIndex) << Layout.RUN_LEVEL_SHIFT
- | (bidi.getRunLimit(vIndex) - dirs[i * 2]);
+ // Reorder directionality run visually.
+ byte[] levels = new byte[bidi.getRunCount()];
+ for (int i = 0; i < bidi.getRunCount(); ++i) {
+ levels[i] = (byte) bidi.getRunLevel(i);
+ }
+ int[] visualOrders = Bidi.reorderVisual(levels);
+
+ int[] dirs = new int[bidi.getRunCount() * 2];
+ for (int i = 0; i < bidi.getRunCount(); ++i) {
+ int vIndex;
+ if ((mBidi.getBaseLevel() & 0x01) == 1) {
+ // For the historical reasons, if the base directionality is RTL, the Android
+ // draws from the right, i.e. the visually reordered run needs to be reversed.
+ vIndex = visualOrders[bidi.getRunCount() - i - 1];
+ } else {
+ vIndex = visualOrders[i];
}
- return new Directions(dirs);
- }
- if (mLtrWithoutBidi) {
- return Layout.DIRS_ALL_LEFT_TO_RIGHT;
+ // Special packing of dire
+ dirs[i * 2] = bidi.getRunStart(vIndex);
+ dirs[i * 2 + 1] = bidi.getRunLevel(vIndex) << Layout.RUN_LEVEL_SHIFT
+ | (bidi.getRunLimit(vIndex) - dirs[i * 2]);
}
- final int length = end - start;
- return AndroidBidi.directions(mParaDir, mLevels.getRawArray(), start, mCopiedBuffer, start,
- length);
+ return new Directions(dirs);
}
/**
@@ -681,84 +667,56 @@ public class MeasuredParagraph {
}
}
- if (Flags.icuBidiMigration()) {
- if ((textDir == TextDirectionHeuristics.LTR
- || textDir == TextDirectionHeuristics.FIRSTSTRONG_LTR
- || textDir == TextDirectionHeuristics.ANYRTL_LTR)
- && TextUtils.doesNotNeedBidi(mCopiedBuffer, 0, mTextLength)) {
- mLevels.clear();
- mLtrWithoutBidi = true;
- return;
- }
- final int bidiRequest;
- if (textDir == TextDirectionHeuristics.LTR) {
- bidiRequest = Bidi.LTR;
- } else if (textDir == TextDirectionHeuristics.RTL) {
- bidiRequest = Bidi.RTL;
- } else if (textDir == TextDirectionHeuristics.FIRSTSTRONG_LTR) {
- bidiRequest = Bidi.LEVEL_DEFAULT_LTR;
- } else if (textDir == TextDirectionHeuristics.FIRSTSTRONG_RTL) {
- bidiRequest = Bidi.LEVEL_DEFAULT_RTL;
- } else {
- final boolean isRtl = textDir.isRtl(mCopiedBuffer, 0, mTextLength);
- bidiRequest = isRtl ? Bidi.RTL : Bidi.LTR;
- }
- mBidi = new Bidi(mCopiedBuffer, 0, null, 0, mCopiedBuffer.length, bidiRequest);
-
- if (mCopiedBuffer.length > 0
- && mBidi.getParagraphIndex(mCopiedBuffer.length - 1) != 0) {
- // Historically, the MeasuredParagraph does not treat the CR letters as paragraph
- // breaker but ICU BiDi treats it as paragraph breaker. In the MeasureParagraph,
- // the given range always represents a single paragraph, so if the BiDi object has
- // multiple paragraph, it should contains a CR letters in the text. Using CR is not
- // common in Android and also it should not penalize the easy case, e.g. all LTR,
- // check the paragraph count here and replace the CR letters and re-calculate
- // BiDi again.
- for (int i = 0; i < mTextLength; ++i) {
- if (Character.isSurrogate(mCopiedBuffer[i])) {
- // All block separators are in BMP.
- continue;
- }
- if (UCharacter.getDirection(mCopiedBuffer[i])
- == UCharacterDirection.BLOCK_SEPARATOR) {
- mCopiedBuffer[i] = OBJECT_REPLACEMENT_CHARACTER;
- }
- }
- mBidi = new Bidi(mCopiedBuffer, 0, null, 0, mCopiedBuffer.length, bidiRequest);
- }
- mLevels.resize(mTextLength);
- byte[] rawArray = mLevels.getRawArray();
- for (int i = 0; i < mTextLength; ++i) {
- rawArray[i] = mBidi.getLevelAt(i);
- }
- mLtrWithoutBidi = false;
- return;
- }
if ((textDir == TextDirectionHeuristics.LTR
|| textDir == TextDirectionHeuristics.FIRSTSTRONG_LTR
|| textDir == TextDirectionHeuristics.ANYRTL_LTR)
&& TextUtils.doesNotNeedBidi(mCopiedBuffer, 0, mTextLength)) {
mLevels.clear();
- mParaDir = Layout.DIR_LEFT_TO_RIGHT;
mLtrWithoutBidi = true;
+ return;
+ }
+ final int bidiRequest;
+ if (textDir == TextDirectionHeuristics.LTR) {
+ bidiRequest = Bidi.LTR;
+ } else if (textDir == TextDirectionHeuristics.RTL) {
+ bidiRequest = Bidi.RTL;
+ } else if (textDir == TextDirectionHeuristics.FIRSTSTRONG_LTR) {
+ bidiRequest = Bidi.LEVEL_DEFAULT_LTR;
+ } else if (textDir == TextDirectionHeuristics.FIRSTSTRONG_RTL) {
+ bidiRequest = Bidi.LEVEL_DEFAULT_RTL;
} else {
- final int bidiRequest;
- if (textDir == TextDirectionHeuristics.LTR) {
- bidiRequest = Layout.DIR_REQUEST_LTR;
- } else if (textDir == TextDirectionHeuristics.RTL) {
- bidiRequest = Layout.DIR_REQUEST_RTL;
- } else if (textDir == TextDirectionHeuristics.FIRSTSTRONG_LTR) {
- bidiRequest = Layout.DIR_REQUEST_DEFAULT_LTR;
- } else if (textDir == TextDirectionHeuristics.FIRSTSTRONG_RTL) {
- bidiRequest = Layout.DIR_REQUEST_DEFAULT_RTL;
- } else {
- final boolean isRtl = textDir.isRtl(mCopiedBuffer, 0, mTextLength);
- bidiRequest = isRtl ? Layout.DIR_REQUEST_RTL : Layout.DIR_REQUEST_LTR;
+ final boolean isRtl = textDir.isRtl(mCopiedBuffer, 0, mTextLength);
+ bidiRequest = isRtl ? Bidi.RTL : Bidi.LTR;
+ }
+ mBidi = new Bidi(mCopiedBuffer, 0, null, 0, mCopiedBuffer.length, bidiRequest);
+
+ if (mCopiedBuffer.length > 0
+ && mBidi.getParagraphIndex(mCopiedBuffer.length - 1) != 0) {
+ // Historically, the MeasuredParagraph does not treat the CR letters as paragraph
+ // breaker but ICU BiDi treats it as paragraph breaker. In the MeasureParagraph,
+ // the given range always represents a single paragraph, so if the BiDi object has
+ // multiple paragraph, it should contains a CR letters in the text. Using CR is not
+ // common in Android and also it should not penalize the easy case, e.g. all LTR,
+ // check the paragraph count here and replace the CR letters and re-calculate
+ // BiDi again.
+ for (int i = 0; i < mTextLength; ++i) {
+ if (Character.isSurrogate(mCopiedBuffer[i])) {
+ // All block separators are in BMP.
+ continue;
+ }
+ if (UCharacter.getDirection(mCopiedBuffer[i])
+ == UCharacterDirection.BLOCK_SEPARATOR) {
+ mCopiedBuffer[i] = OBJECT_REPLACEMENT_CHARACTER;
+ }
}
- mLevels.resize(mTextLength);
- mParaDir = AndroidBidi.bidi(bidiRequest, mCopiedBuffer, mLevels.getRawArray());
- mLtrWithoutBidi = false;
+ mBidi = new Bidi(mCopiedBuffer, 0, null, 0, mCopiedBuffer.length, bidiRequest);
+ }
+ mLevels.resize(mTextLength);
+ byte[] rawArray = mLevels.getRawArray();
+ for (int i = 0; i < mTextLength; ++i) {
+ rawArray[i] = mBidi.getLevelAt(i);
}
+ mLtrWithoutBidi = false;
}
private void applyReplacementRun(@NonNull ReplacementSpan replacement,
diff --git a/core/java/android/text/TextFlags.java b/core/java/android/text/TextFlags.java
index 0f1b031a8fad..076721f629ed 100644
--- a/core/java/android/text/TextFlags.java
+++ b/core/java/android/text/TextFlags.java
@@ -55,9 +55,6 @@ public final class TextFlags {
* List of text flags to be transferred to the application process.
*/
public static final String[] TEXT_ACONFIGS_FLAGS = {
- Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN,
- Flags.FLAG_FIX_LINE_HEIGHT_FOR_LOCALE,
- Flags.FLAG_ICU_BIDI_MIGRATION,
Flags.FLAG_FIX_MISALIGNED_CONTEXT_MENU,
};
@@ -67,9 +64,6 @@ public final class TextFlags {
* The order must be the same to the TEXT_ACONFIG_FLAGS.
*/
public static final boolean[] TEXT_ACONFIG_DEFAULT_VALUE = {
- Flags.noBreakNoHyphenationSpan(),
- Flags.fixLineHeightForLocale(),
- Flags.icuBidiMigration(),
Flags.fixMisalignedContextMenu(),
};
diff --git a/core/java/android/text/flags/24Q3.aconfig b/core/java/android/text/flags/24Q3.aconfig
new file mode 100644
index 000000000000..7035fc842a48
--- /dev/null
+++ b/core/java/android/text/flags/24Q3.aconfig
@@ -0,0 +1,54 @@
+package: "com.android.text.flags"
+container: "system"
+
+# This aconfig file contains released flags in 24Q3 those cannot be removed.
+
+flag {
+ name: "use_bounds_for_width"
+ is_exported: true
+ namespace: "text"
+ description: "Feature flag for preventing horizontal clipping."
+ bug: "63938206"
+}
+
+flag {
+ name: "word_style_auto"
+ is_exported: true
+ namespace: "text"
+ description: "A feature flag that implements line break word style auto."
+ bug: "280005585"
+}
+
+flag {
+ name: "letter_spacing_justification"
+ is_exported: true
+ namespace: "text"
+ description: "A feature flag that implement inter character justification."
+ bug: "283193133"
+}
+
+flag {
+ name: "fix_line_height_for_locale"
+ is_exported: true
+ namespace: "text"
+ description: "Feature flag that preserve the line height of the TextView and EditText even if the the locale is different from Latin"
+ bug: "303326708"
+}
+
+flag {
+ name: "new_fonts_fallback_xml"
+ is_exported: true
+ namespace: "text"
+ description: "Feature flag for deprecating fonts.xml. By setting true for this feature flag, the new font configuration XML, /system/etc/font_fallback.xml is used. The new XML has a new syntax and flexibility of variable font declarations, but it is not compatible with the apps that reads fonts.xml. So, fonts.xml is maintained as a subset of the font_fallback.xml"
+ # Make read only, as it could be used before the Settings provider is initialized.
+ is_fixed_read_only: true
+ bug: "281769620"
+}
+
+flag {
+ name: "no_break_no_hyphenation_span"
+ is_exported: true
+ namespace: "text"
+ description: "A feature flag that adding new spans that prevents line breaking and hyphenation."
+ bug: "283193586"
+}
diff --git a/core/java/android/text/flags/flags.aconfig b/core/java/android/text/flags/flags.aconfig
index b2be1a7ef351..3c61f4f5a33c 100644
--- a/core/java/android/text/flags/flags.aconfig
+++ b/core/java/android/text/flags/flags.aconfig
@@ -2,32 +2,6 @@ package: "com.android.text.flags"
container: "system"
flag {
- name: "new_fonts_fallback_xml"
- is_exported: true
- namespace: "text"
- description: "Feature flag for deprecating fonts.xml. By setting true for this feature flag, the new font configuration XML, /system/etc/font_fallback.xml is used. The new XML has a new syntax and flexibility of variable font declarations, but it is not compatible with the apps that reads fonts.xml. So, fonts.xml is maintained as a subset of the font_fallback.xml"
- # Make read only, as it could be used before the Settings provider is initialized.
- is_fixed_read_only: true
- bug: "281769620"
-}
-
-flag {
- name: "fix_line_height_for_locale"
- is_exported: true
- namespace: "text"
- description: "Feature flag that preserve the line height of the TextView and EditText even if the the locale is different from Latin"
- bug: "303326708"
-}
-
-flag {
- name: "no_break_no_hyphenation_span"
- is_exported: true
- namespace: "text"
- description: "A feature flag that adding new spans that prevents line breaking and hyphenation."
- bug: "283193586"
-}
-
-flag {
name: "use_optimized_boottime_font_loading"
namespace: "text"
description: "Feature flag ensuring that font is loaded once and asynchronously."
@@ -51,37 +25,6 @@ flag {
}
flag {
- name: "use_bounds_for_width"
- is_exported: true
- namespace: "text"
- description: "Feature flag for preventing horizontal clipping."
- bug: "63938206"
-}
-
-flag {
- name: "deprecate_ui_fonts"
- namespace: "text"
- description: "Feature flag for deprecating UI fonts. By setting true for this feature flag, the elegant text height of will be turned on by default unless explicitly setting it to false by attribute or Java API call."
- bug: "279646685"
-}
-
-flag {
- name: "word_style_auto"
- is_exported: true
- namespace: "text"
- description: "A feature flag that implements line break word style auto."
- bug: "280005585"
-}
-
-flag {
- name: "letter_spacing_justification"
- is_exported: true
- namespace: "text"
- description: "A feature flag that implement inter character justification."
- bug: "283193133"
-}
-
-flag {
name: "escape_clears_focus"
namespace: "text"
description: "Feature flag for clearing focus when the escape key is pressed."
@@ -120,22 +63,6 @@ flag {
}
flag {
- name: "icu_bidi_migration"
- namespace: "text"
- description: "A flag for replacing AndroidBidi with android.icu.text.Bidi."
- bug: "317144801"
-}
-
-flag {
- name: "lazy_variation_instance"
- namespace: "text"
- description: "A flag for enabling lazy variation instance creation."
- # Make read only, as it could be used before the Settings provider is initialized.
- is_fixed_read_only: true
- bug: "324676775"
-}
-
-flag {
name: "handwriting_end_of_line_tap"
namespace: "text"
description: "Initiate handwriting when stylus taps at the end of a line in a focused non-empty TextView with the cursor at the end of that line"
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 3b5286a04b3d..22374173b988 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -4504,6 +4504,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final View[] children = mChildren;
for (int i = 0; i < count; i++) {
final View child = children[i];
+ if (child == null) {
+ throw new IllegalStateException(getClass().getSimpleName() + " contains null " +
+ "child at index " + i + " when traversal in dispatchGetDisplayList," +
+ " the view may have been removed.");
+ }
if (((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null)) {
recreateChildDisplayList(child);
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 67a207e34a1a..4fe11e6ce274 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -107,6 +107,7 @@ import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
+import android.graphics.Insets;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
@@ -2371,7 +2372,7 @@ public interface WindowManager extends ViewManager {
public static final int TYPE_SECURE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+15;
/**
- * Window type: the drag-and-drop pseudowindow. There is only one
+ * Window type: the drag-and-drop pseudowindow. There is only one
* drag layer (at most), and it is placed on top of all other windows.
* In multiuser systems shows only on the owning user's window.
* @hide
@@ -2381,7 +2382,7 @@ public interface WindowManager extends ViewManager {
/**
* Window type: panel that slides out from over the status bar
* In multiuser systems shows on all users' windows. These windows
- * are displayed on top of the stauts bar and any {@link #TYPE_STATUS_BAR_PANEL}
+ * are displayed on top of the status bar and any {@link #TYPE_STATUS_BAR_PANEL}
* windows.
* @hide
*/
@@ -4649,6 +4650,30 @@ public interface WindowManager extends ViewManager {
public InsetsFrameProvider[] providedInsets;
/**
+ * Sets the insets to be provided by the window.
+ *
+ * @param insetsParams The parameters for the insets to be provided by the window.
+ *
+ * @hide
+ */
+ @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_STATUS_BAR_AND_INSETS)
+ @SystemApi
+ public void setInsetsParams(@NonNull List<InsetsParams> insetsParams) {
+ if (insetsParams.isEmpty()) {
+ providedInsets = null;
+ } else {
+ providedInsets = new InsetsFrameProvider[insetsParams.size()];
+ for (int i = 0; i < insetsParams.size(); ++i) {
+ final InsetsParams params = insetsParams.get(i);
+ providedInsets[i] =
+ new InsetsFrameProvider(/* owner= */ this, /* index= */ i,
+ params.getType())
+ .setInsetsSize(params.getInsetsSize());
+ }
+ }
+ }
+
+ /**
* Specifies which {@link InsetsType}s should be forcibly shown. The types shown by this
* method won't affect the app's layout. This field only takes effects if the caller has
* {@link android.Manifest.permission#STATUS_BAR_SERVICE} or the caller has the same uid as
@@ -6117,6 +6142,55 @@ public interface WindowManager extends ViewManager {
}
/**
+ * Specifies the parameters of the insets provided by a window.
+ *
+ * @see WindowManager.LayoutParams#setInsetsParams(List)
+ * @see android.graphics.Insets
+ *
+ * @hide
+ */
+ @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_STATUS_BAR_AND_INSETS)
+ @SystemApi
+ public static class InsetsParams {
+
+ private final @InsetsType int mType;
+ private @Nullable Insets mInsets;
+
+ /**
+ * Creates an instance of InsetsParams.
+ *
+ * @param type the type of insets to provide, e.g. {@link WindowInsets.Type#statusBars()}.
+ * @see WindowInsets.Type
+ */
+ public InsetsParams(@InsetsType int type) {
+ mType = type;
+ }
+
+ /**
+ * Sets the size of the provided insets. If {@code null}, then the provided insets will
+ * have the same size as the window frame.
+ */
+ public @NonNull InsetsParams setInsetsSize(@Nullable Insets insets) {
+ mInsets = insets;
+ return this;
+ }
+
+ /**
+ * Returns the type of provided insets.
+ */
+ public @InsetsType int getType() {
+ return mType;
+ }
+
+ /**
+ * Returns the size of the provided insets.
+ */
+ public @Nullable Insets getInsetsSize() {
+ return mInsets;
+ }
+ }
+
+ /**
* Holds the WM lock for the specified amount of milliseconds.
* Intended for use by the tests that need to imitate lock contention.
* The token should be obtained by
diff --git a/core/java/android/webkit/UserPackage.java b/core/java/android/webkit/UserPackage.java
index 1da2af459348..b18dbbc21cda 100644
--- a/core/java/android/webkit/UserPackage.java
+++ b/core/java/android/webkit/UserPackage.java
@@ -15,12 +15,14 @@
*/
package android.webkit;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.UserInfo;
+import android.content.pm.PackageManager;
import android.os.Build;
+import android.os.UserHandle;
import android.os.UserManager;
import java.util.ArrayList;
@@ -31,30 +33,31 @@ import java.util.List;
* @hide
*/
public class UserPackage {
- private final UserInfo mUserInfo;
+ private final UserHandle mUser;
private final PackageInfo mPackageInfo;
public static final int MINIMUM_SUPPORTED_SDK = Build.VERSION_CODES.TIRAMISU;
- public UserPackage(UserInfo user, PackageInfo packageInfo) {
- this.mUserInfo = user;
- this.mPackageInfo = packageInfo;
+ public UserPackage(@NonNull UserHandle user, @Nullable PackageInfo packageInfo) {
+ mUser = user;
+ mPackageInfo = packageInfo;
}
/**
* Returns a list of (User,PackageInfo) pairs corresponding to the PackageInfos for all
* device users for the package named {@param packageName}.
*/
- public static List<UserPackage> getPackageInfosAllUsers(Context context,
- String packageName, int packageFlags) {
- List<UserInfo> users = getAllUsers(context);
+ public static @NonNull List<UserPackage> getPackageInfosAllUsers(@NonNull Context context,
+ @NonNull String packageName, int packageFlags) {
+ UserManager userManager = context.getSystemService(UserManager.class);
+ List<UserHandle> users = userManager.getUserHandles(false);
List<UserPackage> userPackages = new ArrayList<UserPackage>(users.size());
- for (UserInfo user : users) {
+ for (UserHandle user : users) {
+ PackageManager pm = context.createContextAsUser(user, 0).getPackageManager();
PackageInfo packageInfo = null;
try {
- packageInfo = context.getPackageManager().getPackageInfoAsUser(
- packageName, packageFlags, user.id);
- } catch (NameNotFoundException e) {
+ packageInfo = pm.getPackageInfo(packageName, packageFlags);
+ } catch (PackageManager.NameNotFoundException e) {
}
userPackages.add(new UserPackage(user, packageInfo));
}
@@ -88,18 +91,11 @@ public class UserPackage {
return packageInfo.applicationInfo.targetSdkVersion >= MINIMUM_SUPPORTED_SDK;
}
- public UserInfo getUserInfo() {
- return mUserInfo;
+ public UserHandle getUser() {
+ return mUser;
}
public PackageInfo getPackageInfo() {
return mPackageInfo;
}
-
-
- private static List<UserInfo> getAllUsers(Context context) {
- UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
- return userManager.getUsers();
- }
-
}
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index 3998ac634f43..8e81951ba4ca 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -251,3 +251,10 @@ flag {
description: "Persists the desktop windowing session across reboots."
bug: "350456942"
}
+
+flag {
+ name: "enable_display_focus_in_shell_transitions"
+ namespace: "lse_desktop_experience"
+ description: "Creates a shell transition when display focus switches."
+ bug: "356109871"
+}
diff --git a/core/java/com/android/internal/jank/flags.aconfig b/core/java/com/android/internal/jank/flags.aconfig
index b6b8bc5ac44c..82f50ae848b3 100644
--- a/core/java/com/android/internal/jank/flags.aconfig
+++ b/core/java/com/android/internal/jank/flags.aconfig
@@ -3,7 +3,7 @@ container: "system"
flag {
name: "use_sf_frame_duration"
- namespace: "android_platform_window_surfaces"
+ namespace: "window_surfaces"
description: "Whether to get the frame duration from SurfaceFlinger, or HWUI"
bug: "354763298"
is_fixed_read_only: true
diff --git a/core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java b/core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java
index 032ac4283712..12d326486e77 100644
--- a/core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java
+++ b/core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java
@@ -3025,7 +3025,6 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal,
@Override
public PackageImpl setSplitCodePaths(@Nullable String[] splitCodePaths) {
this.splitCodePaths = splitCodePaths;
- this.mSplits = null; // reset for paths changed
if (splitCodePaths != null) {
int size = splitCodePaths.length;
for (int index = 0; index < size; index++) {
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java
index 516253b0ebff..44beb55b77db 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java
@@ -19,18 +19,18 @@ package com.android.server.broadcastradio;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doThrow;
-import static com.google.common.truth.Truth.assertWithMessage;
-
import static org.mockito.Mockito.when;
import android.app.ActivityManager;
-import android.app.compat.CompatChanges;
import android.os.Binder;
import android.os.UserHandle;
import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
+import com.google.common.truth.Expect;
+
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
@@ -41,36 +41,40 @@ public final class RadioServiceUserControllerTest extends ExtendedRadioMockitoTe
private static final int USER_ID_1 = 11;
private static final int USER_ID_2 = 12;
+ private RadioServiceUserController mUserController;
@Mock
private UserHandle mUserHandleMock;
+ @Rule
+ public final Expect expect = Expect.create();
+
@Override
protected void initializeSession(StaticMockitoSessionBuilder builder) {
- builder.spyStatic(ActivityManager.class).spyStatic(Binder.class)
- .spyStatic(CompatChanges.class);
+ builder.spyStatic(ActivityManager.class).spyStatic(Binder.class);
}
@Before
public void setUp() {
doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle());
doReturn(USER_ID_1).when(() -> ActivityManager.getCurrentUser());
+ mUserController = new RadioServiceUserControllerImpl();
}
@Test
public void isCurrentOrSystemUser_forCurrentUser_returnsFalse() {
when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1);
- assertWithMessage("Current user")
- .that(RadioServiceUserController.isCurrentOrSystemUser()).isTrue();
+ expect.withMessage("Current user")
+ .that(mUserController.isCurrentOrSystemUser()).isTrue();
}
@Test
public void isCurrentOrSystemUser_forNonCurrentUser_returnsFalse() {
when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_2);
- assertWithMessage("Non-current user")
- .that(RadioServiceUserController.isCurrentOrSystemUser()).isFalse();
+ expect.withMessage("Non-current user")
+ .that(mUserController.isCurrentOrSystemUser()).isFalse();
}
@Test
@@ -78,8 +82,8 @@ public final class RadioServiceUserControllerTest extends ExtendedRadioMockitoTe
when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1);
when(mUserHandleMock.getIdentifier()).thenReturn(UserHandle.USER_SYSTEM);
- assertWithMessage("System user")
- .that(RadioServiceUserController.isCurrentOrSystemUser()).isTrue();
+ expect.withMessage("System user")
+ .that(mUserController.isCurrentOrSystemUser()).isTrue();
}
@Test
@@ -87,14 +91,14 @@ public final class RadioServiceUserControllerTest extends ExtendedRadioMockitoTe
when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1);
doThrow(new RuntimeException()).when(ActivityManager::getCurrentUser);
- assertWithMessage("User when activity manager fails")
- .that(RadioServiceUserController.isCurrentOrSystemUser()).isFalse();
+ expect.withMessage("User when activity manager fails")
+ .that(mUserController.isCurrentOrSystemUser()).isFalse();
}
@Test
public void getCurrentUser() {
- assertWithMessage("Current user")
- .that(RadioServiceUserController.getCurrentUser()).isEqualTo(USER_ID_1);
+ expect.withMessage("Current user")
+ .that(mUserController.getCurrentUser()).isEqualTo(USER_ID_1);
}
@Test
@@ -102,7 +106,15 @@ public final class RadioServiceUserControllerTest extends ExtendedRadioMockitoTe
when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1);
doThrow(new RuntimeException()).when(ActivityManager::getCurrentUser);
- assertWithMessage("Current user when activity manager fails")
- .that(RadioServiceUserController.getCurrentUser()).isEqualTo(UserHandle.USER_NULL);
+ expect.withMessage("Current user when activity manager fails")
+ .that(mUserController.getCurrentUser()).isEqualTo(UserHandle.USER_NULL);
+ }
+
+ @Test
+ public void getCallingUserId() {
+ when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1);
+
+ expect.withMessage("Calling user id")
+ .that(mUserController.getCallingUserId()).isEqualTo(USER_ID_1);
}
}
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java
index 22f3bd4abe11..63f12d82b48a 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java
@@ -91,12 +91,13 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes
private IAnnouncementListener mAnnouncementListenerMock;
@Mock
private IBinder mListenerBinderMock;
+ @Mock
+ private RadioServiceUserController mUserControllerMock;
@Override
protected void initializeSession(StaticMockitoSessionBuilder builder) {
builder.spyStatic(ServiceManager.class)
- .spyStatic(RadioModule.class)
- .spyStatic(RadioServiceUserController.class);
+ .spyStatic(RadioModule.class);
}
@Test
@@ -156,7 +157,7 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes
@Test
public void openSession_forNonCurrentUser_throwsException() throws Exception {
createBroadcastRadioService();
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
IllegalStateException thrown = assertThrows(IllegalStateException.class,
() -> mBroadcastRadioService.openSession(FM_RADIO_MODULE_ID,
@@ -206,9 +207,9 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes
}
private void createBroadcastRadioService() throws RemoteException {
- doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(true).when(mUserControllerMock).isCurrentOrSystemUser();
mockServiceManager();
- mBroadcastRadioService = new BroadcastRadioServiceImpl(SERVICE_LIST);
+ mBroadcastRadioService = new BroadcastRadioServiceImpl(SERVICE_LIST, mUserControllerMock);
}
private void mockServiceManager() throws RemoteException {
@@ -222,9 +223,9 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes
any(IServiceCallback.class)));
doReturn(mFmRadioModuleMock).when(() -> RadioModule.tryLoadingModule(
- eq(FM_RADIO_MODULE_ID), anyString(), any(IBinder.class)));
+ eq(FM_RADIO_MODULE_ID), anyString(), any(IBinder.class), any()));
doReturn(mDabRadioModuleMock).when(() -> RadioModule.tryLoadingModule(
- eq(DAB_RADIO_MODULE_ID), anyString(), any(IBinder.class)));
+ eq(DAB_RADIO_MODULE_ID), anyString(), any(IBinder.class), any()));
when(mFmRadioModuleMock.getProperties()).thenReturn(mFmModuleMock);
when(mDabRadioModuleMock.getProperties()).thenReturn(mDabModuleMock);
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/RadioModuleTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/RadioModuleTest.java
index a952bde956d8..368df090070b 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/RadioModuleTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/RadioModuleTest.java
@@ -34,6 +34,8 @@ import android.hardware.radio.RadioManager;
import android.os.ParcelableException;
import android.os.RemoteException;
+import com.android.server.broadcastradio.RadioServiceUserController;
+
import com.google.common.truth.Expect;
import org.junit.Before;
@@ -63,6 +65,8 @@ public final class RadioModuleTest {
private IAnnouncementListener mListenerMock;
@Mock
private android.hardware.broadcastradio.ICloseHandle mHalCloseHandleMock;
+ @Mock
+ private RadioServiceUserController mUserControllerMock;
// RadioModule under test
private RadioModule mRadioModule;
@@ -70,7 +74,8 @@ public final class RadioModuleTest {
@Before
public void setup() throws RemoteException {
- mRadioModule = new RadioModule(mBroadcastRadioMock, TEST_MODULE_PROPERTIES);
+ mRadioModule = new RadioModule(mBroadcastRadioMock, TEST_MODULE_PROPERTIES,
+ mUserControllerMock);
// TODO(b/241118988): test non-null image for getImage method
when(mBroadcastRadioMock.getImage(anyInt())).thenReturn(null);
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
index 92dfe38c31fe..24d18e0893d0 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
@@ -49,12 +49,10 @@ import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.hardware.radio.RadioTuner;
import android.hardware.radio.UniqueProgramIdentifier;
-import android.os.Binder;
import android.os.DeadObjectException;
import android.os.ParcelableException;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
-import android.os.UserHandle;
import android.platform.test.flag.junit.SetFlagsRule;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -148,10 +146,10 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
// Mocks
@Mock
- private UserHandle mUserHandleMock;
- @Mock
private IBroadcastRadio mBroadcastRadioMock;
private android.hardware.radio.ITunerCallback[] mAidlTunerCallbackMocks;
+ @Mock
+ private RadioServiceUserController mUserControllerMock;
// RadioModule under test
private RadioModule mRadioModule;
@@ -170,8 +168,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
@Override
protected void initializeSession(StaticMockitoSessionBuilder builder) {
- builder.spyStatic(RadioServiceUserController.class).spyStatic(CompatChanges.class)
- .spyStatic(Binder.class);
+ builder.spyStatic(CompatChanges.class);
}
@Before
@@ -182,13 +179,12 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
doReturn(true).when(() -> CompatChanges.isChangeEnabled(
eq(ConversionUtils.RADIO_U_VERSION_REQUIRED), anyInt()));
- doReturn(USER_ID_1).when(mUserHandleMock).getIdentifier();
- doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle());
- doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
- doReturn(USER_ID_1).when(() -> RadioServiceUserController.getCurrentUser());
+ doReturn(USER_ID_1).when(mUserControllerMock).getCallingUserId();
+ doReturn(true).when(mUserControllerMock).isCurrentOrSystemUser();
+ doReturn(USER_ID_1).when(mUserControllerMock).getCurrentUser();
mRadioModule = new RadioModule(mBroadcastRadioMock,
- AidlTestUtils.makeDefaultModuleProperties());
+ AidlTestUtils.makeDefaultModuleProperties(), mUserControllerMock);
doAnswer(invocation -> {
mHalTunerCallback = (ITunerCallback) invocation.getArguments()[0];
@@ -237,7 +233,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
@Test
public void setConfiguration_forNonCurrentUser_doesNotInvokesCallback() throws Exception {
openAidlClients(/* numClients= */ 1);
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
mTunerSessions[0].setConfiguration(FM_BAND_CONFIG);
@@ -434,7 +430,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
@Test
public void tune_forNonCurrentUser_doesNotTune() throws Exception {
openAidlClients(/* numClients= */ 1);
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
ProgramSelector initialSel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
RadioManager.ProgramInfo tuneInfo =
AidlTestUtils.makeProgramInfo(initialSel, SIGNAL_QUALITY);
@@ -514,7 +510,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
openAidlClients(/* numClients= */ 1);
mHalCurrentInfo = AidlTestUtils.makeHalProgramInfo(
ConversionUtils.programSelectorToHalProgramSelector(initialSel), SIGNAL_QUALITY);
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
mTunerSessions[0].step(/* directionDown= */ true, /* skipSubChannel= */ false);
@@ -593,7 +589,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
openAidlClients(/* numClients= */ 1);
mHalCurrentInfo = AidlTestUtils.makeHalProgramInfo(
ConversionUtils.programSelectorToHalProgramSelector(initialSel), SIGNAL_QUALITY);
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
mTunerSessions[0].seek(/* directionDown= */ true, /* skipSubChannel= */ false);
@@ -627,7 +623,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
@Test
public void cancel_forNonCurrentUser_doesNotCancel() throws Exception {
openAidlClients(/* numClients= */ 1);
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
mTunerSessions[0].cancel();
@@ -698,7 +694,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
@Test
public void startBackgroundScan_forNonCurrentUser_doesNotInvokesCallback() throws Exception {
openAidlClients(/* numClients= */ 1);
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
mTunerSessions[0].startBackgroundScan();
@@ -968,7 +964,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
openAidlClients(/* numClients= */ 1);
ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(),
/* includeCategories= */ true, /* excludeModifications= */ false);
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
mTunerSessions[0].startProgramListUpdates(filter);
@@ -1007,7 +1003,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(),
/* includeCategories= */ true, /* excludeModifications= */ false);
mTunerSessions[0].startProgramListUpdates(filter);
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
mTunerSessions[0].stopProgramListUpdates();
@@ -1073,7 +1069,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
public void setConfigFlag_forNonCurrentUser_doesNotSetConfigFlag() throws Exception {
openAidlClients(/* numClients= */ 1);
int flag = UNSUPPORTED_CONFIG_FLAG + 1;
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
mTunerSessions[0].setConfigFlag(flag, /* value= */ true);
@@ -1138,7 +1134,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
openAidlClients(/* numClients= */ 1);
Map<String, String> parametersSet = Map.of("mockParam1", "mockValue1",
"mockParam2", "mockValue2");
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
mTunerSessions[0].setParameters(parametersSet);
@@ -1192,7 +1188,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
public void onCurrentProgramInfoChanged_withNonCurrentUser_doesNotInvokeCallback()
throws Exception {
openAidlClients(1);
- doReturn(USER_ID_2).when(() -> RadioServiceUserController.getCurrentUser());
+ doReturn(USER_ID_2).when(mUserControllerMock).getCurrentUser();
mHalTunerCallback.onCurrentProgramInfoChanged(AidlTestUtils.makeHalProgramInfo(
AidlTestUtils.makeHalFmSelector(AM_FM_FREQUENCY_LIST[1]), SIGNAL_QUALITY));
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java
index acf698bce33d..7c3f221f9bf5 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java
@@ -88,11 +88,12 @@ public final class BroadcastRadioServiceHidlTest extends ExtendedRadioMockitoTes
private IAnnouncementListener mAnnouncementListenerMock;
@Mock
private IBinder mBinderMock;
+ @Mock
+ private RadioServiceUserController mUserControllerMock;
@Override
protected void initializeSession(StaticMockitoSessionBuilder builder) {
- builder.spyStatic(RadioModule.class)
- .spyStatic(RadioServiceUserController.class);
+ builder.spyStatic(RadioModule.class);
}
@Test
@@ -156,7 +157,7 @@ public final class BroadcastRadioServiceHidlTest extends ExtendedRadioMockitoTes
@Test
public void openSession_forNonCurrentUser_throwsException() throws Exception {
createBroadcastRadioService();
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ when(mUserControllerMock.isCurrentOrSystemUser()).thenReturn(false);
IllegalStateException thrown = assertThrows(IllegalStateException.class,
() -> mBroadcastRadioService.openSession(FM_RADIO_MODULE_ID,
@@ -206,11 +207,11 @@ public final class BroadcastRadioServiceHidlTest extends ExtendedRadioMockitoTes
}
private void createBroadcastRadioService() throws RemoteException {
- doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ when(mUserControllerMock.isCurrentOrSystemUser()).thenReturn(true);
mockServiceManager();
mBroadcastRadioService = new BroadcastRadioService(/* nextModuleId= */ FM_RADIO_MODULE_ID,
- mServiceManagerMock);
+ mServiceManagerMock, mUserControllerMock);
}
private void mockServiceManager() throws RemoteException {
@@ -231,9 +232,9 @@ public final class BroadcastRadioServiceHidlTest extends ExtendedRadioMockitoTes
}).thenReturn(true);
doReturn(mFmRadioModuleMock).when(() -> RadioModule.tryLoadingModule(
- eq(FM_RADIO_MODULE_ID), anyString()));
+ eq(FM_RADIO_MODULE_ID), anyString(), any()));
doReturn(mDabRadioModuleMock).when(() -> RadioModule.tryLoadingModule(
- eq(DAB_RADIO_MODULE_ID), anyString()));
+ eq(DAB_RADIO_MODULE_ID), anyString(), any()));
when(mFmRadioModuleMock.getProperties()).thenReturn(mFmModuleMock);
when(mDabRadioModuleMock.getProperties()).thenReturn(mDabModuleMock);
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/RadioModuleHidlTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/RadioModuleHidlTest.java
index 1f5e77038728..b53f7ca879aa 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/RadioModuleHidlTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/RadioModuleHidlTest.java
@@ -36,6 +36,8 @@ import android.hardware.radio.ICloseHandle;
import android.hardware.radio.RadioManager;
import android.os.RemoteException;
+import com.android.server.broadcastradio.RadioServiceUserController;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -61,13 +63,16 @@ public final class RadioModuleHidlTest {
private IAnnouncementListener mListenerMock;
@Mock
private android.hardware.broadcastradio.V2_0.ICloseHandle mHalCloseHandleMock;
+ @Mock
+ private RadioServiceUserController mUserControllerMock;
private RadioModule mRadioModule;
private android.hardware.broadcastradio.V2_0.IAnnouncementListener mHalListener;
@Before
public void setup() throws RemoteException {
- mRadioModule = new RadioModule(mBroadcastRadioMock, TEST_MODULE_PROPERTIES);
+ mRadioModule = new RadioModule(mBroadcastRadioMock, TEST_MODULE_PROPERTIES,
+ mUserControllerMock);
when(mBroadcastRadioMock.getImage(anyInt())).thenReturn(new ArrayList<Byte>(0));
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java
index 8c16d79133ce..fa0744775f6d 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java
@@ -38,13 +38,13 @@ import android.hardware.radio.RadioManager;
import android.hardware.radio.UniqueProgramIdentifier;
import android.os.RemoteException;
-import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
-import com.android.server.broadcastradio.ExtendedRadioMockitoTestCase;
import com.android.server.broadcastradio.RadioServiceUserController;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
import org.mockito.verification.VerificationWithTimeout;
@@ -55,7 +55,8 @@ import java.util.List;
/**
* Tests for v2 HAL RadioModule.
*/
-public class StartProgramListUpdatesFanoutTest extends ExtendedRadioMockitoTestCase {
+@RunWith(MockitoJUnitRunner.class)
+public class StartProgramListUpdatesFanoutTest {
private static final String TAG = "BroadcastRadioTests.hal2.StartProgramListUpdatesFanout";
private static final VerificationWithTimeout CB_TIMEOUT = timeout(500);
@@ -64,6 +65,8 @@ public class StartProgramListUpdatesFanoutTest extends ExtendedRadioMockitoTestC
@Mock IBroadcastRadio mBroadcastRadioMock;
@Mock ITunerSession mHalTunerSessionMock;
private android.hardware.radio.ITunerCallback[] mAidlTunerCallbackMocks;
+ @Mock
+ private RadioServiceUserController mUserControllerMock;
// RadioModule under test
private RadioModule mRadioModule;
@@ -110,17 +113,12 @@ public class StartProgramListUpdatesFanoutTest extends ExtendedRadioMockitoTestC
private static final RadioManager.ProgramInfo TEST_DAB_INFO = TestUtils.makeProgramInfo(
TEST_DAB_SELECTOR, TEST_QUALITY);
- @Override
- protected void initializeSession(StaticMockitoSessionBuilder builder) {
- builder.spyStatic(RadioServiceUserController.class);
- }
-
@Before
public void setup() throws RemoteException {
- doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(true).when(mUserControllerMock).isCurrentOrSystemUser();
- mRadioModule = new RadioModule(mBroadcastRadioMock,
- TestUtils.makeDefaultModuleProperties());
+ mRadioModule = new RadioModule(mBroadcastRadioMock, TestUtils.makeDefaultModuleProperties(),
+ mUserControllerMock);
doAnswer((Answer) invocation -> {
mHalTunerCallback = (ITunerCallback) invocation.getArguments()[0];
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java
index 55aae9d3396a..62445cf90028 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java
@@ -44,16 +44,12 @@ import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.hardware.radio.RadioTuner;
-import android.os.Binder;
import android.os.DeadObjectException;
import android.os.ParcelableException;
import android.os.RemoteException;
-import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArraySet;
-import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
-import com.android.server.broadcastradio.ExtendedRadioMockitoTestCase;
import com.android.server.broadcastradio.RadioServiceUserController;
import com.google.common.truth.Expect;
@@ -76,7 +72,7 @@ import java.util.Map;
* Tests for HIDL HAL TunerSession.
*/
@RunWith(MockitoJUnitRunner.class)
-public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
+public final class TunerSessionHidlTest {
private static final int USER_ID_1 = 11;
private static final int USER_ID_2 = 12;
@@ -104,27 +100,21 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
public final Expect mExpect = Expect.create();
@Mock
- private UserHandle mUserHandleMock;
- @Mock
private IBroadcastRadio mBroadcastRadioMock;
@Mock
ITunerSession mHalTunerSessionMock;
private android.hardware.radio.ITunerCallback[] mAidlTunerCallbackMocks;
-
- @Override
- protected void initializeSession(StaticMockitoSessionBuilder builder) {
- builder.spyStatic(RadioServiceUserController.class).spyStatic(Binder.class);
- }
+ @Mock
+ private RadioServiceUserController mUserControllerMock;
@Before
public void setup() throws Exception {
- doReturn(USER_ID_1).when(mUserHandleMock).getIdentifier();
- doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle());
- doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
- doReturn(USER_ID_1).when(() -> RadioServiceUserController.getCurrentUser());
+ doReturn(USER_ID_1).when(mUserControllerMock).getCallingUserId();
+ doReturn(true).when(mUserControllerMock).isCurrentOrSystemUser();
+ doReturn(USER_ID_1).when(mUserControllerMock).getCurrentUser();
mRadioModule = new RadioModule(mBroadcastRadioMock,
- TestUtils.makeDefaultModuleProperties());
+ TestUtils.makeDefaultModuleProperties(), mUserControllerMock);
doAnswer(invocation -> {
mHalTunerCallback = (ITunerCallback) invocation.getArguments()[0];
@@ -228,7 +218,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
@Test
public void setConfiguration_forNonCurrentUser_doesNotInvokesCallback() throws Exception {
openAidlClients(/* numClients= */ 1);
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
mTunerSessions[0].setConfiguration(FM_BAND_CONFIG);
@@ -403,7 +393,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
@Test
public void tune_forNonCurrentUser_doesNotTune() throws Exception {
openAidlClients(/* numClients= */ 1);
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
ProgramSelector initialSel = TestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
RadioManager.ProgramInfo tuneInfo =
TestUtils.makeProgramInfo(initialSel, SIGNAL_QUALITY);
@@ -481,7 +471,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
openAidlClients(/* numClients= */ 1);
mHalCurrentInfo = TestUtils.makeHalProgramInfo(
Convert.programSelectorToHal(initialSel), SIGNAL_QUALITY);
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
mTunerSessions[0].step(/* directionDown= */ true, /* skipSubChannel= */ false);
@@ -559,7 +549,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
openAidlClients(/* numClients= */ 1);
mHalCurrentInfo = TestUtils.makeHalProgramInfo(
Convert.programSelectorToHal(initialSel), SIGNAL_QUALITY);
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
mTunerSessions[0].seek(/* directionDown= */ true, /* skipSubChannel= */ false);
@@ -593,7 +583,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
@Test
public void cancel_forNonCurrentUser_doesNotCancel() throws Exception {
openAidlClients(/* numClients= */ 1);
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
mTunerSessions[0].cancel();
@@ -663,7 +653,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
@Test
public void startBackgroundScan_forNonCurrentUser_doesNotInvokesCallback() throws Exception {
openAidlClients(/* numClients= */ 1);
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
mTunerSessions[0].startBackgroundScan();
@@ -676,7 +666,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
openAidlClients(/* numClients= */ 1);
ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(),
/* includeCategories= */ true, /* excludeModifications= */ false);
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
mTunerSessions[0].startProgramListUpdates(filter);
@@ -715,7 +705,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
ProgramList.Filter aidlFilter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(),
/* includeCategories= */ true, /* excludeModifications= */ false);
mTunerSessions[0].startProgramListUpdates(aidlFilter);
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
mTunerSessions[0].stopProgramListUpdates();
@@ -781,7 +771,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
public void setConfigFlag_forNonCurrentUser_doesNotSetConfigFlag() throws Exception {
openAidlClients(/* numClients= */ 1);
int flag = UNSUPPORTED_CONFIG_FLAG + 1;
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
mTunerSessions[0].setConfigFlag(flag, /* value= */ true);
@@ -846,7 +836,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
openAidlClients(/* numClients= */ 1);
Map<String, String> parametersSet = Map.of("mockParam1", "mockValue1",
"mockParam2", "mockValue2");
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+ doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
mTunerSessions[0].setParameters(parametersSet);
@@ -900,7 +890,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
public void onCurrentProgramInfoChanged_withNonCurrentUser_doesNotInvokeCallback()
throws Exception {
openAidlClients(1);
- doReturn(USER_ID_2).when(() -> RadioServiceUserController.getCurrentUser());
+ doReturn(USER_ID_2).when(mUserControllerMock).getCurrentUser();
mHalTunerCallback.onCurrentProgramInfoChanged(TestUtils.makeHalProgramInfo(
TestUtils.makeHalFmSelector(/* freq= */ 97300), SIGNAL_QUALITY));
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index 99cbf0504be6..41599aea1a80 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -299,11 +299,6 @@ android_ravenwood_test {
auto_gen_config: true,
}
-FLAKY_OR_IGNORED = [
- "androidx.test.filters.FlakyTest",
- "org.junit.Ignore",
-]
-
test_module_config {
name: "FrameworksCoreTests_Presubmit",
base: "FrameworksCoreTests",
@@ -312,7 +307,6 @@ test_module_config {
"device-platinum-tests",
],
include_annotations: ["android.platform.test.annotations.Presubmit"],
- exclude_annotations: FLAKY_OR_IGNORED,
}
test_module_config {
@@ -337,7 +331,6 @@ test_module_config {
"device-platinum-tests",
],
include_filters: ["android.content.ContextTest"],
- exclude_annotations: FLAKY_OR_IGNORED,
}
test_module_config {
@@ -348,7 +341,6 @@ test_module_config {
"device-platinum-tests",
],
include_filters: ["android.app.KeyguardManagerTest"],
- exclude_annotations: FLAKY_OR_IGNORED,
}
test_module_config {
@@ -359,7 +351,6 @@ test_module_config {
"device-platinum-tests",
],
include_filters: ["android.app.PropertyInvalidatedCacheTests"],
- exclude_annotations: FLAKY_OR_IGNORED,
}
test_module_config {
@@ -374,7 +365,6 @@ test_module_config {
"android.content.ComponentCallbacksControllerTest",
"android.content.ContextWrapperTest",
],
- exclude_annotations: FLAKY_OR_IGNORED,
}
test_module_config {
@@ -385,7 +375,6 @@ test_module_config {
"device-platinum-tests",
],
include_filters: ["android.database.sqlite.SQLiteRawStatementTest"],
- exclude_annotations: FLAKY_OR_IGNORED,
}
test_module_config {
@@ -397,7 +386,6 @@ test_module_config {
],
include_filters: ["android.net"],
include_annotations: ["android.platform.test.annotations.Presubmit"],
- exclude_annotations: FLAKY_OR_IGNORED,
}
test_module_config {
@@ -510,7 +498,6 @@ test_module_config {
"device-platinum-tests",
],
include_filters: ["com.android.internal.jank"],
- exclude_annotations: FLAKY_OR_IGNORED,
}
test_module_config {
@@ -569,7 +556,6 @@ test_module_config {
"device-platinum-tests",
],
include_filters: ["com.android.internal.util.LatencyTrackerTest"],
- exclude_annotations: FLAKY_OR_IGNORED,
}
test_module_config {
@@ -580,7 +566,6 @@ test_module_config {
"device-platinum-tests",
],
include_filters: ["android.content.ContentCaptureOptionsTest"],
- exclude_annotations: FLAKY_OR_IGNORED,
}
test_module_config {
@@ -602,7 +587,6 @@ test_module_config {
],
include_filters: ["android.content.pm."],
include_annotations: ["android.platform.test.annotations.Presubmit"],
- exclude_annotations: FLAKY_OR_IGNORED,
}
test_module_config {
@@ -614,7 +598,6 @@ test_module_config {
],
include_filters: ["android.content.pm."],
include_annotations: ["android.platform.test.annotations.Postsubmit"],
- exclude_annotations: FLAKY_OR_IGNORED,
}
test_module_config {
@@ -642,7 +625,6 @@ test_module_config {
],
include_filters: ["android.content.res."],
include_annotations: ["android.platform.test.annotations.Postsubmit"],
- exclude_annotations: FLAKY_OR_IGNORED,
}
test_module_config {
@@ -672,7 +654,6 @@ test_module_config {
"device-platinum-tests",
],
include_filters: ["android.view.contentcapture"],
- exclude_annotations: FLAKY_OR_IGNORED,
}
test_module_config {
@@ -683,7 +664,6 @@ test_module_config {
"device-platinum-tests",
],
include_filters: ["android.view.contentprotection"],
- exclude_annotations: FLAKY_OR_IGNORED,
}
test_module_config {
@@ -695,7 +675,6 @@ test_module_config {
],
include_filters: ["com.android.internal.content."],
include_annotations: ["android.platform.test.annotations.Presubmit"],
- exclude_annotations: FLAKY_OR_IGNORED,
}
test_module_config {
@@ -709,21 +688,6 @@ test_module_config {
}
test_module_config {
- name: "FrameworksCoreTests_accessibility_NO_FLAKES",
- base: "FrameworksCoreTests",
- test_suites: [
- "device-tests",
- "device-platinum-tests",
- ],
- include_filters: [
- "com.android.internal.accessibility",
- "android.accessibilityservice",
- "android.view.accessibility",
- ],
- exclude_annotations: ["androidx.test.filters.FlakyTest"],
-}
-
-test_module_config {
name: "FrameworksCoreTests_accessibility",
base: "FrameworksCoreTests",
test_suites: [
@@ -792,7 +756,6 @@ test_module_config {
"com.android.internal.jank.InteractionJankMonitorTest",
"com.android.internal.util.LatencyTrackerTest",
],
- exclude_annotations: FLAKY_OR_IGNORED,
}
test_module_config {
@@ -803,7 +766,6 @@ test_module_config {
"device-platinum-tests",
],
include_annotations: ["android.platform.test.annotations.PlatinumTest"],
- exclude_annotations: FLAKY_OR_IGNORED,
}
test_module_config {
diff --git a/core/tests/coretests/src/android/content/pm/LauncherActivityInfoTest.java b/core/tests/coretests/src/android/content/pm/LauncherActivityInfoTest.java
index e19c4b15d300..3616ff5cc144 100644
--- a/core/tests/coretests/src/android/content/pm/LauncherActivityInfoTest.java
+++ b/core/tests/coretests/src/android/content/pm/LauncherActivityInfoTest.java
@@ -33,71 +33,169 @@ import org.junit.runner.RunWith;
public class LauncherActivityInfoTest {
@Test
- public void testTrimStart() {
- // Invisible case
- assertThat(LauncherActivityInfo.trimStart("\u0009").toString()).isEmpty();
- // It is not supported in the system font
- assertThat(LauncherActivityInfo.trimStart("\u0FE1").toString()).isEmpty();
- // Surrogates case
- assertThat(LauncherActivityInfo.trimStart("\uD83E\uDD36").toString())
- .isEqualTo("\uD83E\uDD36");
- assertThat(LauncherActivityInfo.trimStart("\u0009\u0FE1\uD83E\uDD36A").toString())
- .isEqualTo("\uD83E\uDD36A");
- assertThat(LauncherActivityInfo.trimStart("\uD83E\uDD36A\u0009\u0FE1").toString())
- .isEqualTo("\uD83E\uDD36A\u0009\u0FE1");
- assertThat(LauncherActivityInfo.trimStart("A\uD83E\uDD36\u0009\u0FE1A").toString())
- .isEqualTo("A\uD83E\uDD36\u0009\u0FE1A");
- assertThat(LauncherActivityInfo.trimStart(
- "A\uD83E\uDD36\u0009\u0FE1A\uD83E\uDD36").toString())
- .isEqualTo("A\uD83E\uDD36\u0009\u0FE1A\uD83E\uDD36");
- assertThat(LauncherActivityInfo.trimStart(
- "\u0009\u0FE1\uD83E\uDD36A\u0009\u0FE1").toString())
- .isEqualTo("\uD83E\uDD36A\u0009\u0FE1");
+ public void testIsVisible_normal() {
+ // normal
+ assertThat(LauncherActivityInfo.isVisible("label")).isTrue();
+ // 1 surrogates case
+ assertThat(LauncherActivityInfo.isVisible("\uD83E\uDD36")).isTrue();
}
@Test
- public void testTrimEnd() {
- // Invisible case
- assertThat(LauncherActivityInfo.trimEnd("\u0009").toString()).isEmpty();
- // It is not supported in the system font
- assertThat(LauncherActivityInfo.trimEnd("\u0FE1").toString()).isEmpty();
- // Surrogates case
- assertThat(LauncherActivityInfo.trimEnd("\uD83E\uDD36").toString())
- .isEqualTo("\uD83E\uDD36");
- assertThat(LauncherActivityInfo.trimEnd("\u0009\u0FE1\uD83E\uDD36A").toString())
- .isEqualTo("\u0009\u0FE1\uD83E\uDD36A");
- assertThat(LauncherActivityInfo.trimEnd("\uD83E\uDD36A\u0009\u0FE1").toString())
- .isEqualTo("\uD83E\uDD36A");
- assertThat(LauncherActivityInfo.trimEnd("A\uD83E\uDD36\u0009\u0FE1A").toString())
- .isEqualTo("A\uD83E\uDD36\u0009\u0FE1A");
- assertThat(LauncherActivityInfo.trimEnd(
- "A\uD83E\uDD36\u0009\u0FE1A\uD83E\uDD36").toString())
- .isEqualTo("A\uD83E\uDD36\u0009\u0FE1A\uD83E\uDD36");
- assertThat(LauncherActivityInfo.trimEnd(
- "\u0009\u0FE1\uD83E\uDD36A\u0009\u0FE1").toString())
- .isEqualTo("\u0009\u0FE1\uD83E\uDD36A");
+ public void testIsVisible_onlyInvisibleCharacter() {
+ // 1 invisible
+ assertThat(LauncherActivityInfo.isVisible("\u0009")).isFalse();
+ // 2 invisible
+ assertThat(LauncherActivityInfo.isVisible("\u0009\u3164")).isFalse();
+ // 3 invisible
+ assertThat(LauncherActivityInfo.isVisible("\u3000\u0009\u3164")).isFalse();
+ // 4 invisible
+ assertThat(LauncherActivityInfo.isVisible("\u200F\u3000\u0009\u3164")).isFalse();
}
@Test
- public void testTrim() {
- // Invisible case
- assertThat(LauncherActivityInfo.trim("\u0009").toString()).isEmpty();
- // It is not supported in the system font
- assertThat(LauncherActivityInfo.trim("\u0FE1").toString()).isEmpty();
- // Surrogates case
- assertThat(LauncherActivityInfo.trim("\uD83E\uDD36").toString())
- .isEqualTo("\uD83E\uDD36");
- assertThat(LauncherActivityInfo.trim("\u0009\u0FE1\uD83E\uDD36A").toString())
- .isEqualTo("\uD83E\uDD36A");
- assertThat(LauncherActivityInfo.trim("\uD83E\uDD36A\u0009\u0FE1").toString())
- .isEqualTo("\uD83E\uDD36A");
- assertThat(LauncherActivityInfo.trim("A\uD83E\uDD36\u0009\u0FE1A").toString())
- .isEqualTo("A\uD83E\uDD36\u0009\u0FE1A");
- assertThat(LauncherActivityInfo.trim(
- "A\uD83E\uDD36\u0009\u0FE1A\uD83E\uDD36").toString())
- .isEqualTo("A\uD83E\uDD36\u0009\u0FE1A\uD83E\uDD36");
- assertThat(LauncherActivityInfo.trim(
- "\u0009\u0FE1\uD83E\uDD36A\u0009\u0FE1").toString())
- .isEqualTo("\uD83E\uDD36A");
+ public void testIsVisible_onlyNotSupportedCharacter() {
+ // 1 not supported
+ assertThat(LauncherActivityInfo.isVisible("\u0FE1")).isFalse();
+ // 2 not supported
+ assertThat(LauncherActivityInfo.isVisible("\u0FE1\u0FE2")).isFalse();
+ // 3 not supported
+ assertThat(LauncherActivityInfo.isVisible("\u0FE1\u0FE2\u0FE3")).isFalse();
+ // 4 not supported
+ assertThat(LauncherActivityInfo.isVisible("\u0FE1\u0FE2\u0FE3\u0FE4")).isFalse();
+ }
+
+ @Test
+ public void testIsVisible_invisibleAndNotSupportedCharacter() {
+ // 1 invisible, 1 not supported
+ assertThat(LauncherActivityInfo.isVisible("\u0009\u0FE1")).isFalse();
+ // 1 invisible, 2 not supported
+ assertThat(LauncherActivityInfo.isVisible("\u0009\u0FE1\u0FE2")).isFalse();
+ // 1 invisible, 3 not supported
+ assertThat(LauncherActivityInfo.isVisible("\u0009\u0FE1\u0FE2\u0FE3")).isFalse();
+ // 1 invisible, 4 not supported
+ assertThat(LauncherActivityInfo.isVisible("\u0009\u0FE1\u0FE2\u0FE3\u0FE4")).isFalse();
+
+ // 2 invisible, 1 not supported
+ assertThat(LauncherActivityInfo.isVisible("\u0009\u3164\u0FE1")).isFalse();
+ // 2 invisible, 2 not supported
+ assertThat(LauncherActivityInfo.isVisible("\u0009\u3164\u0FE1\u0FE2")).isFalse();
+ // 2 invisible, 3 not supported
+ assertThat(LauncherActivityInfo.isVisible("\u0009\u3164\u0FE1\u0FE2\u0FE3")).isFalse();
+ // 2 invisible, 4 not supported
+ assertThat(LauncherActivityInfo.isVisible(
+ "\u0009\u3164\u0FE1\u0FE2\u0FE3\u0FE4")).isFalse();
+
+ // 3 invisible, 1 not supported
+ assertThat(LauncherActivityInfo.isVisible("\u3000\u0009\u3164\u0FE1")).isFalse();
+ // 3 invisible, 2 not supported
+ assertThat(LauncherActivityInfo.isVisible("\u3000\u0009\u3164\u0FE1\u0FE2")).isFalse();
+ // 3 invisible, 3 not supported
+ assertThat(LauncherActivityInfo.isVisible(
+ "\u3000\u0009\u3164\u0FE1\u0FE2\u0FE3")).isFalse();
+ // 3 invisible, 4 not supported
+ assertThat(LauncherActivityInfo.isVisible(
+ "\u3000\u0009\u3164\u0FE1\u0FE2\u0FE3\u0FE4")).isFalse();
+
+ // 4 invisible, 1 not supported
+ assertThat(LauncherActivityInfo.isVisible("\u200F\u3000\u0009\u3164\u0FE1")).isFalse();
+ // 4 invisible, 2 not supported
+ assertThat(LauncherActivityInfo.isVisible(
+ "\u200F\u3000\u0009\u3164\u0FE1\u0FE2")).isFalse();
+ // 4 invisible, 3 not supported
+ assertThat(LauncherActivityInfo.isVisible(
+ "\u200F\u3000\u0009\u3164\u0FE1\u0FE2\u0FE3")).isFalse();
+ // 4 invisible, 4 not supported
+ assertThat(LauncherActivityInfo.isVisible(
+ "\u200F\u3000\u0009\u3164\u0FE1\u0FE2\u0FE3\u0FE4")).isFalse();
+
+ // 1 not supported, 1 invisible,
+ assertThat(LauncherActivityInfo.isVisible("\u0FE1\u0009")).isFalse();
+ // 1 not supported, 2 invisible
+ assertThat(LauncherActivityInfo.isVisible("\u0FE1\u0009\u3164")).isFalse();
+ // 1 not supported, 3 invisible
+ assertThat(LauncherActivityInfo.isVisible("\u0FE1\u3000\u0009\u3164")).isFalse();
+ // 1 not supported, 4 invisible
+ assertThat(LauncherActivityInfo.isVisible("\u0FE1\u200F\u3000\u0009\u3164")).isFalse();
+ }
+
+ @Test
+ public void testIsVisible_invisibleAndNormalCharacter() {
+ // 1 invisible, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible("\u0009\uD83E\uDD36")).isTrue();
+ // 2 invisible, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible("\u0009\u3164\uD83E\uDD36")).isTrue();
+ // 3 invisible, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible("\u3000\u0009\u3164\uD83E\uDD36")).isFalse();
+ // 4 invisible, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible(
+ "\u200F\u3000\u0009\u3164\uD83E\uDD36")).isFalse();
+ }
+
+ @Test
+ public void testIsVisible_notSupportedAndNormalCharacter() {
+ // 1 not supported, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible("\u0FE1\uD83E\uDD36")).isTrue();
+ // 2 not supported, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible("\u0FE1\u0FE2\uD83E\uDD36")).isTrue();
+ // 3 not supported, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible("\u0FE1\u0FE2\u0FE3\uD83E\uDD36")).isTrue();
+ // 4 not supported, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible(
+ "\u0FE1\u0FE2\u0FE3\u0FE4\uD83E\uDD36")).isTrue();
+ }
+
+ @Test
+ public void testIsVisible_mixAllCharacter() {
+ // 1 invisible, 1 not supported, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible("\u0009\u0FE1\uD83E\uDD36")).isTrue();
+ // 1 invisible, 1 not supported, 1 invisible, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible("\u0009\u0FE1\u3164\uD83E\uDD36")).isTrue();
+ // 1 invisible, 1 not supported, 2 invisible, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible(
+ "\u0009\u0FE1\u3000\u3164\uD83E\uDD36")).isTrue();
+ // 1 invisible, 1 not supported, 3 invisible, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible(
+ "\u0009\u0FE1\u200F\u3000\u3164\uD83E\uDD36")).isTrue();
+
+ // 2 invisible, 1 not supported, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible("\u0009\u3164\u0FE1\uD83E\uDD36")).isTrue();
+ // 2 invisible, 2 not supported, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible(
+ "\u0009\u3164\u0FE1\u0FE2\uD83E\uDD36")).isTrue();
+
+ // 3 invisible, 1 not supported, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible(
+ "\u3000\u0009\u3164\u0FE1\uD83E\uDD36")).isFalse();
+ // 3 invisible, 2 not supported, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible(
+ "\u3000\u0009\u3164\u0FE1\u0FE2\uD83E\uDD36")).isFalse();
+ // 3 invisible, 3 not supported, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible(
+ "\u3000\u0009\u3164\u0FE1\u0FE2\u0FE3\uD83E\uDD36")).isFalse();
+
+ // 4 invisible, 1 not supported, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible(
+ "\u200F\u3000\u0009\u3164\u0FE1\uD83E\uDD36")).isFalse();
+ // 4 invisible, 2 not supported, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible(
+ "\u200F\u3000\u0009\u3164\u0FE1\u0FE2\uD83E\uDD36")).isFalse();
+ // 4 invisible, 3 not supported, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible(
+ "\u200F\u3000\u0009\u3164\u0FE1\u0FE2\u0FE3\uD83E\uDD36")).isFalse();
+ // 4 invisible, 4 not supported, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible(
+ "\u200F\u3000\u0009\u3164\u0FE1\u0FE2\u0FE3\u0FE4\uD83E\uDD36")).isFalse();
+
+ // 1 not supported, 1 invisible, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible("\u0FE1\u0009\uD83E\uDD36")).isTrue();
+ // 1 not supported, 2 invisible, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible("\u0FE1\u0009\u3164\uD83E\uDD36")).isTrue();
+ // 1 not supported, 3 invisible, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible(
+ "\u0FE1\u3000\u0009\u3164\uD83E\uDD36")).isTrue();
+ // 1 not supported, 4 invisible, 1 surrogates
+ assertThat(LauncherActivityInfo.isVisible(
+ "\u0FE1\u200F\u3000\u0009\u3164\uD83E\uDD36")).isTrue();
+
}
}
diff --git a/core/tests/coretests/src/android/text/TextLineLetterSpacingTest.kt b/core/tests/coretests/src/android/text/TextLineLetterSpacingTest.kt
index 71980c125f01..e4e04a028588 100644
--- a/core/tests/coretests/src/android/text/TextLineLetterSpacingTest.kt
+++ b/core/tests/coretests/src/android/text/TextLineLetterSpacingTest.kt
@@ -17,11 +17,9 @@
package android.text
import android.graphics.Paint
-import android.platform.test.annotations.RequiresFlagsEnabled
import android.platform.test.flag.junit.DeviceFlagsValueProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.text.flags.Flags.FLAG_LETTER_SPACING_JUSTIFICATION
import com.google.common.truth.Truth.assertThat
import org.junit.Rule
import org.junit.Test
@@ -40,7 +38,6 @@ class TextLineLetterSpacingTest {
@JvmField
val mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
- @RequiresFlagsEnabled(FLAG_LETTER_SPACING_JUSTIFICATION)
@Test
fun calculateRunFlagTest() {
// Only one Bidi run
@@ -84,7 +81,6 @@ class TextLineLetterSpacingTest {
.isEqualTo(LEFT_EDGE)
}
- @RequiresFlagsEnabled(FLAG_LETTER_SPACING_JUSTIFICATION)
@Test
fun resolveRunFlagForSubSequenceTest() {
val runStart = 5
diff --git a/graphics/java/android/graphics/OWNERS b/graphics/java/android/graphics/OWNERS
index 9fa8f1b284bb..ef8d26cc65b9 100644
--- a/graphics/java/android/graphics/OWNERS
+++ b/graphics/java/android/graphics/OWNERS
@@ -11,3 +11,4 @@ per-file BLASTBufferQueue.java = file:/services/core/java/com/android/server/wm/
per-file FontFamily.java = file:fonts/OWNERS
per-file FontListParser.java = file:fonts/OWNERS
per-file Typeface.java = file:fonts/OWNERS
+per-file Paint.java = file:fonts/OWNERS
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index df95a91d72d7..b866382e4061 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -1805,16 +1805,7 @@ public class Paint {
* @return true if elegant metrics are enabled for text drawing.
*/
public boolean isElegantTextHeight() {
- int rawValue = nGetElegantTextHeight(mNativePaint);
- switch (rawValue) {
- case ELEGANT_TEXT_HEIGHT_DISABLED:
- return false;
- case ELEGANT_TEXT_HEIGHT_ENABLED:
- return true;
- case ELEGANT_TEXT_HEIGHT_UNSET:
- default:
- return com.android.text.flags.Flags.deprecateUiFonts();
- }
+ return nGetElegantTextHeight(mNativePaint) != ELEGANT_TEXT_HEIGHT_DISABLED;
}
// Note: the following three values must be equal to the ones in the JNI file: Paint.cpp
diff --git a/graphics/java/android/graphics/fonts/SystemFonts.java b/graphics/java/android/graphics/fonts/SystemFonts.java
index f727f5b076a1..0e25c346064c 100644
--- a/graphics/java/android/graphics/fonts/SystemFonts.java
+++ b/graphics/java/android/graphics/fonts/SystemFonts.java
@@ -306,13 +306,7 @@ public final class SystemFonts {
long lastModifiedDate,
int configVersion
) {
- final String fontsXml;
- if (com.android.text.flags.Flags.newFontsFallbackXml()) {
- fontsXml = FONTS_XML;
- } else {
- fontsXml = LEGACY_FONTS_XML;
- }
- return getSystemFontConfigInternal(fontsXml, SYSTEM_FONT_DIR, OEM_XML, OEM_FONT_DIR,
+ return getSystemFontConfigInternal(FONTS_XML, SYSTEM_FONT_DIR, OEM_XML, OEM_FONT_DIR,
updatableFontMap, lastModifiedDate, configVersion);
}
@@ -337,13 +331,7 @@ public final class SystemFonts {
* @hide
*/
public static @NonNull FontConfig getSystemPreinstalledFontConfig() {
- final String fontsXml;
- if (com.android.text.flags.Flags.newFontsFallbackXml()) {
- fontsXml = FONTS_XML;
- } else {
- fontsXml = LEGACY_FONTS_XML;
- }
- return getSystemFontConfigInternal(fontsXml, SYSTEM_FONT_DIR, OEM_XML, OEM_FONT_DIR, null,
+ return getSystemFontConfigInternal(FONTS_XML, SYSTEM_FONT_DIR, OEM_XML, OEM_FONT_DIR, null,
0, 0);
}
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt
index 424d4bf5c6e8..b5d63bd6addc 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt
@@ -49,6 +49,7 @@ enum class DesktopModeFlags(
SIZE_CONSTRAINTS(Flags::enableDesktopWindowingSizeConstraints, true),
DISABLE_SNAP_RESIZE(Flags::disableNonResizableAppSnapResizing, true),
DYNAMIC_INITIAL_BOUNDS(Flags::enableWindowingDynamicInitialBounds, false),
+ SCALED_RESIZING(Flags::enableWindowingScaledResizing, false),
ENABLE_DESKTOP_WINDOWING_TASK_LIMIT(Flags::enableDesktopWindowingTaskLimit, true),
BACK_NAVIGATION(Flags::enableDesktopWindowingBackNavigation, true),
EDGE_DRAG_RESIZE(Flags::enableWindowingEdgeDragResize, true),
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 1ffa54103d62..832e2d2bc77b 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
@@ -118,7 +118,7 @@ public class FreeformTaskTransitionHandler
@Override
public IBinder startMinimizedModeTransition(WindowContainerTransaction wct) {
- final int type = WindowManager.TRANSIT_TO_BACK;
+ final int type = Transitions.TRANSIT_MINIMIZE;
final IBinder token = mTransitions.startTransition(type, wct, this);
mPendingTransitionTokens.add(token);
return token;
@@ -161,7 +161,8 @@ public class FreeformTaskTransitionHandler
transition, info.getType(), change);
break;
case WindowManager.TRANSIT_TO_BACK:
- transitionHandled |= startMinimizeTransition(transition);
+ transitionHandled |= startMinimizeTransition(
+ transition, info.getType(), change);
break;
case WindowManager.TRANSIT_CLOSE:
if (change.getTaskInfo().getWindowingMode() == WINDOWING_MODE_FREEFORM) {
@@ -227,8 +228,20 @@ public class FreeformTaskTransitionHandler
return handled;
}
- private boolean startMinimizeTransition(IBinder transition) {
- return mPendingTransitionTokens.contains(transition);
+ private boolean startMinimizeTransition(
+ IBinder transition,
+ int type,
+ TransitionInfo.Change change) {
+ if (!mPendingTransitionTokens.contains(transition)) {
+ return false;
+ }
+
+ final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
+ if (type != Transitions.TRANSIT_MINIMIZE) {
+ return false;
+ }
+ // TODO(b/361524575): Add minimize animations
+ return true;
}
private boolean startCloseTransition(IBinder transition, TransitionInfo.Change change,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitscreenEventLogger.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitscreenEventLogger.java
index 1e6fa2807b9b..2033902f03c7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitscreenEventLogger.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitscreenEventLogger.java
@@ -24,6 +24,7 @@ import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED_
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__CHILD_TASK_ENTER_PIP;
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__DEVICE_FOLDED;
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__DRAG_DIVIDER;
+import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__FULLSCREEN_REQUEST;
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__FULLSCREEN_SHORTCUT;
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__DESKTOP_MODE;
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__RECREATE_SPLIT;
@@ -45,6 +46,7 @@ import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DEVICE_FOLDED;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DESKTOP_MODE;
+import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_FULLSCREEN_REQUEST;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_FULLSCREEN_SHORTCUT;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_RECREATE_SPLIT;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_RETURN_HOME;
@@ -211,6 +213,8 @@ public class SplitscreenEventLogger {
return SPLITSCREEN_UICHANGED__EXIT_REASON__FULLSCREEN_SHORTCUT;
case EXIT_REASON_DESKTOP_MODE:
return SPLITSCREEN_UICHANGED__EXIT_REASON__DESKTOP_MODE;
+ case EXIT_REASON_FULLSCREEN_REQUEST:
+ return SPLITSCREEN_UICHANGED__EXIT_REASON__FULLSCREEN_REQUEST;
case EXIT_REASON_UNKNOWN:
// Fall through
default:
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 dad0d4eb4d8d..1b143ebddde7 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
@@ -1175,6 +1175,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSplitTransitions.startDismissTransition(wct, this, mLastActiveStage, reason);
setSplitsVisible(false);
mBreakOnNextWake = false;
+ logExit(reason);
}
void exitSplitScreenOnHide(boolean exitSplitScreenOnHide) {
@@ -1265,6 +1266,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
final WindowContainerTransaction wct = new WindowContainerTransaction();
prepareExitSplitScreen(stage, wct);
mSplitTransitions.startDismissTransition(wct, this, stage, exitReason);
+ logExit(exitReason);
}
/**
@@ -1361,6 +1363,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mMainStage.doForAllChildTasks(taskId -> recentTasks.removeSplitPair(taskId));
mSideStage.doForAllChildTasks(taskId -> recentTasks.removeSplitPair(taskId));
});
+ logExit(exitReason);
}
/**
@@ -1579,7 +1582,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
if (stage == STAGE_TYPE_MAIN) {
mLogger.logMainStageAppChange(getMainStagePosition(), mMainStage.getTopChildTaskUid(),
mSplitLayout.isLeftRightSplit());
- } else {
+ } else if (stage == STAGE_TYPE_SIDE) {
mLogger.logSideStageAppChange(getSideStagePosition(), mSideStage.getTopChildTaskUid(),
mSplitLayout.isLeftRightSplit());
}
@@ -2275,6 +2278,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
if (isOpening && inFullscreen) {
// One task is opening into fullscreen mode, remove the corresponding split record.
mRecentTasks.ifPresent(recentTasks -> recentTasks.removeSplitPair(triggerTask.taskId));
+ logExit(EXIT_REASON_FULLSCREEN_REQUEST);
}
if (isSplitActive()) {
@@ -2402,6 +2406,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
if (triggerTask != null) {
mRecentTasks.ifPresent(
recentTasks -> recentTasks.removeSplitPair(triggerTask.taskId));
+ logExit(EXIT_REASON_CHILD_TASK_ENTER_PIP);
}
@StageType int topStage = STAGE_TYPE_UNDEFINED;
if (isSplitScreenVisible()) {
@@ -2743,7 +2748,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
final int dismissTop = mainChild != null ? STAGE_TYPE_MAIN :
(sideChild != null ? STAGE_TYPE_SIDE : STAGE_TYPE_UNDEFINED);
pendingEnter.cancel(
- (cancelWct, cancelT) -> prepareExitSplitScreen(dismissTop, cancelWct));
+ (cancelWct, cancelT) -> {
+ prepareExitSplitScreen(dismissTop, cancelWct);
+ logExit(EXIT_REASON_UNKNOWN);
+ });
Log.w(TAG, splitFailureMessage("startPendingEnterAnimation",
"launched 2 tasks in split, but didn't receive "
+ "2 tasks in transition. Possibly one of them failed to launch"));
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 7dc336bdfb7d..aba8b61af306 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
@@ -196,6 +196,9 @@ public class Transitions implements RemoteCallable<Transitions>,
/** Transition to set windowing mode after exit pip transition is finished animating. */
public static final int TRANSIT_CLEANUP_PIP_EXIT = WindowManager.TRANSIT_FIRST_CUSTOM + 19;
+ /** Transition type to minimize a task. */
+ public static final int TRANSIT_MINIMIZE = WindowManager.TRANSIT_FIRST_CUSTOM + 20;
+
/** Transition type for desktop mode transitions. */
public static final int TRANSIT_DESKTOP_MODE_TYPES =
WindowManager.TRANSIT_FIRST_CUSTOM + 100;
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index 5955915c9fcd..e6182454ad8a 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -1420,20 +1420,18 @@ void AssetManager::mergeInfoLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo
Mutex AssetManager::SharedZip::gLock;
DefaultKeyedVector<String8, wp<AssetManager::SharedZip> > AssetManager::SharedZip::gOpen;
-AssetManager::SharedZip::SharedZip(const String8& path, ModDate modWhen)
- : mPath(path),
- mZipFile(NULL),
- mModWhen(modWhen),
- mResourceTableAsset(NULL),
- mResourceTable(NULL) {
- if (kIsDebug) {
- ALOGI("Creating SharedZip %p %s\n", this, mPath.c_str());
- }
- ALOGV("+++ opening zip '%s'\n", mPath.c_str());
- mZipFile = ZipFileRO::open(mPath.c_str());
- if (mZipFile == NULL) {
- ALOGD("failed to open Zip archive '%s'\n", mPath.c_str());
- }
+AssetManager::SharedZip::SharedZip(const String8& path, time_t modWhen)
+ : mPath(path), mZipFile(NULL), mModWhen(modWhen),
+ mResourceTableAsset(NULL), mResourceTable(NULL)
+{
+ if (kIsDebug) {
+ ALOGI("Creating SharedZip %p %s\n", this, mPath.c_str());
+ }
+ ALOGV("+++ opening zip '%s'\n", mPath.c_str());
+ mZipFile = ZipFileRO::open(mPath.c_str());
+ if (mZipFile == NULL) {
+ ALOGD("failed to open Zip archive '%s'\n", mPath.c_str());
+ }
}
AssetManager::SharedZip::SharedZip(int fd, const String8& path)
@@ -1455,7 +1453,7 @@ sp<AssetManager::SharedZip> AssetManager::SharedZip::get(const String8& path,
bool createIfNotPresent)
{
AutoMutex _l(gLock);
- auto modWhen = getFileModDate(path.c_str());
+ time_t modWhen = getFileModDate(path.c_str());
sp<SharedZip> zip = gOpen.valueFor(path).promote();
if (zip != NULL && zip->mModWhen == modWhen) {
return zip;
@@ -1522,8 +1520,8 @@ ResTable* AssetManager::SharedZip::setResourceTable(ResTable* res)
bool AssetManager::SharedZip::isUpToDate()
{
- auto modWhen = getFileModDate(mPath.c_str());
- return mModWhen == modWhen;
+ time_t modWhen = getFileModDate(mPath.c_str());
+ return mModWhen == modWhen;
}
void AssetManager::SharedZip::addOverlay(const asset_path& ap)
diff --git a/libs/androidfw/include/androidfw/AssetManager.h b/libs/androidfw/include/androidfw/AssetManager.h
index 376c881ea376..ce0985b38986 100644
--- a/libs/androidfw/include/androidfw/AssetManager.h
+++ b/libs/androidfw/include/androidfw/AssetManager.h
@@ -280,21 +280,21 @@ private:
~SharedZip();
private:
- SharedZip(const String8& path, ModDate modWhen);
- SharedZip(int fd, const String8& path);
- SharedZip(); // <-- not implemented
+ SharedZip(const String8& path, time_t modWhen);
+ SharedZip(int fd, const String8& path);
+ SharedZip(); // <-- not implemented
- String8 mPath;
- ZipFileRO* mZipFile;
- ModDate mModWhen;
+ String8 mPath;
+ ZipFileRO* mZipFile;
+ time_t mModWhen;
- Asset* mResourceTableAsset;
- ResTable* mResourceTable;
+ Asset* mResourceTableAsset;
+ ResTable* mResourceTable;
- Vector<asset_path> mOverlays;
+ Vector<asset_path> mOverlays;
- static Mutex gLock;
- static DefaultKeyedVector<String8, wp<SharedZip> > gOpen;
+ static Mutex gLock;
+ static DefaultKeyedVector<String8, wp<SharedZip> > gOpen;
};
/*
diff --git a/libs/androidfw/include/androidfw/Idmap.h b/libs/androidfw/include/androidfw/Idmap.h
index 98f1aa86f2db..64b1f0c6ed03 100644
--- a/libs/androidfw/include/androidfw/Idmap.h
+++ b/libs/androidfw/include/androidfw/Idmap.h
@@ -25,9 +25,8 @@
#include "android-base/macros.h"
#include "android-base/unique_fd.h"
#include "androidfw/ConfigDescription.h"
-#include "androidfw/ResourceTypes.h"
#include "androidfw/StringPiece.h"
-#include "androidfw/misc.h"
+#include "androidfw/ResourceTypes.h"
#include "utils/ByteOrder.h"
namespace android {
@@ -203,7 +202,7 @@ class LoadedIdmap {
android::base::unique_fd idmap_fd_;
std::string_view overlay_apk_path_;
std::string_view target_apk_path_;
- ModDate idmap_last_mod_time_;
+ time_t idmap_last_mod_time_;
private:
DISALLOW_COPY_AND_ASSIGN(LoadedIdmap);
diff --git a/libs/androidfw/include/androidfw/misc.h b/libs/androidfw/include/androidfw/misc.h
index 09ae40c35369..077609d20d55 100644
--- a/libs/androidfw/include/androidfw/misc.h
+++ b/libs/androidfw/include/androidfw/misc.h
@@ -13,13 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#pragma once
-#include <time.h>
+#include <sys/types.h>
//
// Handy utility functions and portability code.
//
+#ifndef _LIBS_ANDROID_FW_MISC_H
+#define _LIBS_ANDROID_FW_MISC_H
namespace android {
@@ -40,35 +41,15 @@ typedef enum FileType {
} FileType;
/* get the file's type; follows symlinks */
FileType getFileType(const char* fileName);
-
-// MinGW doesn't support nanosecond resolution in stat() modification time, and given
-// that it only matters on the device it's ok to keep it at the second level there.
-#ifdef _WIN32
-using ModDate = time_t;
-inline constexpr ModDate kInvalidModDate = ModDate(-1);
-inline constexpr unsigned long long kModDateResolutionNs = 1ull * 1000 * 1000 * 1000;
-inline time_t toTimeT(ModDate m) {
- return m;
-}
-#else
-using ModDate = timespec;
-inline constexpr ModDate kInvalidModDate = {-1, -1};
-inline constexpr unsigned long long kModDateResolutionNs = 1;
-inline time_t toTimeT(ModDate m) {
- return m.tv_sec;
-}
-#endif
-
-/* get the file's modification date; returns kInvalidModDate w/errno set on failure */
-ModDate getFileModDate(const char* fileName);
+/* get the file's modification date; returns -1 w/errno set on failure */
+time_t getFileModDate(const char* fileName);
/* same, but also returns -1 if the file has already been deleted */
-ModDate getFileModDate(int fd);
+time_t getFileModDate(int fd);
// Check if |path| or |fd| resides on a readonly filesystem.
bool isReadonlyFilesystem(const char* path);
bool isReadonlyFilesystem(int fd);
-} // namespace android
+}; // namespace android
-// Whoever uses getFileModDate() will need this as well
-bool operator==(const timespec& l, const timespec& r);
+#endif // _LIBS_ANDROID_FW_MISC_H
diff --git a/libs/androidfw/misc.cpp b/libs/androidfw/misc.cpp
index 9bdaf18a116a..93dcaf549a90 100644
--- a/libs/androidfw/misc.cpp
+++ b/libs/androidfw/misc.cpp
@@ -28,13 +28,11 @@
#include <sys/vfs.h>
#endif // __linux__
+#include <cstring>
+#include <cstdio>
#include <errno.h>
#include <sys/stat.h>
-#include <cstdio>
-#include <cstring>
-#include <tuple>
-
namespace android {
/*
@@ -75,32 +73,27 @@ FileType getFileType(const char* fileName)
}
}
-static ModDate getModDate(const struct stat& st) {
-#ifdef _WIN32
- return st.st_mtime;
-#else
- return st.st_mtim;
-#endif
-}
-
-ModDate getFileModDate(const char* fileName) {
- struct stat sb;
- if (stat(fileName, &sb) < 0) {
- return kInvalidModDate;
- }
- return getModDate(sb);
+/*
+ * Get a file's modification date.
+ */
+time_t getFileModDate(const char* fileName) {
+ struct stat sb;
+ if (stat(fileName, &sb) < 0) {
+ return (time_t)-1;
+ }
+ return sb.st_mtime;
}
-ModDate getFileModDate(int fd) {
- struct stat sb;
- if (fstat(fd, &sb) < 0) {
- return kInvalidModDate;
- }
- if (sb.st_nlink <= 0) {
- errno = ENOENT;
- return kInvalidModDate;
- }
- return getModDate(sb);
+time_t getFileModDate(int fd) {
+ struct stat sb;
+ if (fstat(fd, &sb) < 0) {
+ return (time_t)-1;
+ }
+ if (sb.st_nlink <= 0) {
+ errno = ENOENT;
+ return (time_t)-1;
+ }
+ return sb.st_mtime;
}
#ifndef __linux__
@@ -131,8 +124,4 @@ bool isReadonlyFilesystem(int fd) {
}
#endif // __linux__
-} // namespace android
-
-bool operator==(const timespec& l, const timespec& r) {
- return std::tie(l.tv_sec, l.tv_nsec) == std::tie(r.tv_sec, l.tv_nsec);
-}
+}; // namespace android
diff --git a/libs/androidfw/tests/Idmap_test.cpp b/libs/androidfw/tests/Idmap_test.cpp
index cb2e56f5f5e4..60aa7d88925d 100644
--- a/libs/androidfw/tests/Idmap_test.cpp
+++ b/libs/androidfw/tests/Idmap_test.cpp
@@ -14,9 +14,6 @@
* limitations under the License.
*/
-#include <chrono>
-#include <thread>
-
#include "android-base/file.h"
#include "androidfw/ApkAssets.h"
#include "androidfw/AssetManager2.h"
@@ -30,7 +27,6 @@
#include "data/overlayable/R.h"
#include "data/system/R.h"
-using namespace std::chrono_literals;
using ::testing::NotNull;
namespace overlay = com::android::overlay;
@@ -222,13 +218,10 @@ TEST_F(IdmapTest, OverlayAssetsIsUpToDate) {
unlink(temp_file.path);
ASSERT_FALSE(apk_assets->IsUpToDate());
-
- const auto sleep_duration =
- std::chrono::nanoseconds(std::max(kModDateResolutionNs, 1'000'000ull));
- std::this_thread::sleep_for(sleep_duration);
+ sleep(2);
base::WriteStringToFile("hello", temp_file.path);
- std::this_thread::sleep_for(sleep_duration);
+ sleep(2);
ASSERT_FALSE(apk_assets->IsUpToDate());
}
diff --git a/libs/hwui/FeatureFlags.h b/libs/hwui/FeatureFlags.h
index c0cedf12c0ae..fddcf29b9197 100644
--- a/libs/hwui/FeatureFlags.h
+++ b/libs/hwui/FeatureFlags.h
@@ -25,14 +25,6 @@ namespace android {
namespace text_feature {
-inline bool deprecate_ui_fonts() {
-#ifdef __ANDROID__
- return com_android_text_flags_deprecate_ui_fonts();
-#else
- return true;
-#endif // __ANDROID__
-}
-
inline bool letter_spacing_justification() {
#ifdef __ANDROID__
return com_android_text_flags_letter_spacing_justification();
diff --git a/libs/hwui/hwui/MinikinUtils.cpp b/libs/hwui/hwui/MinikinUtils.cpp
index d66d7f8e83f4..ede385adc779 100644
--- a/libs/hwui/hwui/MinikinUtils.cpp
+++ b/libs/hwui/hwui/MinikinUtils.cpp
@@ -53,9 +53,7 @@ minikin::MinikinPaint MinikinUtils::prepareMinikinPaint(const Paint* paint,
if (familyVariant.has_value()) {
minikinPaint.familyVariant = familyVariant.value();
} else {
- minikinPaint.familyVariant = text_feature::deprecate_ui_fonts()
- ? minikin::FamilyVariant::ELEGANT
- : minikin::FamilyVariant::DEFAULT;
+ minikinPaint.familyVariant = minikin::FamilyVariant::ELEGANT;
}
return minikinPaint;
}
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index dfda25d013ed..8ec04304a808 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -654,6 +654,9 @@ void CanvasContext::draw(bool solelyTextureViewUpdates) {
if (vsyncId != UiFrameInfoBuilder::INVALID_VSYNC_ID) {
const auto inputEventId =
static_cast<int32_t>(mCurrentFrameInfo->get(FrameInfoIndex::InputEventId));
+ ATRACE_FORMAT(
+ "frameTimelineInfo(frameNumber=%llu, vsyncId=%lld, inputEventId=0x%" PRIx32 ")",
+ frameCompleteNr, vsyncId, inputEventId);
const ANativeWindowFrameTimelineInfo ftl = {
.frameNumber = frameCompleteNr,
.frameTimelineVsyncId = vsyncId,
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index 3409c29d3c2c..defbc1142adb 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -16,8 +16,6 @@
package com.android.externalstorage;
-import static java.util.regex.Pattern.CASE_INSENSITIVE;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.usage.StorageStatsManager;
@@ -61,12 +59,15 @@ import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.UUID;
-import java.util.regex.Pattern;
+import java.util.stream.Collectors;
/**
* Presents content of the shared (a.k.a. "external") storage.
@@ -89,12 +90,9 @@ public class ExternalStorageProvider extends FileSystemProvider {
private static final Uri BASE_URI =
new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(AUTHORITY).build();
- /**
- * Regex for detecting {@code /Android/data/}, {@code /Android/obb/} and
- * {@code /Android/sandbox/} along with all their subdirectories and content.
- */
- private static final Pattern PATTERN_RESTRICTED_ANDROID_SUBTREES =
- Pattern.compile("^Android/(?:data|obb|sandbox)(?:/.+)?", CASE_INSENSITIVE);
+ private static final String PRIMARY_EMULATED_STORAGE_PATH = "/storage/emulated/";
+
+ private static final String STORAGE_PATH = "/storage/";
private static final String[] DEFAULT_ROOT_PROJECTION = new String[] {
Root.COLUMN_ROOT_ID, Root.COLUMN_FLAGS, Root.COLUMN_ICON, Root.COLUMN_TITLE,
@@ -309,11 +307,70 @@ public class ExternalStorageProvider extends FileSystemProvider {
return false;
}
- final String path = getPathFromDocId(documentId);
- return PATTERN_RESTRICTED_ANDROID_SUBTREES.matcher(path).matches();
+ try {
+ final RootInfo root = getRootFromDocId(documentId);
+ final String canonicalPath = getPathFromDocId(documentId);
+ return isRestrictedPath(root.rootId, canonicalPath);
+ } catch (Exception e) {
+ return true;
+ }
}
/**
+ * Based on the given root id and path, we restrict path access if file is Android/data or
+ * Android/obb or Android/sandbox or one of their subdirectories.
+ *
+ * @param canonicalPath of the file
+ * @return true if path is restricted
+ */
+ private boolean isRestrictedPath(String rootId, String canonicalPath) {
+ if (rootId == null || canonicalPath == null) {
+ return true;
+ }
+
+ final String rootPath;
+ if (rootId.equalsIgnoreCase(ROOT_ID_PRIMARY_EMULATED)) {
+ // Creates "/storage/emulated/<user-id>"
+ rootPath = PRIMARY_EMULATED_STORAGE_PATH + UserHandle.myUserId();
+ } else {
+ // Creates "/storage/<volume-uuid>"
+ rootPath = STORAGE_PATH + rootId;
+ }
+ List<java.nio.file.Path> restrictedPathList = Arrays.asList(
+ Paths.get(rootPath, "Android", "data"),
+ Paths.get(rootPath, "Android", "obb"),
+ Paths.get(rootPath, "Android", "sandbox"));
+ // We need to identify restricted parent paths which actually exist on the device
+ List<java.nio.file.Path> validRestrictedPathsToCheck = restrictedPathList.stream().filter(
+ Files::exists).collect(Collectors.toList());
+
+ boolean isRestricted = false;
+ java.nio.file.Path filePathToCheck = Paths.get(rootPath, canonicalPath);
+ try {
+ while (filePathToCheck != null) {
+ for (java.nio.file.Path restrictedPath : validRestrictedPathsToCheck) {
+ if (Files.isSameFile(restrictedPath, filePathToCheck)) {
+ isRestricted = true;
+ Log.v(TAG, "Restricting access for path: " + filePathToCheck);
+ break;
+ }
+ }
+ if (isRestricted) {
+ break;
+ }
+
+ filePathToCheck = filePathToCheck.getParent();
+ }
+ } catch (Exception e) {
+ Log.w(TAG, "Error in checking file equality check.", e);
+ isRestricted = true;
+ }
+
+ return isRestricted;
+ }
+
+
+ /**
* Check that the directory is the root of storage or blocked file from tree.
* <p>
* Note, that this is different from hidden documents: blocked documents <b>WILL</b> appear
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index 0cb85d8638b0..b997c35668d2 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -42,6 +42,8 @@ android_library {
"SettingsLibIllustrationPreference",
"SettingsLibLayoutPreference",
"SettingsLibMainSwitchPreference",
+ "SettingsLibMetadata",
+ "SettingsLibPreference",
"SettingsLibProfileSelector",
"SettingsLibProgressBar",
"SettingsLibRestrictedLockUtils",
diff --git a/packages/SettingsLib/Preference/Android.bp b/packages/SettingsLib/Preference/Android.bp
index 9665dbd17e2d..17852e8e7ece 100644
--- a/packages/SettingsLib/Preference/Android.bp
+++ b/packages/SettingsLib/Preference/Android.bp
@@ -18,6 +18,7 @@ android_library {
"SettingsLibMetadata",
"androidx.annotation_annotation",
"androidx.preference_preference",
+ "guava",
],
kotlincflags: ["-Xjvm-default=all"],
}
diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceFragment.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceFragment.kt
index 207200998b05..68f640bbb9b4 100644
--- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceFragment.kt
+++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceFragment.kt
@@ -79,7 +79,7 @@ open class PreferenceFragment :
* This is for flagging purpose. If false (e.g. flag is disabled), xml resource is used to build
* preference screen.
*/
- protected open fun usePreferenceScreenMetadata(): Boolean = true
+ protected open fun usePreferenceScreenMetadata(): Boolean = false
/** Returns the xml resource to create preference screen. */
@XmlRes protected open fun getPreferenceScreenResId(context: Context): Int = 0
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservablePreferenceFragment.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservablePreferenceFragment.java
index bd1e5a588968..79949248cd8a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservablePreferenceFragment.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservablePreferenceFragment.java
@@ -31,13 +31,14 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import androidx.lifecycle.LifecycleOwner;
-import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceScreen;
+import com.android.settingslib.preference.PreferenceFragment;
+
/**
- * {@link PreferenceFragmentCompat} that has hooks to observe fragment lifecycle events.
+ * Preference fragment that has hooks to observe fragment lifecycle events.
*/
-public abstract class ObservablePreferenceFragment extends PreferenceFragmentCompat
+public abstract class ObservablePreferenceFragment extends PreferenceFragment
implements LifecycleOwner {
private final Lifecycle mLifecycle = new Lifecycle(this);
diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt
index 3e2d8328f21e..d3c345deebad 100644
--- a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt
@@ -98,7 +98,7 @@ interface AudioRepository {
*/
suspend fun setMuted(audioStream: AudioStream, isMuted: Boolean): Boolean
- suspend fun setRingerMode(audioStream: AudioStream, mode: RingerMode)
+ suspend fun setRingerModeInternal(audioStream: AudioStream, mode: RingerMode)
/** Gets audio device category. */
@AudioDeviceCategory suspend fun getBluetoothAudioDeviceCategory(bluetoothAddress: String): Int
@@ -248,8 +248,8 @@ class AudioRepositoryImpl(
}
}
- override suspend fun setRingerMode(audioStream: AudioStream, mode: RingerMode) {
- withContext(backgroundCoroutineContext) { audioManager.ringerMode = mode.value }
+ override suspend fun setRingerModeInternal(audioStream: AudioStream, mode: RingerMode) {
+ withContext(backgroundCoroutineContext) { audioManager.ringerModeInternal = mode.value }
}
@AudioDeviceCategory
diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/domain/interactor/AudioVolumeInteractor.kt b/packages/SettingsLib/src/com/android/settingslib/volume/domain/interactor/AudioVolumeInteractor.kt
index 08863b56cbe0..dca890d34bc0 100644
--- a/packages/SettingsLib/src/com/android/settingslib/volume/domain/interactor/AudioVolumeInteractor.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/volume/domain/interactor/AudioVolumeInteractor.kt
@@ -68,7 +68,7 @@ class AudioVolumeInteractor(
if (audioStream.value == AudioManager.STREAM_RING) {
val mode =
if (isMuted) AudioManager.RINGER_MODE_VIBRATE else AudioManager.RINGER_MODE_NORMAL
- audioRepository.setRingerMode(audioStream, RingerMode(mode))
+ audioRepository.setRingerModeInternal(audioStream, RingerMode(mode))
}
val mutedChanged = audioRepository.setMuted(audioStream, isMuted)
if (mutedChanged && !isMuted) {
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioRepositoryTest.kt b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioRepositoryTest.kt
index 52e639172af5..8a3b1dfb0846 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioRepositoryTest.kt
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioRepositoryTest.kt
@@ -74,6 +74,8 @@ class AudioRepositoryTest {
private lateinit var underTest: AudioRepository
+ private var ringerModeInternal: RingerMode = RingerMode(AudioManager.RINGER_MODE_NORMAL)
+
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
@@ -82,7 +84,7 @@ class AudioRepositoryTest {
`when`(audioManager.communicationDevice).thenReturn(communicationDevice)
`when`(audioManager.getStreamMinVolume(anyInt())).thenReturn(MIN_VOLUME)
`when`(audioManager.getStreamMaxVolume(anyInt())).thenReturn(MAX_VOLUME)
- `when`(audioManager.ringerModeInternal).thenReturn(AudioManager.RINGER_MODE_NORMAL)
+ `when`(audioManager.ringerModeInternal).then { ringerModeInternal.value }
`when`(audioManager.setStreamVolume(anyInt(), anyInt(), anyInt())).then {
val streamType = it.arguments[0] as Int
volumeByStream[it.arguments[0] as Int] = it.arguments[1] as Int
@@ -103,6 +105,10 @@ class AudioRepositoryTest {
`when`(audioManager.isStreamMute(anyInt())).thenAnswer {
isMuteByStream.getOrDefault(it.arguments[0] as Int, false)
}
+ `when`(audioManager.setRingerModeInternal(anyInt())).then {
+ ringerModeInternal = RingerMode(it.arguments[0] as Int)
+ Unit
+ }
underTest =
AudioRepositoryImpl(
@@ -137,7 +143,7 @@ class AudioRepositoryTest {
underTest.ringerMode.onEach { modes.add(it) }.launchIn(backgroundScope)
runCurrent()
- `when`(audioManager.ringerModeInternal).thenReturn(AudioManager.RINGER_MODE_SILENT)
+ ringerModeInternal = RingerMode(AudioManager.RINGER_MODE_SILENT)
triggerEvent(AudioManagerEvent.InternalRingerModeChanged)
runCurrent()
@@ -150,6 +156,19 @@ class AudioRepositoryTest {
}
@Test
+ fun changingRingerMode_changesRingerModeInternal() {
+ testScope.runTest {
+ underTest.setRingerModeInternal(
+ AudioStream(AudioManager.STREAM_SYSTEM),
+ RingerMode(AudioManager.RINGER_MODE_SILENT),
+ )
+ runCurrent()
+
+ assertThat(ringerModeInternal).isEqualTo(RingerMode(AudioManager.RINGER_MODE_SILENT))
+ }
+ }
+
+ @Test
fun communicationDeviceChanges_repositoryEmits() {
testScope.runTest {
var device: AudioDeviceInfo? = null
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinInputDisplay.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinInputDisplay.kt
index ba885f7da2cf..1f98cd8e07c0 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinInputDisplay.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinInputDisplay.kt
@@ -65,7 +65,6 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
-import androidx.compose.ui.window.Dialog
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.PlatformOutlinedButton
import com.android.compose.animation.Easings
@@ -355,7 +354,10 @@ private class PinInputRow(
fun Content(modifier: Modifier) {
// Wrap PIN entry in a Box so it is visible to accessibility (even if empty).
- Box(modifier = modifier.fillMaxWidth().wrapContentHeight()) {
+ Box(
+ modifier = modifier.fillMaxWidth().wrapContentHeight(),
+ contentAlignment = Alignment.Center,
+ ) {
Row(
modifier
.heightIn(min = shapeAnimations.shapeSize)
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/TextExt.kt b/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/TextExt.kt
index e1f73e304b9e..4e8121f14e4b 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/TextExt.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/TextExt.kt
@@ -17,9 +17,12 @@
package com.android.systemui.common.ui.compose
+import android.content.Context
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.AnnotatedString
import com.android.systemui.common.shared.model.Text
+import com.android.systemui.common.shared.model.Text.Companion.loadText
/** Returns the loaded [String] or `null` if there isn't one. */
@Composable
@@ -29,3 +32,7 @@ fun Text.load(): String? {
is Text.Resource -> stringResource(res)
}
}
+
+fun Text.toAnnotatedString(context: Context): AnnotatedString? {
+ return loadText(context)?.let { AnnotatedString(it) }
+}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt
index 0d05f4e8c613..b99b7f9f4fe4 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt
@@ -200,7 +200,7 @@ internal class MultiPointerDraggableNode(
override fun onPointerEvent(
pointerEvent: PointerEvent,
pass: PointerEventPass,
- bounds: IntSize
+ bounds: IntSize,
) {
// The order is important here: the tracker is always called first.
pointerTracker.onPointerEvent(pointerEvent, pass, bounds)
@@ -312,13 +312,13 @@ internal class MultiPointerDraggableNode(
velocityTracker.calculateVelocity(maxVelocity)
}
.toFloat(),
- onFling = { controller.onStop(it, canChangeContent = true) }
+ onFling = { controller.onStop(it, canChangeContent = true) },
)
},
onDragCancel = { controller ->
startFlingGesture(
initialVelocity = 0f,
- onFling = { controller.onStop(it, canChangeContent = true) }
+ onFling = { controller.onStop(it, canChangeContent = true) },
)
},
swipeDetector = swipeDetector,
@@ -369,10 +369,7 @@ internal class MultiPointerDraggableNode(
// PreScroll phase
val consumedByPreScroll =
dispatcher
- .dispatchPreScroll(
- available = availableOnPreScroll.toOffset(),
- source = source,
- )
+ .dispatchPreScroll(available = availableOnPreScroll.toOffset(), source = source)
.toFloat()
// Scroll phase
@@ -484,12 +481,12 @@ internal class MultiPointerDraggableNode(
Orientation.Horizontal ->
awaitHorizontalTouchSlopOrCancellation(
consumablePointer.id,
- onSlopReached
+ onSlopReached,
)
Orientation.Vertical ->
awaitVerticalTouchSlopOrCancellation(
consumablePointer.id,
- onSlopReached
+ onSlopReached,
)
}
@@ -553,7 +550,7 @@ internal class MultiPointerDraggableNode(
}
private suspend fun AwaitPointerEventScope.awaitConsumableEvent(
- pass: () -> PointerEventPass,
+ pass: () -> PointerEventPass
): PointerEvent {
fun canBeConsumed(changes: List<PointerInputChange>): Boolean {
// At least one pointer down AND
@@ -661,7 +658,4 @@ internal fun interface PointersInfoOwner {
fun pointersInfo(): PointersInfo
}
-internal data class PointersInfo(
- val startedPosition: Offset?,
- val pointersDown: Int,
-)
+internal data class PointersInfo(val startedPosition: Offset?, val pointersDown: Int)
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt
index bf192e7708d0..942cb2303dc5 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt
@@ -259,7 +259,7 @@ class MultiPointerDraggableTest {
it
}
),
- Orientation.Vertical
+ Orientation.Vertical,
)
.fillMaxSize()
)
@@ -640,7 +640,7 @@ class MultiPointerDraggableTest {
override fun onPostScroll(
consumed: Offset,
available: Offset,
- source: NestedScrollSource
+ source: NestedScrollSource,
): Offset {
availableOnPostScroll = available.y
return Offset.Zero
@@ -653,7 +653,7 @@ class MultiPointerDraggableTest {
override suspend fun onPostFling(
consumed: Velocity,
- available: Velocity
+ available: Velocity,
): Velocity {
availableOnPostFling = available.y
return Velocity.Zero
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
index 75a77cf781d2..4bc71fd6d363 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
@@ -27,6 +27,17 @@ import android.hardware.face.FaceSensorProperties
import android.hardware.face.FaceSensorPropertiesInternal
import android.hardware.fingerprint.FingerprintSensorProperties
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
+import com.android.keyguard.keyguardUpdateMonitor
+import com.android.systemui.SysuiTestableContext
+import com.android.systemui.biometrics.data.repository.biometricStatusRepository
+import com.android.systemui.biometrics.shared.model.AuthenticationReason
+import com.android.systemui.bouncer.data.repository.keyguardBouncerRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.res.R
+import com.android.systemui.util.mockito.whenever
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
/** Create [FingerprintSensorPropertiesInternal] for a test. */
internal fun fingerprintSensorPropertiesInternal(
@@ -145,3 +156,67 @@ internal fun promptInfo(
info.negativeButtonText = negativeButton
return info
}
+
+@OptIn(ExperimentalCoroutinesApi::class)
+internal fun TestScope.updateSfpsIndicatorRequests(
+ kosmos: Kosmos,
+ mContext: SysuiTestableContext,
+ primaryBouncerRequest: Boolean? = null,
+ alternateBouncerRequest: Boolean? = null,
+ biometricPromptRequest: Boolean? = null,
+ // TODO(b/365182034): update when rest to unlock feature is implemented
+ // progressBarShowing: Boolean? = null
+) {
+ biometricPromptRequest?.let { hasBiometricPromptRequest ->
+ if (hasBiometricPromptRequest) {
+ kosmos.biometricStatusRepository.setFingerprintAuthenticationReason(
+ AuthenticationReason.BiometricPromptAuthentication
+ )
+ } else {
+ kosmos.biometricStatusRepository.setFingerprintAuthenticationReason(
+ AuthenticationReason.NotRunning
+ )
+ }
+ }
+
+ primaryBouncerRequest?.let { hasPrimaryBouncerRequest ->
+ updatePrimaryBouncer(
+ kosmos,
+ mContext,
+ isShowing = hasPrimaryBouncerRequest,
+ isAnimatingAway = false,
+ fpsDetectionRunning = true,
+ isUnlockingWithFpAllowed = true
+ )
+ }
+
+ alternateBouncerRequest?.let { hasAlternateBouncerRequest ->
+ kosmos.keyguardBouncerRepository.setAlternateVisible(hasAlternateBouncerRequest)
+ }
+
+ // TODO(b/365182034): set progress bar visibility when rest to unlock feature is implemented
+
+ runCurrent()
+}
+
+internal fun updatePrimaryBouncer(
+ kosmos: Kosmos,
+ mContext: SysuiTestableContext,
+ isShowing: Boolean,
+ isAnimatingAway: Boolean,
+ fpsDetectionRunning: Boolean,
+ isUnlockingWithFpAllowed: Boolean,
+) {
+ kosmos.keyguardBouncerRepository.setPrimaryShow(isShowing)
+ kosmos.keyguardBouncerRepository.setPrimaryStartingToHide(false)
+ val primaryStartDisappearAnimation = if (isAnimatingAway) Runnable {} else null
+ kosmos.keyguardBouncerRepository.setPrimaryStartDisappearAnimation(
+ primaryStartDisappearAnimation
+ )
+
+ whenever(kosmos.keyguardUpdateMonitor.isFingerprintDetectionRunning)
+ .thenReturn(fpsDetectionRunning)
+ whenever(kosmos.keyguardUpdateMonitor.isUnlockingWithFingerprintAllowed)
+ .thenReturn(isUnlockingWithFpAllowed)
+ mContext.orCreateTestableResources.addOverride(R.bool.config_show_sidefps_hint_on_bouncer, true)
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/SideFpsOverlayInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/SideFpsOverlayInteractorTest.kt
new file mode 100644
index 000000000000..298b54a5be5a
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/SideFpsOverlayInteractorTest.kt
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.domain.interactor
+
+import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.data.repository.biometricStatusRepository
+import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
+import com.android.systemui.biometrics.shared.model.AuthenticationReason
+import com.android.systemui.biometrics.shared.model.FingerprintSensorType
+import com.android.systemui.biometrics.shared.model.SensorStrength
+import com.android.systemui.biometrics.updateSfpsIndicatorRequests
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.display.data.repository.displayRepository
+import com.android.systemui.display.data.repository.displayStateRepository
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class SideFpsOverlayInteractorTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ private val underTest = kosmos.sideFpsOverlayInteractor
+
+ @Test
+ fun verifyIsShowingFalse_whenInRearDisplayMode() {
+ kosmos.testScope.runTest {
+ val isShowing by collectLastValue(underTest.isShowing)
+ setupTestConfiguration(isInRearDisplayMode = true)
+
+ updateSfpsIndicatorRequests(kosmos, mContext, primaryBouncerRequest = true)
+ runCurrent()
+
+ assertThat(isShowing).isFalse()
+ }
+ }
+
+ @Test
+ fun verifyIsShowingUpdates_onPrimaryBouncerShowAndHide() {
+ kosmos.testScope.runTest {
+ val isShowing by collectLastValue(underTest.isShowing)
+ setupTestConfiguration(isInRearDisplayMode = false)
+
+ // Show primary bouncer
+ updateSfpsIndicatorRequests(kosmos, mContext, primaryBouncerRequest = true)
+ runCurrent()
+
+ assertThat(isShowing).isTrue()
+
+ // Hide primary bouncer
+ updateSfpsIndicatorRequests(kosmos, mContext, primaryBouncerRequest = false)
+ runCurrent()
+
+ assertThat(isShowing).isFalse()
+ }
+ }
+
+ @Test
+ fun verifyIsShowingUpdates_onAlternateBouncerShowAndHide() {
+ kosmos.testScope.runTest {
+ val isShowing by collectLastValue(underTest.isShowing)
+ setupTestConfiguration(isInRearDisplayMode = false)
+
+ updateSfpsIndicatorRequests(kosmos, mContext, alternateBouncerRequest = true)
+ runCurrent()
+
+ assertThat(isShowing).isTrue()
+
+ // Hide alternate bouncer
+ updateSfpsIndicatorRequests(kosmos, mContext, alternateBouncerRequest = false)
+ runCurrent()
+
+ assertThat(isShowing).isFalse()
+ }
+ }
+
+ @Test
+ fun verifyIsShowingUpdates_onSystemServerAuthenticationStartedAndStopped() {
+ kosmos.testScope.runTest {
+ val isShowing by collectLastValue(underTest.isShowing)
+ setupTestConfiguration(isInRearDisplayMode = false)
+
+ updateSfpsIndicatorRequests(kosmos, mContext, biometricPromptRequest = true)
+ runCurrent()
+
+ assertThat(isShowing).isTrue()
+
+ // System server authentication stopped
+ updateSfpsIndicatorRequests(kosmos, mContext, biometricPromptRequest = false)
+ runCurrent()
+
+ assertThat(isShowing).isFalse()
+ }
+ }
+
+ // On progress bar shown - hide indicator
+ // On progress bar hidden - show indicator
+ // TODO(b/365182034): update + enable when rest to unlock feature is implemented
+ @Ignore("b/365182034")
+ @Test
+ fun verifyIsShowingUpdates_onProgressBarInteraction() {
+ kosmos.testScope.runTest {
+ val isShowing by collectLastValue(underTest.isShowing)
+ setupTestConfiguration(isInRearDisplayMode = false)
+
+ updateSfpsIndicatorRequests(kosmos, mContext, primaryBouncerRequest = true)
+ runCurrent()
+
+ assertThat(isShowing).isTrue()
+
+ // updateSfpsIndicatorRequests(
+ // kosmos, mContext, primaryBouncerRequest = true, progressBarShowing =
+ // true
+ // )
+ runCurrent()
+
+ assertThat(isShowing).isFalse()
+
+ // Set progress bar invisible
+ // updateSfpsIndicatorRequests(
+ // kosmos, mContext, primaryBouncerRequest = true, progressBarShowing =
+ // false
+ // )
+ runCurrent()
+
+ // Verify indicator shown
+ assertThat(isShowing).isTrue()
+ }
+ }
+
+ private suspend fun TestScope.setupTestConfiguration(isInRearDisplayMode: Boolean) {
+ kosmos.fingerprintPropertyRepository.setProperties(
+ sensorId = 1,
+ strength = SensorStrength.STRONG,
+ sensorType = FingerprintSensorType.POWER_BUTTON,
+ sensorLocations = emptyMap()
+ )
+
+ kosmos.displayStateRepository.setIsInRearDisplayMode(isInRearDisplayMode)
+ kosmos.displayRepository.emitDisplayChangeEvent(0)
+ runCurrent()
+
+ kosmos.biometricStatusRepository.setFingerprintAuthenticationReason(
+ AuthenticationReason.NotRunning
+ )
+ // TODO(b/365182034): set progress bar visibility once rest to unlock feature is implemented
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt
index 7fa165c19f60..2eea6681ecca 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt
@@ -16,64 +16,48 @@
package com.android.systemui.biometrics.ui.binder
-import android.animation.Animator
-import android.graphics.Rect
-import android.hardware.biometrics.SensorLocationInternal
-import android.hardware.display.DisplayManager
-import android.hardware.display.DisplayManagerGlobal
import android.testing.TestableLooper
-import android.view.Display
-import android.view.DisplayInfo
import android.view.LayoutInflater
import android.view.View
-import android.view.ViewPropertyAnimator
-import android.view.WindowInsets
import android.view.WindowManager
-import android.view.WindowMetrics
import android.view.layoutInflater
import android.view.windowManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.airbnb.lottie.LottieAnimationView
-import com.android.keyguard.keyguardUpdateMonitor
import com.android.systemui.SysuiTestCase
-import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider
-import com.android.systemui.biometrics.data.repository.biometricStatusRepository
import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
-import com.android.systemui.biometrics.shared.model.AuthenticationReason
import com.android.systemui.biometrics.shared.model.DisplayRotation
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
import com.android.systemui.biometrics.shared.model.SensorStrength
-import com.android.systemui.bouncer.data.repository.keyguardBouncerRepository
+import com.android.systemui.biometrics.updateSfpsIndicatorRequests
import com.android.systemui.display.data.repository.displayRepository
import com.android.systemui.display.data.repository.displayStateRepository
-import com.android.systemui.keyguard.ui.viewmodel.sideFpsProgressBarViewModel
import com.android.systemui.kosmos.testScope
import com.android.systemui.res.R
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.eq
-import com.android.systemui.util.mockito.whenever
import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
import org.mockito.Mock
-import org.mockito.Mockito
import org.mockito.Mockito.any
import org.mockito.Mockito.inOrder
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
-import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.junit.MockitoJUnit
import org.mockito.junit.MockitoRule
-import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.firstValue
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@@ -83,84 +67,25 @@ class SideFpsOverlayViewBinderTest : SysuiTestCase() {
private val kosmos = testKosmos()
@JvmField @Rule var mockitoRule: MockitoRule = MockitoJUnit.rule()
- @Mock private lateinit var displayManager: DisplayManager
- @Mock
- private lateinit var fingerprintInteractiveToAuthProvider: FingerprintInteractiveToAuthProvider
@Mock private lateinit var layoutInflater: LayoutInflater
@Mock private lateinit var sideFpsView: View
-
- private val contextDisplayInfo = DisplayInfo()
-
- private var displayWidth: Int = 0
- private var displayHeight: Int = 0
- private var boundsWidth: Int = 0
- private var boundsHeight: Int = 0
-
- private lateinit var deviceConfig: DeviceConfig
- private lateinit var sensorLocation: SensorLocationInternal
-
- enum class DeviceConfig {
- X_ALIGNED,
- Y_ALIGNED,
- }
+ @Captor private lateinit var viewCaptor: ArgumentCaptor<View>
@Before
fun setup() {
allowTestableLooperAsMainThread() // repeatWhenAttached requires the main thread
-
- mContext = spy(mContext)
-
- val resources = mContext.resources
- whenever(mContext.display)
- .thenReturn(
- Display(mock(DisplayManagerGlobal::class.java), 1, contextDisplayInfo, resources)
- )
-
kosmos.layoutInflater = layoutInflater
-
- whenever(fingerprintInteractiveToAuthProvider.enabledForCurrentUser)
- .thenReturn(MutableStateFlow(false))
-
- context.addMockSystemService(DisplayManager::class.java, displayManager)
context.addMockSystemService(WindowManager::class.java, kosmos.windowManager)
-
`when`(layoutInflater.inflate(R.layout.sidefps_view, null, false)).thenReturn(sideFpsView)
`when`(sideFpsView.requireViewById<LottieAnimationView>(eq(R.id.sidefps_animation)))
.thenReturn(mock(LottieAnimationView::class.java))
- with(mock(ViewPropertyAnimator::class.java)) {
- `when`(sideFpsView.animate()).thenReturn(this)
- `when`(alpha(Mockito.anyFloat())).thenReturn(this)
- `when`(setStartDelay(Mockito.anyLong())).thenReturn(this)
- `when`(setDuration(Mockito.anyLong())).thenReturn(this)
- `when`(setListener(any())).thenAnswer {
- (it.arguments[0] as Animator.AnimatorListener).onAnimationEnd(
- mock(Animator::class.java)
- )
- this
- }
- }
}
@Test
fun verifyIndicatorNotAdded_whenInRearDisplayMode() {
kosmos.testScope.runTest {
- setupTestConfiguration(
- DeviceConfig.X_ALIGNED,
- rotation = DisplayRotation.ROTATION_0,
- isInRearDisplayMode = true
- )
- kosmos.biometricStatusRepository.setFingerprintAuthenticationReason(
- AuthenticationReason.NotRunning
- )
- kosmos.sideFpsProgressBarViewModel.setVisible(false)
- updatePrimaryBouncer(
- isShowing = true,
- isAnimatingAway = false,
- fpsDetectionRunning = true,
- isUnlockingWithFpAllowed = true
- )
- runCurrent()
-
+ setupTestConfiguration(isInRearDisplayMode = true)
+ updateSfpsIndicatorRequests(kosmos, mContext, primaryBouncerRequest = true)
verify(kosmos.windowManager, never()).addView(any(), any())
}
}
@@ -168,33 +93,14 @@ class SideFpsOverlayViewBinderTest : SysuiTestCase() {
@Test
fun verifyIndicatorShowAndHide_onPrimaryBouncerShowAndHide() {
kosmos.testScope.runTest {
- setupTestConfiguration(
- DeviceConfig.X_ALIGNED,
- rotation = DisplayRotation.ROTATION_0,
- isInRearDisplayMode = false
- )
- kosmos.biometricStatusRepository.setFingerprintAuthenticationReason(
- AuthenticationReason.NotRunning
- )
- kosmos.sideFpsProgressBarViewModel.setVisible(false)
- // Show primary bouncer
- updatePrimaryBouncer(
- isShowing = true,
- isAnimatingAway = false,
- fpsDetectionRunning = true,
- isUnlockingWithFpAllowed = true
- )
+ setupTestConfiguration(isInRearDisplayMode = false)
+ updateSfpsIndicatorRequests(kosmos, mContext, primaryBouncerRequest = true)
runCurrent()
verify(kosmos.windowManager).addView(any(), any())
// Hide primary bouncer
- updatePrimaryBouncer(
- isShowing = false,
- isAnimatingAway = false,
- fpsDetectionRunning = true,
- isUnlockingWithFpAllowed = true
- )
+ updateSfpsIndicatorRequests(kosmos, mContext, primaryBouncerRequest = false)
runCurrent()
verify(kosmos.windowManager).removeView(any())
@@ -204,30 +110,19 @@ class SideFpsOverlayViewBinderTest : SysuiTestCase() {
@Test
fun verifyIndicatorShowAndHide_onAlternateBouncerShowAndHide() {
kosmos.testScope.runTest {
- setupTestConfiguration(
- DeviceConfig.X_ALIGNED,
- rotation = DisplayRotation.ROTATION_0,
- isInRearDisplayMode = false
- )
- kosmos.biometricStatusRepository.setFingerprintAuthenticationReason(
- AuthenticationReason.NotRunning
- )
- kosmos.sideFpsProgressBarViewModel.setVisible(false)
- // Show alternate bouncer
- kosmos.keyguardBouncerRepository.setAlternateVisible(true)
+ setupTestConfiguration(isInRearDisplayMode = false)
+ updateSfpsIndicatorRequests(kosmos, mContext, alternateBouncerRequest = true)
runCurrent()
verify(kosmos.windowManager).addView(any(), any())
- var viewCaptor = argumentCaptor<View>()
verify(kosmos.windowManager).addView(viewCaptor.capture(), any())
verify(viewCaptor.firstValue)
.announceForAccessibility(
mContext.getText(R.string.accessibility_side_fingerprint_indicator_label)
)
- // Hide alternate bouncer
- kosmos.keyguardBouncerRepository.setAlternateVisible(false)
+ updateSfpsIndicatorRequests(kosmos, mContext, alternateBouncerRequest = false)
runCurrent()
verify(kosmos.windowManager).removeView(any())
@@ -237,30 +132,14 @@ class SideFpsOverlayViewBinderTest : SysuiTestCase() {
@Test
fun verifyIndicatorShownAndHidden_onSystemServerAuthenticationStartedAndStopped() {
kosmos.testScope.runTest {
- setupTestConfiguration(
- DeviceConfig.X_ALIGNED,
- rotation = DisplayRotation.ROTATION_0,
- isInRearDisplayMode = false
- )
- kosmos.sideFpsProgressBarViewModel.setVisible(false)
- updatePrimaryBouncer(
- isShowing = false,
- isAnimatingAway = false,
- fpsDetectionRunning = true,
- isUnlockingWithFpAllowed = true
- )
- // System server authentication started
- kosmos.biometricStatusRepository.setFingerprintAuthenticationReason(
- AuthenticationReason.BiometricPromptAuthentication
- )
+ setupTestConfiguration(isInRearDisplayMode = false)
+ updateSfpsIndicatorRequests(kosmos, mContext, biometricPromptRequest = true)
runCurrent()
verify(kosmos.windowManager).addView(any(), any())
// System server authentication stopped
- kosmos.biometricStatusRepository.setFingerprintAuthenticationReason(
- AuthenticationReason.NotRunning
- )
+ updateSfpsIndicatorRequests(kosmos, mContext, biometricPromptRequest = false)
runCurrent()
verify(kosmos.windowManager).removeView(any())
@@ -269,45 +148,35 @@ class SideFpsOverlayViewBinderTest : SysuiTestCase() {
// On progress bar shown - hide indicator
// On progress bar hidden - show indicator
+ // TODO(b/365182034): update + enable when rest to unlock feature is implemented
+ @Ignore("b/365182034")
@Test
fun verifyIndicatorProgressBarInteraction() {
kosmos.testScope.runTest {
// Pre-auth conditions
- setupTestConfiguration(
- DeviceConfig.X_ALIGNED,
- rotation = DisplayRotation.ROTATION_0,
- isInRearDisplayMode = false
- )
- kosmos.biometricStatusRepository.setFingerprintAuthenticationReason(
- AuthenticationReason.NotRunning
- )
- kosmos.sideFpsProgressBarViewModel.setVisible(false)
-
- // Show primary bouncer
- updatePrimaryBouncer(
- isShowing = true,
- isAnimatingAway = false,
- fpsDetectionRunning = true,
- isUnlockingWithFpAllowed = true
- )
+ setupTestConfiguration(isInRearDisplayMode = false)
+ updateSfpsIndicatorRequests(kosmos, mContext, primaryBouncerRequest = true)
runCurrent()
val inOrder = inOrder(kosmos.windowManager)
-
// Verify indicator shown
inOrder.verify(kosmos.windowManager).addView(any(), any())
// Set progress bar visible
- kosmos.sideFpsProgressBarViewModel.setVisible(true)
-
+ // updateSfpsIndicatorRequests(
+ // kosmos, mContext, primaryBouncerRequest = true, progressBarShowing =
+ // true
+ // )
runCurrent()
// Verify indicator hidden
inOrder.verify(kosmos.windowManager).removeView(any())
// Set progress bar invisible
- kosmos.sideFpsProgressBarViewModel.setVisible(false)
-
+ // updateSfpsIndicatorRequests(
+ // kosmos, mContext, primaryBouncerRequest = true, progressBarShowing =
+ // false
+ // )
runCurrent()
// Verify indicator shown
@@ -315,78 +184,18 @@ class SideFpsOverlayViewBinderTest : SysuiTestCase() {
}
}
- private fun updatePrimaryBouncer(
- isShowing: Boolean,
- isAnimatingAway: Boolean,
- fpsDetectionRunning: Boolean,
- isUnlockingWithFpAllowed: Boolean,
- ) {
- kosmos.keyguardBouncerRepository.setPrimaryShow(isShowing)
- kosmos.keyguardBouncerRepository.setPrimaryStartingToHide(false)
- val primaryStartDisappearAnimation = if (isAnimatingAway) Runnable {} else null
- kosmos.keyguardBouncerRepository.setPrimaryStartDisappearAnimation(
- primaryStartDisappearAnimation
- )
-
- whenever(kosmos.keyguardUpdateMonitor.isFingerprintDetectionRunning)
- .thenReturn(fpsDetectionRunning)
- whenever(kosmos.keyguardUpdateMonitor.isUnlockingWithFingerprintAllowed)
- .thenReturn(isUnlockingWithFpAllowed)
- mContext.orCreateTestableResources.addOverride(
- R.bool.config_show_sidefps_hint_on_bouncer,
- true
- )
- }
-
- private suspend fun TestScope.setupTestConfiguration(
- deviceConfig: DeviceConfig,
- rotation: DisplayRotation = DisplayRotation.ROTATION_0,
- isInRearDisplayMode: Boolean,
- ) {
- this@SideFpsOverlayViewBinderTest.deviceConfig = deviceConfig
-
- when (deviceConfig) {
- DeviceConfig.X_ALIGNED -> {
- displayWidth = 3000
- displayHeight = 1500
- boundsWidth = 200
- boundsHeight = 100
- sensorLocation = SensorLocationInternal("", 2500, 0, boundsWidth / 2)
- }
- DeviceConfig.Y_ALIGNED -> {
- displayWidth = 2500
- displayHeight = 2000
- boundsWidth = 100
- boundsHeight = 200
- sensorLocation = SensorLocationInternal("", displayWidth, 300, boundsHeight / 2)
- }
- }
-
- whenever(kosmos.windowManager.maximumWindowMetrics)
- .thenReturn(
- WindowMetrics(
- Rect(0, 0, displayWidth, displayHeight),
- mock(WindowInsets::class.java),
- )
- )
-
- contextDisplayInfo.uniqueId = DISPLAY_ID
-
+ private suspend fun TestScope.setupTestConfiguration(isInRearDisplayMode: Boolean) {
kosmos.fingerprintPropertyRepository.setProperties(
sensorId = 1,
strength = SensorStrength.STRONG,
sensorType = FingerprintSensorType.POWER_BUTTON,
- sensorLocations = mapOf(DISPLAY_ID to sensorLocation)
+ sensorLocations = emptyMap()
)
kosmos.displayStateRepository.setIsInRearDisplayMode(isInRearDisplayMode)
- kosmos.displayStateRepository.setCurrentRotation(rotation)
+ kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_0)
kosmos.displayRepository.emitDisplayChangeEvent(0)
kosmos.sideFpsOverlayViewBinder.start()
runCurrent()
}
-
- companion object {
- private const val DISPLAY_ID = "displayId"
- }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
index 0db7b62b8ef1..27b1371deb12 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
@@ -30,23 +30,19 @@ import android.view.windowManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.airbnb.lottie.model.KeyPath
-import com.android.keyguard.keyguardUpdateMonitor
import com.android.settingslib.Utils
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider
-import com.android.systemui.biometrics.data.repository.biometricStatusRepository
import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
import com.android.systemui.biometrics.domain.interactor.displayStateInteractor
-import com.android.systemui.biometrics.shared.model.AuthenticationReason
import com.android.systemui.biometrics.shared.model.DisplayRotation
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
import com.android.systemui.biometrics.shared.model.LottieCallback
import com.android.systemui.biometrics.shared.model.SensorStrength
-import com.android.systemui.bouncer.data.repository.keyguardBouncerRepository
+import com.android.systemui.biometrics.updateSfpsIndicatorRequests
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.display.data.repository.displayRepository
import com.android.systemui.display.data.repository.displayStateRepository
-import com.android.systemui.keyguard.ui.viewmodel.sideFpsProgressBarViewModel
import com.android.systemui.kosmos.testScope
import com.android.systemui.res.R
import com.android.systemui.testKosmos
@@ -284,17 +280,7 @@ class SideFpsOverlayViewModelTest : SysuiTestCase() {
kosmos.testScope.runTest {
val lottieCallbacks by collectLastValue(kosmos.sideFpsOverlayViewModel.lottieCallbacks)
- kosmos.biometricStatusRepository.setFingerprintAuthenticationReason(
- AuthenticationReason.NotRunning
- )
- kosmos.sideFpsProgressBarViewModel.setVisible(false)
-
- updatePrimaryBouncer(
- isShowing = true,
- isAnimatingAway = false,
- fpsDetectionRunning = true,
- isUnlockingWithFpAllowed = true
- )
+ updateSfpsIndicatorRequests(kosmos, mContext, primaryBouncerRequest = true)
runCurrent()
assertThat(lottieCallbacks)
@@ -312,17 +298,7 @@ class SideFpsOverlayViewModelTest : SysuiTestCase() {
val lottieCallbacks by collectLastValue(kosmos.sideFpsOverlayViewModel.lottieCallbacks)
setDarkMode(true)
- kosmos.biometricStatusRepository.setFingerprintAuthenticationReason(
- AuthenticationReason.BiometricPromptAuthentication
- )
- kosmos.sideFpsProgressBarViewModel.setVisible(false)
-
- updatePrimaryBouncer(
- isShowing = false,
- isAnimatingAway = false,
- fpsDetectionRunning = true,
- isUnlockingWithFpAllowed = true
- )
+ updateSfpsIndicatorRequests(kosmos, mContext, biometricPromptRequest = true)
runCurrent()
assertThat(lottieCallbacks)
@@ -338,17 +314,7 @@ class SideFpsOverlayViewModelTest : SysuiTestCase() {
val lottieCallbacks by collectLastValue(kosmos.sideFpsOverlayViewModel.lottieCallbacks)
setDarkMode(false)
- kosmos.biometricStatusRepository.setFingerprintAuthenticationReason(
- AuthenticationReason.BiometricPromptAuthentication
- )
- kosmos.sideFpsProgressBarViewModel.setVisible(false)
-
- updatePrimaryBouncer(
- isShowing = false,
- isAnimatingAway = false,
- fpsDetectionRunning = true,
- isUnlockingWithFpAllowed = true
- )
+ updateSfpsIndicatorRequests(kosmos, mContext, biometricPromptRequest = true)
runCurrent()
assertThat(lottieCallbacks)
@@ -371,29 +337,6 @@ class SideFpsOverlayViewModelTest : SysuiTestCase() {
mContext.resources.configuration.uiMode = uiMode
}
- private fun updatePrimaryBouncer(
- isShowing: Boolean,
- isAnimatingAway: Boolean,
- fpsDetectionRunning: Boolean,
- isUnlockingWithFpAllowed: Boolean,
- ) {
- kosmos.keyguardBouncerRepository.setPrimaryShow(isShowing)
- kosmos.keyguardBouncerRepository.setPrimaryStartingToHide(false)
- val primaryStartDisappearAnimation = if (isAnimatingAway) Runnable {} else null
- kosmos.keyguardBouncerRepository.setPrimaryStartDisappearAnimation(
- primaryStartDisappearAnimation
- )
-
- whenever(kosmos.keyguardUpdateMonitor.isFingerprintDetectionRunning)
- .thenReturn(fpsDetectionRunning)
- whenever(kosmos.keyguardUpdateMonitor.isUnlockingWithFingerprintAllowed)
- .thenReturn(isUnlockingWithFpAllowed)
- mContext.orCreateTestableResources.addOverride(
- R.bool.config_show_sidefps_hint_on_bouncer,
- true
- )
- }
-
private suspend fun TestScope.setupTestConfiguration(
deviceConfig: DeviceConfig,
rotation: DisplayRotation = DisplayRotation.ROTATION_0,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadStatsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadStatsInteractorTest.kt
index cd0c58feebed..c4fc13227eef 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadStatsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadStatsInteractorTest.kt
@@ -19,12 +19,15 @@ package com.android.systemui.education.domain.interactor
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.contextualeducation.GestureType.ALL_APPS
import com.android.systemui.contextualeducation.GestureType.BACK
+import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.education.data.repository.contextualEducationRepository
import com.android.systemui.education.data.repository.fakeEduClock
+import com.android.systemui.keyboard.data.repository.keyboardRepository
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
+import com.android.systemui.touchpad.data.repository.touchpadRepository
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
import org.junit.Test
@@ -36,22 +39,62 @@ class KeyboardTouchpadStatsInteractorTest : SysuiTestCase() {
private val kosmos = testKosmos()
private val testScope = kosmos.testScope
private val underTest = kosmos.keyboardTouchpadEduStatsInteractor
+ private val keyboardRepository = kosmos.keyboardRepository
+ private val touchpadRepository = kosmos.touchpadRepository
+ private val repository = kosmos.contextualEducationRepository
@Test
- fun dataUpdatedOnIncrementSignalCount() =
+ fun dataUpdatedOnIncrementSignalCountWhenTouchpadConnected() =
testScope.runTest {
- val model by
- collectLastValue(kosmos.contextualEducationRepository.readGestureEduModelFlow(BACK))
+ touchpadRepository.setIsAnyTouchpadConnected(true)
+
+ val model by collectLastValue(repository.readGestureEduModelFlow(BACK))
val originalValue = model!!.signalCount
underTest.incrementSignalCount(BACK)
+
assertThat(model?.signalCount).isEqualTo(originalValue + 1)
}
@Test
+ fun dataUnchangedOnIncrementSignalCountWhenTouchpadDisconnected() =
+ testScope.runTest {
+ touchpadRepository.setIsAnyTouchpadConnected(false)
+
+ val model by collectLastValue(repository.readGestureEduModelFlow(BACK))
+ val originalValue = model!!.signalCount
+ underTest.incrementSignalCount(BACK)
+
+ assertThat(model?.signalCount).isEqualTo(originalValue)
+ }
+
+ @Test
+ fun dataUpdatedOnIncrementSignalCountWhenKeyboardConnected() =
+ testScope.runTest {
+ keyboardRepository.setIsAnyKeyboardConnected(true)
+
+ val model by collectLastValue(repository.readGestureEduModelFlow(ALL_APPS))
+ val originalValue = model!!.signalCount
+ underTest.incrementSignalCount(ALL_APPS)
+
+ assertThat(model?.signalCount).isEqualTo(originalValue + 1)
+ }
+
+ @Test
+ fun dataUnchangedOnIncrementSignalCountWhenKeyboardDisconnected() =
+ testScope.runTest {
+ keyboardRepository.setIsAnyKeyboardConnected(false)
+
+ val model by collectLastValue(repository.readGestureEduModelFlow(ALL_APPS))
+ val originalValue = model!!.signalCount
+ underTest.incrementSignalCount(ALL_APPS)
+
+ assertThat(model?.signalCount).isEqualTo(originalValue)
+ }
+
+ @Test
fun dataAddedOnUpdateShortcutTriggerTime() =
testScope.runTest {
- val model by
- collectLastValue(kosmos.contextualEducationRepository.readGestureEduModelFlow(BACK))
+ val model by collectLastValue(repository.readGestureEduModelFlow(BACK))
assertThat(model?.lastShortcutTriggeredTime).isNull()
underTest.updateShortcutTriggerTime(BACK)
assertThat(model?.lastShortcutTriggeredTime).isEqualTo(kosmos.fakeEduClock.instant())
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/IconAndNameCustomRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/IconAndNameCustomRepositoryTest.kt
index 1e5599bfe1d5..93ba26517e37 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/IconAndNameCustomRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/IconAndNameCustomRepositoryTest.kt
@@ -19,7 +19,6 @@ package com.android.systemui.qs.panels.data.repository
import android.content.ComponentName
import android.content.packageManager
import android.content.pm.PackageManager
-import android.content.pm.ServiceInfo
import android.content.pm.UserInfo
import android.graphics.drawable.TestStubDrawable
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -35,6 +34,7 @@ import com.android.systemui.qs.pipeline.data.repository.FakeInstalledTilesCompon
import com.android.systemui.qs.pipeline.data.repository.fakeInstalledTilesRepository
import com.android.systemui.qs.pipeline.data.repository.installedTilesRepository
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.settings.FakeUserTracker
import com.android.systemui.settings.fakeUserTracker
import com.android.systemui.testKosmos
@@ -100,6 +100,7 @@ class IconAndNameCustomRepositoryTest : SysuiTestCase() {
Icon.Loaded(drawable1, ContentDescription.Loaded(tileService1)),
Text.Loaded(tileService1),
Text.Loaded(appName1),
+ TileCategory.PROVIDED_BY_APP,
)
val expectedData2 =
EditTileData(
@@ -107,6 +108,7 @@ class IconAndNameCustomRepositoryTest : SysuiTestCase() {
Icon.Loaded(drawable2, ContentDescription.Loaded(tileService2)),
Text.Loaded(tileService2),
Text.Loaded(appName2),
+ TileCategory.PROVIDED_BY_APP,
)
assertThat(editTileDataList).containsExactly(expectedData1, expectedData2)
@@ -144,6 +146,7 @@ class IconAndNameCustomRepositoryTest : SysuiTestCase() {
Icon.Loaded(drawable1, ContentDescription.Loaded(tileService1)),
Text.Loaded(tileService1),
Text.Loaded(appName1),
+ TileCategory.PROVIDED_BY_APP,
)
val editTileDataList = underTest.getCustomTileData()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorTest.kt
index deefbf585ba9..053a59aa533a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorTest.kt
@@ -31,6 +31,7 @@ import com.android.systemui.qs.panels.shared.model.EditTileData
import com.android.systemui.qs.pipeline.data.repository.FakeInstalledTilesComponentRepository
import com.android.systemui.qs.pipeline.data.repository.fakeInstalledTilesRepository
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tiles.impl.battery.qsBatterySaverTileConfig
import com.android.systemui.qs.tiles.impl.flashlight.qsFlashlightTileConfig
import com.android.systemui.qs.tiles.impl.internet.qsInternetTileConfig
@@ -132,6 +133,7 @@ class EditTilesListInteractorTest : SysuiTestCase() {
icon = Icon.Loaded(icon, ContentDescription.Loaded(tileName)),
label = Text.Loaded(tileName),
appName = Text.Loaded(appName),
+ category = TileCategory.PROVIDED_BY_APP,
)
assertThat(editTiles.customTiles).hasSize(1)
@@ -181,7 +183,8 @@ class EditTilesListInteractorTest : SysuiTestCase() {
tileSpec = this,
icon = Icon.Resource(android.R.drawable.star_on, ContentDescription.Loaded(spec)),
label = Text.Loaded(spec),
- appName = null
+ appName = null,
+ category = TileCategory.UNKNOWN,
)
}
@@ -192,6 +195,7 @@ class EditTilesListInteractorTest : SysuiTestCase() {
Icon.Resource(uiConfig.iconRes, ContentDescription.Resource(uiConfig.labelRes)),
label = Text.Resource(uiConfig.labelRes),
appName = null,
+ category = category,
)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt
index 7f01fad1ce55..484a8ff973c1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt
@@ -16,11 +16,11 @@
package com.android.systemui.qs.panels.ui.compose
+import androidx.compose.ui.text.AnnotatedString
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.common.shared.model.Text
import com.android.systemui.qs.panels.shared.model.SizedTile
import com.android.systemui.qs.panels.shared.model.SizedTileImpl
import com.android.systemui.qs.panels.ui.model.GridCell
@@ -28,6 +28,7 @@ import com.android.systemui.qs.panels.ui.model.SpacerGridCell
import com.android.systemui.qs.panels.ui.model.TileGridCell
import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
@@ -141,10 +142,11 @@ class EditTileListStateTest : SysuiTestCase() {
EditTileViewModel(
tileSpec = TileSpec.create(tileSpec),
icon = Icon.Resource(0, null),
- label = Text.Loaded("unused"),
+ label = AnnotatedString("unused"),
appName = null,
isCurrent = true,
availableEditActions = emptySet(),
+ category = TileCategory.UNKNOWN,
),
width,
)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt
index 601779f8fb02..583db722a759 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt
@@ -26,6 +26,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.shared.model.Text
+import com.android.systemui.common.ui.compose.toAnnotatedString
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
@@ -42,6 +43,7 @@ import com.android.systemui.qs.pipeline.data.repository.fakeMinimumTilesReposito
import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.qs.qsTileFactory
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tiles.impl.alarm.qsAlarmTileConfig
import com.android.systemui.qs.tiles.impl.battery.qsBatterySaverTileConfig
import com.android.systemui.qs.tiles.impl.flashlight.qsFlashlightTileConfig
@@ -190,7 +192,7 @@ class EditModeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
.forEach {
val data = getEditTileData(it.tileSpec)
- assertThat(it.label).isEqualTo(data.label)
+ assertThat(it.label).isEqualTo(data.label.toAnnotatedString(context))
assertThat(it.icon).isEqualTo(data.icon)
assertThat(it.appName).isNull()
}
@@ -224,15 +226,19 @@ class EditModeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
// service1
val model1 = tiles!!.first { it.tileSpec == TileSpec.create(component1) }
- assertThat(model1.label).isEqualTo(Text.Loaded(tileService1))
- assertThat(model1.appName).isEqualTo(Text.Loaded(appName1))
+ assertThat(model1.label)
+ .isEqualTo(Text.Loaded(tileService1).toAnnotatedString(context))
+ assertThat(model1.appName)
+ .isEqualTo(Text.Loaded(appName1).toAnnotatedString(context))
assertThat(model1.icon)
.isEqualTo(Icon.Loaded(drawable1, ContentDescription.Loaded(tileService1)))
// service2
val model2 = tiles!!.first { it.tileSpec == TileSpec.create(component2) }
- assertThat(model2.label).isEqualTo(Text.Loaded(tileService2))
- assertThat(model2.appName).isEqualTo(Text.Loaded(appName2))
+ assertThat(model2.label)
+ .isEqualTo(Text.Loaded(tileService2).toAnnotatedString(context))
+ assertThat(model2.appName)
+ .isEqualTo(Text.Loaded(appName2).toAnnotatedString(context))
assertThat(model2.icon)
.isEqualTo(Icon.Loaded(drawable2, ContentDescription.Loaded(tileService2)))
}
@@ -559,7 +565,8 @@ class EditModeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
tileSpec = this,
icon = Icon.Resource(R.drawable.star_on, ContentDescription.Loaded(spec)),
label = Text.Loaded(spec),
- appName = null
+ appName = null,
+ category = TileCategory.UNKNOWN,
)
}
@@ -570,6 +577,7 @@ class EditModeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
Icon.Resource(uiConfig.iconRes, ContentDescription.Resource(uiConfig.labelRes)),
label = Text.Resource(uiConfig.labelRes),
appName = null,
+ category = category,
)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/shared/model/GroupAndSortCategoryAndNameTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/shared/model/GroupAndSortCategoryAndNameTest.kt
new file mode 100644
index 000000000000..7f90e3b6f5e0
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/shared/model/GroupAndSortCategoryAndNameTest.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.shared.model
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class GroupAndSortCategoryAndNameTest : SysuiTestCase() {
+
+ private val elements =
+ listOf(
+ CategoryAndName(TileCategory.DISPLAY, "B"),
+ CategoryAndName(TileCategory.PRIVACY, "A"),
+ CategoryAndName(TileCategory.DISPLAY, "C"),
+ CategoryAndName(TileCategory.UTILITIES, "B"),
+ CategoryAndName(TileCategory.CONNECTIVITY, "A"),
+ CategoryAndName(TileCategory.PROVIDED_BY_APP, "B"),
+ CategoryAndName(TileCategory.CONNECTIVITY, "C"),
+ CategoryAndName(TileCategory.ACCESSIBILITY, "A")
+ )
+
+ @Test
+ fun allElementsInResult() {
+ val grouped = groupAndSort(elements)
+ val allValues = grouped.values.reduce { acc, el -> acc + el }
+ assertThat(allValues).containsExactlyElementsIn(elements)
+ }
+
+ @Test
+ fun groupedByCategory() {
+ val grouped = groupAndSort(elements)
+ grouped.forEach { tileCategory, categoryAndNames ->
+ categoryAndNames.forEach { element ->
+ assertThat(element.category).isEqualTo(tileCategory)
+ }
+ }
+ }
+
+ @Test
+ fun sortedAlphabeticallyInEachCategory() {
+ val grouped = groupAndSort(elements)
+ grouped.values.forEach { elements ->
+ assertThat(elements.map(CategoryAndName::name)).isInOrder()
+ }
+ }
+
+ @Test
+ fun categoriesSortedInNaturalOrder() {
+ val grouped = groupAndSort(elements)
+ assertThat(grouped.keys).isInOrder()
+ }
+
+ @Test
+ fun missingCategoriesAreNotInResult() {
+ val grouped = groupAndSort(elements.filterNot { it.category == TileCategory.CONNECTIVITY })
+ assertThat(grouped.keys).doesNotContain(TileCategory.CONNECTIVITY)
+ }
+
+ companion object {
+ private fun CategoryAndName(category: TileCategory, name: String): CategoryAndName {
+ return object : CategoryAndName {
+ override val category = category
+ override val name = name
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractorTest.kt
index aaad0fc1b644..5a4506086058 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractorTest.kt
@@ -184,7 +184,7 @@ class InternetTileDataInteractorTest : SysuiTestCase() {
)
val networkModel =
- WifiNetworkModel.Active(
+ WifiNetworkModel.Active.of(
level = 4,
ssid = "test ssid",
)
@@ -219,7 +219,7 @@ class InternetTileDataInteractorTest : SysuiTestCase() {
)
val networkModel =
- WifiNetworkModel.Active(
+ WifiNetworkModel.Active.of(
level = 4,
ssid = "test ssid",
hotspotDeviceType = WifiNetworkModel.HotspotDeviceType.NONE,
@@ -398,7 +398,7 @@ class InternetTileDataInteractorTest : SysuiTestCase() {
collectLastValue(
underTest.tileData(testUser, flowOf(DataUpdateTrigger.InitialRequest))
)
- val networkModel = WifiNetworkModel.Inactive
+ val networkModel = WifiNetworkModel.Inactive()
connectivityRepository.setWifiConnected(validated = false)
wifiRepository.setIsWifiDefault(true)
@@ -416,7 +416,7 @@ class InternetTileDataInteractorTest : SysuiTestCase() {
underTest.tileData(testUser, flowOf(DataUpdateTrigger.InitialRequest))
)
- val networkModel = WifiNetworkModel.Inactive
+ val networkModel = WifiNetworkModel.Inactive()
connectivityRepository.setWifiConnected(validated = false)
wifiRepository.setIsWifiDefault(true)
@@ -543,7 +543,7 @@ class InternetTileDataInteractorTest : SysuiTestCase() {
private fun setWifiNetworkWithHotspot(hotspot: WifiNetworkModel.HotspotDeviceType) {
val networkModel =
- WifiNetworkModel.Active(
+ WifiNetworkModel.Active.of(
level = 4,
ssid = "test ssid",
hotspotDeviceType = hotspot,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapperTest.kt
index 244422943309..fa6d8bf4a317 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapperTest.kt
@@ -24,6 +24,7 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testCase
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.qs.qsEventLogger
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
import com.android.systemui.qs.tiles.viewmodel.QSTileState
import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
@@ -43,7 +44,8 @@ class IssueRecordingMapperTest : SysuiTestCase() {
QSTileConfig(
TileSpec.create(RecordIssueModule.TILE_SPEC),
uiConfig,
- kosmos.qsEventLogger.getNewInstanceId()
+ kosmos.qsEventLogger.getNewInstanceId(),
+ TileCategory.UTILITIES,
)
private val resources = kosmos.mainResources
private val theme = resources.newTheme()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
index 3f550ca27868..3f550ca27868 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegateTest.kt
index 7dae5ccd05c4..7dae5ccd05c4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegateTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt
index aceea909e595..aceea909e595 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentExecutorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ActionIntentExecutorTest.kt
index 612d646bb7d4..612d646bb7d4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentExecutorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ActionIntentExecutorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/AnnouncementResolverTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/AnnouncementResolverTest.kt
index 2e8498a6da28..2e8498a6da28 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/AnnouncementResolverTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/AnnouncementResolverTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/DraggableConstraintLayoutTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/DraggableConstraintLayoutTest.java
index ba330f7b6ec0..ba330f7b6ec0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/DraggableConstraintLayoutTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/DraggableConstraintLayoutTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeImageCapture.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/FakeImageCapture.kt
index 447e28cd9527..447e28cd9527 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeImageCapture.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/FakeImageCapture.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeScreenshotPolicy.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/FakeScreenshotPolicy.kt
index 28d53c72640f..28d53c72640f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeScreenshotPolicy.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/FakeScreenshotPolicy.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt
index 15da77dfe33d..15da77dfe33d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/RecyclerViewActivity.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/RecyclerViewActivity.java
index fde56ba76736..fde56ba76736 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/RecyclerViewActivity.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/RecyclerViewActivity.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotActionsControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ScreenshotActionsControllerTest.kt
index 29e7a8a4ca85..29e7a8a4ca85 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotActionsControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ScreenshotActionsControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDataTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ScreenshotDataTest.kt
index 3ed09770b189..3ed09770b189 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDataTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ScreenshotDataTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDetectionControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ScreenshotDetectionControllerTest.kt
index 1538c72f8df8..1538c72f8df8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDetectionControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ScreenshotDetectionControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
index 89c13b0468f1..89c13b0468f1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotSoundControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ScreenshotSoundControllerTest.kt
index 5987e74e02ec..5987e74e02ec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotSoundControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ScreenshotSoundControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/SmartActionsReceiverTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/SmartActionsReceiverTest.java
index 9dc5cfed2bd6..9dc5cfed2bd6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/SmartActionsReceiverTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/SmartActionsReceiverTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt
index a2959811cd0a..a2959811cd0a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java
index 7d2d7c452426..7d2d7c452426 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperServiceTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperServiceTest.java
index ba3d39248762..ba3d39248762 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperServiceTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperServiceTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsServiceTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/appclips/AppClipsServiceTest.java
index d8897e9048c3..d8897e9048c3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsServiceTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/appclips/AppClipsServiceTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/data/model/DisplayContentScenarios.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/data/model/DisplayContentScenarios.kt
index 254f1e1efe13..254f1e1efe13 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/data/model/DisplayContentScenarios.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/data/model/DisplayContentScenarios.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/data/repository/ProfileTypeRepositoryKosmos.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/data/repository/ProfileTypeRepositoryKosmos.kt
index 9d2b56aa81d5..9d2b56aa81d5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/data/repository/ProfileTypeRepositoryKosmos.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/data/repository/ProfileTypeRepositoryKosmos.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/message/ProfileMessageControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/message/ProfileMessageControllerTest.kt
index 6b9865fbbacc..6b9865fbbacc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/message/ProfileMessageControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/message/ProfileMessageControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/NewRootTaskInfo.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/policy/NewRootTaskInfo.kt
index 6c35b233ffec..6c35b233ffec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/NewRootTaskInfo.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/policy/NewRootTaskInfo.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/PolicyRequestProcessorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/policy/PolicyRequestProcessorTest.kt
index bab9bbbfde4f..bab9bbbfde4f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/PolicyRequestProcessorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/policy/PolicyRequestProcessorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/PrivateProfilePolicyTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/policy/PrivateProfilePolicyTest.kt
index 6e57761aafa6..6e57761aafa6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/PrivateProfilePolicyTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/policy/PrivateProfilePolicyTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/TestUserIds.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/policy/TestUserIds.kt
index 7a6d2809471d..7a6d2809471d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/TestUserIds.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/policy/TestUserIds.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/WorkProfilePolicyTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/policy/WorkProfilePolicyTest.kt
index be9fcc2be3a3..be9fcc2be3a3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/WorkProfilePolicyTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/policy/WorkProfilePolicyTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/scroll/FakeSessionTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/scroll/FakeSessionTest.java
index 88cb00cda638..88cb00cda638 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/scroll/FakeSessionTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/scroll/FakeSessionTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/scroll/ScrollCaptureFrameworkSmokeTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/scroll/ScrollCaptureFrameworkSmokeTest.java
index 5699cfc96c8a..5699cfc96c8a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/scroll/ScrollCaptureFrameworkSmokeTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/scroll/ScrollCaptureFrameworkSmokeTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/scroll/ScrollViewActivity.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/scroll/ScrollViewActivity.java
index 04aba1133a78..04aba1133a78 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/scroll/ScrollViewActivity.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/scroll/ScrollViewActivity.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModelTest.kt
index e39e0fbad6e7..e39e0fbad6e7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scrim/ScrimViewTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/scrim/ScrimViewTest.java
index ca8da635e0f1..ca8da635e0f1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scrim/ScrimViewTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scrim/ScrimViewTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/BrightnessControllerTest.kt
index 98260d88f389..98260d88f389 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/BrightnessControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
index c7bea5911a15..c7bea5911a15 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ConstraintChangeTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ConstraintChangeTest.kt
index 8c8083543823..8c8083543823 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ConstraintChangeTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ConstraintChangeTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ConstraintChangesTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ConstraintChangesTest.kt
index 05c17060b461..05c17060b461 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ConstraintChangesTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ConstraintChangesTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/LockscreenHostedDreamGestureListenerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/LockscreenHostedDreamGestureListenerTest.kt
index 2ac0ed0efff4..2ac0ed0efff4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/LockscreenHostedDreamGestureListenerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/LockscreenHostedDreamGestureListenerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt
index abc96ee3c5f0..abc96ee3c5f0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index e0c4ab737511..e0c4ab737511 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index a7fd1609d1ca..a7fd1609d1ca 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt
index 90655c3cf4b3..90655c3cf4b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
index ca29dd98a637..ca29dd98a637 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQuickSettingsContainerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationsQuickSettingsContainerTest.kt
index 97ce37c82c83..97ce37c82c83 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQuickSettingsContainerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationsQuickSettingsContainerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/PulsingGestureListenerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/PulsingGestureListenerTest.kt
index effd28edc68b..effd28edc68b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/PulsingGestureListenerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/PulsingGestureListenerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt
index f38bf13d0bda..f38bf13d0bda 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
index a52f1737117a..a52f1737117a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplWithCoroutinesTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplWithCoroutinesTest.kt
index 46961d4db0f6..46961d4db0f6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplWithCoroutinesTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplWithCoroutinesTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerImplTest.kt
index 02172383485d..02172383485d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/CellSignalStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/carrier/CellSignalStateTest.kt
index c6699590e499..c6699590e499 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/CellSignalStateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/carrier/CellSignalStateTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/carrier/ShadeCarrierTest.java
index 1a2531ac8c75..1a2531ac8c75 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/carrier/ShadeCarrierTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
index 7d4918a30d9c..7d4918a30d9c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/LinearLargeScreenShadeInterpolator.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/transition/LinearLargeScreenShadeInterpolator.kt
index d24bcdc834a7..d24bcdc834a7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/LinearLargeScreenShadeInterpolator.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/transition/LinearLargeScreenShadeInterpolator.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt
index 10c017bdc525..10c017bdc525 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/animation/DisableSubpixelTextTransitionListenerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/animation/DisableSubpixelTextTransitionListenerTest.kt
index 5d8f868158e7..5d8f868158e7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/animation/DisableSubpixelTextTransitionListenerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/animation/DisableSubpixelTextTransitionListenerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldConstantTranslateAnimatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/animation/UnfoldConstantTranslateAnimatorTest.kt
index 3a53a5aaedfa..3a53a5aaedfa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldConstantTranslateAnimatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/animation/UnfoldConstantTranslateAnimatorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimatorTest.kt
index fbaddfaf7216..fbaddfaf7216 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimatorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
index 022825a48de3..022825a48de3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt
index bbe03f001b03..bbe03f001b03 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt
index 83fb14aaf792..83fb14aaf792 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java
index 267f22bb2569..267f22bb2569 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionTest.java
index a224843e592a..a224843e592a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/FakeCondition.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/FakeCondition.java
index 5416536305fc..5416536305fc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/FakeCondition.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/FakeCondition.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/plugins/PluginManagerTest.java
index c721ceb10f86..c721ceb10f86 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginManagerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/plugins/PluginManagerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/VersionInfoTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/plugins/VersionInfoTest.java
index 15fdc7c84060..15fdc7c84060 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/VersionInfoTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/plugins/VersionInfoTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/regionsampling/RegionSamplerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/regionsampling/RegionSamplerTest.kt
index 7fc845c17613..7fc845c17613 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/regionsampling/RegionSamplerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/regionsampling/RegionSamplerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/rotation/RotationButtonControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/rotation/RotationButtonControllerTest.kt
index 5a4ef055265c..5a4ef055265c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/rotation/RotationButtonControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/rotation/RotationButtonControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/BlurUtilsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/BlurUtilsTest.kt
index d0ba629c4998..d0ba629c4998 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/BlurUtilsTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/BlurUtilsTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/DragDownHelperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/DragDownHelperTest.kt
index 05d9495db091..05d9495db091 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/DragDownHelperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/DragDownHelperTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java
index 59678a2f8c90..59678a2f8c90 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt
index 948a73208d10..948a73208d10 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt
index e48242a3e003..e48242a3e003 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationListenerTest.java
index 27a1bb5ea556..27a1bb5ea556 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationListenerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
index c9d910c530ea..c9d910c530ea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
index 9f94cff4ead4..9f94cff4ead4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java
index 5f9c9df7ab23..5f9c9df7ab23 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt
index 9907740672ed..9907740672ed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilderTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilderTest.java
index 58943ea3b4ee..58943ea3b4ee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilderTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilderTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerTest.kt
index 6b9a19a92fc4..6b9a19a92fc4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
index 3346e19b4ce9..3346e19b4ce9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt
index 26692c908c5a..26692c908c5a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/VibratorHelperTest.kt
index 78c1887f7c0d..78c1887f7c0d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/VibratorHelperTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/view/ChipBackgroundContainerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/view/ChipBackgroundContainerTest.kt
index 5fbdfbf17df4..5fbdfbf17df4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/view/ChipBackgroundContainerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/view/ChipBackgroundContainerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/view/ChipChronometerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/view/ChipChronometerTest.kt
index 6f7711759603..6f7711759603 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/view/ChipChronometerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/view/ChipChronometerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ParametersTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/commandline/ParametersTest.kt
index 83811cd61581..83811cd61581 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ParametersTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/commandline/ParametersTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ParseableCommandTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/commandline/ParseableCommandTest.kt
index 1a7c8a336c81..1a7c8a336c81 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ParseableCommandTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/commandline/ParseableCommandTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ValueParserTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/commandline/ValueParserTest.kt
index 1efb3f74b04f..1efb3f74b04f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ValueParserTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/commandline/ValueParserTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt
index 643acdbb9277..643acdbb9277 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/MobileIconCarrierIdOverridesFake.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/connectivity/MobileIconCarrierIdOverridesFake.kt
index 62b4e7b79f5e..62b4e7b79f5e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/MobileIconCarrierIdOverridesFake.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/connectivity/MobileIconCarrierIdOverridesFake.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkTypeResIdCacheTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/connectivity/NetworkTypeResIdCacheTest.kt
index 3eeed73a539c..3eeed73a539c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkTypeResIdCacheTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/connectivity/NetworkTypeResIdCacheTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/ui/MobileContextProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/connectivity/ui/MobileContextProviderTest.kt
index ca90f742db40..ca90f742db40 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/ui/MobileContextProviderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/connectivity/ui/MobileContextProviderTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/KeyguardStatusBarRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/KeyguardStatusBarRepositoryImplTest.kt
index 7c98037a5c41..7c98037a5c41 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/KeyguardStatusBarRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/KeyguardStatusBarRepositoryImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt
index 48ae7a2aa260..48ae7a2aa260 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/DisableFlagsLoggerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/disableflags/DisableFlagsLoggerTest.kt
index fffcbb6ccd32..fffcbb6ccd32 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/DisableFlagsLoggerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/disableflags/DisableFlagsLoggerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/DisableStateTrackerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/disableflags/DisableStateTrackerTest.kt
index cf78c71fe047..cf78c71fe047 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/DisableStateTrackerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/disableflags/DisableStateTrackerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt
index d2dfc9257e7e..d2dfc9257e7e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/FakeStatusEvent.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/FakeStatusEvent.kt
index df8afde1b9a3..df8afde1b9a3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/FakeStatusEvent.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/FakeStatusEvent.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt
index 984bda1c0d21..984bda1c0d21 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt
index 742494b769de..742494b769de 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
index 7a8533ee6d69..7a8533ee6d69 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java
index 77fd06757595..77fd06757595 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java
index d879fcecffab..d879fcecffab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLoggerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLoggerTest.kt
index a5206f52b6f2..a5206f52b6f2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLoggerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLoggerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
index 9f752a89b16d..9f752a89b16d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java
index 8e95ac599ce1..8e95ac599ce1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NoManSimulator.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NoManSimulator.java
index ee7d55864931..ee7d55864931 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NoManSimulator.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NoManSimulator.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataImplTest.kt
index 2a587511eaec..2a587511eaec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImplTest.kt
index d87f827de776..d87f827de776 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreMocks.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreMocks.kt
index 6e81c69045ce..6e81c69045ce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreMocks.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreMocks.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographerTest.kt
index f1da22f08e75..f1da22f08e75 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/SectionStyleProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/SectionStyleProviderTest.kt
index 1fd6b042ad67..1fd6b042ad67 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/SectionStyleProviderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/SectionStyleProviderTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescerTest.java
index f029a2ca6099..f029a2ca6099 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java
index 1f2925528077..1f2925528077 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinatorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinatorTest.java
index 3676a3d15cc8..3676a3d15cc8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinatorTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinatorTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DismissibilityCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/DismissibilityCoordinatorTest.kt
index 543f0c72a8ec..543f0c72a8ec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DismissibilityCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/DismissibilityCoordinatorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DreamCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/DreamCoordinatorTest.kt
index 4d5ea92aa0e6..4d5ea92aa0e6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DreamCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/DreamCoordinatorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinatorTest.kt
index 7b688d4f91fd..7b688d4f91fd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinatorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupWhenCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupWhenCoordinatorTest.kt
index 3f140265e5f1..3f140265e5f1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupWhenCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupWhenCoordinatorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorTest.kt
index 7fe97d27f273..7fe97d27f273 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
index b4f4138fd409..b4f4138fd409 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java
index 5dcad4bb9e62..5dcad4bb9e62 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
index 4218be26c58e..4218be26c58e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/MediaCoordinatorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/MediaCoordinatorTest.java
index 07c29a024a6c..07c29a024a6c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/MediaCoordinatorTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/MediaCoordinatorTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/NotificationStatsLoggerCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/NotificationStatsLoggerCoordinatorTest.kt
index 501bca248c76..501bca248c76 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/NotificationStatsLoggerCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/NotificationStatsLoggerCoordinatorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
index dc9c22f566bf..dc9c22f566bf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java
index c05b13163d32..c05b13163d32 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RemoteInputCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/RemoteInputCoordinatorTest.kt
index deb3fc1224ce..deb3fc1224ce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RemoteInputCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/RemoteInputCoordinatorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAlertTimeCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAlertTimeCoordinatorTest.kt
index 1b7ec5381713..1b7ec5381713 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAlertTimeCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAlertTimeCoordinatorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt
index 689fc7cb647b..689fc7cb647b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinatorTest.kt
index ef2a2aa67a08..ef2a2aa67a08 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinatorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt
index 2f77b33c96cb..2f77b33c96cb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/listbuilder/SemiStableSortTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/listbuilder/SemiStableSortTest.kt
index d2057703d560..d2057703d560 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/listbuilder/SemiStableSortTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/listbuilder/SemiStableSortTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderHelperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderHelperTest.kt
index 49f836fe9f81..49f836fe9f81 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderHelperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderHelperTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionInconsistencyTrackerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionInconsistencyTrackerTest.kt
index 341a51e32a46..341a51e32a46 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionInconsistencyTrackerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionInconsistencyTrackerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/SelfTrackingLifetimeExtenderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/notifcollection/SelfTrackingLifetimeExtenderTest.kt
index 99e55a85344a..99e55a85344a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/SelfTrackingLifetimeExtenderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/notifcollection/SelfTrackingLifetimeExtenderTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProviderTest.kt
index 586b947d5299..586b947d5299 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProviderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProviderTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/FakeNodeController.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/FakeNodeController.kt
index 2de21ae8f0a1..2de21ae8f0a1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/FakeNodeController.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/FakeNodeController.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt
index 99bd4fc549a8..99bd4fc549a8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt
index ca75ca679c31..ca75ca679c31 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferTest.kt
index 9d3e2e8dfcb4..9d3e2e8dfcb4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractorTest.kt
index 79ff4be253e1..79ff4be253e1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationLaunchAnimationInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationLaunchAnimationInteractorTest.kt
index 982b7b113a02..982b7b113a02 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationLaunchAnimationInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationLaunchAnimationInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractorTest.kt
index 133a114fed9d..133a114fed9d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt
index 572a0c1b1869..572a0c1b1869 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt
index f07303ed32e3..f07303ed32e3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt
index 1f4e80e48bb7..1f4e80e48bb7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java
index af2789b8401a..af2789b8401a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java
index 19214fb831eb..19214fb831eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt
index 284efc71a96d..284efc71a96d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt
index 7fd9c9fbdd6b..7fd9c9fbdd6b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/ExpansionStateLoggerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/logging/ExpansionStateLoggerTest.java
index 59741718476f..59741718476f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/ExpansionStateLoggerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/logging/ExpansionStateLoggerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLoggerFake.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLoggerFake.java
index d61fc05c699f..d61fc05c699f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLoggerFake.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLoggerFake.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
index 9f98fd4c8508..9f98fd4c8508 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
index c0057431f536..c0057431f536 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java
index d04d6fc5f593..d04d6fc5f593 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/HeadsUpStyleProviderImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/HeadsUpStyleProviderImplTest.kt
index c325791b1f05..c325791b1f05 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/HeadsUpStyleProviderImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/HeadsUpStyleProviderImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineTest.java
index 18fd42da78ea..18fd42da78ea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManagerTest.kt
index 29252b27f6d0..29252b27f6d0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManagerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifRemoteViewCacheImplTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotifRemoteViewCacheImplTest.java
index 8b1c95babe38..8b1c95babe38 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifRemoteViewCacheImplTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotifRemoteViewCacheImplTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt
index 350f90dcbe91..350f90dcbe91 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
index 245a6a0b130c..245a6a0b130c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolverTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolverTest.java
index 180c8c88c59f..180c8c88c59f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolverTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolverTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
index 027e899e20df..027e899e20df 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java
index 22f1e4604bbd..22f1e4604bbd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java
index 57b0f3f8d8c5..57b0f3f8d8c5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java
index 841cb4a3669b..841cb4a3669b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt
index 0dc871a523ee..0dc871a523ee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/NotificationViewFlipperViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/NotificationViewFlipperViewModelTest.kt
index f88bd7ec60bb..f88bd7ec60bb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/NotificationViewFlipperViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/NotificationViewFlipperViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shared/TestActiveNotificationModel.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shared/TestActiveNotificationModel.kt
index 16c5c8a98253..16c5c8a98253 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shared/TestActiveNotificationModel.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shared/TestActiveNotificationModel.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt
index 4c6e25a530a5..4c6e25a530a5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt
index e2fb3ba11a02..e2fb3ba11a02 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt
index 2349c252369c..2349c252369c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/DisplaySwitchNotificationsHiderTrackerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/DisplaySwitchNotificationsHiderTrackerTest.kt
index 578950fa88b5..578950fa88b5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/DisplaySwitchNotificationsHiderTrackerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/DisplaySwitchNotificationsHiderTrackerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt
index 3a77d822eb7e..3a77d822eb7e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
index 1a1af2eecc00..1a1af2eecc00 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
index dae5542123ed..dae5542123ed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
index 95db95cd288b..95db95cd288b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
index 3e8bf4792f02..3e8bf4792f02 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt
index 798465e7b165..798465e7b165 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt
index e493420b64a1..e493420b64a1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt
index 476252737454..476252737454 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorTest.kt
index 1c6bda985a0e..1c6bda985a0e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationLoggerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationLoggerViewModelTest.kt
index e9d88ccb0cbc..e9d88ccb0cbc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationLoggerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationLoggerViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
index 9eafcdbadfa5..9eafcdbadfa5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
index d9e94953e757..d9e94953e757 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ConfigurationControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ConfigurationControllerImplTest.kt
index 942ea65ec49e..942ea65ec49e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ConfigurationControllerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ConfigurationControllerImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
index 5052a008af68..5052a008af68 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java
index 3b3ec263145a..3b3ec263145a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt
index cb40f72ff1af..cb40f72ff1af 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardDismissUtilTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardDismissUtilTest.java
index d880becaa4bd..d880becaa4bd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardDismissUtilTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardDismissUtilTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java
index 109cd948b5b3..109cd948b5b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
index 68e17c1b2d73..68e17c1b2d73 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java
index 0932a0c9307c..0932a0c9307c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LegacyLightsOutNotifControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyLightsOutNotifControllerTest.java
index 782ca91bc8fb..782ca91bc8fb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LegacyLightsOutNotifControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyLightsOutNotifControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt
index 518b327036cb..518b327036cb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProviderTest.kt
index 788c2cb2a485..788c2cb2a485 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProviderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProviderTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java
index 88ec18dd65f3..88ec18dd65f3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarTransitionsControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LightBarTransitionsControllerTest.java
index 7dfdb9228936..7dfdb9228936 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarTransitionsControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LightBarTransitionsControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImplTest.kt
index c7919df7e0d0..c7919df7e0d0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java
index c5abd026b369..c5abd026b369 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt
index 15958ef4af8a..15958ef4af8a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java
index 9522e1f65a4c..9522e1f65a4c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt
index 2ed34735db1f..2ed34735db1f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
index 95472cad4b90..95472cad4b90 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
index c5238194d0a4..c5238194d0a4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt
index 48c2cc7f11c4..48c2cc7f11c4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt
index 11dd587a04ad..11dd587a04ad 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialogTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialogTest.kt
index b560c591af1e..b560c591af1e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialogTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialogTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
index 624c070e95e0..624c070e95e0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt
index 2d9880a48f80..2d9880a48f80 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt
index 219b16f1e0ef..219b16f1e0ef 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModelTest.kt
index 9f6f51a28764..9f6f51a28764 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaListenerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaListenerTest.kt
index 597e2e45ea14..597e2e45ea14 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaListenerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaListenerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt
index dfe01bf45f38..dfe01bf45f38 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt
index 4c6eaa589e6a..4c6eaa589e6a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/IconManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ui/IconManagerTest.kt
index 90732d0183d2..90732d0183d2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/IconManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ui/IconManagerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImplTest.kt
index 50a13b93ea15..50a13b93ea15 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerTest.java
index 891ff38764fe..891ff38764fe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconListTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconListTest.java
index 02a6301a14e5..02a6301a14e5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconListTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconListTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/AirplaneModeRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/AirplaneModeRepositoryImplTest.kt
index 0641e173576d..0641e173576d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/AirplaneModeRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/AirplaneModeRepositoryImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt
index f9ae5ff9bbc3..f9ae5ff9bbc3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.kt
index ec04da7030b7..ec04da7030b7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLoggerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLoggerTest.kt
index 4511be954692..4511be954692 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLoggerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLoggerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModelParameterizedTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModelParameterizedTest.kt
index ebec00380cf4..ebec00380cf4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModelParameterizedTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModelParameterizedTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt
index fc1ea227f1bd..fc1ea227f1bd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/demo/DemoDeviceBasedSatelliteRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/data/demo/DemoDeviceBasedSatelliteRepositoryTest.kt
index 87693891a281..87693891a281 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/demo/DemoDeviceBasedSatelliteRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/data/demo/DemoDeviceBasedSatelliteRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/FakeDeviceBasedSatelliteRepository.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/FakeDeviceBasedSatelliteRepository.kt
index 55460bd5b801..55460bd5b801 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/FakeDeviceBasedSatelliteRepository.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/FakeDeviceBasedSatelliteRepository.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/FakeDeviceBasedSatelliteViewModel.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/FakeDeviceBasedSatelliteViewModel.kt
index f125ef12aa97..f125ef12aa97 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/FakeDeviceBasedSatelliteViewModel.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/FakeDeviceBasedSatelliteViewModel.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/model/DefaultConnectionModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/data/model/DefaultConnectionModelTest.kt
index 4c2bb7f8069d..4c2bb7f8069d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/model/DefaultConnectionModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/data/model/DefaultConnectionModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt
index c3ad0f9d5148..c3ad0f9d5148 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/SingleBindableStatusBarIconViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/SingleBindableStatusBarIconViewTest.kt
index a6cdfe23aa5a..a6cdfe23aa5a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/SingleBindableStatusBarIconViewTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/SingleBindableStatusBarIconViewTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewBinder.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewBinder.kt
index 2ee928fa6d17..2ee928fa6d17 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewBinder.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewBinder.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt
index b9ca8fc2d181..c0a15922642e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt
@@ -78,7 +78,7 @@ class WifiInteractorImplTest : SysuiTestCase() {
@Test
fun ssid_inactiveNetwork_outputsNull() =
testScope.runTest {
- wifiRepository.setWifiNetwork(WifiNetworkModel.Inactive)
+ wifiRepository.setWifiNetwork(WifiNetworkModel.Inactive())
var latest: String? = "default"
val job = underTest.ssid.onEach { latest = it }.launchIn(this)
@@ -93,7 +93,7 @@ class WifiInteractorImplTest : SysuiTestCase() {
fun ssid_carrierMergedNetwork_outputsNull() =
testScope.runTest {
wifiRepository.setWifiNetwork(
- WifiNetworkModel.CarrierMerged(subscriptionId = 2, level = 1)
+ WifiNetworkModel.CarrierMerged.of(subscriptionId = 2, level = 1)
)
var latest: String? = "default"
@@ -109,7 +109,7 @@ class WifiInteractorImplTest : SysuiTestCase() {
fun ssid_unknownSsid_outputsNull() =
testScope.runTest {
wifiRepository.setWifiNetwork(
- WifiNetworkModel.Active(
+ WifiNetworkModel.Active.of(
level = 1,
ssid = WifiManager.UNKNOWN_SSID,
)
@@ -128,7 +128,7 @@ class WifiInteractorImplTest : SysuiTestCase() {
fun ssid_validSsid_outputsSsid() =
testScope.runTest {
wifiRepository.setWifiNetwork(
- WifiNetworkModel.Active(
+ WifiNetworkModel.Active.of(
level = 1,
ssid = "MyAwesomeWifiNetwork",
)
@@ -189,7 +189,7 @@ class WifiInteractorImplTest : SysuiTestCase() {
fun wifiNetwork_matchesRepoWifiNetwork() =
testScope.runTest {
val wifiNetwork =
- WifiNetworkModel.Active(
+ WifiNetworkModel.Active.of(
isValidated = true,
level = 3,
ssid = "AB",
@@ -263,7 +263,7 @@ class WifiInteractorImplTest : SysuiTestCase() {
val latest by collectLastValue(underTest.areNetworksAvailable)
wifiRepository.wifiScanResults.value = emptyList()
- wifiRepository.setWifiNetwork(WifiNetworkModel.Inactive)
+ wifiRepository.setWifiNetwork(WifiNetworkModel.Inactive())
assertThat(latest).isFalse()
}
@@ -280,7 +280,7 @@ class WifiInteractorImplTest : SysuiTestCase() {
WifiScanEntry(ssid = "ssid 3"),
)
- wifiRepository.setWifiNetwork(WifiNetworkModel.Inactive)
+ wifiRepository.setWifiNetwork(WifiNetworkModel.Inactive())
assertThat(latest).isTrue()
}
@@ -298,7 +298,7 @@ class WifiInteractorImplTest : SysuiTestCase() {
)
wifiRepository.setWifiNetwork(
- WifiNetworkModel.Active(
+ WifiNetworkModel.Active.of(
ssid = "ssid 2",
level = 2,
)
@@ -318,7 +318,7 @@ class WifiInteractorImplTest : SysuiTestCase() {
)
wifiRepository.setWifiNetwork(
- WifiNetworkModel.Active(
+ WifiNetworkModel.Active.of(
ssid = "ssid 2",
level = 2,
)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
index 72a45b9b5452..141e304b63a1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
@@ -115,7 +115,7 @@ class WifiViewModelTest : SysuiTestCase() {
val latestKeyguard by collectLastValue(keyguard.wifiIcon)
val latestQs by collectLastValue(qs.wifiIcon)
- wifiRepository.setWifiNetwork(WifiNetworkModel.Active(isValidated = true, level = 1))
+ wifiRepository.setWifiNetwork(WifiNetworkModel.Active.of(isValidated = true, level = 1))
assertThat(latestHome).isInstanceOf(WifiIcon.Visible::class.java)
assertThat(latestHome).isEqualTo(latestKeyguard)
@@ -129,7 +129,7 @@ class WifiViewModelTest : SysuiTestCase() {
// Even WHEN the network has a valid hotspot type
wifiRepository.setWifiNetwork(
- WifiNetworkModel.Active(
+ WifiNetworkModel.Active.of(
isValidated = true,
level = 1,
hotspotDeviceType = WifiNetworkModel.HotspotDeviceType.LAPTOP,
@@ -191,7 +191,7 @@ class WifiViewModelTest : SysuiTestCase() {
whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true)
createAndSetViewModel()
- wifiRepository.setWifiNetwork(WifiNetworkModel.Active(ssid = null, level = 1))
+ wifiRepository.setWifiNetwork(WifiNetworkModel.Active.of(ssid = null, level = 1))
val activityIn by collectLastValue(underTest.isActivityInViewVisible)
val activityOut by collectLastValue(underTest.isActivityOutViewVisible)
@@ -214,7 +214,7 @@ class WifiViewModelTest : SysuiTestCase() {
whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true)
createAndSetViewModel()
- wifiRepository.setWifiNetwork(WifiNetworkModel.Active(ssid = null, level = 1))
+ wifiRepository.setWifiNetwork(WifiNetworkModel.Active.of(ssid = null, level = 1))
val activityIn by collectLastValue(underTest.isActivityInViewVisible)
val activityOut by collectLastValue(underTest.isActivityOutViewVisible)
@@ -463,6 +463,6 @@ class WifiViewModelTest : SysuiTestCase() {
}
companion object {
- private val ACTIVE_VALID_WIFI_NETWORK = WifiNetworkModel.Active(ssid = "AB", level = 1)
+ private val ACTIVE_VALID_WIFI_NETWORK = WifiNetworkModel.Active.of(ssid = "AB", level = 1)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapterTest.kt
index 0a5e63085b9b..0a5e63085b9b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapterTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapterTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BlockingQueueIntentReceiver.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BlockingQueueIntentReceiver.java
index 7c4629871658..7c4629871658 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BlockingQueueIntentReceiver.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BlockingQueueIntentReceiver.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
index 93071bd9305a..93071bd9305a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java
index 627463b45982..627463b45982 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ClockTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ClockTest.kt
index 7549a7fa0499..7549a7fa0499 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ClockTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ClockTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DevicePostureControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/DevicePostureControllerImplTest.kt
index f871d2748fc9..f871d2748fc9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DevicePostureControllerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/DevicePostureControllerImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImplTest.kt
index 649a4ab2b968..649a4ab2b968 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java
index f5efd6d5fdff..f5efd6d5fdff 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java
index 3721b0ed987a..3721b0ed987a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt
index b7a35158fdf6..b7a35158fdf6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java
index aed9af6df454..aed9af6df454 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt
index 9f74915b4d1b..9f74915b4d1b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt
index 750f0c68bf3f..750f0c68bf3f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt
index 4b14e642063a..4b14e642063a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java
index 36e305244d18..36e305244d18 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java
index 637a0f16cd5d..637a0f16cd5d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepositoryImplTest.kt
index 94f0d196fa21..94f0d196fa21 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepositoryImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/bluetooth/FakeBluetoothRepository.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/bluetooth/FakeBluetoothRepository.kt
index d8c0f777d4cc..d8c0f777d4cc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/bluetooth/FakeBluetoothRepository.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/bluetooth/FakeBluetoothRepository.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/data/repository/DeviceProvisioningRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/data/repository/DeviceProvisioningRepositoryImplTest.kt
index 21ed3841c70b..21ed3841c70b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/data/repository/DeviceProvisioningRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/data/repository/DeviceProvisioningRepositoryImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
index e396b567ac89..e396b567ac89 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt
index 03a25e3d9ce3..03a25e3d9ce3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/FixedCapacityBatteryState.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/stylus/FixedCapacityBatteryState.kt
index 7e010886c394..7e010886c394 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/stylus/FixedCapacityBatteryState.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/stylus/FixedCapacityBatteryState.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/glowboxeffect/GlowBoxEffectTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/glowboxeffect/GlowBoxEffectTest.kt
index 32ef501cd9e3..32ef501cd9e3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/glowboxeffect/GlowBoxEffectTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/glowboxeffect/GlowBoxEffectTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/loadingeffect/LoadingEffectTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/loadingeffect/LoadingEffectTest.kt
index 67a42196d2e2..67a42196d2e2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/loadingeffect/LoadingEffectTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/loadingeffect/LoadingEffectTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/MultiRippleControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/ripple/MultiRippleControllerTest.kt
index a5afe1e33169..a5afe1e33169 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/MultiRippleControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/ripple/MultiRippleControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationTest.kt
index 8dafa824cb8c..8dafa824cb8c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleShaderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/ripple/RippleShaderTest.kt
index 2fee2a4553b0..2fee2a4553b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleShaderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/ripple/RippleShaderTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/ripple/RippleViewTest.kt
index 18644ab67351..18644ab67351 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleViewTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/ripple/RippleViewTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/shaders/SolidColorShaderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/shaders/SolidColorShaderTest.kt
index fbd3eae59046..fbd3eae59046 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/shaders/SolidColorShaderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/shaders/SolidColorShaderTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/shaders/SparkleShaderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/shaders/SparkleShaderTest.kt
index d32bffbdff1d..d32bffbdff1d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/shaders/SparkleShaderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/shaders/SparkleShaderTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseControllerTest.kt
index 4ba64384a186..4ba64384a186 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShaderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShaderTest.kt
index 286f01736497..286f01736497 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShaderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShaderTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseViewTest.kt
index e09d4ea9bcc6..e09d4ea9bcc6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseViewTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseViewTest.kt
diff --git a/packages/SystemUI/res/layout/biometric_prompt_one_pane_layout.xml b/packages/SystemUI/res/layout/biometric_prompt_one_pane_layout.xml
index 3b3ed39c8993..91cd019c85d1 100644
--- a/packages/SystemUI/res/layout/biometric_prompt_one_pane_layout.xml
+++ b/packages/SystemUI/res/layout/biometric_prompt_one_pane_layout.xml
@@ -215,17 +215,4 @@
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0"
tools:srcCompat="@tools:sample/avatars" />
-
- <com.android.systemui.biometrics.BiometricPromptLottieViewWrapper
- android:id="@+id/biometric_icon_overlay"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_gravity="center"
- android:contentDescription="@null"
- android:scaleType="fitXY"
- android:importantForAccessibility="no"
- app:layout_constraintBottom_toBottomOf="@+id/biometric_icon"
- app:layout_constraintEnd_toEndOf="@+id/biometric_icon"
- app:layout_constraintStart_toStartOf="@+id/biometric_icon"
- app:layout_constraintTop_toTopOf="@+id/biometric_icon" />
</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml b/packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml
index 2a00495e9d01..51117a7845df 100644
--- a/packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml
+++ b/packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml
@@ -40,19 +40,6 @@ android:layout_height="match_parent">
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="@tools:sample/avatars" />
- <com.android.systemui.biometrics.BiometricPromptLottieViewWrapper
- android:id="@+id/biometric_icon_overlay"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_gravity="center"
- android:contentDescription="@null"
- android:scaleType="fitXY"
- android:importantForAccessibility="no"
- app:layout_constraintBottom_toBottomOf="@+id/biometric_icon"
- app:layout_constraintEnd_toEndOf="@+id/biometric_icon"
- app:layout_constraintStart_toStartOf="@+id/biometric_icon"
- app:layout_constraintTop_toTopOf="@+id/biometric_icon" />
-
<ScrollView
android:id="@+id/scrollView"
android:layout_width="0dp"
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 1fb1dad067f9..589d9ddd20b9 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -3812,4 +3812,33 @@ Action + ESC for this.</string>
<!-- Toast message for notifying users to use regular brightness bar to lower the brightness. [CHAR LIMIT=NONE] -->
<string name="accessibility_deprecate_extra_dim_dialog_toast">
Extra dim shortcut removed. To lower your brightness, use the regular brightness bar.</string>
+
+ <!-- Label for category in QS Edit mode list of tiles, for tiles that are related to connectivity, e.g. Internet. [CHAR LIMIT=NONE] -->
+ <string name="qs_edit_mode_category_connectivity">
+ Connectivity
+ </string>
+ <!-- Label for category in QS Edit mode list of tiles, for tiles that are related to accessibility functions, e.g. Hearing devices. [CHAR LIMIT=NONE] -->
+ <string name="qs_edit_mode_category_accessibility">
+ Accessibility
+ </string>
+ <!-- Label for category in QS Edit mode list of tiles, for tiles that are related to general utilities, e.g. Flashlight. [CHAR LIMIT=NONE] -->
+ <string name="qs_edit_mode_category_utilities">
+ Utilities
+ </string>
+ <!-- Label for category in QS Edit mode list of tiles, for tiles that are related to privacy, e.g. Mic access. [CHAR LIMIT=NONE] -->
+ <string name="qs_edit_mode_category_privacy">
+ Privacy
+ </string>
+ <!-- Label for category in QS Edit mode list of tiles, for tiles that are provided by an app, e.g. Calculator. [CHAR LIMIT=NONE] -->
+ <string name="qs_edit_mode_category_providedByApps">
+ Provided by apps
+ </string>
+ <!-- Label for category in QS Edit mode list of tiles, for tiles that are related to the display, e.g. Dark theme. [CHAR LIMIT=NONE] -->
+ <string name="qs_edit_mode_category_display">
+ Display
+ </string>
+ <!-- Label for category in QS Edit mode list of tiles, for tiles with an unknown category. [CHAR LIMIT=NONE] -->
+ <string name="qs_edit_mode_category_unknown">
+ Unknown
+ </string>
</resources>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/DisplaySpecific.kt b/packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/DisplaySpecific.kt
index 57a49c83ae17..3e39ae9a3fe5 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/DisplaySpecific.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/DisplaySpecific.kt
@@ -15,10 +15,7 @@
*/
package com.android.systemui.dagger.qualifiers
-import java.lang.annotation.Documented
-import java.lang.annotation.Retention
-import java.lang.annotation.RetentionPolicy.RUNTIME
import javax.inject.Qualifier
/** Annotates a class that is display specific. */
-@Qualifier @Documented @Retention(RUNTIME) annotation class DisplaySpecific
+@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class DisplaySpecific
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl
index c00007b55482..283e4556d05c 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl
@@ -132,4 +132,9 @@ oneway interface IOverviewProxy {
* Sent when {@link TaskbarDelegate#transitionTo} is called.
*/
void transitionTo(int barMode, boolean animate) = 33;
+
+ /**
+ * Sent when {@link TaskbarDelegate#appTransitionPending} is called.
+ */
+ void appTransitionPending(boolean pending) = 34;
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt b/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt
index bb80396c70fb..cd9efaf6e6bb 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt
@@ -19,6 +19,7 @@ package com.android.systemui.accessibility.qs
import com.android.systemui.Flags
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.ColorCorrectionTile
import com.android.systemui.qs.tiles.ColorInversionTile
@@ -179,6 +180,7 @@ interface QSAccessibilityModule {
labelRes = R.string.quick_settings_color_correction_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.ACCESSIBILITY,
)
/** Inject ColorCorrectionTile into tileViewModelMap in QSModule */
@@ -210,6 +212,7 @@ interface QSAccessibilityModule {
labelRes = R.string.quick_settings_inversion_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.ACCESSIBILITY,
)
/** Inject ColorInversionTile into tileViewModelMap in QSModule */
@@ -241,6 +244,7 @@ interface QSAccessibilityModule {
labelRes = R.string.quick_settings_font_scaling_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.DISPLAY,
)
/** Inject FontScaling Tile into tileViewModelMap in QSModule */
@@ -272,6 +276,7 @@ interface QSAccessibilityModule {
labelRes = com.android.internal.R.string.reduce_bright_colors_feature_name,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.DISPLAY,
)
@Provides
@@ -286,6 +291,7 @@ interface QSAccessibilityModule {
labelRes = R.string.quick_settings_hearing_devices_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.ACCESSIBILITY,
)
/**
@@ -322,6 +328,7 @@ interface QSAccessibilityModule {
labelRes = R.string.quick_settings_onehanded_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.ACCESSIBILITY,
)
/** Inject One Handed Mode Tile into tileViewModelMap in QSModule. */
@@ -355,6 +362,7 @@ interface QSAccessibilityModule {
labelRes = R.string.quick_settings_night_display_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.DISPLAY,
)
/**
diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatterySaverModule.kt b/packages/SystemUI/src/com/android/systemui/battery/BatterySaverModule.kt
index 8a9a322ff100..831bc1da5a79 100644
--- a/packages/SystemUI/src/com/android/systemui/battery/BatterySaverModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/battery/BatterySaverModule.kt
@@ -2,6 +2,7 @@ package com.android.systemui.battery
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.BatterySaverTile
import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
@@ -33,7 +34,7 @@ interface BatterySaverModule {
@IntoMap
@StringKey(BATTERY_SAVER_TILE_SPEC)
fun provideBatterySaverAvailabilityInteractor(
- impl: BatterySaverTileDataInteractor
+ impl: BatterySaverTileDataInteractor
): QSTileAvailabilityInteractor
companion object {
@@ -51,6 +52,7 @@ interface BatterySaverModule {
labelRes = R.string.battery_detail_switch_title,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.UTILITIES,
)
/** Inject BatterySaverTile into tileViewModelMap in QSModule */
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/BiometricsDomainLayerModule.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/BiometricsDomainLayerModule.kt
index ec3fd9f7da35..7ecbb88099cb 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/BiometricsDomainLayerModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/BiometricsDomainLayerModule.kt
@@ -25,6 +25,8 @@ import com.android.systemui.biometrics.domain.interactor.LogContextInteractor
import com.android.systemui.biometrics.domain.interactor.LogContextInteractorImpl
import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor
import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractorImpl
+import com.android.systemui.biometrics.domain.interactor.SideFpsOverlayInteractor
+import com.android.systemui.biometrics.domain.interactor.SideFpsOverlayInteractorImpl
import com.android.systemui.dagger.SysUISingleton
import dagger.Binds
import dagger.Module
@@ -46,6 +48,12 @@ interface BiometricsDomainLayerModule {
@Binds
@SysUISingleton
+ fun providesSideFpsOverlayInteractor(
+ impl: SideFpsOverlayInteractorImpl
+ ): SideFpsOverlayInteractor
+
+ @Binds
+ @SysUISingleton
fun providesCredentialInteractor(impl: CredentialInteractorImpl): CredentialInteractor
@Binds
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/SideFpsOverlayInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/SideFpsOverlayInteractor.kt
new file mode 100644
index 000000000000..10c3483de452
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/SideFpsOverlayInteractor.kt
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.domain.interactor
+
+import android.util.Log
+import com.android.systemui.biometrics.shared.model.AuthenticationReason.NotRunning
+import com.android.systemui.keyguard.domain.interactor.DeviceEntrySideFpsOverlayInteractor
+import com.android.systemui.util.kotlin.sample
+import javax.inject.Inject
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.onEach
+
+/** Encapsulates business logic for showing and hiding the side fingerprint sensor indicator. */
+interface SideFpsOverlayInteractor {
+ /** Whether the side fingerprint sensor indicator is currently showing. */
+ val isShowing: Flow<Boolean>
+}
+
+@OptIn(ExperimentalCoroutinesApi::class)
+class SideFpsOverlayInteractorImpl
+@Inject
+constructor(
+ biometricStatusInteractor: BiometricStatusInteractor,
+ displayStateInteractor: DisplayStateInteractor,
+ deviceEntrySideFpsOverlayInteractor: DeviceEntrySideFpsOverlayInteractor,
+ sfpsSensorInteractor: SideFpsSensorInteractor,
+ // TODO(b/365182034): add progress bar input when rest to unlock feature is implemented
+) : SideFpsOverlayInteractor {
+ private val sfpsOverlayEnabled: Flow<Boolean> =
+ sfpsSensorInteractor.isAvailable.sample(displayStateInteractor.isInRearDisplayMode) {
+ isAvailable: Boolean,
+ isInRearDisplayMode: Boolean ->
+ isAvailable && !isInRearDisplayMode
+ }
+
+ private val showSideFpsOverlay: Flow<Boolean> =
+ combine(
+ biometricStatusInteractor.sfpsAuthenticationReason,
+ deviceEntrySideFpsOverlayInteractor.showIndicatorForDeviceEntry,
+ // TODO(b/365182034): add progress bar input when rest to unlock feature is implemented
+ ) { systemServerAuthReason, showIndicatorForDeviceEntry ->
+ Log.d(
+ TAG,
+ "systemServerAuthReason = $systemServerAuthReason, " +
+ "showIndicatorForDeviceEntry = $showIndicatorForDeviceEntry, "
+ )
+ systemServerAuthReason != NotRunning || showIndicatorForDeviceEntry
+ }
+
+ override val isShowing: Flow<Boolean> =
+ sfpsOverlayEnabled
+ .flatMapLatest { sfpsOverlayEnabled ->
+ if (!sfpsOverlayEnabled) {
+ flowOf(false)
+ } else {
+ showSideFpsOverlay
+ }
+ }
+ .onEach { Log.d(TAG, "isShowing: $it") }
+
+ companion object {
+ private const val TAG = "SideFpsOverlayInteractor"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
index d69e87534cb6..d055731b2698 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
@@ -158,16 +158,13 @@ object BiometricViewSizeBinder {
fun setVisibilities(hideSensorIcon: Boolean, size: PromptSize) {
viewsToHideWhenSmall.forEach { it.showContentOrHide(forceHide = size.isSmall) }
largeConstraintSet.setVisibility(iconHolderView.id, View.GONE)
- largeConstraintSet.setVisibility(R.id.biometric_icon_overlay, View.GONE)
largeConstraintSet.setVisibility(R.id.indicator, View.GONE)
largeConstraintSet.setVisibility(R.id.scrollView, View.GONE)
if (hideSensorIcon) {
smallConstraintSet.setVisibility(iconHolderView.id, View.GONE)
- smallConstraintSet.setVisibility(R.id.biometric_icon_overlay, View.GONE)
smallConstraintSet.setVisibility(R.id.indicator, View.GONE)
mediumConstraintSet.setVisibility(iconHolderView.id, View.GONE)
- mediumConstraintSet.setVisibility(R.id.biometric_icon_overlay, View.GONE)
mediumConstraintSet.setVisibility(R.id.indicator, View.GONE)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinder.kt
index 9578da4238ee..9fe1dc51f4c2 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinder.kt
@@ -33,89 +33,44 @@ import com.airbnb.lottie.LottieProperty
import com.android.app.animation.Interpolators
import com.android.keyguard.KeyguardPINView
import com.android.systemui.CoreStartable
-import com.android.systemui.biometrics.domain.interactor.BiometricStatusInteractor
-import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor
-import com.android.systemui.biometrics.domain.interactor.SideFpsSensorInteractor
-import com.android.systemui.biometrics.shared.model.AuthenticationReason.NotRunning
+import com.android.systemui.biometrics.domain.interactor.SideFpsOverlayInteractor
import com.android.systemui.biometrics.shared.model.LottieCallback
import com.android.systemui.biometrics.ui.viewmodel.SideFpsOverlayViewModel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.keyguard.domain.interactor.DeviceEntrySideFpsOverlayInteractor
-import com.android.systemui.keyguard.ui.viewmodel.SideFpsProgressBarViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.res.R
-import com.android.systemui.util.kotlin.sample
import dagger.Lazy
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch
/** Binds the side fingerprint sensor indicator view to [SideFpsOverlayViewModel]. */
-@OptIn(ExperimentalCoroutinesApi::class)
@SysUISingleton
class SideFpsOverlayViewBinder
@Inject
constructor(
@Application private val applicationScope: CoroutineScope,
@Application private val applicationContext: Context,
- private val biometricStatusInteractor: Lazy<BiometricStatusInteractor>,
- private val displayStateInteractor: Lazy<DisplayStateInteractor>,
- private val deviceEntrySideFpsOverlayInteractor: Lazy<DeviceEntrySideFpsOverlayInteractor>,
private val layoutInflater: Lazy<LayoutInflater>,
- private val sideFpsProgressBarViewModel: Lazy<SideFpsProgressBarViewModel>,
- private val sfpsSensorInteractor: Lazy<SideFpsSensorInteractor>,
+ private val sideFpsOverlayInteractor: Lazy<SideFpsOverlayInteractor>,
+ private val sideFpsOverlayViewModel: Lazy<SideFpsOverlayViewModel>,
private val windowManager: Lazy<WindowManager>
) : CoreStartable {
+ private var overlayView: View? = null
override fun start() {
- applicationScope
- .launch {
- sfpsSensorInteractor.get().isAvailable.collect { isSfpsAvailable ->
- if (isSfpsAvailable) {
- combine(
- biometricStatusInteractor.get().sfpsAuthenticationReason,
- deviceEntrySideFpsOverlayInteractor
- .get()
- .showIndicatorForDeviceEntry,
- sideFpsProgressBarViewModel.get().isVisible,
- ::Triple
- )
- .sample(displayStateInteractor.get().isInRearDisplayMode, ::Pair)
- .collect { (combinedFlows, isInRearDisplayMode: Boolean) ->
- val (
- systemServerAuthReason,
- showIndicatorForDeviceEntry,
- progressBarIsVisible) =
- combinedFlows
- Log.d(
- TAG,
- "systemServerAuthReason = $systemServerAuthReason, " +
- "showIndicatorForDeviceEntry = " +
- "$showIndicatorForDeviceEntry, " +
- "progressBarIsVisible = $progressBarIsVisible"
- )
- if (!isInRearDisplayMode) {
- if (progressBarIsVisible) {
- hide()
- } else if (systemServerAuthReason != NotRunning) {
- show()
- } else if (showIndicatorForDeviceEntry) {
- show()
- } else {
- hide()
- }
- }
- }
- }
+ applicationScope.launch {
+ sideFpsOverlayInteractor.get().isShowing.collect { isShowing: Boolean ->
+ if (isShowing) {
+ show()
+ } else {
+ hide()
}
}
+ }
}
- private var overlayView: View? = null
-
/** Show the side fingerprint sensor indicator */
private fun show() {
if (overlayView?.isAttachedToWindow == true) {
@@ -125,17 +80,10 @@ constructor(
)
return
}
-
overlayView = layoutInflater.get().inflate(R.layout.sidefps_view, null, false)
-
- val overlayViewModel =
- SideFpsOverlayViewModel(
- applicationContext,
- deviceEntrySideFpsOverlayInteractor.get(),
- displayStateInteractor.get(),
- sfpsSensorInteractor.get(),
- )
+ val overlayViewModel = sideFpsOverlayViewModel.get()
bind(overlayView!!, overlayViewModel, windowManager.get())
+
overlayView!!.visibility = View.INVISIBLE
Log.d(TAG, "show(): adding overlayView $overlayView")
windowManager.get().addView(overlayView, overlayViewModel.defaultOverlayViewParams)
@@ -161,6 +109,20 @@ constructor(
companion object {
private const val TAG = "SideFpsOverlayViewBinder"
+ private val accessibilityDelegate =
+ object : View.AccessibilityDelegate() {
+ override fun dispatchPopulateAccessibilityEvent(
+ host: View,
+ event: AccessibilityEvent
+ ): Boolean {
+ return if (event.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
+ true
+ } else {
+ super.dispatchPopulateAccessibilityEvent(host, event)
+ }
+ }
+ }
+
/** Binds overlayView (side fingerprint sensor indicator view) to SideFpsOverlayViewModel */
fun bind(
overlayView: View,
@@ -184,24 +146,7 @@ constructor(
overlayShowAnimator.start()
- it.setAccessibilityDelegate(
- object : View.AccessibilityDelegate() {
- override fun dispatchPopulateAccessibilityEvent(
- host: View,
- event: AccessibilityEvent
- ): Boolean {
- return if (
- event.getEventType() ===
- android.view.accessibility.AccessibilityEvent
- .TYPE_WINDOW_STATE_CHANGED
- ) {
- true
- } else {
- super.dispatchPopulateAccessibilityEvent(host, event)
- }
- }
- }
- )
+ it.accessibilityDelegate = accessibilityDelegate
repeatOnLifecycle(Lifecycle.State.STARTED) {
launch {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
index 168ba11309cc..85f221fa951e 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
@@ -78,11 +78,11 @@ import kotlinx.coroutines.launch
class PromptViewModel
@Inject
constructor(
- displayStateInteractor: DisplayStateInteractor,
+ private val displayStateInteractor: DisplayStateInteractor,
private val promptSelectorInteractor: PromptSelectorInteractor,
@Application private val context: Context,
- private val udfpsOverlayInteractor: UdfpsOverlayInteractor,
- private val biometricStatusInteractor: BiometricStatusInteractor,
+ udfpsOverlayInteractor: UdfpsOverlayInteractor,
+ biometricStatusInteractor: BiometricStatusInteractor,
private val udfpsUtils: UdfpsUtils,
private val iconProvider: IconProvider,
private val activityTaskManager: ActivityTaskManager,
@@ -135,11 +135,13 @@ constructor(
R.dimen.biometric_prompt_landscape_medium_horizontal_padding
)
+ val currentRotation: StateFlow<DisplayRotation> = displayStateInteractor.currentRotation
+
val udfpsOverlayParams: StateFlow<UdfpsOverlayParams> =
udfpsOverlayInteractor.udfpsOverlayParams
private val udfpsSensorBounds: Flow<Rect> =
- combine(udfpsOverlayParams, displayStateInteractor.currentRotation) { params, rotation ->
+ combine(udfpsOverlayParams, currentRotation) { params, rotation ->
val rotatedBounds = Rect(params.sensorBounds)
RotationUtils.rotateBounds(
rotatedBounds,
@@ -262,7 +264,7 @@ constructor(
_forceLargeSize,
promptKind,
displayStateInteractor.isLargeScreen,
- displayStateInteractor.currentRotation,
+ currentRotation,
modalities
) { forceLarge, promptKind, isLargeScreen, rotation, modalities ->
when {
@@ -454,7 +456,7 @@ constructor(
/** Padding for prompt UI elements */
val promptPadding: Flow<Rect> =
- combine(size, displayStateInteractor.currentRotation) { size, rotation ->
+ combine(size, currentRotation) { size, rotation ->
if (size != PromptSize.LARGE) {
val navBarInsets = Utils.getNavbarInsets(context)
if (rotation == DisplayRotation.ROTATION_90) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModel.kt
index c2a4ee36dec6..7c1984e506c9 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModel.kt
@@ -147,8 +147,7 @@ constructor(
_lottieBounds,
sensorLocation,
displayRotation,
- ) { bounds: Rect?, sensorLocation: SideFpsSensorLocation, displayRotation: DisplayRotation
- ->
+ ) { _: Rect?, sensorLocation: SideFpsSensorLocation, _: DisplayRotation ->
val topLeft = Point(sensorLocation.left, sensorLocation.top)
defaultOverlayViewParams.apply {
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlags.kt b/packages/SystemUI/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlags.kt
index a1111f68f1ee..d7a4863bde02 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlags.kt
@@ -21,6 +21,10 @@ import com.android.systemui.scene.shared.flag.SceneContainerFlag
object ComposeBouncerFlags {
+ /** @see [isComposeBouncerOrSceneContainerEnabled] */
+ val isEnabled: Boolean
+ get() = isComposeBouncerOrSceneContainerEnabled()
+
/**
* Returns `true` if the Compose bouncer is enabled or if the scene container framework is
* enabled; `false` otherwise.
diff --git a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
index db7ffc1bef79..037b6facc50d 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
@@ -48,6 +48,7 @@ import com.android.systemui.controls.ui.ControlsUiControllerImpl
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.DeviceControlsTile
import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
@@ -86,15 +87,16 @@ abstract class ControlsModule {
@IntoMap
@StringKey(DEVICE_CONTROLS_SPEC)
fun provideDeviceControlsTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
- QSTileConfig(
- tileSpec = TileSpec.create(DEVICE_CONTROLS_SPEC),
- uiConfig =
- QSTileUIConfig.Resource(
- iconRes = com.android.systemui.res.R.drawable.controls_icon,
- labelRes = com.android.systemui.res.R.string.quick_controls_title
- ),
- instanceId = uiEventLogger.getNewInstanceId(),
- )
+ QSTileConfig(
+ tileSpec = TileSpec.create(DEVICE_CONTROLS_SPEC),
+ uiConfig =
+ QSTileUIConfig.Resource(
+ iconRes = com.android.systemui.res.R.drawable.controls_icon,
+ labelRes = com.android.systemui.res.R.string.quick_controls_title
+ ),
+ instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.UTILITIES,
+ )
}
@Binds
@@ -115,12 +117,12 @@ abstract class ControlsModule {
@Binds
abstract fun provideSettingsManager(
- manager: ControlsSettingsRepositoryImpl
+ manager: ControlsSettingsRepositoryImpl
): ControlsSettingsRepository
@Binds
abstract fun provideDialogManager(
- manager: ControlsSettingsDialogManagerImpl
+ manager: ControlsSettingsDialogManagerImpl
): ControlsSettingsDialogManager
@Binds
@@ -141,8 +143,7 @@ abstract class ControlsModule {
repository: SelectedComponentRepositoryImpl
): SelectedComponentRepository
- @BindsOptionalOf
- abstract fun optionalPersistenceWrapper(): ControlsFavoritePersistenceWrapper
+ @BindsOptionalOf abstract fun optionalPersistenceWrapper(): ControlsFavoritePersistenceWrapper
@BindsOptionalOf
abstract fun provideControlsTileResourceConfiguration(): ControlsTileResourceConfiguration
@@ -157,23 +158,17 @@ abstract class ControlsModule {
@Binds
@IntoMap
@ClassKey(ControlsFavoritingActivity::class)
- abstract fun provideControlsFavoritingActivity(
- activity: ControlsFavoritingActivity
- ): Activity
+ abstract fun provideControlsFavoritingActivity(activity: ControlsFavoritingActivity): Activity
@Binds
@IntoMap
@ClassKey(ControlsEditingActivity::class)
- abstract fun provideControlsEditingActivity(
- activity: ControlsEditingActivity
- ): Activity
+ abstract fun provideControlsEditingActivity(activity: ControlsEditingActivity): Activity
@Binds
@IntoMap
@ClassKey(ControlsRequestDialog::class)
- abstract fun provideControlsRequestDialog(
- activity: ControlsRequestDialog
- ): Activity
+ abstract fun provideControlsRequestDialog(activity: ControlsRequestDialog): Activity
@Binds
@IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
index f6ac7a579140..a45ad157837b 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
@@ -38,6 +38,7 @@ import com.android.systemui.dreams.homecontrols.DreamServiceDelegateImpl;
import com.android.systemui.dreams.homecontrols.HomeControlsDreamService;
import com.android.systemui.qs.QsEventLogger;
import com.android.systemui.qs.pipeline.shared.TileSpec;
+import com.android.systemui.qs.shared.model.TileCategory;
import com.android.systemui.qs.tiles.viewmodel.QSTileConfig;
import com.android.systemui.qs.tiles.viewmodel.QSTilePolicy;
import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig;
@@ -196,6 +197,7 @@ public interface DreamModule {
R.drawable.ic_qs_screen_saver,
R.string.quick_settings_screensaver_label),
uiEventLogger.getNewInstanceId(),
+ TileCategory.UTILITIES,
tileSpec.getSpec(),
QSTilePolicy.NoRestrictions.INSTANCE
);
diff --git a/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduStatsInteractor.kt b/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduStatsInteractor.kt
index 3223433568b9..eb4eee204834 100644
--- a/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduStatsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduStatsInteractor.kt
@@ -16,11 +16,17 @@
package com.android.systemui.education.domain.interactor
+import com.android.systemui.contextualeducation.GestureType
+import com.android.systemui.contextualeducation.GestureType.ALL_APPS
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.contextualeducation.GestureType
+import com.android.systemui.inputdevice.data.repository.UserInputDeviceRepository
+import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType
+import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType.KEYBOARD
+import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType.TOUCHPAD
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
/**
@@ -39,12 +45,17 @@ class KeyboardTouchpadEduStatsInteractorImpl
@Inject
constructor(
@Background private val backgroundScope: CoroutineScope,
- private val contextualEducationInteractor: ContextualEducationInteractor
+ private val contextualEducationInteractor: ContextualEducationInteractor,
+ private val inputDeviceRepository: UserInputDeviceRepository,
) : KeyboardTouchpadEduStatsInteractor {
override fun incrementSignalCount(gestureType: GestureType) {
- // Todo: check if keyboard/touchpad is connected before update
- backgroundScope.launch { contextualEducationInteractor.incrementSignalCount(gestureType) }
+ backgroundScope.launch {
+ val targetDevice = getTargetDevice(gestureType)
+ if (isTargetDeviceConnected(targetDevice)) {
+ contextualEducationInteractor.incrementSignalCount(gestureType)
+ }
+ }
}
override fun updateShortcutTriggerTime(gestureType: GestureType) {
@@ -52,4 +63,24 @@ constructor(
contextualEducationInteractor.updateShortcutTriggerTime(gestureType)
}
}
+
+ private suspend fun isTargetDeviceConnected(deviceType: DeviceType): Boolean {
+ if (deviceType == KEYBOARD) {
+ return inputDeviceRepository.isAnyKeyboardConnectedForUser.first().isConnected
+ } else if (deviceType == TOUCHPAD) {
+ return inputDeviceRepository.isAnyTouchpadConnectedForUser.first().isConnected
+ }
+ return false
+ }
+
+ /**
+ * Keyboard shortcut education would be provided for All Apps. Touchpad gesture education would
+ * be provided for the rest of the gesture types (i.e. Home, Overview, Back). This method maps
+ * gesture to its target education device.
+ */
+ private fun getTargetDevice(gestureType: GestureType) =
+ when (gestureType) {
+ ALL_APPS -> KEYBOARD
+ else -> TOUCHPAD
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartable.kt
index 7ecacdc7cf16..092a25aa1cad 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartable.kt
@@ -16,9 +16,17 @@
package com.android.systemui.inputdevice.tutorial
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.os.UserHandle
import com.android.systemui.CoreStartable
+import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.inputdevice.tutorial.ui.TutorialNotificationCoordinator
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity
import com.android.systemui.shared.Flags.newTouchpadGesturesTutorial
import dagger.Lazy
import javax.inject.Inject
@@ -27,11 +35,35 @@ import javax.inject.Inject
@SysUISingleton
class KeyboardTouchpadTutorialCoreStartable
@Inject
-constructor(private val tutorialNotificationCoordinator: Lazy<TutorialNotificationCoordinator>) :
- CoreStartable {
+constructor(
+ private val tutorialNotificationCoordinator: Lazy<TutorialNotificationCoordinator>,
+ private val broadcastDispatcher: BroadcastDispatcher,
+ @Application private val applicationContext: Context,
+) : CoreStartable {
override fun start() {
if (newTouchpadGesturesTutorial()) {
tutorialNotificationCoordinator.get().start()
+ registerTutorialBroadcastReceiver()
}
}
+
+ private fun registerTutorialBroadcastReceiver() {
+ broadcastDispatcher.registerReceiver(
+ receiver =
+ object : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ applicationContext.startActivityAsUser(
+ Intent(
+ applicationContext,
+ KeyboardTouchpadTutorialActivity::class.java
+ ),
+ UserHandle.SYSTEM
+ )
+ }
+ },
+ filter = IntentFilter("com.android.systemui.action.KEYBOARD_TOUCHPAD_TUTORIAL"),
+ flags = Context.RECEIVER_EXPORTED,
+ user = UserHandle.ALL,
+ )
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
index 63f3d52b2d2d..dcca12f29287 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
@@ -82,6 +82,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithContent
+import androidx.compose.ui.focus.FocusDirection
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.geometry.CornerRadius
@@ -92,8 +93,12 @@ import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.input.key.Key
+import androidx.compose.ui.input.key.key
+import androidx.compose.ui.input.key.onKeyEvent
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.rememberNestedScrollInteropConnection
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
@@ -824,9 +829,18 @@ private fun ShortcutsSearchBar(onQueryChange: (String) -> Unit) {
// from the ViewModel.
var queryInternal by remember { mutableStateOf("") }
val focusRequester = remember { FocusRequester() }
+ val focusManager = LocalFocusManager.current
LaunchedEffect(Unit) { focusRequester.requestFocus() }
SearchBar(
- modifier = Modifier.fillMaxWidth().focusRequester(focusRequester),
+ modifier =
+ Modifier.fillMaxWidth().focusRequester(focusRequester).onKeyEvent {
+ if (it.key == Key.DirectionDown) {
+ focusManager.moveFocus(FocusDirection.Down)
+ return@onKeyEvent true
+ } else {
+ return@onKeyEvent false
+ }
+ },
colors = SearchBarDefaults.colors(containerColor = MaterialTheme.colorScheme.surfaceBright),
query = queryInternal,
active = false,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
index 362e016cc97c..df0f10acac1f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
@@ -71,6 +71,7 @@ import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.KeyguardIndicationController
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.phone.ScreenOffAnimationController
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator
import com.google.android.msdl.domain.MSDLPlayer
import dagger.Lazy
@@ -112,6 +113,7 @@ constructor(
private val clockInteractor: KeyguardClockInteractor,
private val keyguardViewMediator: KeyguardViewMediator,
private val deviceEntryUnlockTrackerViewBinder: Optional<DeviceEntryUnlockTrackerViewBinder>,
+ private val statusBarKeyguardViewManager: StatusBarKeyguardViewManager,
@Main private val mainDispatcher: CoroutineDispatcher,
private val msdlPlayer: MSDLPlayer,
) : CoreStartable {
@@ -220,6 +222,7 @@ constructor(
vibratorHelper,
falsingManager,
keyguardViewMediator,
+ statusBarKeyguardViewManager,
mainDispatcher,
msdlPlayer,
)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt
index 7801c00d83b8..60c53863535d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt
@@ -18,6 +18,7 @@
package com.android.systemui.keyguard.domain.interactor
import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
+import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlags
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
@@ -32,6 +33,7 @@ import com.android.systemui.scene.domain.resolver.NotifShadeSceneFamilyResolver
import com.android.systemui.scene.domain.resolver.QuickSettingsSceneFamilyResolver
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.util.kotlin.Utils.Companion.sampleFilter
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
@@ -44,6 +46,7 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterNot
+import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.stateIn
@@ -58,12 +61,14 @@ constructor(
transitionInteractor: KeyguardTransitionInteractor,
val dismissInteractor: KeyguardDismissInteractor,
@Application private val applicationScope: CoroutineScope,
- sceneInteractor: SceneInteractor,
- deviceEntryInteractor: DeviceEntryInteractor,
- quickSettingsSceneFamilyResolver: QuickSettingsSceneFamilyResolver,
- notifShadeSceneFamilyResolver: NotifShadeSceneFamilyResolver,
+ sceneInteractor: dagger.Lazy<SceneInteractor>,
+ deviceEntryInteractor: dagger.Lazy<DeviceEntryInteractor>,
+ quickSettingsSceneFamilyResolver: dagger.Lazy<QuickSettingsSceneFamilyResolver>,
+ notifShadeSceneFamilyResolver: dagger.Lazy<NotifShadeSceneFamilyResolver>,
powerInteractor: PowerInteractor,
alternateBouncerInteractor: AlternateBouncerInteractor,
+ keyguardInteractor: dagger.Lazy<KeyguardInteractor>,
+ shadeInteractor: dagger.Lazy<ShadeInteractor>,
) {
val dismissAction: Flow<DismissAction> = repository.dismissAction
@@ -98,15 +103,31 @@ constructor(
* device is unlocked. Else, false.
*/
private val isOnShadeWhileUnlocked: Flow<Boolean> =
- combine(
- sceneInteractor.currentScene,
- deviceEntryInteractor.isUnlocked,
- ) { scene, isUnlocked ->
- isUnlocked &&
- (quickSettingsSceneFamilyResolver.includesScene(scene) ||
- notifShadeSceneFamilyResolver.includesScene(scene))
+ if (SceneContainerFlag.isEnabled) {
+ combine(
+ sceneInteractor.get().currentScene,
+ deviceEntryInteractor.get().isUnlocked,
+ ) { scene, isUnlocked ->
+ isUnlocked &&
+ (quickSettingsSceneFamilyResolver.get().includesScene(scene) ||
+ notifShadeSceneFamilyResolver.get().includesScene(scene))
+ }
+ .distinctUntilChanged()
+ } else if (ComposeBouncerFlags.isOnlyComposeBouncerEnabled()) {
+ shadeInteractor.get().isAnyExpanded.sample(
+ keyguardInteractor.get().isKeyguardDismissible
+ ) { isAnyExpanded, isKeyguardDismissible ->
+ isAnyExpanded && isKeyguardDismissible
+ }
+ } else {
+ flow {
+ error(
+ "This should not be used when both SceneContainerFlag " +
+ "and ComposeBouncerFlag are disabled"
+ )
}
- .distinctUntilChanged()
+ }
+
val executeDismissAction: Flow<() -> KeyguardDone> =
merge(
finishedTransitionToGone,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardDismissActionBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardDismissActionBinder.kt
index 74a7262d7889..69cb6a92137f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardDismissActionBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardDismissActionBinder.kt
@@ -17,11 +17,11 @@ package com.android.systemui.keyguard.ui.binder
import com.android.keyguard.logging.KeyguardLogger
import com.android.systemui.CoreStartable
+import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlags
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.domain.interactor.KeyguardDismissActionInteractor
import com.android.systemui.log.core.LogLevel
-import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.util.kotlin.sample
import dagger.Lazy
import javax.inject.Inject
@@ -41,7 +41,7 @@ constructor(
) : CoreStartable {
override fun start() {
- if (!SceneContainerFlag.isEnabled) {
+ if (!ComposeBouncerFlags.isEnabled) {
return
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardDismissBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardDismissBinder.kt
index ac24591d69d7..b55f813a1f84 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardDismissBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardDismissBinder.kt
@@ -18,13 +18,12 @@ package com.android.systemui.keyguard.ui.binder
import com.android.keyguard.ViewMediatorCallback
import com.android.keyguard.logging.KeyguardLogger
import com.android.systemui.CoreStartable
+import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlags
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.flags.FeatureFlagsClassic
import com.android.systemui.keyguard.domain.interactor.KeyguardDismissInteractor
import com.android.systemui.keyguard.shared.model.KeyguardDone
import com.android.systemui.log.core.LogLevel
-import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.user.domain.interactor.SelectedUserInteractor
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -40,11 +39,10 @@ constructor(
private val viewMediatorCallback: ViewMediatorCallback,
@Application private val scope: CoroutineScope,
private val keyguardLogger: KeyguardLogger,
- private val featureFlags: FeatureFlagsClassic,
) : CoreStartable {
override fun start() {
- if (!SceneContainerFlag.isEnabled) {
+ if (!ComposeBouncerFlags.isEnabled) {
return
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt
index f2d39dabb1b5..ecfabc3e18ce 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt
@@ -18,13 +18,12 @@ package com.android.systemui.keyguard.ui.binder
import android.annotation.SuppressLint
import android.graphics.PointF
+import android.view.InputDevice
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.view.ViewPropertyAnimator
-import androidx.core.animation.CycleInterpolator
-import androidx.core.animation.ObjectAnimator
-import com.android.systemui.res.R
+import com.android.systemui.Flags
import com.android.systemui.animation.Expandable
import com.android.systemui.common.ui.view.rawDistanceFrom
import com.android.systemui.keyguard.ui.viewmodel.KeyguardQuickAffordanceViewModel
@@ -71,11 +70,10 @@ class KeyguardQuickAffordanceOnTouchListener(
// Moving too far while performing a long-press gesture cancels that
// gesture.
if (
- event
- .rawDistanceFrom(
- downDisplayCoords.x,
- downDisplayCoords.y,
- ) > ViewConfiguration.getTouchSlop()
+ event.rawDistanceFrom(
+ downDisplayCoords.x,
+ downDisplayCoords.y,
+ ) > ViewConfiguration.getTouchSlop()
) {
cancel()
}
@@ -151,10 +149,14 @@ class KeyguardQuickAffordanceOnTouchListener(
event: MotionEvent,
pointerIndex: Int = 0,
): Boolean {
- return when (event.getToolType(pointerIndex)) {
- MotionEvent.TOOL_TYPE_STYLUS -> true
- MotionEvent.TOOL_TYPE_MOUSE -> true
- else -> false
+ return if (Flags.nonTouchscreenDevicesBypassFalsing()) {
+ event.device?.supportsSource(InputDevice.SOURCE_TOUCHSCREEN) == false
+ } else {
+ when (event.getToolType(pointerIndex)) {
+ MotionEvent.TOOL_TYPE_STYLUS -> true
+ MotionEvent.TOOL_TYPE_MOUSE -> true
+ else -> false
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
index 5bb7b6425729..ed82159e6160 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
@@ -24,6 +24,8 @@ import android.graphics.Point
import android.graphics.Rect
import android.util.Log
import android.view.HapticFeedbackConstants
+import android.view.InputDevice
+import android.view.MotionEvent
import android.view.View
import android.view.View.OnLayoutChangeListener
import android.view.View.VISIBLE
@@ -41,6 +43,7 @@ import com.android.app.tracing.coroutines.launch
import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.jank.InteractionJankMonitor.CUJ_SCREEN_OFF_SHOW_AOD
import com.android.keyguard.AuthInteractionProperties
+import com.android.systemui.Flags
import com.android.systemui.Flags.msdlFeedback
import com.android.systemui.Flags.newAodTransition
import com.android.systemui.common.shared.model.Icon
@@ -73,6 +76,7 @@ import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.CrossFadeHelper
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.phone.ScreenOffAnimationController
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import com.android.systemui.temporarydisplay.ViewPriority
import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator
import com.android.systemui.temporarydisplay.chipbar.ChipbarInfo
@@ -115,6 +119,7 @@ object KeyguardRootViewBinder {
vibratorHelper: VibratorHelper?,
falsingManager: FalsingManager?,
keyguardViewMediator: KeyguardViewMediator?,
+ statusBarKeyguardViewManager: StatusBarKeyguardViewManager?,
mainImmediateDispatcher: CoroutineDispatcher,
msdlPlayer: MSDLPlayer?,
): DisposableHandle {
@@ -124,12 +129,30 @@ object KeyguardRootViewBinder {
if (KeyguardBottomAreaRefactor.isEnabled) {
disposables +=
view.onTouchListener { _, event ->
+ var consumed = false
if (falsingManager?.isFalseTap(FalsingManager.LOW_PENALTY) == false) {
+ // signifies a primary button click down has reached keyguardrootview
+ // we need to return true here otherwise an ACTION_UP will never arrive
+ if (Flags.nonTouchscreenDevicesBypassFalsing()) {
+ if (
+ event.action == MotionEvent.ACTION_DOWN &&
+ event.buttonState == MotionEvent.BUTTON_PRIMARY &&
+ !event.isTouchscreenSource()
+ ) {
+ consumed = true
+ } else if (
+ event.action == MotionEvent.ACTION_UP &&
+ !event.isTouchscreenSource()
+ ) {
+ statusBarKeyguardViewManager?.showBouncer(true)
+ consumed = true
+ }
+ }
viewModel.setRootViewLastTapPosition(
Point(event.x.toInt(), event.y.toInt())
)
}
- false
+ consumed
}
}
@@ -637,6 +660,10 @@ object KeyguardRootViewBinder {
}
}
+ private fun MotionEvent.isTouchscreenSource(): Boolean {
+ return device?.supportsSource(InputDevice.SOURCE_TOUCHSCREEN) == true
+ }
+
private fun ViewPropertyAnimator.animateInIconTranslation(): ViewPropertyAnimator =
setInterpolator(Interpolators.DECELERATE_QUINT).translationY(0f)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index f581a2e24546..0b8f7417a49d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -417,6 +417,7 @@ constructor(
null, // device entry haptics not required for preview mode
null, // falsing manager not required for preview mode
null, // keyguard view mediator is not required for preview mode
+ null, // primary bouncer interactor is not required for preview mode
mainDispatcher,
null,
)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt
index 8485a265fc70..1edfec8f9e68 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt
@@ -18,6 +18,7 @@ package com.android.systemui.keyguard.ui.viewmodel
import com.android.app.animation.Interpolators.EMPHASIZED_ACCELERATE
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
+import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlags
import com.android.systemui.keyguard.domain.interactor.KeyguardDismissActionInteractor
import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState
@@ -25,7 +26,6 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
import com.android.systemui.keyguard.shared.model.ScrimAlpha
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
-import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.SysuiStatusBarStateController
@@ -51,7 +51,7 @@ constructor(
) {
/** Common fade for scrim alpha values during *BOUNCER->GONE */
fun scrimAlpha(duration: Duration, fromState: KeyguardState): Flow<ScrimAlpha> {
- return if (SceneContainerFlag.isEnabled) {
+ return if (ComposeBouncerFlags.isEnabled) {
keyguardDismissActionInteractor
.get()
.willAnimateDismissActionOnLockscreen
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
index 8811908e1d45..17c678e79d8b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
@@ -17,6 +17,7 @@
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
+import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlags
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.domain.interactor.FromPrimaryBouncerTransitionInteractor.Companion.TO_GONE_DURATION
import com.android.systemui.keyguard.domain.interactor.KeyguardDismissActionInteractor
@@ -25,7 +26,6 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
import com.android.systemui.keyguard.shared.model.ScrimAlpha
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
-import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.statusbar.SysuiStatusBarStateController
import dagger.Lazy
import javax.inject.Inject
@@ -85,7 +85,7 @@ constructor(
/** Bouncer container alpha */
val bouncerAlpha: Flow<Float> =
- if (SceneContainerFlag.isEnabled) {
+ if (ComposeBouncerFlags.isEnabled) {
keyguardDismissActionInteractor
.get()
.willAnimateDismissActionOnLockscreen
@@ -110,7 +110,7 @@ constructor(
/** Lockscreen alpha */
val lockscreenAlpha: Flow<Float> =
- if (SceneContainerFlag.isEnabled) {
+ if (ComposeBouncerFlags.isEnabled) {
keyguardDismissActionInteractor
.get()
.willAnimateDismissActionOnLockscreen
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/SideFpsProgressBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/SideFpsProgressBarViewModel.kt
index c5909ed24c50..75e38714f1fa 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/SideFpsProgressBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/SideFpsProgressBarViewModel.kt
@@ -107,6 +107,8 @@ constructor(
}
}
+ // TODO(b/365182034): move to interactor, add as dependency of SideFpsOverlayInteractor when
+ // rest to unlock feature is implemented
val isVisible: Flow<Boolean> = _visible.asStateFlow()
val progress: Flow<Float> = _progress.asStateFlow()
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/BouncerTableLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/BouncerTableLog.kt
index 08df7db65af1..9f893e073cb1 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/BouncerTableLog.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/BouncerTableLog.kt
@@ -16,10 +16,7 @@
package com.android.systemui.log.dagger
-import java.lang.annotation.Documented
-import java.lang.annotation.Retention
-import java.lang.annotation.RetentionPolicy
import javax.inject.Qualifier
/** Logger for the primary and alternative bouncers. */
-@Qualifier @Documented @Retention(RetentionPolicy.RUNTIME) annotation class BouncerTableLog
+@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class BouncerTableLog
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index 498c34c03f2d..2053b53dba63 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -382,6 +382,16 @@ public class LogModule {
return factory.create("MediaLog", 20);
}
+ /**
+ * Provides a buffer for media device changes
+ */
+ @Provides
+ @SysUISingleton
+ @MediaDeviceLog
+ public static LogBuffer providesMediaDeviceLogBuffer(LogBufferFactory factory) {
+ return factory.create("MediaDeviceLog", 50);
+ }
+
/** Allows logging buffers to be tweaked via adb on debug builds but not on prod builds. */
@Provides
@SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/MediaDeviceLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/MediaDeviceLog.kt
new file mode 100644
index 000000000000..06bd26971232
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/MediaDeviceLog.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log.dagger
+
+import com.android.systemui.log.LogBuffer
+import javax.inject.Qualifier
+
+/** A [LogBuffer] for [com.android.systemui.media.controls.domain.pipeline.MediaDeviceLogger] */
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class MediaDeviceLog
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImpl.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImpl.kt
index 4ad437c50d61..84aae652795e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImpl.kt
@@ -70,6 +70,7 @@ import com.android.systemui.dump.DumpManager
import com.android.systemui.media.controls.domain.pipeline.MediaDataManager.Companion.isMediaNotification
import com.android.systemui.media.controls.domain.resume.MediaResumeListener
import com.android.systemui.media.controls.domain.resume.ResumeMediaBrowser
+import com.android.systemui.media.controls.shared.MediaLogger
import com.android.systemui.media.controls.shared.model.EXTRA_KEY_TRIGGER_SOURCE
import com.android.systemui.media.controls.shared.model.EXTRA_VALUE_TRIGGER_PERIODIC
import com.android.systemui.media.controls.shared.model.MediaAction
@@ -84,7 +85,7 @@ import com.android.systemui.media.controls.util.MediaControllerFactory
import com.android.systemui.media.controls.util.MediaDataUtils
import com.android.systemui.media.controls.util.MediaFlags
import com.android.systemui.media.controls.util.MediaUiEventLogger
-import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.media.controls.util.SmallHash
import com.android.systemui.plugins.BcSmartspaceDataPlugin
import com.android.systemui.res.R
import com.android.systemui.statusbar.NotificationMediaManager.isPlayingState
@@ -186,7 +187,6 @@ class LegacyMediaDataManagerImpl(
private val mediaDeviceManager: MediaDeviceManager,
mediaDataCombineLatest: MediaDataCombineLatest,
private val mediaDataFilter: LegacyMediaDataFilterImpl,
- private val activityStarter: ActivityStarter,
private val smartspaceMediaDataProvider: SmartspaceMediaDataProvider,
private var useMediaResumption: Boolean,
private val useQsMediaPlayer: Boolean,
@@ -197,6 +197,7 @@ class LegacyMediaDataManagerImpl(
private val smartspaceManager: SmartspaceManager?,
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
private val mediaDataLoader: dagger.Lazy<MediaDataLoader>,
+ private val mediaLogger: MediaLogger,
) : Dumpable, BcSmartspaceDataPlugin.SmartspaceTargetListener, MediaDataManager {
companion object {
@@ -273,7 +274,6 @@ class LegacyMediaDataManagerImpl(
mediaDeviceManager: MediaDeviceManager,
mediaDataCombineLatest: MediaDataCombineLatest,
mediaDataFilter: LegacyMediaDataFilterImpl,
- activityStarter: ActivityStarter,
smartspaceMediaDataProvider: SmartspaceMediaDataProvider,
clock: SystemClock,
tunerService: TunerService,
@@ -282,6 +282,7 @@ class LegacyMediaDataManagerImpl(
smartspaceManager: SmartspaceManager?,
keyguardUpdateMonitor: KeyguardUpdateMonitor,
mediaDataLoader: dagger.Lazy<MediaDataLoader>,
+ mediaLogger: MediaLogger,
) : this(
context,
// Loading bitmap for UMO background can take longer time, so it cannot run on the default
@@ -301,7 +302,6 @@ class LegacyMediaDataManagerImpl(
mediaDeviceManager,
mediaDataCombineLatest,
mediaDataFilter,
- activityStarter,
smartspaceMediaDataProvider,
Utils.useMediaResumption(context),
Utils.useQsMediaPlayer(context),
@@ -312,6 +312,7 @@ class LegacyMediaDataManagerImpl(
smartspaceManager,
keyguardUpdateMonitor,
mediaDataLoader,
+ mediaLogger,
)
private val appChangeReceiver =
@@ -564,6 +565,42 @@ class LegacyMediaDataManagerImpl(
val resumeAction: Runnable? = currentEntry?.resumeAction
val hasCheckedForResume = currentEntry?.hasCheckedForResume == true
val active = currentEntry?.active ?: true
+ val mediaController = mediaControllerFactory.create(result.token!!)
+
+ val mediaData =
+ MediaData(
+ userId = sbn.normalizedUserId,
+ initialized = true,
+ app = result.appName,
+ appIcon = result.appIcon,
+ artist = result.artist,
+ song = result.song,
+ artwork = result.artworkIcon,
+ actions = result.actionIcons,
+ actionsToShowInCompact = result.actionsToShowInCompact,
+ semanticActions = result.semanticActions,
+ packageName = sbn.packageName,
+ token = result.token,
+ clickIntent = result.clickIntent,
+ device = result.device,
+ active = active,
+ resumeAction = resumeAction,
+ playbackLocation = result.playbackLocation,
+ notificationKey = key,
+ hasCheckedForResume = hasCheckedForResume,
+ isPlaying = result.isPlaying,
+ isClearable = !sbn.isOngoing,
+ lastActive = lastActive,
+ createdTimestampMillis = createdTimestampMillis,
+ instanceId = instanceId,
+ appUid = result.appUid,
+ isExplicit = result.isExplicit,
+ )
+
+ if (isSameMediaData(context, mediaController, mediaData, currentEntry)) {
+ mediaLogger.logDuplicateMediaNotification(key)
+ return@withContext
+ }
// We need to log the correct media added.
if (isNewlyActiveEntry) {
@@ -583,40 +620,7 @@ class LegacyMediaDataManagerImpl(
)
}
- withContext(mainDispatcher) {
- onMediaDataLoaded(
- key,
- oldKey,
- MediaData(
- userId = sbn.normalizedUserId,
- initialized = true,
- app = result.appName,
- appIcon = result.appIcon,
- artist = result.artist,
- song = result.song,
- artwork = result.artworkIcon,
- actions = result.actionIcons,
- actionsToShowInCompact = result.actionsToShowInCompact,
- semanticActions = result.semanticActions,
- packageName = sbn.packageName,
- token = result.token,
- clickIntent = result.clickIntent,
- device = result.device,
- active = active,
- resumeAction = resumeAction,
- playbackLocation = result.playbackLocation,
- notificationKey = key,
- hasCheckedForResume = hasCheckedForResume,
- isPlaying = result.isPlaying,
- isClearable = !sbn.isOngoing,
- lastActive = lastActive,
- createdTimestampMillis = createdTimestampMillis,
- instanceId = instanceId,
- appUid = result.appUid,
- isExplicit = result.isExplicit,
- )
- )
- }
+ withContext(mainDispatcher) { onMediaDataLoaded(key, oldKey, mediaData) }
}
/** Add a listener for changes in this class */
@@ -1100,6 +1104,47 @@ class LegacyMediaDataManagerImpl(
val instanceId = currentEntry?.instanceId ?: logger.getNewInstanceId()
val appUid = appInfo?.uid ?: Process.INVALID_UID
+ val lastActive = systemClock.elapsedRealtime()
+ val createdTimestampMillis = currentEntry?.createdTimestampMillis ?: 0L
+ val resumeAction: Runnable? = mediaEntries[key]?.resumeAction
+ val hasCheckedForResume = mediaEntries[key]?.hasCheckedForResume == true
+ val active = mediaEntries[key]?.active ?: true
+ var mediaData =
+ MediaData(
+ sbn.normalizedUserId,
+ true,
+ appName,
+ smallIcon,
+ artist,
+ song,
+ artWorkIcon,
+ actionIcons,
+ actionsToShowCollapsed,
+ semanticActions,
+ sbn.packageName,
+ token,
+ notif.contentIntent,
+ device,
+ active,
+ resumeAction = resumeAction,
+ playbackLocation = playbackLocation,
+ notificationKey = key,
+ hasCheckedForResume = hasCheckedForResume,
+ isPlaying = isPlaying,
+ isClearable = !sbn.isOngoing,
+ lastActive = lastActive,
+ createdTimestampMillis = createdTimestampMillis,
+ instanceId = instanceId,
+ appUid = appUid,
+ isExplicit = isExplicit,
+ smartspaceId = SmallHash.hash(appUid + systemClock.currentTimeMillis().toInt()),
+ )
+
+ if (isSameMediaData(context, mediaController, mediaData, currentEntry)) {
+ mediaLogger.logDuplicateMediaNotification(key)
+ return
+ }
+
if (isNewlyActiveEntry) {
logSingleVsMultipleMediaAdded(appUid, sbn.packageName, instanceId)
logger.logActiveMediaAdded(appUid, sbn.packageName, instanceId, playbackLocation)
@@ -1107,44 +1152,17 @@ class LegacyMediaDataManagerImpl(
logger.logPlaybackLocationChange(appUid, sbn.packageName, instanceId, playbackLocation)
}
- val lastActive = systemClock.elapsedRealtime()
- val createdTimestampMillis = currentEntry?.createdTimestampMillis ?: 0L
foregroundExecutor.execute {
- val resumeAction: Runnable? = mediaEntries[key]?.resumeAction
- val hasCheckedForResume = mediaEntries[key]?.hasCheckedForResume == true
- val active = mediaEntries[key]?.active ?: true
- onMediaDataLoaded(
- key,
- oldKey,
- MediaData(
- sbn.normalizedUserId,
- true,
- appName,
- smallIcon,
- artist,
- song,
- artWorkIcon,
- actionIcons,
- actionsToShowCollapsed,
- semanticActions,
- sbn.packageName,
- token,
- notif.contentIntent,
- device,
- active,
- resumeAction = resumeAction,
- playbackLocation = playbackLocation,
- notificationKey = key,
- hasCheckedForResume = hasCheckedForResume,
- isPlaying = isPlaying,
- isClearable = !sbn.isOngoing,
- lastActive = lastActive,
- createdTimestampMillis = createdTimestampMillis,
- instanceId = instanceId,
- appUid = appUid,
- isExplicit = isExplicit,
+ val oldResumeAction: Runnable? = mediaEntries[key]?.resumeAction
+ val oldHasCheckedForResume = mediaEntries[key]?.hasCheckedForResume == true
+ val oldActive = mediaEntries[key]?.active ?: true
+ mediaData =
+ mediaData.copy(
+ resumeAction = oldResumeAction,
+ hasCheckedForResume = oldHasCheckedForResume,
+ active = oldActive
)
- )
+ onMediaDataLoaded(key, oldKey, mediaData)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceLogger.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceLogger.kt
new file mode 100644
index 000000000000..f886166b986b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceLogger.kt
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.controls.domain.pipeline
+
+import android.media.session.MediaController
+import com.android.settingslib.media.MediaDevice
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.log.dagger.MediaDeviceLog
+import com.android.systemui.media.controls.shared.model.MediaDeviceData
+import javax.inject.Inject
+
+/** A [LogBuffer] for media device changes */
+class MediaDeviceLogger @Inject constructor(@MediaDeviceLog private val buffer: LogBuffer) {
+
+ fun logBroadcastEvent(event: String, reason: Int, broadcastId: Int) {
+ buffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ str1 = event
+ int1 = reason
+ int2 = broadcastId
+ },
+ { "$str1, reason = $int1, broadcastId = $int2" }
+ )
+ }
+
+ fun logBroadcastEvent(event: String, reason: Int) {
+ buffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ str1 = event
+ int1 = reason
+ },
+ { "$str1, reason = $int1" }
+ )
+ }
+
+ fun logBroadcastMetadataChanged(broadcastId: Int, metadata: String) {
+ buffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ int1 = broadcastId
+ str1 = metadata
+ },
+ { "onBroadcastMetadataChanged, broadcastId = $int1, metadata = $str1" }
+ )
+ }
+
+ fun logNewDeviceName(name: String?) {
+ buffer.log(TAG, LogLevel.DEBUG, { str1 = name }, { "New device name $str1" })
+ }
+
+ fun logLocalDevice(sassDevice: MediaDeviceData?, connectedDevice: MediaDeviceData?) {
+ buffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ str1 = sassDevice?.name?.toString()
+ str2 = connectedDevice?.name?.toString()
+ },
+ { "Local device: $str1 or $str2" }
+ )
+ }
+
+ fun logRemoteDevice(routingSessionName: CharSequence?, connectedDevice: MediaDeviceData?) {
+ buffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ str1 = routingSessionName?.toString()
+ str2 = connectedDevice?.name?.toString()
+ },
+ { "Remote device: $str1 or $str2 or unknown" }
+ )
+ }
+
+ fun logDeviceName(
+ device: MediaDevice?,
+ controller: MediaController?,
+ routingSessionName: CharSequence?,
+ selectedRouteName: CharSequence?
+ ) {
+ buffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ str1 = "device $device, controller: $controller"
+ str2 = routingSessionName?.toString()
+ str3 = selectedRouteName?.toString()
+ },
+ { "$str1, routingSession $str2 or selected route $str3" }
+ )
+ }
+
+ companion object {
+ private const val TAG = "MediaDeviceLog"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceManager.kt
index a193f7f8f498..49b53c2d78ae 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceManager.kt
@@ -71,6 +71,7 @@ constructor(
private val localBluetoothManager: Lazy<LocalBluetoothManager?>,
@Main private val fgExecutor: Executor,
@Background private val bgExecutor: Executor,
+ private val logger: MediaDeviceLogger,
) : MediaDataManager.Listener {
private val listeners: MutableSet<Listener> = mutableSetOf()
@@ -281,59 +282,38 @@ constructor(
}
override fun onBroadcastStarted(reason: Int, broadcastId: Int) {
- if (DEBUG) {
- Log.d(TAG, "onBroadcastStarted(), reason = $reason , broadcastId = $broadcastId")
- }
+ logger.logBroadcastEvent("onBroadcastStarted", reason, broadcastId)
updateCurrent()
}
override fun onBroadcastStartFailed(reason: Int) {
- if (DEBUG) {
- Log.d(TAG, "onBroadcastStartFailed(), reason = $reason")
- }
+ logger.logBroadcastEvent("onBroadcastStartFailed", reason)
}
override fun onBroadcastMetadataChanged(
broadcastId: Int,
metadata: BluetoothLeBroadcastMetadata
) {
- if (DEBUG) {
- Log.d(
- TAG,
- "onBroadcastMetadataChanged(), broadcastId = $broadcastId , " +
- "metadata = $metadata"
- )
- }
+ logger.logBroadcastMetadataChanged(broadcastId, metadata.toString())
updateCurrent()
}
override fun onBroadcastStopped(reason: Int, broadcastId: Int) {
- if (DEBUG) {
- Log.d(TAG, "onBroadcastStopped(), reason = $reason , broadcastId = $broadcastId")
- }
+ logger.logBroadcastEvent("onBroadcastStopped", reason, broadcastId)
updateCurrent()
}
override fun onBroadcastStopFailed(reason: Int) {
- if (DEBUG) {
- Log.d(TAG, "onBroadcastStopFailed(), reason = $reason")
- }
+ logger.logBroadcastEvent("onBroadcastStopFailed", reason)
}
override fun onBroadcastUpdated(reason: Int, broadcastId: Int) {
- if (DEBUG) {
- Log.d(TAG, "onBroadcastUpdated(), reason = $reason , broadcastId = $broadcastId")
- }
+ logger.logBroadcastEvent("onBroadcastUpdated", reason, broadcastId)
updateCurrent()
}
override fun onBroadcastUpdateFailed(reason: Int, broadcastId: Int) {
- if (DEBUG) {
- Log.d(
- TAG,
- "onBroadcastUpdateFailed(), reason = $reason , " + "broadcastId = $broadcastId"
- )
- }
+ logger.logBroadcastEvent("onBroadcastUpdateFailed", reason, broadcastId)
}
override fun onPlaybackStarted(reason: Int, broadcastId: Int) {}
@@ -381,12 +361,16 @@ constructor(
name = context.getString(R.string.media_seamless_other_device),
showBroadcastButton = false
)
+ logger.logRemoteDevice(routingSession?.name, connectedDevice)
} else {
// Prefer SASS if available when playback is local.
- activeDevice = getSassDevice() ?: connectedDevice
+ val sassDevice = getSassDevice()
+ activeDevice = sassDevice ?: connectedDevice
+ logger.logLocalDevice(sassDevice, connectedDevice)
}
current = activeDevice ?: EMPTY_AND_DISABLED_MEDIA_DEVICE_DATA
+ logger.logNewDeviceName(current?.name?.toString())
} else {
val aboutToConnect = aboutToConnectDeviceOverride
if (
@@ -407,9 +391,7 @@ constructor(
val enabled = device != null && (controller == null || routingSession != null)
val name = getDeviceName(device, routingSession)
- if (DEBUG) {
- Log.d(TAG, "new device name $name")
- }
+ logger.logNewDeviceName(name)
current =
MediaDeviceData(
enabled,
@@ -463,14 +445,12 @@ constructor(
): String? {
val selectedRoutes = routingSession?.let { mr2manager.get().getSelectedRoutes(it) }
- if (DEBUG) {
- Log.d(
- TAG,
- "device is $device, controller $controller," +
- " routingSession ${routingSession?.name}" +
- " or ${selectedRoutes?.firstOrNull()?.name}"
- )
- }
+ logger.logDeviceName(
+ device,
+ controller,
+ routingSession?.name,
+ selectedRoutes?.firstOrNull()?.name
+ )
if (controller == null) {
// In resume state, we don't have a controller - just use the device name
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/resume/MediaResumeListener.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/resume/MediaResumeListener.kt
index e4047e5f96c5..9ee59d1875a6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/resume/MediaResumeListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/resume/MediaResumeListener.kt
@@ -80,6 +80,7 @@ constructor(
field?.disconnect()
field = value
}
+
private var currentUserId: Int = context.userId
@VisibleForTesting
@@ -89,7 +90,7 @@ constructor(
if (Intent.ACTION_USER_UNLOCKED == intent.action) {
val userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1)
if (userId == currentUserId) {
- loadMediaResumptionControls()
+ backgroundExecutor.execute { loadMediaResumptionControls() }
}
}
}
@@ -254,15 +255,15 @@ constructor(
if (data.resumeAction == null && !data.hasCheckedForResume && isEligibleForResume) {
// TODO also check for a media button receiver intended for restarting (b/154127084)
// Set null action to prevent additional attempts to connect
- mediaDataManager.setResumeAction(key, null)
- Log.d(TAG, "Checking for service component for " + data.packageName)
- val pm = context.packageManager
- val serviceIntent = Intent(MediaBrowserService.SERVICE_INTERFACE)
- val resumeInfo = pm.queryIntentServicesAsUser(serviceIntent, 0, currentUserId)
+ backgroundExecutor.execute {
+ mediaDataManager.setResumeAction(key, null)
+ Log.d(TAG, "Checking for service component for " + data.packageName)
+ val pm = context.packageManager
+ val serviceIntent = Intent(MediaBrowserService.SERVICE_INTERFACE)
+ val resumeInfo = pm.queryIntentServicesAsUser(serviceIntent, 0, currentUserId)
- val inf = resumeInfo?.filter { it.serviceInfo.packageName == data.packageName }
- if (inf != null && inf.size > 0) {
- backgroundExecutor.execute {
+ val inf = resumeInfo?.filter { it.serviceInfo.packageName == data.packageName }
+ if (inf != null && inf.size > 0) {
tryUpdateResumptionList(key, inf!!.get(0).componentInfo.componentName)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModel.kt
index cef1e69e7b6a..2a9fe8314349 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModel.kt
@@ -32,6 +32,7 @@ import androidx.annotation.WorkerThread
import androidx.core.view.GestureDetectorCompat
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
+import com.android.systemui.Flags
import com.android.systemui.classifier.Classifier.MEDIA_SEEKBAR
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.plugins.FalsingManager
@@ -102,9 +103,11 @@ constructor(
}
_progress.postValue(value)
}
+
private val _progress = MutableLiveData<Progress>().apply { postValue(_data) }
val progress: LiveData<Progress>
get() = _progress
+
private var controller: MediaController? = null
set(value) {
if (field?.sessionToken != value?.sessionToken) {
@@ -113,6 +116,7 @@ constructor(
field = value
}
}
+
private var playbackState: PlaybackState? = null
private var callback =
object : MediaController.Callback() {
@@ -128,6 +132,15 @@ constructor(
override fun onSessionDestroyed() {
clearController()
}
+
+ override fun onMetadataChanged(metadata: MediaMetadata?) {
+ if (!Flags.mediaControlsPostsOptimization()) return
+
+ val (enabled, duration) = getEnabledStateAndDuration(metadata)
+ if (_data.duration != duration) {
+ _data = _data.copy(enabled = enabled, duration = duration)
+ }
+ }
}
private var cancel: Runnable? = null
@@ -233,22 +246,13 @@ constructor(
fun updateController(mediaController: MediaController?) {
controller = mediaController
playbackState = controller?.playbackState
- val mediaMetadata = controller?.metadata
+ val (enabled, duration) = getEnabledStateAndDuration(controller?.metadata)
val seekAvailable = ((playbackState?.actions ?: 0L) and PlaybackState.ACTION_SEEK_TO) != 0L
val position = playbackState?.position?.toInt()
- val duration = mediaMetadata?.getLong(MediaMetadata.METADATA_KEY_DURATION)?.toInt() ?: 0
val playing =
NotificationMediaManager.isPlayingState(
playbackState?.state ?: PlaybackState.STATE_NONE
)
- val enabled =
- if (
- playbackState == null ||
- playbackState?.getState() == PlaybackState.STATE_NONE ||
- (duration <= 0)
- )
- false
- else true
_data = Progress(enabled, seekAvailable, playing, scrubbing, position, duration, listening)
checkIfPollingNeeded()
}
@@ -368,6 +372,16 @@ constructor(
}
}
+ /** returns a pair of whether seekbar is enabled and the duration of media. */
+ private fun getEnabledStateAndDuration(metadata: MediaMetadata?): Pair<Boolean, Int> {
+ val duration = metadata?.getLong(MediaMetadata.METADATA_KEY_DURATION)?.toInt() ?: 0
+ val enabled =
+ !(playbackState == null ||
+ playbackState?.state == PlaybackState.STATE_NONE ||
+ (duration <= 0))
+ return Pair(enabled, duration)
+ }
+
/**
* This method specifies if user made a bad seekbar grab or not. If the vertical distance from
* first touch on seekbar is more than the horizontal distance, this means that the seekbar grab
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
index 18c6f53630a4..4251b81226b3 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
@@ -307,7 +307,7 @@ public class MediaProjectionPermissionActivity extends Activity {
private void setUpDialog(AlertDialog dialog) {
SystemUIDialog.registerDismissListener(dialog);
- SystemUIDialog.applyFlags(dialog);
+ SystemUIDialog.applyFlags(dialog, /* showWhenLocked= */ false);
SystemUIDialog.setDialogSize(dialog);
dialog.setOnCancelListener(this::onDialogDismissedOrCancelled);
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
index e44069f78ee3..b3c697e06a92 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
@@ -425,6 +425,18 @@ public class TaskbarDelegate implements CommandQueue.Callbacks,
}
}
+ private void appTransitionPending(boolean pending) {
+ if (mOverviewProxyService.getProxy() == null) {
+ return;
+ }
+
+ try {
+ mOverviewProxyService.getProxy().appTransitionPending(pending);
+ } catch (RemoteException e) {
+ Log.e(TAG, "appTransitionPending() failed, pending: " + pending, e);
+ }
+ }
+
@Override
public void setImeWindowStatus(int displayId, @ImeWindowVisibility int vis,
@BackDispositionMode int backDisposition, boolean showImeSwitcher) {
@@ -533,6 +545,21 @@ public class TaskbarDelegate implements CommandQueue.Callbacks,
}
}
+ @Override
+ public void appTransitionPending(int displayId, boolean forced) {
+ appTransitionPending(true);
+ }
+
+ @Override
+ public void appTransitionCancelled(int displayId) {
+ appTransitionPending(false);
+ }
+
+ @Override
+ public void appTransitionFinished(int displayId) {
+ appTransitionPending(false);
+ }
+
private void clearTransient() {
if (mTaskbarTransientShowing) {
mTaskbarTransientShowing = false;
diff --git a/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt b/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt
index 3a8fe7198ebd..ef1f8341cb15 100644
--- a/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt
@@ -19,6 +19,7 @@ package com.android.systemui.qrcodescanner.dagger
import com.android.systemui.Flags
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.QRCodeScannerTile
import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
@@ -51,7 +52,7 @@ interface QRCodeScannerModule {
@IntoMap
@StringKey(QR_CODE_SCANNER_TILE_SPEC)
fun provideQrCodeScannerAvailabilityInteractor(
- impl: QRCodeScannerTileDataInteractor
+ impl: QRCodeScannerTileDataInteractor
): QSTileAvailabilityInteractor
companion object {
@@ -69,6 +70,7 @@ interface QRCodeScannerModule {
labelRes = R.string.qr_code_scanner_title,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.UTILITIES,
)
/** Inject QR Code Scanner Tile into tileViewModelMap in QSModule. */
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/IconAndNameCustomRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/IconAndNameCustomRepository.kt
index 28c1fbf2007d..2f054b0a82c0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/IconAndNameCustomRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/IconAndNameCustomRepository.kt
@@ -24,10 +24,10 @@ import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.qs.panels.shared.model.EditTileData
import com.android.systemui.qs.pipeline.data.repository.InstalledTilesComponentRepository
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.settings.UserTracker
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
-import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext
@SysUISingleton
@@ -60,6 +60,7 @@ constructor(
Icon.Loaded(icon, ContentDescription.Loaded(label.toString())),
Text.Loaded(label.toString()),
Text.Loaded(appName.toString()),
+ TileCategory.PROVIDED_BY_APP,
)
} else {
null
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractor.kt
index 3b29422ccfc3..a2cee3b68d49 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractor.kt
@@ -24,6 +24,7 @@ import com.android.systemui.qs.panels.data.repository.IconAndNameCustomRepositor
import com.android.systemui.qs.panels.data.repository.StockTilesRepository
import com.android.systemui.qs.panels.domain.model.EditTilesModel
import com.android.systemui.qs.panels.shared.model.EditTileData
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider
import javax.inject.Inject
@@ -53,6 +54,7 @@ constructor(
),
Text.Resource(config.uiConfig.labelRes),
null,
+ category = config.category,
)
} else {
EditTileData(
@@ -62,7 +64,8 @@ constructor(
ContentDescription.Loaded(it.spec)
),
Text.Loaded(it.spec),
- null
+ null,
+ category = TileCategory.UNKNOWN,
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/EditTileData.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/EditTileData.kt
index 8b70bb9f9e23..b153ef7e8a62 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/EditTileData.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/EditTileData.kt
@@ -19,12 +19,14 @@ package com.android.systemui.qs.panels.shared.model
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.shared.model.Text
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
data class EditTileData(
val tileSpec: TileSpec,
val icon: Icon,
val label: Text,
val appName: Text?,
+ val category: TileCategory,
) {
init {
check(
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt
index 24af09d62313..93037d1d2572 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt
@@ -34,6 +34,7 @@ import androidx.compose.animation.graphics.vector.AnimatedImageVector
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.LocalOverscrollConfiguration
+import androidx.compose.foundation.background
import androidx.compose.foundation.basicMarquee
import androidx.compose.foundation.border
import androidx.compose.foundation.combinedClickable
@@ -95,6 +96,8 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.compose.ui.util.fastMap
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.animation.Expandable
import com.android.compose.modifiers.background
@@ -115,6 +118,7 @@ import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
import com.android.systemui.qs.panels.ui.viewmodel.toUiState
import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.groupAndSort
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.res.R
import java.util.function.Supplier
@@ -472,31 +476,39 @@ private fun AvailableTileGrid(
onClick: (TileSpec) -> Unit,
dragAndDropState: DragAndDropState,
) {
- // Available tiles aren't visible during drag and drop, so the row isn't needed
- val (otherTilesStock, otherTilesCustom) =
- tiles.map { TileGridCell(it, 0) }.partition { it.tile.appName == null }
val availableTileHeight = tileHeight(true)
val availableGridHeight = gridHeight(tiles.size, availableTileHeight, columns, tilePadding)
+ // Available tiles aren't visible during drag and drop, so the row isn't needed
+ val groupedTiles =
+ remember(tiles.fastMap { it.tile.category }, tiles.fastMap { it.tile.label }) {
+ groupAndSort(tiles.fastMap { TileGridCell(it, 0) })
+ }
+ val labelColors = TileDefaults.inactiveTileColors()
// Available tiles
TileLazyGrid(
modifier = Modifier.height(availableGridHeight).testTag(AVAILABLE_TILES_GRID_TEST_TAG),
columns = GridCells.Fixed(columns)
) {
- editTiles(
- otherTilesStock,
- ClickAction.ADD,
- onClick,
- dragAndDropState = dragAndDropState,
- showLabels = true,
- )
- editTiles(
- otherTilesCustom,
- ClickAction.ADD,
- onClick,
- dragAndDropState = dragAndDropState,
- showLabels = true,
- )
+ groupedTiles.forEach { category, tiles ->
+ stickyHeader {
+ Text(
+ text = category.label.load() ?: "",
+ fontSize = 20.sp,
+ color = labelColors.label,
+ modifier =
+ Modifier.background(Color.Black)
+ .padding(start = 16.dp, bottom = 8.dp, top = 8.dp)
+ )
+ }
+ editTiles(
+ tiles,
+ ClickAction.ADD,
+ onClick,
+ dragAndDropState = dragAndDropState,
+ showLabels = true,
+ )
+ }
}
}
@@ -618,7 +630,7 @@ fun EditTile(
showLabels: Boolean,
modifier: Modifier = Modifier,
) {
- val label = tileViewModel.label.load() ?: tileViewModel.tileSpec.spec
+ val label = tileViewModel.label.text
val colors = TileDefaults.inactiveTileColors()
TileContainer(
@@ -638,7 +650,7 @@ fun EditTile(
} else {
LargeTileContent(
label = label,
- secondaryLabel = tileViewModel.appName?.load(),
+ secondaryLabel = tileViewModel.appName?.text,
icon = tileViewModel.icon,
colors = colors,
iconShape = RoundedCornerShape(TileDefaults.InactiveCornerRadius),
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/model/TileGridCell.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/model/TileGridCell.kt
index 8ca8de762772..08ee856a0ec6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/model/TileGridCell.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/model/TileGridCell.kt
@@ -21,6 +21,7 @@ import androidx.compose.runtime.Immutable
import com.android.systemui.qs.panels.shared.model.SizedTile
import com.android.systemui.qs.panels.shared.model.splitInRowsSequence
import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
+import com.android.systemui.qs.shared.model.CategoryAndName
/** Represents an item from a grid associated with a row and a span */
interface GridCell {
@@ -38,7 +39,7 @@ data class TileGridCell(
override val row: Int,
override val width: Int,
override val span: GridItemSpan = GridItemSpan(width)
-) : GridCell, SizedTile<EditTileViewModel> {
+) : GridCell, SizedTile<EditTileViewModel>, CategoryAndName by tile {
val key: String = "${tile.tileSpec.spec}-$row"
constructor(
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
index 42715be6f6c0..4a8aa83e7d4e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
@@ -16,6 +16,9 @@
package com.android.systemui.qs.panels.ui.viewmodel
+import android.content.Context
+import androidx.compose.ui.util.fastMap
+import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.qs.panels.domain.interactor.EditTilesListInteractor
@@ -27,6 +30,7 @@ import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor
import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor.Companion.POSITION_AT_END
import com.android.systemui.qs.pipeline.domain.interactor.MinimumTilesInteractor
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.util.kotlin.emitOnStart
import javax.inject.Inject
import javax.inject.Named
import kotlinx.coroutines.CoroutineScope
@@ -35,6 +39,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
@@ -49,6 +54,8 @@ constructor(
private val currentTilesInteractor: CurrentTilesInteractor,
private val tilesAvailabilityInteractor: TilesAvailabilityInteractor,
private val minTilesInteractor: MinimumTilesInteractor,
+ private val configurationInteractor: ConfigurationInteractor,
+ @Application private val applicationContext: Context,
@Named("Default") private val defaultGridLayout: GridLayout,
@Application private val applicationScope: CoroutineScope,
gridLayoutTypeInteractor: GridLayoutTypeInteractor,
@@ -99,38 +106,45 @@ constructor(
.map { it.tileSpec }
.minus(currentTilesInteractor.currentTilesSpecs.toSet())
)
- currentTilesInteractor.currentTiles.map { tiles ->
- val currentSpecs = tiles.map { it.spec }
- val canRemoveTiles = currentSpecs.size > minimumTiles
- val allTiles = editTilesData.stockTiles + editTilesData.customTiles
- val allTilesMap = allTiles.associate { it.tileSpec to it }
- val currentTiles = currentSpecs.map { allTilesMap.get(it) }.filterNotNull()
- val nonCurrentTiles = allTiles.filter { it.tileSpec !in currentSpecs }
-
- (currentTiles + nonCurrentTiles)
- .filterNot { it.tileSpec in unavailable }
- .map {
- val current = it.tileSpec in currentSpecs
- val availableActions = buildSet {
- if (current) {
- add(AvailableEditActions.MOVE)
- if (canRemoveTiles) {
- add(AvailableEditActions.REMOVE)
+ currentTilesInteractor.currentTiles
+ .map { tiles ->
+ val currentSpecs = tiles.map { it.spec }
+ val canRemoveTiles = currentSpecs.size > minimumTiles
+ val allTiles = editTilesData.stockTiles + editTilesData.customTiles
+ val allTilesMap = allTiles.associate { it.tileSpec to it }
+ val currentTiles = currentSpecs.map { allTilesMap.get(it) }.filterNotNull()
+ val nonCurrentTiles = allTiles.filter { it.tileSpec !in currentSpecs }
+
+ (currentTiles + nonCurrentTiles)
+ .filterNot { it.tileSpec in unavailable }
+ .map {
+ val current = it.tileSpec in currentSpecs
+ val availableActions = buildSet {
+ if (current) {
+ add(AvailableEditActions.MOVE)
+ if (canRemoveTiles) {
+ add(AvailableEditActions.REMOVE)
+ }
+ } else {
+ add(AvailableEditActions.ADD)
}
- } else {
- add(AvailableEditActions.ADD)
}
+ UnloadedEditTileViewModel(
+ it.tileSpec,
+ it.icon,
+ it.label,
+ it.appName,
+ current,
+ availableActions,
+ it.category,
+ )
}
- EditTileViewModel(
- it.tileSpec,
- it.icon,
- it.label,
- it.appName,
- current,
- availableActions
- )
- }
- }
+ }
+ .combine(configurationInteractor.onAnyConfigurationChange.emitOnStart()) {
+ tiles,
+ _ ->
+ tiles.fastMap { it.load(applicationContext) }
+ }
} else {
emptyFlow()
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditTileViewModel.kt
index a4c86381b785..ee12736f6db4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditTileViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditTileViewModel.kt
@@ -16,9 +16,15 @@
package com.android.systemui.qs.panels.ui.viewmodel
+import android.content.Context
+import androidx.compose.runtime.Immutable
+import androidx.compose.ui.text.AnnotatedString
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.shared.model.Text
+import com.android.systemui.common.ui.compose.toAnnotatedString
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.CategoryAndName
+import com.android.systemui.qs.shared.model.TileCategory
/**
* View model for each tile that is available to be added/removed/moved in Edit mode.
@@ -26,14 +32,41 @@ import com.android.systemui.qs.pipeline.shared.TileSpec
* [isCurrent] indicates whether this tile is part of the current set of tiles that the user sees in
* Quick Settings.
*/
-data class EditTileViewModel(
+data class UnloadedEditTileViewModel(
val tileSpec: TileSpec,
val icon: Icon,
val label: Text,
val appName: Text?,
val isCurrent: Boolean,
val availableEditActions: Set<AvailableEditActions>,
-)
+ val category: TileCategory,
+) {
+ fun load(context: Context): EditTileViewModel {
+ return EditTileViewModel(
+ tileSpec,
+ icon,
+ label.toAnnotatedString(context) ?: AnnotatedString(tileSpec.spec),
+ appName?.toAnnotatedString(context),
+ isCurrent,
+ availableEditActions,
+ category,
+ )
+ }
+}
+
+@Immutable
+data class EditTileViewModel(
+ val tileSpec: TileSpec,
+ val icon: Icon,
+ val label: AnnotatedString,
+ val appName: AnnotatedString?,
+ val isCurrent: Boolean,
+ val availableEditActions: Set<AvailableEditActions>,
+ override val category: TileCategory,
+) : CategoryAndName {
+ override val name
+ get() = label.text
+}
enum class AvailableEditActions {
ADD,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/dagger/QSTileListLog.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/dagger/QSTileListLog.kt
index c56ca8c27a1f..d50374b3c24c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/dagger/QSTileListLog.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/dagger/QSTileListLog.kt
@@ -15,9 +15,7 @@
*/
package com.android.systemui.qs.pipeline.dagger
-import java.lang.annotation.Retention
-import java.lang.annotation.RetentionPolicy
import javax.inject.Qualifier
/** A [LogBuffer] for the new QS Pipeline for logging changes to the set of current tiles. */
-@Qualifier @MustBeDocumented @Retention(RetentionPolicy.RUNTIME) annotation class QSTileListLog
+@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class QSTileListLog
diff --git a/packages/SystemUI/src/com/android/systemui/qs/shared/model/TileCategory.kt b/packages/SystemUI/src/com/android/systemui/qs/shared/model/TileCategory.kt
new file mode 100644
index 000000000000..59cb7d3d5345
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/shared/model/TileCategory.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.shared.model
+
+import com.android.systemui.common.shared.model.Text
+import com.android.systemui.res.R
+
+/** Categories for tiles. This can be used to sort tiles in edit mode. */
+enum class TileCategory(val label: Text) {
+ CONNECTIVITY(Text.Resource(R.string.qs_edit_mode_category_connectivity)),
+ UTILITIES(Text.Resource(R.string.qs_edit_mode_category_utilities)),
+ DISPLAY(Text.Resource(R.string.qs_edit_mode_category_display)),
+ PRIVACY(Text.Resource(R.string.qs_edit_mode_category_privacy)),
+ ACCESSIBILITY(Text.Resource(R.string.qs_edit_mode_category_accessibility)),
+ PROVIDED_BY_APP(Text.Resource(R.string.qs_edit_mode_category_providedByApps)),
+ UNKNOWN(Text.Resource(R.string.qs_edit_mode_category_unknown)),
+}
+
+interface CategoryAndName {
+ val category: TileCategory
+ val name: String
+}
+
+/**
+ * Groups the elements of the list by [CategoryAndName.category] (with the keys sorted in the
+ * natural order of [TileCategory]), and sorts the elements of each group based on the
+ * [CategoryAndName.name].
+ */
+fun <T : CategoryAndName> groupAndSort(list: List<T>): Map<TileCategory, List<T>> {
+ val groupedByCategory = list.groupBy { it.category }.toSortedMap()
+ return groupedByCategory.mapValues { it.value.sortedBy { it.name } }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt
index cdcefdb50b0f..3a9cb170040c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt
@@ -21,6 +21,7 @@ import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import com.android.internal.logging.InstanceId
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
data class QSTileConfig
@JvmOverloads
@@ -28,6 +29,7 @@ constructor(
val tileSpec: TileSpec,
val uiConfig: QSTileUIConfig,
val instanceId: InstanceId,
+ val category: TileCategory,
val metricsSpec: String = tileSpec.spec,
val policy: QSTilePolicy = QSTilePolicy.NoRestrictions,
val autoRemoveOnUnavailable: Boolean = true,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProvider.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProvider.kt
index 0609e797d53b..4dbddd91092a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProvider.kt
@@ -20,6 +20,7 @@ import com.android.internal.util.Preconditions
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import javax.inject.Inject
interface QSTileConfigProvider {
@@ -73,6 +74,7 @@ constructor(
spec,
QSTileUIConfig.Empty,
qsEventLogger.getNewInstanceId(),
+ category = TileCategory.PROVIDED_BY_APP,
)
is TileSpec.Invalid ->
throw IllegalArgumentException("TileSpec.Invalid doesn't support configs")
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt
index 907b92ce4c9b..c092c2f86799 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt
@@ -19,6 +19,7 @@ package com.android.systemui.recordissue
import com.android.systemui.Flags
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.RecordIssueTile
import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory
@@ -61,6 +62,7 @@ interface RecordIssueModule {
labelRes = R.string.qs_record_issue_label
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.UTILITIES,
)
/** Inject FlashlightTile into tileViewModelMap in QSModule */
diff --git a/packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockNewModule.kt b/packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockNewModule.kt
index 0589e6c63931..c9712fcdaa27 100644
--- a/packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockNewModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockNewModule.kt
@@ -19,6 +19,7 @@ package com.android.systemui.rotationlock
import com.android.systemui.camera.CameraRotationModule
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory
import com.android.systemui.qs.tiles.impl.rotation.domain.interactor.RotationLockTileDataInteractor
@@ -42,8 +43,9 @@ interface RotationLockNewModule {
@IntoMap
@StringKey(ROTATION_TILE_SPEC)
fun provideRotationAvailabilityInteractor(
- impl: RotationLockTileDataInteractor
+ impl: RotationLockTileDataInteractor
): QSTileAvailabilityInteractor
+
companion object {
private const val ROTATION_TILE_SPEC = "rotation"
@@ -60,6 +62,7 @@ interface RotationLockNewModule {
labelRes = R.string.quick_settings_rotation_unlocked_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.DISPLAY,
)
/** Inject Rotation tile into tileViewModelMap in QSModule */
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractor.kt
index 738b18495f3f..e477efe0808e 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractor.kt
@@ -25,6 +25,7 @@ import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.scene.data.repository.WindowRootViewVisibilityRepository
import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.NotificationPresenter
import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
@@ -34,6 +35,7 @@ import com.android.systemui.statusbar.policy.HeadsUpManager
import javax.inject.Inject
import javax.inject.Provider
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
@@ -45,6 +47,7 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
/** Business logic about the visibility of various parts of the window root view. */
+@OptIn(ExperimentalCoroutinesApi::class)
@SysUISingleton
class WindowRootViewVisibilityInteractor
@Inject
@@ -80,9 +83,9 @@ constructor(
is ObservableTransitionState.Idle ->
flowOf(
state.currentScene == Scenes.Shade ||
- state.currentScene == Scenes.NotificationsShade ||
- state.currentScene == Scenes.QuickSettingsShade ||
- state.currentScene == Scenes.Lockscreen
+ state.currentScene == Scenes.Lockscreen ||
+ Overlays.NotificationsShade in state.currentOverlays ||
+ Overlays.QuickSettingsShade in state.currentOverlays
)
is ObservableTransitionState.Transition ->
if (
@@ -94,12 +97,12 @@ constructor(
} else {
flowOf(
state.toContent == Scenes.Shade ||
- state.toContent == Scenes.NotificationsShade ||
- state.toContent == Scenes.QuickSettingsShade ||
+ state.toContent == Overlays.NotificationsShade ||
+ state.toContent == Overlays.QuickSettingsShade ||
state.toContent == Scenes.Lockscreen ||
state.fromContent == Scenes.Shade ||
- state.fromContent == Scenes.NotificationsShade ||
- state.fromContent == Scenes.QuickSettingsShade ||
+ state.fromContent == Overlays.NotificationsShade ||
+ state.fromContent == Overlays.QuickSettingsShade ||
state.fromContent == Scenes.Lockscreen
)
}
@@ -115,10 +118,9 @@ constructor(
* false if the device is asleep.
*/
val isLockscreenOrShadeVisibleAndInteractive: StateFlow<Boolean> =
- combine(
- isLockscreenOrShadeVisible,
- powerInteractor.isAwake,
- ) { isKeyguardAodOrShadeVisible, isAwake ->
+ combine(isLockscreenOrShadeVisible, powerInteractor.isAwake) {
+ isKeyguardAodOrShadeVisible,
+ isAwake ->
isKeyguardAodOrShadeVisible && isAwake
}
.stateIn(scope, SharingStarted.Eagerly, initialValue = false)
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/ScrimStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/ScrimStartable.kt
index d1629c799732..e352bfe938f6 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/ScrimStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/ScrimStartable.kt
@@ -19,7 +19,9 @@
package com.android.systemui.scene.domain.startable
import androidx.annotation.VisibleForTesting
+import com.android.compose.animation.scene.ContentKey
import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.compose.animation.scene.OverlayKey
import com.android.compose.animation.scene.SceneKey
import com.android.systemui.CoreStartable
import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
@@ -33,6 +35,7 @@ import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.settings.brightness.domain.interactor.BrightnessMirrorShowingInteractor
import com.android.systemui.statusbar.phone.DozeServiceHost
@@ -74,6 +77,7 @@ constructor(
deviceEntryInteractor.isDeviceEntered,
occlusionInteractor.invisibleDueToOcclusion,
sceneInteractor.currentScene,
+ sceneInteractor.currentOverlays,
sceneInteractor.transitionState,
keyguardInteractor.isDozing,
keyguardInteractor.isDreaming,
@@ -95,34 +99,29 @@ constructor(
val isDeviceEntered = flowValues[0] as Boolean
val isOccluded = flowValues[1] as Boolean
val currentScene = flowValues[2] as SceneKey
- val transitionState = flowValues[3] as ObservableTransitionState
- val isDozing = flowValues[4] as Boolean
- val isDreaming = flowValues[5] as Boolean
- val biometricUnlockState = flowValues[6] as BiometricUnlockModel
- val isBrightnessMirrorVisible = flowValues[7] as Boolean
- val isPulsing = flowValues[8] as Boolean
- val hasPendingScreenOffCallback = flowValues[9] as Boolean
+ val currentOverlays = flowValues[3] as Set<OverlayKey>
+ val transitionState = flowValues[4] as ObservableTransitionState
+ val isDozing = flowValues[5] as Boolean
+ val isDreaming = flowValues[6] as Boolean
+ val biometricUnlockState = flowValues[7] as BiometricUnlockModel
+ val isBrightnessMirrorVisible = flowValues[8] as Boolean
+ val isPulsing = flowValues[9] as Boolean
+ val hasPendingScreenOffCallback = flowValues[10] as Boolean
// This is true when the lockscreen scene is either the current scene or somewhere
- // in the
- // navigation back stack of scenes.
+ // in the navigation back stack of scenes.
val isOnKeyguard = !isDeviceEntered
val isCurrentSceneBouncer = currentScene == Scenes.Bouncer
// This is true when moving away from one of the keyguard scenes to the gone scene.
- // It
- // happens only when unlocking or when dismissing a dismissible lockscreen.
+ // It happens only when unlocking or when dismissing a dismissible lockscreen.
val isTransitioningAwayFromKeyguard =
transitionState is ObservableTransitionState.Transition.ChangeScene &&
transitionState.fromScene.isKeyguard() &&
transitionState.toScene == Scenes.Gone
- // This is true when any of the shade scenes is the current scene.
- val isCurrentSceneShade = currentScene.isShade()
- // This is true when moving into one of the shade scenes when a non-shade scene.
- val isTransitioningToShade =
- transitionState is ObservableTransitionState.Transition.ChangeScene &&
- !transitionState.fromScene.isShade() &&
- transitionState.toScene.isShade()
+ // This is true when any of the shade scenes or overlays is the current content.
+ val isCurrentContentShade =
+ currentScene.isShade() || currentOverlays.any { it.isShade() }
// This is true after completing a transition to communal.
val isIdleOnCommunal = transitionState.isIdle(Scenes.Communal)
@@ -137,10 +136,10 @@ constructor(
if (alternateBouncerInteractor.isVisibleState()) {
// This will cancel the keyguardFadingAway animation if it is running. We need
- // to do
- // this as otherwise it can remain pending and leave keyguard in a weird state.
+ // to do this as otherwise it can remain pending and leave keyguard in a weird
+ // state.
onKeyguardFadedAway(isTransitioningAwayFromKeyguard)
- if (!isTransitioningToShade) {
+ if (!transitionState.isTransitioningToShade()) {
// Safeguard which prevents the scrim from being stuck in the wrong
// state
Model(scrimState = ScrimState.KEYGUARD, unlocking = unlocking)
@@ -163,7 +162,7 @@ constructor(
)
} else if (isBrightnessMirrorVisible) {
Model(scrimState = ScrimState.BRIGHTNESS_MIRROR, unlocking = unlocking)
- } else if (isCurrentSceneShade && !isDeviceEntered) {
+ } else if (isCurrentContentShade && !isDeviceEntered) {
Model(scrimState = ScrimState.SHADE_LOCKED, unlocking = unlocking)
} else if (isPulsing) {
Model(scrimState = ScrimState.PULSING, unlocking = unlocking)
@@ -171,8 +170,8 @@ constructor(
Model(scrimState = ScrimState.OFF, unlocking = unlocking)
} else if (isDozing && !unlocking) {
// This will cancel the keyguardFadingAway animation if it is running. We need
- // to do
- // this as otherwise it can remain pending and leave keyguard in a weird state.
+ // to do this as otherwise it can remain pending and leave keyguard in a weird
+ // state.
onKeyguardFadedAway(isTransitioningAwayFromKeyguard)
Model(scrimState = ScrimState.AOD, unlocking = false)
} else if (isIdleOnCommunal) {
@@ -222,15 +221,24 @@ constructor(
return this == Scenes.Lockscreen || this == Scenes.Bouncer
}
- private fun SceneKey.isShade(): Boolean {
+ private fun ContentKey.isShade(): Boolean {
return this == Scenes.Shade ||
this == Scenes.QuickSettings ||
- this == Scenes.NotificationsShade ||
- this == Scenes.QuickSettingsShade
+ this == Overlays.NotificationsShade ||
+ this == Overlays.QuickSettingsShade
+ }
+
+ private fun ObservableTransitionState.isTransitioningToShade(): Boolean {
+ return when (this) {
+ is ObservableTransitionState.Idle -> false
+ is ObservableTransitionState.Transition.ChangeScene ->
+ !fromScene.isShade() && toScene.isShade()
+ is ObservableTransitionState.Transition.ReplaceOverlay ->
+ !fromOverlay.isShade() && toOverlay.isShade()
+ is ObservableTransitionState.Transition.ShowOrHideOverlay ->
+ !fromContent.isShade() && toContent.isShade()
+ }
}
- private data class Model(
- val scrimState: ScrimState,
- val unlocking: Boolean,
- )
+ private data class Model(val scrimState: ScrimState, val unlocking: Boolean)
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt
index a830e1bbfe72..9a9c576c5af6 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt
@@ -21,6 +21,7 @@ import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogBufferFactory
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.ScreenRecordTile
import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
@@ -74,6 +75,7 @@ interface ScreenRecordModule {
labelRes = R.string.quick_settings_screen_record_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.DISPLAY,
)
/** Inject ScreenRecord Tile into tileViewModelMap in QSModule */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index f88fd7d00a2b..862f33bb4ec3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -63,6 +63,7 @@ import android.view.accessibility.Flags;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
+import com.android.internal.annotations.KeepForWeakReference;
import com.android.internal.os.SomeArgs;
import com.android.internal.statusbar.IAddTileResultCallback;
import com.android.internal.statusbar.IStatusBar;
@@ -192,10 +193,10 @@ public class CommandQueue extends IStatusBar.Stub implements
private static final String SHOW_IME_SWITCHER_KEY = "showImeSwitcherKey";
private final Object mLock = new Object();
- private ArrayList<Callbacks> mCallbacks = new ArrayList<>();
- private Handler mHandler = new H(Looper.getMainLooper());
+ private final ArrayList<Callbacks> mCallbacks = new ArrayList<>();
+ private final Handler mHandler = new H(Looper.getMainLooper());
/** A map of display id - disable flag pair */
- private SparseArray<Pair<Integer, Integer>> mDisplayDisabled = new SparseArray<>();
+ private final SparseArray<Pair<Integer, Integer>> mDisplayDisabled = new SparseArray<>();
/**
* The last ID of the display where IME window for which we received setImeWindowStatus
* event.
@@ -207,6 +208,21 @@ public class CommandQueue extends IStatusBar.Stub implements
private final @Nullable DumpHandler mDumpHandler;
private final @Nullable Lazy<PowerInteractor> mPowerInteractor;
+ @KeepForWeakReference
+ private final DisplayTracker.Callback mDisplayTrackerCallback = new DisplayTracker.Callback() {
+ @Override
+ public void onDisplayRemoved(int displayId) {
+ synchronized (mLock) {
+ mDisplayDisabled.remove(displayId);
+ }
+ // This callback is registered with {@link #mHandler} that already posts to run on
+ // main thread, so it is safe to dispatch directly.
+ for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+ mCallbacks.get(i).onDisplayRemoved(displayId);
+ }
+ }
+ };
+
/**
* These methods are called back on the main thread.
*/
@@ -576,19 +592,8 @@ public class CommandQueue extends IStatusBar.Stub implements
mDisplayTracker = displayTracker;
mRegistry = registry;
mDumpHandler = dumpHandler;
- mDisplayTracker.addDisplayChangeCallback(new DisplayTracker.Callback() {
- @Override
- public void onDisplayRemoved(int displayId) {
- synchronized (mLock) {
- mDisplayDisabled.remove(displayId);
- }
- // This callback is registered with {@link #mHandler} that already posts to run on
- // main thread, so it is safe to dispatch directly.
- for (int i = mCallbacks.size() - 1; i >= 0; i--) {
- mCallbacks.get(i).onDisplayRemoved(displayId);
- }
- }
- }, new HandlerExecutor(mHandler));
+ mDisplayTracker.addDisplayChangeCallback(mDisplayTrackerCallback,
+ new HandlerExecutor(mHandler));
// We always have default display.
setDisabled(mDisplayTracker.getDefaultDisplayId(), DISABLE_NONE, DISABLE2_NONE);
mPowerInteractor = powerInteractor;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt
index 400f8af99e07..dac01028ef64 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt
@@ -21,6 +21,7 @@ import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags.SIGNAL_CALLBACK_DEPRECATION
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.AirplaneModeTile
import com.android.systemui.qs.tiles.BluetoothTile
@@ -95,21 +96,21 @@ interface ConnectivityModule {
@IntoMap
@StringKey(AIRPLANE_MODE_TILE_SPEC)
fun provideAirplaneModeAvailabilityInteractor(
- impl: AirplaneModeTileDataInteractor
+ impl: AirplaneModeTileDataInteractor
): QSTileAvailabilityInteractor
@Binds
@IntoMap
@StringKey(DATA_SAVER_TILE_SPEC)
fun provideDataSaverAvailabilityInteractor(
- impl: DataSaverTileDataInteractor
+ impl: DataSaverTileDataInteractor
): QSTileAvailabilityInteractor
@Binds
@IntoMap
@StringKey(INTERNET_TILE_SPEC)
fun provideInternetAvailabilityInteractor(
- impl: InternetTileDataInteractor
+ impl: InternetTileDataInteractor
): QSTileAvailabilityInteractor
companion object {
@@ -149,6 +150,7 @@ interface ConnectivityModule {
),
instanceId = uiEventLogger.getNewInstanceId(),
policy = QSTilePolicy.Restricted(listOf(UserManager.DISALLOW_AIRPLANE_MODE)),
+ category = TileCategory.CONNECTIVITY,
)
/** Inject AirplaneModeTile into tileViewModelMap in QSModule */
@@ -180,6 +182,7 @@ interface ConnectivityModule {
labelRes = R.string.data_saver,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.CONNECTIVITY,
)
/** Inject DataSaverTile into tileViewModelMap in QSModule */
@@ -211,6 +214,7 @@ interface ConnectivityModule {
labelRes = R.string.quick_settings_internet_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.CONNECTIVITY,
)
/** Inject InternetTile into tileViewModelMap in QSModule */
@@ -242,6 +246,7 @@ interface ConnectivityModule {
labelRes = R.string.quick_settings_hotspot_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.CONNECTIVITY,
)
@Provides
@@ -256,6 +261,7 @@ interface ConnectivityModule {
labelRes = R.string.quick_settings_cast_title,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.CONNECTIVITY,
)
@Provides
@@ -270,6 +276,7 @@ interface ConnectivityModule {
labelRes = R.string.quick_settings_bluetooth_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.CONNECTIVITY,
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index f3b937100db2..1ea26e5727ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -61,6 +61,7 @@ import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor;
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback;
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor;
+import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlags;
import com.android.systemui.bouncer.ui.BouncerView;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
@@ -70,8 +71,8 @@ import com.android.systemui.dock.DockManager;
import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.keyguard.KeyguardWmStateRefactor;
-import com.android.systemui.keyguard.domain.interactor.KeyguardDismissTransitionInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardDismissActionInteractor;
+import com.android.systemui.keyguard.domain.interactor.KeyguardDismissTransitionInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.keyguard.shared.model.DismissAction;
import com.android.systemui.keyguard.shared.model.Edge;
@@ -839,7 +840,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
public void dismissWithAction(OnDismissAction r, Runnable cancelAction,
boolean afterKeyguardGone, String message) {
- if (SceneContainerFlag.isEnabled()) {
+ if (ComposeBouncerFlags.INSTANCE.isEnabled()) {
if (r == null) {
return;
}
@@ -891,7 +892,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
return;
}
- if (!SceneContainerFlag.isEnabled()) {
+ if (!ComposeBouncerFlags.INSTANCE.isEnabled()) {
mAfterKeyguardGoneAction = r;
mKeyguardGoneCancelAction = cancelAction;
mDismissActionWillAnimateOnKeyguard = r != null
@@ -965,7 +966,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
* Adds a {@param runnable} to be executed after Keyguard is gone.
*/
public void addAfterKeyguardGoneRunnable(Runnable runnable) {
- if (SceneContainerFlag.isEnabled()) {
+ if (ComposeBouncerFlags.INSTANCE.isEnabled()) {
if (runnable != null) {
mKeyguardDismissActionInteractor.get().runAfterKeyguardGone(runnable);
}
@@ -1180,7 +1181,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
// We update the state (which will show the keyguard) only if an animation will run on
// the keyguard. If there is no animation, we wait before updating the state so that we
// go directly from bouncer to launcher/app.
- if (SceneContainerFlag.isEnabled()) {
+ if (ComposeBouncerFlags.INSTANCE.isEnabled()) {
if (mKeyguardDismissActionInteractor.get().runDismissAnimationOnKeyguard()) {
updateStates();
}
@@ -1307,7 +1308,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
}
private void executeAfterKeyguardGoneAction() {
- if (SceneContainerFlag.isEnabled()) {
+ if (ComposeBouncerFlags.INSTANCE.isEnabled()) {
return;
}
if (mAfterKeyguardGoneAction != null) {
@@ -1703,6 +1704,8 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
pw.println(" Registered KeyguardViewManagerCallbacks:");
pw.println(" SceneContainerFlag enabled:"
+ SceneContainerFlag.isEnabled());
+ pw.println(" ComposeBouncerFlags enabled:"
+ + ComposeBouncerFlags.INSTANCE.isEnabled());
for (KeyguardViewManagerCallback callback : mCallbacks) {
pw.println(" " + callback);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
index c04616847ebe..0ad1042a665f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
@@ -480,10 +480,16 @@ public class SystemUIDialog extends AlertDialog implements ViewRootImpl.ConfigCh
}
public static AlertDialog applyFlags(AlertDialog dialog) {
+ return applyFlags(dialog, true);
+ }
+
+ public static AlertDialog applyFlags(AlertDialog dialog, boolean showWhenLocked) {
final Window window = dialog.getWindow();
window.setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL);
- window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
- | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
+ window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
+ if (showWhenLocked) {
+ window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
+ }
window.getAttributes().setFitInsetsTypes(
window.getAttributes().getFitInsetsTypes() & ~Type.statusBars());
return dialog;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
index fc7a67233bb6..bc7d376a8740 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
@@ -64,9 +64,6 @@ interface WifiRepository {
const val COL_NAME_IS_ENABLED = "isEnabled"
/** Column name to use for [isWifiDefault] for table logging. */
const val COL_NAME_IS_DEFAULT = "isDefault"
-
- const val CARRIER_MERGED_INVALID_SUB_ID_REASON =
- "Wifi network was carrier merged but had invalid sub ID"
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt
index 7163e67eaa5d..f4bb1a34b05f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt
@@ -46,7 +46,7 @@ constructor(
private val _isWifiDefault = MutableStateFlow(false)
override val isWifiDefault: StateFlow<Boolean> = _isWifiDefault
- private val _wifiNetwork = MutableStateFlow<WifiNetworkModel>(WifiNetworkModel.Inactive)
+ private val _wifiNetwork = MutableStateFlow<WifiNetworkModel>(WifiNetworkModel.Inactive())
override val wifiNetwork: StateFlow<WifiNetworkModel> = _wifiNetwork
private val _secondaryNetworks = MutableStateFlow<List<WifiNetworkModel>>(emptyList())
@@ -82,7 +82,7 @@ constructor(
_isWifiEnabled.value = false
_isWifiDefault.value = false
_wifiActivity.value = DataActivityModel(hasActivityIn = false, hasActivityOut = false)
- _wifiNetwork.value = WifiNetworkModel.Inactive
+ _wifiNetwork.value = WifiNetworkModel.Inactive()
}
private fun processEnabledWifiState(event: FakeWifiEventModel.Wifi) {
@@ -100,7 +100,7 @@ constructor(
}
private fun FakeWifiEventModel.Wifi.toWifiNetworkModel(): WifiNetworkModel =
- WifiNetworkModel.Active(
+ WifiNetworkModel.Active.of(
isValidated = validated ?: true,
level = level ?: 0,
ssid = ssid ?: DEMO_NET_SSID,
@@ -108,7 +108,7 @@ constructor(
)
private fun FakeWifiEventModel.CarrierMerged.toCarrierMergedModel(): WifiNetworkModel =
- WifiNetworkModel.CarrierMerged(
+ WifiNetworkModel.CarrierMerged.of(
subscriptionId = subscriptionId,
level = level,
numberOfLevels = numberOfLevels,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt
index b6e73e0f4b9e..76024cd565d1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt
@@ -19,7 +19,6 @@ package com.android.systemui.statusbar.pipeline.wifi.data.repository.prod
import android.annotation.SuppressLint
import android.net.wifi.ScanResult
import android.net.wifi.WifiManager
-import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
@@ -39,18 +38,14 @@ import com.android.systemui.statusbar.pipeline.dagger.WifiTableLog
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.shared.data.model.toWifiDataActivityModel
import com.android.systemui.statusbar.pipeline.wifi.data.repository.RealWifiRepository
-import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository.Companion.CARRIER_MERGED_INVALID_SUB_ID_REASON
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository.Companion.COL_NAME_IS_DEFAULT
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository.Companion.COL_NAME_IS_ENABLED
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
-import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel.Inactive.toHotspotDeviceType
+import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel.Unavailable.toHotspotDeviceType
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiScanEntry
import com.android.wifitrackerlib.HotspotNetworkEntry
import com.android.wifitrackerlib.MergedCarrierEntry
import com.android.wifitrackerlib.WifiEntry
-import com.android.wifitrackerlib.WifiEntry.WIFI_LEVEL_MAX
-import com.android.wifitrackerlib.WifiEntry.WIFI_LEVEL_MIN
-import com.android.wifitrackerlib.WifiEntry.WIFI_LEVEL_UNREACHABLE
import com.android.wifitrackerlib.WifiPickerTracker
import java.util.concurrent.Executor
import javax.inject.Inject
@@ -246,36 +241,28 @@ constructor(
}
private fun MergedCarrierEntry.convertCarrierMergedToModel(): WifiNetworkModel {
- return if (this.subscriptionId == INVALID_SUBSCRIPTION_ID) {
- WifiNetworkModel.Invalid(CARRIER_MERGED_INVALID_SUB_ID_REASON)
- } else {
- WifiNetworkModel.CarrierMerged(
- subscriptionId = this.subscriptionId,
- level = this.level,
- // WifiManager APIs to calculate the signal level start from 0, so
- // maxSignalLevel + 1 represents the total level buckets count.
- numberOfLevels = wifiManager.maxSignalLevel + 1,
- )
- }
+ // WifiEntry instance values aren't guaranteed to be stable between method calls
+ // because
+ // WifiPickerTracker is continuously updating the same object. Save the level in a
+ // local
+ // variable so that checking the level validity here guarantees that the level will
+ // still be
+ // valid when we create the `WifiNetworkModel.Active` instance later. Otherwise, the
+ // level
+ // could be valid here but become invalid later, and `WifiNetworkModel.Active` will
+ // throw
+ // an exception. See b/362384551.
+
+ return WifiNetworkModel.CarrierMerged.of(
+ subscriptionId = this.subscriptionId,
+ level = this.level,
+ // WifiManager APIs to calculate the signal level start from 0, so
+ // maxSignalLevel + 1 represents the total level buckets count.
+ numberOfLevels = wifiManager.maxSignalLevel + 1,
+ )
}
private fun WifiEntry.convertNormalToModel(): WifiNetworkModel {
- // WifiEntry instance values aren't guaranteed to be stable between method calls because
- // WifiPickerTracker is continuously updating the same object. Save the level in a local
- // variable so that checking the level validity here guarantees that the level will still be
- // valid when we create the `WifiNetworkModel.Active` instance later. Otherwise, the level
- // could be valid here but become invalid later, and `WifiNetworkModel.Active` will throw
- // an exception. See b/362384551.
- val currentLevel = this.level
- if (
- currentLevel == WIFI_LEVEL_UNREACHABLE ||
- currentLevel !in WIFI_LEVEL_MIN..WIFI_LEVEL_MAX
- ) {
- // If our level means the network is unreachable or the level is otherwise invalid, we
- // don't have an active network.
- return WifiNetworkModel.Inactive
- }
-
val hotspotDeviceType =
if (this is HotspotNetworkEntry) {
this.deviceType.toHotspotDeviceType()
@@ -283,9 +270,9 @@ constructor(
WifiNetworkModel.HotspotDeviceType.NONE
}
- return WifiNetworkModel.Active(
+ return WifiNetworkModel.Active.of(
isValidated = this.hasInternetAccess(),
- level = currentLevel,
+ level = this.level,
ssid = this.title,
hotspotDeviceType = hotspotDeviceType,
)
@@ -421,7 +408,7 @@ constructor(
companion object {
// Start out with no known wifi network.
- @VisibleForTesting val WIFI_NETWORK_DEFAULT = WifiNetworkModel.Inactive
+ @VisibleForTesting val WIFI_NETWORK_DEFAULT = WifiNetworkModel.Inactive()
private const val WIFI_STATE_DEFAULT = WifiManager.WIFI_STATE_DISABLED
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModel.kt
index 39842fb39e24..32203774afd1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModel.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.pipeline.wifi.shared.model
+import android.net.wifi.WifiManager
import android.net.wifi.WifiManager.UNKNOWN_SSID
import android.net.wifi.sharedconnectivity.app.NetworkProviderInfo
import android.telephony.SubscriptionManager
@@ -23,8 +24,12 @@ import androidx.annotation.VisibleForTesting
import com.android.systemui.log.table.Diffable
import com.android.systemui.log.table.TableRowLogger
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
+import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel.Active.Companion.MAX_VALID_LEVEL
+import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel.Active.Companion.isValid
+import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel.Active.Companion.of
import com.android.wifitrackerlib.HotspotNetworkEntry.DeviceType
import com.android.wifitrackerlib.WifiEntry
+import com.android.wifitrackerlib.WifiEntry.WIFI_LEVEL_UNREACHABLE
/** Provides information about the current wifi network. */
sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
@@ -64,7 +69,7 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
/** A description of why the wifi information was invalid. */
val invalidReason: String,
) : WifiNetworkModel() {
- override fun toString() = "WifiNetwork.Invalid[$invalidReason]"
+ override fun toString() = "WifiNetwork.Invalid[reason=$invalidReason]"
override fun logDiffs(prevVal: WifiNetworkModel, row: TableRowLogger) {
if (prevVal !is Invalid) {
@@ -73,12 +78,12 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
}
if (invalidReason != prevVal.invalidReason) {
- row.logChange(COL_NETWORK_TYPE, "$TYPE_UNAVAILABLE $invalidReason")
+ row.logChange(COL_NETWORK_TYPE, "$TYPE_UNAVAILABLE[reason=$invalidReason]")
}
}
override fun logFull(row: TableRowLogger) {
- row.logChange(COL_NETWORK_TYPE, "$TYPE_UNAVAILABLE $invalidReason")
+ row.logChange(COL_NETWORK_TYPE, "$TYPE_UNAVAILABLE[reason=$invalidReason]")
row.logChange(COL_SUB_ID, SUB_ID_DEFAULT)
row.logChange(COL_VALIDATED, false)
row.logChange(COL_LEVEL, LEVEL_DEFAULT)
@@ -89,20 +94,25 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
}
/** A model representing that we have no active wifi network. */
- object Inactive : WifiNetworkModel() {
- override fun toString() = "WifiNetwork.Inactive"
+ data class Inactive(
+ /** An optional description of why the wifi information was inactive. */
+ val inactiveReason: String? = null,
+ ) : WifiNetworkModel() {
+ override fun toString() = "WifiNetwork.Inactive[reason=$inactiveReason]"
override fun logDiffs(prevVal: WifiNetworkModel, row: TableRowLogger) {
- if (prevVal is Inactive) {
+ if (prevVal !is Inactive) {
+ logFull(row)
return
}
- // When changing to Inactive, we need to log diffs to all the fields.
- logFull(row)
+ if (inactiveReason != prevVal.inactiveReason) {
+ row.logChange(COL_NETWORK_TYPE, "$TYPE_INACTIVE[reason=$inactiveReason]")
+ }
}
override fun logFull(row: TableRowLogger) {
- row.logChange(COL_NETWORK_TYPE, TYPE_INACTIVE)
+ row.logChange(COL_NETWORK_TYPE, "$TYPE_INACTIVE[reason=$inactiveReason]")
row.logChange(COL_SUB_ID, SUB_ID_DEFAULT)
row.logChange(COL_VALIDATED, false)
row.logChange(COL_LEVEL, LEVEL_DEFAULT)
@@ -117,31 +127,71 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
* treated as more of a mobile network.
*
* See [android.net.wifi.WifiInfo.isCarrierMerged] for more information.
+ *
+ * IMPORTANT: Do *not* call [copy] on this class. Instead, use the factory [of] methods. [of]
+ * will verify preconditions correctly.
*/
- data class CarrierMerged(
+ data class CarrierMerged
+ private constructor(
/**
* The subscription ID that this connection represents.
*
* Comes from [android.net.wifi.WifiInfo.getSubscriptionId].
*
- * Per that method, this value must not be [INVALID_SUBSCRIPTION_ID] (if it was invalid,
- * then this is *not* a carrier merged network).
+ * Per that method, this value must not be [SubscriptionManager.INVALID_SUBSCRIPTION_ID] (if
+ * it was invalid, then this is *not* a carrier merged network).
*/
val subscriptionId: Int,
- /** The signal level, guaranteed to be 0 <= level <= numberOfLevels. */
+ /** The signal level, required to be 0 <= level <= numberOfLevels. */
val level: Int,
/** The maximum possible level. */
- val numberOfLevels: Int = MobileConnectionRepository.DEFAULT_NUM_LEVELS,
+ val numberOfLevels: Int,
) : WifiNetworkModel() {
- init {
- require(level in MIN_VALID_LEVEL..numberOfLevels) {
- "CarrierMerged: $MIN_VALID_LEVEL <= wifi level <= $numberOfLevels required; " +
+ companion object {
+ /**
+ * Creates a [CarrierMerged] instance, or an [Invalid] instance if any of the arguments
+ * are invalid.
+ */
+ fun of(
+ subscriptionId: Int,
+ level: Int,
+ numberOfLevels: Int = MobileConnectionRepository.DEFAULT_NUM_LEVELS
+ ): WifiNetworkModel {
+ if (!subscriptionId.isSubscriptionIdValid()) {
+ return Invalid(INVALID_SUB_ID_ERROR_STRING)
+ }
+ if (!level.isLevelValid(numberOfLevels)) {
+ return Invalid(getInvalidLevelErrorString(level, numberOfLevels))
+ }
+ return CarrierMerged(subscriptionId, level, numberOfLevels)
+ }
+
+ private fun Int.isLevelValid(maxLevel: Int): Boolean {
+ return this != WIFI_LEVEL_UNREACHABLE && this in MIN_VALID_LEVEL..maxLevel
+ }
+
+ private fun getInvalidLevelErrorString(level: Int, maxLevel: Int): String {
+ return "Wifi network was carrier merged but had invalid level. " +
+ "$MIN_VALID_LEVEL <= wifi level <= $maxLevel required; " +
"level was $level"
}
- require(subscriptionId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
- "subscription ID cannot be invalid"
+
+ private fun Int.isSubscriptionIdValid(): Boolean {
+ return this != SubscriptionManager.INVALID_SUBSCRIPTION_ID
+ }
+
+ private const val INVALID_SUB_ID_ERROR_STRING =
+ "Wifi network was carrier merged but had invalid sub ID"
+ }
+
+ init {
+ require(level.isLevelValid(numberOfLevels)) {
+ "${getInvalidLevelErrorString(level, numberOfLevels)}. $DO_NOT_USE_COPY_ERROR"
+ }
+ require(subscriptionId.isSubscriptionIdValid()) {
+ "$INVALID_SUB_ID_ERROR_STRING. $DO_NOT_USE_COPY_ERROR"
}
}
@@ -173,28 +223,64 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
}
}
- /** Provides information about an active wifi network. */
- data class Active(
+ /**
+ * Provides information about an active wifi network.
+ *
+ * IMPORTANT: Do *not* call [copy] on this class. Instead, use the factory [of] method. [of]
+ * will verify preconditions correctly.
+ */
+ data class Active
+ private constructor(
/** See [android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED]. */
- val isValidated: Boolean = false,
+ val isValidated: Boolean,
- /** The wifi signal level, guaranteed to be 0 <= level <= 4. */
+ /** The wifi signal level, required to be 0 <= level <= 4. */
val level: Int,
/** See [android.net.wifi.WifiInfo.ssid]. */
- val ssid: String? = null,
+ val ssid: String?,
/**
* The type of device providing a hotspot connection, or [HotspotDeviceType.NONE] if this
* isn't a hotspot connection.
*/
- val hotspotDeviceType: HotspotDeviceType = WifiNetworkModel.HotspotDeviceType.NONE,
+ val hotspotDeviceType: HotspotDeviceType,
) : WifiNetworkModel() {
- init {
- require(level in MIN_VALID_LEVEL..MAX_VALID_LEVEL) {
- "Active: $MIN_VALID_LEVEL <= wifi level <= $MAX_VALID_LEVEL required; " +
+ companion object {
+ /**
+ * Creates an [Active] instance, or an [Inactive] instance if any of the arguments are
+ * invalid.
+ */
+ @JvmStatic
+ fun of(
+ isValidated: Boolean = false,
+ level: Int,
+ ssid: String? = null,
+ hotspotDeviceType: HotspotDeviceType = HotspotDeviceType.NONE,
+ ): WifiNetworkModel {
+ if (!level.isValid()) {
+ return Inactive(getInvalidLevelErrorString(level))
+ }
+ return Active(isValidated, level, ssid, hotspotDeviceType)
+ }
+
+ private fun Int.isValid(): Boolean {
+ return this != WIFI_LEVEL_UNREACHABLE && this in MIN_VALID_LEVEL..MAX_VALID_LEVEL
+ }
+
+ private fun getInvalidLevelErrorString(level: Int): String {
+ return "Wifi network was active but had invalid level. " +
+ "$MIN_VALID_LEVEL <= wifi level <= $MAX_VALID_LEVEL required; " +
"level was $level"
}
+
+ @VisibleForTesting internal const val MAX_VALID_LEVEL = WifiEntry.WIFI_LEVEL_MAX
+ }
+
+ init {
+ require(level.isValid()) {
+ "${getInvalidLevelErrorString(level)}. $DO_NOT_USE_COPY_ERROR"
+ }
}
/** Returns true if this network has a valid SSID and false otherwise. */
@@ -231,10 +317,6 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
row.logChange(COL_SSID, ssid)
row.logChange(COL_HOTSPOT, hotspotDeviceType.name)
}
-
- companion object {
- @VisibleForTesting internal const val MAX_VALID_LEVEL = WifiEntry.WIFI_LEVEL_MAX
- }
}
companion object {
@@ -292,3 +374,7 @@ const val COL_HOTSPOT = "hotspot"
val LEVEL_DEFAULT: String? = null
val NUM_LEVELS_DEFAULT: String? = null
val SUB_ID_DEFAULT: String? = null
+
+private const val DO_NOT_USE_COPY_ERROR =
+ "This should only be an issue if the caller incorrectly used `copy` to get a new instance. " +
+ "Please use the `of` method instead."
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt
index 591d7af44db1..cf9f9f4a2a81 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt
@@ -23,6 +23,7 @@ import android.os.UserManager.DISALLOW_SHARE_LOCATION
import com.android.systemui.Flags
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.AlarmTile
import com.android.systemui.qs.tiles.CameraToggleTile
@@ -157,6 +158,7 @@ interface PolicyModule {
labelRes = R.string.quick_settings_flashlight_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.UTILITIES,
)
/** Inject FlashlightTile into tileViewModelMap in QSModule */
@@ -192,7 +194,8 @@ interface PolicyModule {
policy =
QSTilePolicy.Restricted(
listOf(DISALLOW_SHARE_LOCATION, DISALLOW_CONFIG_LOCATION)
- )
+ ),
+ category = TileCategory.PRIVACY,
)
/** Inject LocationTile into tileViewModelMap in QSModule */
@@ -225,6 +228,7 @@ interface PolicyModule {
labelRes = R.string.status_bar_alarm,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.UTILITIES,
)
/** Inject AlarmTile into tileViewModelMap in QSModule */
@@ -257,6 +261,7 @@ interface PolicyModule {
labelRes = R.string.quick_settings_ui_mode_night_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.DISPLAY,
)
/** Inject uimodenight into tileViewModelMap in QSModule */
@@ -290,6 +295,7 @@ interface PolicyModule {
),
instanceId = uiEventLogger.getNewInstanceId(),
autoRemoveOnUnavailable = false,
+ category = TileCategory.PRIVACY,
)
/** Inject work mode into tileViewModelMap in QSModule */
@@ -323,6 +329,7 @@ interface PolicyModule {
),
instanceId = uiEventLogger.getNewInstanceId(),
policy = QSTilePolicy.Restricted(listOf(DISALLOW_CAMERA_TOGGLE)),
+ category = TileCategory.PRIVACY,
)
/** Inject camera toggle tile into tileViewModelMap in QSModule */
@@ -365,6 +372,7 @@ interface PolicyModule {
),
instanceId = uiEventLogger.getNewInstanceId(),
policy = QSTilePolicy.Restricted(listOf(DISALLOW_MICROPHONE_TOGGLE)),
+ category = TileCategory.PRIVACY,
)
/** Inject microphone toggle tile into tileViewModelMap in QSModule */
@@ -407,6 +415,7 @@ interface PolicyModule {
labelRes = R.string.quick_settings_modes_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.CONNECTIVITY,
)
} else {
QSTileConfig(
@@ -417,6 +426,7 @@ interface PolicyModule {
labelRes = R.string.quick_settings_dnd_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.CONNECTIVITY,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java b/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java
index ea213cba9567..dd1c11d11d1e 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java
@@ -25,6 +25,7 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.qs.QsEventLogger;
import com.android.systemui.qs.pipeline.shared.TileSpec;
+import com.android.systemui.qs.shared.model.TileCategory;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.qs.tiles.QuickAccessWalletTile;
import com.android.systemui.qs.tiles.viewmodel.QSTileConfig;
@@ -34,8 +35,6 @@ import com.android.systemui.res.R;
import com.android.systemui.wallet.controller.WalletContextualLocationsService;
import com.android.systemui.wallet.ui.WalletActivity;
-import java.util.concurrent.Executor;
-
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
@@ -43,6 +42,8 @@ import dagger.multibindings.ClassKey;
import dagger.multibindings.IntoMap;
import dagger.multibindings.StringKey;
+import java.util.concurrent.Executor;
+
/**
* Module for injecting classes in Wallet.
*/
@@ -90,6 +91,7 @@ public abstract class WalletModule {
R.string.wallet_title
),
uiEventLogger.getNewInstanceId(),
+ TileCategory.UTILITIES,
tileSpec.getSpec(),
QSTilePolicy.NoRestrictions.INSTANCE
);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java
index d85b77413338..bf13ceb5666a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java
@@ -445,7 +445,7 @@ public class CarrierTextManagerTest extends SysuiTestCase {
assertFalse(mWifiRepository.isWifiConnectedWithValidSsid());
mWifiRepository.setWifiNetwork(
- new WifiNetworkModel.Active(
+ WifiNetworkModel.Active.Companion.of(
/* isValidated= */ false,
/* level= */ 0,
/* ssid= */ "",
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
index 55fd3440ea07..48505102eba5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
@@ -54,6 +54,7 @@ import com.android.systemui.biometrics.data.repository.biometricStatusRepository
import com.android.systemui.biometrics.data.repository.fakeFingerprintPropertyRepository
import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor
import com.android.systemui.biometrics.domain.interactor.promptSelectorInteractor
+import com.android.systemui.biometrics.domain.interactor.sideFpsOverlayInteractor
import com.android.systemui.biometrics.domain.interactor.udfpsOverlayInteractor
import com.android.systemui.biometrics.extractAuthenticatorTypes
import com.android.systemui.biometrics.faceSensorPropertiesInternal
@@ -1453,11 +1454,15 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
@Test
fun switch_to_credential_fallback() = runGenericTest {
val size by collectLastValue(kosmos.promptViewModel.size)
+ val isShowingSfpsIndicator by collectLastValue(kosmos.sideFpsOverlayInteractor.isShowing)
// TODO(b/251476085): remove Spaghetti, migrate logic, and update this test
kosmos.promptViewModel.onSwitchToCredential()
assertThat(size).isEqualTo(PromptSize.LARGE)
+ if (testCase.modalities.hasSfps) {
+ assertThat(isShowingSfpsIndicator).isFalse()
+ }
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartableTest.kt
new file mode 100644
index 000000000000..9da68853a5aa
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartableTest.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.inputdevice.tutorial
+
+import android.content.Context
+import android.content.Intent
+import android.os.UserHandle
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.broadcast.broadcastDispatcher
+import com.android.systemui.inputdevice.tutorial.ui.TutorialNotificationCoordinator
+import com.android.systemui.testKosmos
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class KeyboardTouchpadTutorialCoreStartableTest : SysuiTestCase() {
+
+ private val kosmos = testKosmos()
+ private val broadcastDispatcher = kosmos.broadcastDispatcher
+ private val context = mock<Context>()
+ private val underTest =
+ KeyboardTouchpadTutorialCoreStartable(
+ { mock<TutorialNotificationCoordinator>() },
+ broadcastDispatcher,
+ context
+ )
+
+ @Test
+ fun registersBroadcastReceiverStartingActivityAsSystemUser() {
+ underTest.start()
+
+ broadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ context,
+ Intent("com.android.systemui.action.KEYBOARD_TOUCHPAD_TUTORIAL")
+ )
+
+ verify(context).startActivityAsUser(any(), eq(UserHandle.SYSTEM))
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt
index 3cbbb648af94..bea415cbb934 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt
@@ -22,8 +22,8 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
-import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor
import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
+import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.flags.EnableSceneContainer
@@ -42,6 +42,7 @@ import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.domain.resolver.notifShadeSceneFamilyResolver
import com.android.systemui.scene.domain.resolver.quickSettingsSceneFamilyResolver
import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -77,12 +78,14 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() {
transitionInteractor = kosmos.keyguardTransitionInteractor,
dismissInteractor = dismissInteractor,
applicationScope = testScope.backgroundScope,
- sceneInteractor = kosmos.sceneInteractor,
- deviceEntryInteractor = kosmos.deviceEntryInteractor,
- quickSettingsSceneFamilyResolver = kosmos.quickSettingsSceneFamilyResolver,
- notifShadeSceneFamilyResolver = kosmos.notifShadeSceneFamilyResolver,
+ sceneInteractor = { kosmos.sceneInteractor },
+ deviceEntryInteractor = { kosmos.deviceEntryInteractor },
+ quickSettingsSceneFamilyResolver = { kosmos.quickSettingsSceneFamilyResolver },
+ notifShadeSceneFamilyResolver = { kosmos.notifShadeSceneFamilyResolver },
powerInteractor = kosmos.powerInteractor,
alternateBouncerInteractor = kosmos.alternateBouncerInteractor,
+ keyguardInteractor = { kosmos.keyguardInteractor },
+ shadeInteractor = { kosmos.shadeInteractor },
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt
index 3c743744dd58..823a23dec4ea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt
@@ -38,6 +38,8 @@ import android.media.session.MediaSession
import android.media.session.PlaybackState
import android.net.Uri
import android.os.Bundle
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.FlagsParameterization
import android.provider.Settings
import android.service.notification.StatusBarNotification
@@ -61,6 +63,8 @@ import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.media.controls.domain.resume.MediaResumeListener
import com.android.systemui.media.controls.domain.resume.ResumeMediaBrowser
+import com.android.systemui.media.controls.shared.mediaLogger
+import com.android.systemui.media.controls.shared.mockMediaLogger
import com.android.systemui.media.controls.shared.model.EXTRA_KEY_TRIGGER_SOURCE
import com.android.systemui.media.controls.shared.model.EXTRA_VALUE_TRIGGER_PERIODIC
import com.android.systemui.media.controls.shared.model.MediaData
@@ -69,7 +73,6 @@ import com.android.systemui.media.controls.shared.model.SmartspaceMediaDataProvi
import com.android.systemui.media.controls.util.MediaUiEventLogger
import com.android.systemui.media.controls.util.fakeMediaControllerFactory
import com.android.systemui.media.controls.util.mediaFlags
-import com.android.systemui.plugins.activityStarter
import com.android.systemui.res.R
import com.android.systemui.statusbar.SbnBuilder
import com.android.systemui.testKosmos
@@ -186,11 +189,10 @@ class LegacyMediaDataManagerImplTest(flags: FlagsParameterization) : SysuiTestCa
mSetFlagsRule.setFlagsParameterization(flags)
}
- private val kosmos = testKosmos()
+ private val kosmos = testKosmos().apply { mediaLogger = mockMediaLogger }
private val testDispatcher = kosmos.testDispatcher
private val testScope = kosmos.testScope
private val fakeFeatureFlags = kosmos.fakeFeatureFlagsClassic
- private val activityStarter = kosmos.activityStarter
private val mediaControllerFactory = kosmos.fakeMediaControllerFactory
private val instanceIdSequence = InstanceIdSequenceFake(1 shl 20)
@@ -240,7 +242,6 @@ class LegacyMediaDataManagerImplTest(flags: FlagsParameterization) : SysuiTestCa
mediaDeviceManager = mediaDeviceManager,
mediaDataCombineLatest = mediaDataCombineLatest,
mediaDataFilter = mediaDataFilter,
- activityStarter = activityStarter,
smartspaceMediaDataProvider = smartspaceMediaDataProvider,
useMediaResumption = true,
useQsMediaPlayer = true,
@@ -251,6 +252,7 @@ class LegacyMediaDataManagerImplTest(flags: FlagsParameterization) : SysuiTestCa
smartspaceManager = smartspaceManager,
keyguardUpdateMonitor = keyguardUpdateMonitor,
mediaDataLoader = { kosmos.mediaDataLoader },
+ mediaLogger = kosmos.mediaLogger,
)
verify(tunerService)
.addTunable(capture(tunableCaptor), eq(Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION))
@@ -2404,6 +2406,45 @@ class LegacyMediaDataManagerImplTest(flags: FlagsParameterization) : SysuiTestCa
assertThat(mediaDataCaptor.value.artwork).isNull()
}
+ @Test
+ @EnableFlags(Flags.FLAG_MEDIA_CONTROLS_POSTS_OPTIMIZATION)
+ fun postDuplicateNotification_doesNotCallListeners() {
+ addNotificationAndLoad()
+ reset(listener)
+ mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+
+ testScope.assertRunAllReady(foreground = 0, background = 1)
+ verify(listener, never())
+ .onMediaDataLoaded(
+ eq(KEY),
+ eq(KEY),
+ capture(mediaDataCaptor),
+ eq(true),
+ eq(0),
+ eq(false)
+ )
+ verify(kosmos.mediaLogger).logDuplicateMediaNotification(eq(KEY))
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_MEDIA_CONTROLS_POSTS_OPTIMIZATION)
+ fun postDuplicateNotification_callsListeners() {
+ addNotificationAndLoad()
+ reset(listener)
+ mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+ testScope.assertRunAllReady(foreground = 1, background = 1)
+ verify(listener)
+ .onMediaDataLoaded(
+ eq(KEY),
+ eq(KEY),
+ capture(mediaDataCaptor),
+ eq(true),
+ eq(0),
+ eq(false)
+ )
+ verify(kosmos.mediaLogger, never()).logDuplicateMediaNotification(eq(KEY))
+ }
+
private fun TestScope.assertRunAllReady(foreground: Int = 0, background: Int = 0) {
runCurrent()
if (Flags.mediaLoadMetadataViaMediaDataLoader()) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceManagerTest.kt
index 6a66c4087615..0c8d88065a73 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceManagerTest.kt
@@ -54,6 +54,7 @@ import com.android.systemui.media.muteawait.MediaMuteAwaitConnectionManager
import com.android.systemui.media.muteawait.MediaMuteAwaitConnectionManagerFactory
import com.android.systemui.res.R
import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.testKosmos
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
@@ -125,6 +126,8 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
private lateinit var mediaData: MediaData
@JvmField @Rule val mockito = MockitoJUnit.rule()
+ private val kosmos = testKosmos()
+
@Before
fun setUp() {
fakeFgExecutor = FakeExecutor(FakeSystemClock())
@@ -141,6 +144,7 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
{ localBluetoothManager },
fakeFgExecutor,
fakeBgExecutor,
+ kosmos.mediaDeviceLogger,
)
manager.addListener(listener)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/resume/MediaResumeListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/resume/MediaResumeListenerTest.kt
index 02d741385cf9..bc29d2a8ba0d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/resume/MediaResumeListenerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/resume/MediaResumeListenerTest.kt
@@ -138,6 +138,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
whenever(mockContext.packageManager).thenReturn(context.packageManager)
whenever(mockContext.contentResolver).thenReturn(context.contentResolver)
whenever(mockContext.userId).thenReturn(context.userId)
+ whenever(mockContext.resources).thenReturn(context.resources)
whenever(mediaFlags.isRemoteResumeAllowed()).thenReturn(false)
executor = FakeExecutor(clock)
@@ -210,7 +211,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
@Test
fun testOnLoad_checksForResume_noService() {
// When media data is loaded that has not been checked yet, and does not have a MBS
- resumeListener.onMediaDataLoaded(KEY, null, data)
+ onMediaDataLoaded(KEY, null, data)
// Then we report back to the manager
verify(mediaDataManager).setResumeAction(KEY, null)
@@ -223,8 +224,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
whenever(resumeBrowser.testConnection()).thenAnswer { callbackCaptor.value.onError() }
// When media data is loaded that has not been checked yet, and does not have a MBS
- resumeListener.onMediaDataLoaded(KEY, null, data)
- executor.runAllReady()
+ onMediaDataLoaded(KEY, null, data)
// Then we report back to the manager
verify(mediaDataManager).setResumeAction(eq(KEY), eq(null))
@@ -234,7 +234,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
fun testOnLoad_localCast_doesNotCheck() {
// When media data is loaded that has not been checked yet, and is a local cast
val dataCast = data.copy(playbackLocation = MediaData.PLAYBACK_CAST_LOCAL)
- resumeListener.onMediaDataLoaded(KEY, null, dataCast)
+ onMediaDataLoaded(KEY, null, dataCast, false)
// Then we do not take action
verify(mediaDataManager, never()).setResumeAction(any(), any())
@@ -244,7 +244,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
fun testOnload_remoteCast_doesNotCheck() {
// When media data is loaded that has not been checked yet, and is a remote cast
val dataRcn = data.copy(playbackLocation = MediaData.PLAYBACK_CAST_REMOTE)
- resumeListener.onMediaDataLoaded(KEY, null, dataRcn)
+ onMediaDataLoaded(KEY, null, dataRcn, resume = false)
// Then we do not take action
verify(mediaDataManager, never()).setResumeAction(any(), any())
@@ -257,7 +257,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
// When media data is loaded that has not been checked yet, and is a local cast
val dataCast = data.copy(playbackLocation = MediaData.PLAYBACK_CAST_LOCAL)
- resumeListener.onMediaDataLoaded(KEY, null, dataCast)
+ onMediaDataLoaded(KEY, null, dataCast)
// Then we report back to the manager
verify(mediaDataManager).setResumeAction(KEY, null)
@@ -270,7 +270,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
// When media data is loaded that has not been checked yet, and is a remote cast
val dataRcn = data.copy(playbackLocation = MediaData.PLAYBACK_CAST_REMOTE)
- resumeListener.onMediaDataLoaded(KEY, null, dataRcn)
+ onMediaDataLoaded(KEY, null, dataRcn, false)
// Then we do not take action
verify(mediaDataManager, never()).setResumeAction(any(), any())
@@ -288,10 +288,9 @@ class MediaResumeListenerTest : SysuiTestCase() {
// When media data is loaded that has not been checked yet, and does have a MBS
val dataCopy = data.copy(resumeAction = null, hasCheckedForResume = false)
- resumeListener.onMediaDataLoaded(KEY, null, dataCopy)
+ onMediaDataLoaded(KEY, null, dataCopy)
// Then we test whether the service is valid
- executor.runAllReady()
verify(mediaDataManager).setResumeAction(eq(KEY), eq(null))
verify(resumeBrowser).testConnection()
@@ -307,7 +306,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
fun testOnLoad_doesNotCheckAgain() {
// When a media data is loaded that has been checked already
var dataCopy = data.copy(hasCheckedForResume = true)
- resumeListener.onMediaDataLoaded(KEY, null, dataCopy)
+ onMediaDataLoaded(KEY, null, dataCopy, resume = false)
// Then we should not check it again
verify(resumeBrowser, never()).testConnection()
@@ -320,17 +319,15 @@ class MediaResumeListenerTest : SysuiTestCase() {
setUpMbsWithValidResolveInfo()
resumeListener.onMediaDataLoaded(KEY, null, data)
- // We notify the manager to set a null action
- verify(mediaDataManager).setResumeAction(KEY, null)
-
// If we then get another update from the app before the first check completes
assertThat(executor.numPending()).isEqualTo(1)
var dataWithCheck = data.copy(hasCheckedForResume = true)
resumeListener.onMediaDataLoaded(KEY, null, dataWithCheck)
// We do not try to start another check
- assertThat(executor.numPending()).isEqualTo(1)
+ executor.runAllReady()
verify(mediaDataManager).setResumeAction(KEY, null)
+ verify(resumeBrowserFactory, times(1)).create(any(), any(), anyInt())
}
@Test
@@ -363,6 +360,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
resumeListener.userUnlockReceiver.onReceive(context, intent)
// Then we should attempt to find recent media for each saved component
+ executor.runAllReady()
verify(resumeBrowser, times(3)).findRecentMedia()
// Then since the mock service found media, the manager should be informed
@@ -382,10 +380,9 @@ class MediaResumeListenerTest : SysuiTestCase() {
// When media data is loaded that has not been checked yet, and does have a MBS
val dataCopy = data.copy(resumeAction = null, hasCheckedForResume = false)
- resumeListener.onMediaDataLoaded(KEY, null, dataCopy)
+ onMediaDataLoaded(KEY, null, dataCopy)
// Then we test whether the service is valid and set the resume action
- executor.runAllReady()
verify(mediaDataManager).setResumeAction(eq(KEY), eq(null))
verify(resumeBrowser).testConnection()
verify(mediaDataManager, times(2)).setResumeAction(eq(KEY), capture(actionCaptor))
@@ -455,6 +452,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
resumeListener.userUnlockReceiver.onReceive(mockContext, intent)
// We add its resume controls
+ executor.runAllReady()
verify(resumeBrowser).findRecentMedia()
verify(mediaDataManager)
.addResumptionControls(anyInt(), any(), any(), any(), any(), any(), eq(PACKAGE_NAME))
@@ -527,7 +525,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
// When media data is loaded that has not been checked yet, and does have a MBS
val dataCopy = data.copy(resumeAction = null, hasCheckedForResume = false)
- resumeListener.onMediaDataLoaded(KEY, null, dataCopy)
+ onMediaDataLoaded(KEY, null, dataCopy)
// Then we store the new lastPlayed time
verify(sharedPrefsEditor).putString(any(), (capture(componentCaptor)))
@@ -546,10 +544,9 @@ class MediaResumeListenerTest : SysuiTestCase() {
fun testOnMediaDataLoaded_newKeyDifferent_oldMediaBrowserDisconnected() {
setUpMbsWithValidResolveInfo()
- resumeListener.onMediaDataLoaded(key = KEY, oldKey = null, data)
- executor.runAllReady()
+ onMediaDataLoaded(key = KEY, oldKey = null, data)
- resumeListener.onMediaDataLoaded(key = "newKey", oldKey = KEY, data)
+ onMediaDataLoaded(key = "newKey", oldKey = KEY, data)
verify(resumeBrowser).disconnect()
}
@@ -561,8 +558,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
// Set up mocks to return with an error
whenever(resumeBrowser.testConnection()).thenAnswer { callbackCaptor.value.onError() }
- resumeListener.onMediaDataLoaded(key = KEY, oldKey = null, data)
- executor.runAllReady()
+ onMediaDataLoaded(key = KEY, oldKey = null, data)
// Ensure we disconnect the browser
verify(resumeBrowser).disconnect()
@@ -579,8 +575,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
callbackCaptor.value.addTrack(description, component, resumeBrowser)
}
- resumeListener.onMediaDataLoaded(key = KEY, oldKey = null, data)
- executor.runAllReady()
+ onMediaDataLoaded(key = KEY, oldKey = null, data)
// Ensure we disconnect the browser
verify(resumeBrowser).disconnect()
@@ -598,8 +593,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
// Load media data that will require us to get the resume action
val dataCopy = data.copy(resumeAction = null, hasCheckedForResume = false)
- resumeListener.onMediaDataLoaded(KEY, null, dataCopy)
- executor.runAllReady()
+ onMediaDataLoaded(KEY, null, dataCopy)
verify(mediaDataManager, times(2)).setResumeAction(eq(KEY), capture(actionCaptor))
// Set up our factory to return a new browser so we can verify we disconnected the old one
@@ -634,6 +628,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
// When the first user unlocks and we query their recent media
userCallbackCaptor.value.onUserChanged(firstUserId, context)
resumeListener.userUnlockReceiver.onReceive(context, unlockIntent)
+ executor.runAllReady()
whenever(resumeBrowser.userId).thenReturn(userIdCaptor.value)
verify(resumeBrowser, times(3)).findRecentMedia()
@@ -688,4 +683,16 @@ class MediaResumeListenerTest : SysuiTestCase() {
whenever(pm.resolveServiceAsUser(any(), anyInt(), anyInt())).thenReturn(resolveInfo)
whenever(pm.getApplicationLabel(any())).thenReturn(PACKAGE_NAME)
}
+
+ private fun onMediaDataLoaded(
+ key: String,
+ oldKey: String?,
+ data: MediaData,
+ resume: Boolean = true
+ ) {
+ resumeListener.onMediaDataLoaded(key, oldKey, data)
+ if (resume) {
+ assertThat(executor.runAllReady()).isEqualTo(1)
+ }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt
index d9faa30cb072..70af5e75105d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt
@@ -31,17 +31,18 @@ import androidx.compose.ui.test.onChildren
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
+import androidx.compose.ui.text.AnnotatedString
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.FlakyTest
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.common.shared.model.Text
import com.android.systemui.qs.panels.shared.model.SizedTile
import com.android.systemui.qs.panels.shared.model.SizedTileImpl
import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -199,10 +200,11 @@ class DragAndDropTest : SysuiTestCase() {
android.R.drawable.star_on,
ContentDescription.Loaded(tileSpec)
),
- label = Text.Loaded(tileSpec),
+ label = AnnotatedString(tileSpec),
appName = null,
isCurrent = true,
availableEditActions = emptySet(),
+ category = TileCategory.UNKNOWN,
),
getWidth(tileSpec),
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt
index e6ec07e97d17..9f84e346d54a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt
@@ -258,7 +258,7 @@ class InternetTileNewImplTest : SysuiTestCase() {
companion object {
const val WIFI_SSID = "test ssid"
val ACTIVE_WIFI =
- WifiNetworkModel.Active(
+ WifiNetworkModel.Active.of(
isValidated = true,
level = 4,
ssid = WIFI_SSID,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt
index cea8857c01bf..cea8857c01bf 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt
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 b6e23c1f42ee..715e3b472373 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
@@ -85,7 +85,7 @@ class CarrierMergedConnectionRepositoryTest : SysuiTestCase() {
underTest.dataConnectionState.onEach { latestConnState = it }.launchIn(this)
val netJob = underTest.resolvedNetworkType.onEach { latestNetType = it }.launchIn(this)
- wifiRepository.setWifiNetwork(WifiNetworkModel.Inactive)
+ wifiRepository.setWifiNetwork(WifiNetworkModel.Inactive())
assertThat(latestConnState).isEqualTo(DataConnectionState.Disconnected)
assertThat(latestNetType).isNotEqualTo(ResolvedNetworkType.CarrierMergedNetworkType)
@@ -104,7 +104,7 @@ class CarrierMergedConnectionRepositoryTest : SysuiTestCase() {
underTest.dataConnectionState.onEach { latestConnState = it }.launchIn(this)
val netJob = underTest.resolvedNetworkType.onEach { latestNetType = it }.launchIn(this)
- wifiRepository.setWifiNetwork(WifiNetworkModel.Active(level = 1))
+ wifiRepository.setWifiNetwork(WifiNetworkModel.Active.of(level = 1))
assertThat(latestConnState).isEqualTo(DataConnectionState.Disconnected)
assertThat(latestNetType).isNotEqualTo(ResolvedNetworkType.CarrierMergedNetworkType)
@@ -123,7 +123,7 @@ class CarrierMergedConnectionRepositoryTest : SysuiTestCase() {
wifiRepository.setIsWifiDefault(true)
wifiRepository.setWifiNetwork(
- WifiNetworkModel.CarrierMerged(
+ WifiNetworkModel.CarrierMerged.of(
subscriptionId = SUB_ID,
level = 3,
)
@@ -143,7 +143,7 @@ class CarrierMergedConnectionRepositoryTest : SysuiTestCase() {
wifiRepository.setIsWifiEnabled(true)
wifiRepository.setIsWifiDefault(true)
wifiRepository.setWifiNetwork(
- WifiNetworkModel.CarrierMerged(
+ WifiNetworkModel.CarrierMerged.of(
subscriptionId = SUB_ID,
level = 3,
)
@@ -180,7 +180,7 @@ class CarrierMergedConnectionRepositoryTest : SysuiTestCase() {
val typeJob = underTest.resolvedNetworkType.onEach { latestType = it }.launchIn(this)
wifiRepository.setWifiNetwork(
- WifiNetworkModel.CarrierMerged(
+ WifiNetworkModel.CarrierMerged.of(
subscriptionId = SUB_ID + 10,
level = 3,
)
@@ -201,7 +201,7 @@ class CarrierMergedConnectionRepositoryTest : SysuiTestCase() {
val job = underTest.primaryLevel.onEach { latest = it }.launchIn(this)
wifiRepository.setWifiNetwork(
- WifiNetworkModel.CarrierMerged(
+ WifiNetworkModel.CarrierMerged.of(
subscriptionId = SUB_ID,
level = 3,
)
@@ -221,7 +221,7 @@ class CarrierMergedConnectionRepositoryTest : SysuiTestCase() {
val job = underTest.primaryLevel.onEach { latest = it }.launchIn(this)
wifiRepository.setWifiNetwork(
- WifiNetworkModel.CarrierMerged(
+ WifiNetworkModel.CarrierMerged.of(
subscriptionId = SUB_ID,
level = 3,
)
@@ -240,7 +240,7 @@ class CarrierMergedConnectionRepositoryTest : SysuiTestCase() {
val job = underTest.numberOfLevels.onEach { latest = it }.launchIn(this)
wifiRepository.setWifiNetwork(
- WifiNetworkModel.CarrierMerged(
+ WifiNetworkModel.CarrierMerged.of(
subscriptionId = SUB_ID,
level = 1,
numberOfLevels = 6,
@@ -303,7 +303,7 @@ class CarrierMergedConnectionRepositoryTest : SysuiTestCase() {
whenever(telephonyManager.simOperatorName).thenReturn("New SIM name")
wifiRepository.setWifiNetwork(
- WifiNetworkModel.CarrierMerged(
+ WifiNetworkModel.CarrierMerged.of(
subscriptionId = SUB_ID,
level = 3,
)
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 a03980a9d45f..fd23655ffc1c 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
@@ -488,7 +488,7 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() {
// WHEN we set up carrier merged info
wifiRepository.setWifiNetwork(
- WifiNetworkModel.CarrierMerged(
+ WifiNetworkModel.CarrierMerged.of(
SUB_ID,
level = 3,
)
@@ -499,7 +499,7 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() {
// WHEN we update the info
wifiRepository.setWifiNetwork(
- WifiNetworkModel.CarrierMerged(
+ WifiNetworkModel.CarrierMerged.of(
SUB_ID,
level = 1,
)
@@ -538,7 +538,7 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() {
// WHEN isCarrierMerged is set to true
wifiRepository.setWifiNetwork(
- WifiNetworkModel.CarrierMerged(
+ WifiNetworkModel.CarrierMerged.of(
SUB_ID,
level = 3,
)
@@ -550,7 +550,7 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() {
// WHEN the carrier merge network is updated
wifiRepository.setWifiNetwork(
- WifiNetworkModel.CarrierMerged(
+ WifiNetworkModel.CarrierMerged.of(
SUB_ID,
level = 4,
)
@@ -602,7 +602,7 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() {
// THEN updates to the carrier merged level aren't logged
wifiRepository.setWifiNetwork(
- WifiNetworkModel.CarrierMerged(
+ WifiNetworkModel.CarrierMerged.of(
SUB_ID,
level = 4,
)
@@ -610,7 +610,7 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() {
assertThat(dumpBuffer()).doesNotContain("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}4")
wifiRepository.setWifiNetwork(
- WifiNetworkModel.CarrierMerged(
+ WifiNetworkModel.CarrierMerged.of(
SUB_ID,
level = 3,
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
index a1cb29b8e95c..c0a206afe64b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
@@ -574,7 +574,7 @@ class DeviceBasedSatelliteInteractorTest : SysuiTestCase() {
val latest by collectLastValue(underTest.isWifiActive)
// WHEN wifi is active
- wifiRepository.setWifiNetwork(WifiNetworkModel.Active(level = 1))
+ wifiRepository.setWifiNetwork(WifiNetworkModel.Active.of(level = 1))
// THEN the interactor returns true due to the wifi network being active
assertThat(latest).isTrue()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
index c1abf9826ea3..e7e496938033 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
@@ -375,7 +375,7 @@ class DeviceBasedSatelliteViewModelTest : SysuiTestCase() {
repo.isSatelliteProvisioned.value = true
// GIVEN wifi network is active
- wifiRepository.setWifiNetwork(WifiNetworkModel.Active(level = 1))
+ wifiRepository.setWifiNetwork(WifiNetworkModel.Active.of(level = 1))
// THEN icon is null because the device is connected to wifi
assertThat(latest).isNull()
@@ -573,7 +573,7 @@ class DeviceBasedSatelliteViewModelTest : SysuiTestCase() {
repo.isSatelliteProvisioned.value = true
// GIVEN wifi network is active
- wifiRepository.setWifiNetwork(WifiNetworkModel.Active(level = 1))
+ wifiRepository.setWifiNetwork(WifiNetworkModel.Active.of(level = 1))
// THEN carrier text is null because the device is connected to wifi
assertThat(latest).isNull()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt
index fed33179250b..975e2caef2fe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt
@@ -154,7 +154,7 @@ class InternetTileViewModelTest : SysuiTestCase() {
val latest by collectLastValue(underTest.tileModel)
val networkModel =
- WifiNetworkModel.Active(
+ WifiNetworkModel.Active.of(
level = 4,
ssid = "test ssid",
)
@@ -183,7 +183,7 @@ class InternetTileViewModelTest : SysuiTestCase() {
val latest by collectLastValue(underTest.tileModel)
val networkModel =
- WifiNetworkModel.Active(
+ WifiNetworkModel.Active.of(
level = 4,
ssid = "test ssid",
hotspotDeviceType = WifiNetworkModel.HotspotDeviceType.NONE,
@@ -295,7 +295,7 @@ class InternetTileViewModelTest : SysuiTestCase() {
testScope.runTest {
val latest by collectLastValue(underTest.tileModel)
- val networkModel = WifiNetworkModel.Inactive
+ val networkModel = WifiNetworkModel.Inactive()
connectivityRepository.setWifiConnected(validated = false)
wifiRepository.setIsWifiDefault(true)
@@ -310,7 +310,7 @@ class InternetTileViewModelTest : SysuiTestCase() {
testScope.runTest {
val latest by collectLastValue(underTest.tileModel)
- val networkModel = WifiNetworkModel.Inactive
+ val networkModel = WifiNetworkModel.Inactive()
connectivityRepository.setWifiConnected(validated = false)
wifiRepository.setIsWifiDefault(true)
@@ -390,7 +390,7 @@ class InternetTileViewModelTest : SysuiTestCase() {
private fun setWifiNetworkWithHotspot(hotspot: WifiNetworkModel.HotspotDeviceType) {
val networkModel =
- WifiNetworkModel.Active(
+ WifiNetworkModel.Active.of(
level = 4,
ssid = "test ssid",
hotspotDeviceType = hotspot,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
index 46f34e82c688..fd4b77d7fb95 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
@@ -295,7 +295,10 @@ class WifiRepositoryImplTest : SysuiTestCase() {
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
getCallback().onWifiEntriesChanged()
- assertThat(latest).isEqualTo(WifiNetworkModel.Inactive)
+ assertThat(latest).isInstanceOf(WifiNetworkModel.Inactive::class.java)
+ val inactiveReason = (latest as WifiNetworkModel.Inactive).inactiveReason
+ assertThat(inactiveReason).contains("level")
+ assertThat(inactiveReason).contains("$WIFI_LEVEL_UNREACHABLE")
}
@Test
@@ -311,7 +314,10 @@ class WifiRepositoryImplTest : SysuiTestCase() {
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
getCallback().onWifiEntriesChanged()
- assertThat(latest).isEqualTo(WifiNetworkModel.Inactive)
+ assertThat(latest).isInstanceOf(WifiNetworkModel.Inactive::class.java)
+ val inactiveReason = (latest as WifiNetworkModel.Inactive).inactiveReason
+ assertThat(inactiveReason).contains("level")
+ assertThat(inactiveReason).contains("${WIFI_LEVEL_MAX + 1}")
}
@Test
@@ -327,7 +333,10 @@ class WifiRepositoryImplTest : SysuiTestCase() {
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
getCallback().onWifiEntriesChanged()
- assertThat(latest).isEqualTo(WifiNetworkModel.Inactive)
+ assertThat(latest).isInstanceOf(WifiNetworkModel.Inactive::class.java)
+ val inactiveReason = (latest as WifiNetworkModel.Inactive).inactiveReason
+ assertThat(inactiveReason).contains("level")
+ assertThat(inactiveReason).contains("${WIFI_LEVEL_MIN - 1}")
}
@Test
@@ -530,6 +539,25 @@ class WifiRepositoryImplTest : SysuiTestCase() {
}
@Test
+ fun wifiNetwork_carrierMergedButInvalidLevel_flowHasInvalid() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.wifiNetwork)
+
+ val mergedEntry =
+ mock<MergedCarrierEntry>().apply {
+ whenever(this.isPrimaryNetwork).thenReturn(true)
+ whenever(this.subscriptionId).thenReturn(3)
+ whenever(this.isDefaultNetwork).thenReturn(true)
+ whenever(this.level).thenReturn(WIFI_LEVEL_UNREACHABLE)
+ }
+ whenever(wifiPickerTracker.mergedCarrierEntry).thenReturn(mergedEntry)
+
+ getCallback().onWifiEntriesChanged()
+
+ assertThat(latest).isInstanceOf(WifiNetworkModel.Invalid::class.java)
+ }
+
+ @Test
fun wifiNetwork_notValidated_networkNotValidated() =
testScope.runTest {
val latest by collectLastValue(underTest.wifiNetwork)
@@ -571,7 +599,7 @@ class WifiRepositoryImplTest : SysuiTestCase() {
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
getCallback().onWifiEntriesChanged()
- assertThat(latest).isEqualTo(WifiNetworkModel.Inactive)
+ assertThat(latest).isEqualTo(WifiNetworkModel.Inactive())
}
@Test
@@ -587,7 +615,7 @@ class WifiRepositoryImplTest : SysuiTestCase() {
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(null)
getCallback().onWifiEntriesChanged()
- assertThat(latest).isEqualTo(WifiNetworkModel.Inactive)
+ assertThat(latest).isEqualTo(WifiNetworkModel.Inactive())
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModelTest.kt
index 92860efc0c35..1495519cc1a1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModelTest.kt
@@ -24,6 +24,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.log.table.TableRowLogger
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel.Active.Companion.MAX_VALID_LEVEL
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel.Companion.MIN_VALID_LEVEL
+import com.android.wifitrackerlib.WifiEntry.WIFI_LEVEL_UNREACHABLE
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
@@ -32,59 +33,109 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class WifiNetworkModelTest : SysuiTestCase() {
@Test
- fun active_levelsInValidRange_noException() {
+ fun active_levelsInValidRange_createsActive() {
(MIN_VALID_LEVEL..MAX_VALID_LEVEL).forEach { level ->
- WifiNetworkModel.Active(level = level)
- // No assert, just need no crash
+ val result = WifiNetworkModel.Active.of(level = level)
+ assertThat(result).isInstanceOf(WifiNetworkModel.Active::class.java)
}
}
+ fun active_levelTooLow_returnsInactive() {
+ val result = WifiNetworkModel.Active.of(level = MIN_VALID_LEVEL - 1)
+ assertThat(result).isInstanceOf(WifiNetworkModel.Inactive::class.java)
+ }
+
@Test(expected = IllegalArgumentException::class)
- fun active_levelNegative_exceptionThrown() {
- WifiNetworkModel.Active(level = MIN_VALID_LEVEL - 1)
+ fun active_levelTooLow_createdByCopy_exceptionThrown() {
+ val starting = WifiNetworkModel.Active.of(level = MIN_VALID_LEVEL)
+
+ (starting as WifiNetworkModel.Active).copy(level = MIN_VALID_LEVEL - 1)
+ }
+
+ fun active_levelTooHigh_returnsInactive() {
+ val result = WifiNetworkModel.Active.of(level = MAX_VALID_LEVEL + 1)
+
+ assertThat(result).isInstanceOf(WifiNetworkModel.Inactive::class.java)
}
@Test(expected = IllegalArgumentException::class)
- fun active_levelTooHigh_exceptionThrown() {
- WifiNetworkModel.Active(level = MAX_VALID_LEVEL + 1)
+ fun active_levelTooHigh_createdByCopy_exceptionThrown() {
+ val starting = WifiNetworkModel.Active.of(level = MAX_VALID_LEVEL)
+
+ (starting as WifiNetworkModel.Active).copy(level = MAX_VALID_LEVEL + 1)
+ }
+
+ fun active_levelUnreachable_returnsInactive() {
+ val result = WifiNetworkModel.Active.of(level = WIFI_LEVEL_UNREACHABLE)
+
+ assertThat(result).isInstanceOf(WifiNetworkModel.Inactive::class.java)
}
@Test(expected = IllegalArgumentException::class)
- fun carrierMerged_invalidSubId_exceptionThrown() {
- WifiNetworkModel.CarrierMerged(INVALID_SUBSCRIPTION_ID, 1)
+ fun active_levelUnreachable_createdByCopy_exceptionThrown() {
+ val starting = WifiNetworkModel.Active.of(level = MAX_VALID_LEVEL)
+
+ (starting as WifiNetworkModel.Active).copy(level = WIFI_LEVEL_UNREACHABLE)
+ }
+
+ fun carrierMerged_invalidSubId_returnsInvalid() {
+ val result = WifiNetworkModel.CarrierMerged.of(INVALID_SUBSCRIPTION_ID, level = 1)
+
+ assertThat(result).isInstanceOf(WifiNetworkModel.Invalid::class.java)
+ }
+
+ @Test(expected = IllegalArgumentException::class)
+ fun carrierMerged_invalidSubId_createdByCopy_exceptionThrown() {
+ val starting = WifiNetworkModel.CarrierMerged.of(subscriptionId = 1, level = 1)
+
+ (starting as WifiNetworkModel.CarrierMerged).copy(subscriptionId = INVALID_SUBSCRIPTION_ID)
+ }
+
+ fun carrierMerged_levelUnreachable_returnsInvalid() {
+ val result =
+ WifiNetworkModel.CarrierMerged.of(subscriptionId = 1, level = WIFI_LEVEL_UNREACHABLE)
+
+ assertThat(result).isInstanceOf(WifiNetworkModel.Invalid::class.java)
+ }
+
+ @Test(expected = IllegalArgumentException::class)
+ fun carrierMerged_levelUnreachable_createdByCopy_exceptionThrown() {
+ val starting = WifiNetworkModel.CarrierMerged.of(subscriptionId = 1, level = 1)
+
+ (starting as WifiNetworkModel.CarrierMerged).copy(level = WIFI_LEVEL_UNREACHABLE)
}
@Test
fun active_hasValidSsid_nullSsid_false() {
val network =
- WifiNetworkModel.Active(
+ WifiNetworkModel.Active.of(
level = MAX_VALID_LEVEL,
ssid = null,
)
- assertThat(network.hasValidSsid()).isFalse()
+ assertThat((network as WifiNetworkModel.Active).hasValidSsid()).isFalse()
}
@Test
fun active_hasValidSsid_unknownSsid_false() {
val network =
- WifiNetworkModel.Active(
+ WifiNetworkModel.Active.of(
level = MAX_VALID_LEVEL,
ssid = UNKNOWN_SSID,
)
- assertThat(network.hasValidSsid()).isFalse()
+ assertThat((network as WifiNetworkModel.Active).hasValidSsid()).isFalse()
}
@Test
fun active_hasValidSsid_validSsid_true() {
val network =
- WifiNetworkModel.Active(
+ WifiNetworkModel.Active.of(
level = MAX_VALID_LEVEL,
ssid = "FakeSsid",
)
- assertThat(network.hasValidSsid()).isTrue()
+ assertThat((network as WifiNetworkModel.Active).hasValidSsid()).isTrue()
}
// Non-exhaustive logDiffs test -- just want to make sure the logging logic isn't totally broken
@@ -93,14 +144,15 @@ class WifiNetworkModelTest : SysuiTestCase() {
fun logDiffs_carrierMergedToInactive_resetsAllFields() {
val logger = TestLogger()
val prevVal =
- WifiNetworkModel.CarrierMerged(
+ WifiNetworkModel.CarrierMerged.of(
subscriptionId = 3,
level = 1,
)
- WifiNetworkModel.Inactive.logDiffs(prevVal, logger)
+ WifiNetworkModel.Inactive(inactiveReason = "TestReason").logDiffs(prevVal, logger)
- assertThat(logger.changes).contains(Pair(COL_NETWORK_TYPE, TYPE_INACTIVE))
+ assertThat(logger.changes)
+ .contains(Pair(COL_NETWORK_TYPE, "$TYPE_INACTIVE[reason=TestReason]"))
assertThat(logger.changes).contains(Pair(COL_VALIDATED, "false"))
assertThat(logger.changes).contains(Pair(COL_LEVEL, LEVEL_DEFAULT.toString()))
assertThat(logger.changes).contains(Pair(COL_SSID, "null"))
@@ -110,12 +162,12 @@ class WifiNetworkModelTest : SysuiTestCase() {
fun logDiffs_inactiveToCarrierMerged_logsAllFields() {
val logger = TestLogger()
val carrierMerged =
- WifiNetworkModel.CarrierMerged(
+ WifiNetworkModel.CarrierMerged.of(
subscriptionId = 3,
level = 2,
)
- carrierMerged.logDiffs(prevVal = WifiNetworkModel.Inactive, logger)
+ carrierMerged.logDiffs(prevVal = WifiNetworkModel.Inactive(), logger)
assertThat(logger.changes).contains(Pair(COL_NETWORK_TYPE, TYPE_CARRIER_MERGED))
assertThat(logger.changes).contains(Pair(COL_SUB_ID, "3"))
@@ -128,14 +180,14 @@ class WifiNetworkModelTest : SysuiTestCase() {
fun logDiffs_inactiveToActive_logsAllActiveFields() {
val logger = TestLogger()
val activeNetwork =
- WifiNetworkModel.Active(
+ WifiNetworkModel.Active.of(
isValidated = true,
level = 3,
ssid = "Test SSID",
hotspotDeviceType = WifiNetworkModel.HotspotDeviceType.LAPTOP,
)
- activeNetwork.logDiffs(prevVal = WifiNetworkModel.Inactive, logger)
+ activeNetwork.logDiffs(prevVal = WifiNetworkModel.Inactive(), logger)
assertThat(logger.changes).contains(Pair(COL_NETWORK_TYPE, TYPE_ACTIVE))
assertThat(logger.changes).contains(Pair(COL_VALIDATED, "true"))
@@ -148,11 +200,13 @@ class WifiNetworkModelTest : SysuiTestCase() {
fun logDiffs_activeToInactive_resetsAllActiveFields() {
val logger = TestLogger()
val activeNetwork =
- WifiNetworkModel.Active(isValidated = true, level = 3, ssid = "Test SSID")
+ WifiNetworkModel.Active.of(isValidated = true, level = 3, ssid = "Test SSID")
- WifiNetworkModel.Inactive.logDiffs(prevVal = activeNetwork, logger)
+ WifiNetworkModel.Inactive(inactiveReason = "TestReason")
+ .logDiffs(prevVal = activeNetwork, logger)
- assertThat(logger.changes).contains(Pair(COL_NETWORK_TYPE, TYPE_INACTIVE))
+ assertThat(logger.changes)
+ .contains(Pair(COL_NETWORK_TYPE, "$TYPE_INACTIVE[reason=TestReason]"))
assertThat(logger.changes).contains(Pair(COL_VALIDATED, "false"))
assertThat(logger.changes).contains(Pair(COL_LEVEL, LEVEL_DEFAULT.toString()))
assertThat(logger.changes).contains(Pair(COL_SSID, "null"))
@@ -163,14 +217,14 @@ class WifiNetworkModelTest : SysuiTestCase() {
fun logDiffs_carrierMergedToActive_logsAllActiveFields() {
val logger = TestLogger()
val activeNetwork =
- WifiNetworkModel.Active(
+ WifiNetworkModel.Active.of(
isValidated = true,
level = 3,
ssid = "Test SSID",
hotspotDeviceType = WifiNetworkModel.HotspotDeviceType.AUTO,
)
val prevVal =
- WifiNetworkModel.CarrierMerged(
+ WifiNetworkModel.CarrierMerged.of(
subscriptionId = 3,
level = 1,
)
@@ -188,9 +242,9 @@ class WifiNetworkModelTest : SysuiTestCase() {
fun logDiffs_activeToCarrierMerged_logsAllFields() {
val logger = TestLogger()
val activeNetwork =
- WifiNetworkModel.Active(isValidated = true, level = 3, ssid = "Test SSID")
+ WifiNetworkModel.Active.of(isValidated = true, level = 3, ssid = "Test SSID")
val carrierMerged =
- WifiNetworkModel.CarrierMerged(
+ WifiNetworkModel.CarrierMerged.of(
subscriptionId = 3,
level = 2,
)
@@ -208,9 +262,9 @@ class WifiNetworkModelTest : SysuiTestCase() {
fun logDiffs_activeChangesLevel_onlyLevelLogged() {
val logger = TestLogger()
val prevActiveNetwork =
- WifiNetworkModel.Active(isValidated = true, level = 3, ssid = "Test SSID")
+ WifiNetworkModel.Active.of(isValidated = true, level = 3, ssid = "Test SSID")
val newActiveNetwork =
- WifiNetworkModel.Active(isValidated = true, level = 2, ssid = "Test SSID")
+ WifiNetworkModel.Active.of(isValidated = true, level = 2, ssid = "Test SSID")
newActiveNetwork.logDiffs(prevActiveNetwork, logger)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
index ff398f988636..37c7a484a117 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
@@ -195,7 +195,7 @@ class ModernStatusBarWifiViewTest : SysuiTestCase() {
@Test
fun isIconVisible_notEnabled_outputsFalse() {
wifiRepository.setIsWifiEnabled(false)
- wifiRepository.setWifiNetwork(WifiNetworkModel.Active(isValidated = true, level = 2))
+ wifiRepository.setWifiNetwork(WifiNetworkModel.Active.of(isValidated = true, level = 2))
val view = ModernStatusBarWifiView.constructAndBind(context, SLOT_NAME, viewModel)
@@ -210,7 +210,7 @@ class ModernStatusBarWifiViewTest : SysuiTestCase() {
@Test
fun isIconVisible_enabled_outputsTrue() {
wifiRepository.setIsWifiEnabled(true)
- wifiRepository.setWifiNetwork(WifiNetworkModel.Active(isValidated = true, level = 2))
+ wifiRepository.setWifiNetwork(WifiNetworkModel.Active.of(isValidated = true, level = 2))
val view = ModernStatusBarWifiView.constructAndBind(context, SLOT_NAME, viewModel)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt
index 82acb40ec90c..96a01949b243 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt
@@ -206,51 +206,51 @@ internal class WifiViewModelIconParameterizedTest(private val testCase: TestCase
// Enabled = false => no networks shown
TestCase(
enabled = false,
- network = WifiNetworkModel.CarrierMerged(subscriptionId = 1, level = 1),
+ network = WifiNetworkModel.CarrierMerged.of(subscriptionId = 1, level = 1),
expected = null,
),
TestCase(
enabled = false,
- network = WifiNetworkModel.Inactive,
+ network = WifiNetworkModel.Inactive(),
expected = null,
),
TestCase(
enabled = false,
- network = WifiNetworkModel.Active(isValidated = false, level = 1),
+ network = WifiNetworkModel.Active.of(isValidated = false, level = 1),
expected = null,
),
TestCase(
enabled = false,
- network = WifiNetworkModel.Active(isValidated = true, level = 3),
+ network = WifiNetworkModel.Active.of(isValidated = true, level = 3),
expected = null,
),
// forceHidden = true => no networks shown
TestCase(
forceHidden = true,
- network = WifiNetworkModel.CarrierMerged(subscriptionId = 1, level = 1),
+ network = WifiNetworkModel.CarrierMerged.of(subscriptionId = 1, level = 1),
expected = null,
),
TestCase(
forceHidden = true,
- network = WifiNetworkModel.Inactive,
+ network = WifiNetworkModel.Inactive(),
expected = null,
),
TestCase(
enabled = false,
- network = WifiNetworkModel.Active(isValidated = false, level = 2),
+ network = WifiNetworkModel.Active.of(isValidated = false, level = 2),
expected = null,
),
TestCase(
forceHidden = true,
- network = WifiNetworkModel.Active(isValidated = true, level = 1),
+ network = WifiNetworkModel.Active.of(isValidated = true, level = 1),
expected = null,
),
// alwaysShowIconWhenEnabled = true => all Inactive and Active networks shown
TestCase(
alwaysShowIconWhenEnabled = true,
- network = WifiNetworkModel.Inactive,
+ network = WifiNetworkModel.Inactive(),
expected =
Expected(
iconResource = WIFI_NO_NETWORK,
@@ -263,7 +263,7 @@ internal class WifiViewModelIconParameterizedTest(private val testCase: TestCase
),
TestCase(
alwaysShowIconWhenEnabled = true,
- network = WifiNetworkModel.Active(isValidated = false, level = 4),
+ network = WifiNetworkModel.Active.of(isValidated = false, level = 4),
expected =
Expected(
iconResource = WIFI_NO_INTERNET_ICONS[4],
@@ -276,7 +276,7 @@ internal class WifiViewModelIconParameterizedTest(private val testCase: TestCase
),
TestCase(
alwaysShowIconWhenEnabled = true,
- network = WifiNetworkModel.Active(isValidated = true, level = 2),
+ network = WifiNetworkModel.Active.of(isValidated = true, level = 2),
expected =
Expected(
iconResource = WIFI_FULL_ICONS[2],
@@ -290,7 +290,7 @@ internal class WifiViewModelIconParameterizedTest(private val testCase: TestCase
// hasDataCapabilities = false => all Inactive and Active networks shown
TestCase(
hasDataCapabilities = false,
- network = WifiNetworkModel.Inactive,
+ network = WifiNetworkModel.Inactive(),
expected =
Expected(
iconResource = WIFI_NO_NETWORK,
@@ -303,7 +303,7 @@ internal class WifiViewModelIconParameterizedTest(private val testCase: TestCase
),
TestCase(
hasDataCapabilities = false,
- network = WifiNetworkModel.Active(isValidated = false, level = 2),
+ network = WifiNetworkModel.Active.of(isValidated = false, level = 2),
expected =
Expected(
iconResource = WIFI_NO_INTERNET_ICONS[2],
@@ -316,7 +316,7 @@ internal class WifiViewModelIconParameterizedTest(private val testCase: TestCase
),
TestCase(
hasDataCapabilities = false,
- network = WifiNetworkModel.Active(isValidated = true, level = 0),
+ network = WifiNetworkModel.Active.of(isValidated = true, level = 0),
expected =
Expected(
iconResource = WIFI_FULL_ICONS[0],
@@ -330,7 +330,7 @@ internal class WifiViewModelIconParameterizedTest(private val testCase: TestCase
// isDefault = true => all Inactive and Active networks shown
TestCase(
isDefault = true,
- network = WifiNetworkModel.Inactive,
+ network = WifiNetworkModel.Inactive(),
expected =
Expected(
iconResource = WIFI_NO_NETWORK,
@@ -343,7 +343,7 @@ internal class WifiViewModelIconParameterizedTest(private val testCase: TestCase
),
TestCase(
isDefault = true,
- network = WifiNetworkModel.Active(isValidated = false, level = 3),
+ network = WifiNetworkModel.Active.of(isValidated = false, level = 3),
expected =
Expected(
iconResource = WIFI_NO_INTERNET_ICONS[3],
@@ -356,7 +356,7 @@ internal class WifiViewModelIconParameterizedTest(private val testCase: TestCase
),
TestCase(
isDefault = true,
- network = WifiNetworkModel.Active(isValidated = true, level = 1),
+ network = WifiNetworkModel.Active.of(isValidated = true, level = 1),
expected =
Expected(
iconResource = WIFI_FULL_ICONS[1],
@@ -372,14 +372,14 @@ internal class WifiViewModelIconParameterizedTest(private val testCase: TestCase
enabled = true,
isDefault = true,
forceHidden = false,
- network = WifiNetworkModel.CarrierMerged(subscriptionId = 1, level = 1),
+ network = WifiNetworkModel.CarrierMerged.of(subscriptionId = 1, level = 1),
expected = null,
),
// isDefault = false => no networks shown
TestCase(
isDefault = false,
- network = WifiNetworkModel.Inactive,
+ network = WifiNetworkModel.Inactive(),
expected = null,
),
TestCase(
@@ -389,7 +389,7 @@ internal class WifiViewModelIconParameterizedTest(private val testCase: TestCase
),
TestCase(
isDefault = false,
- network = WifiNetworkModel.Active(isValidated = false, level = 3),
+ network = WifiNetworkModel.Active.of(isValidated = false, level = 3),
expected = null,
),
@@ -397,7 +397,7 @@ internal class WifiViewModelIconParameterizedTest(private val testCase: TestCase
// because wifi isn't the default connection (b/272509965).
TestCase(
isDefault = false,
- network = WifiNetworkModel.Active(isValidated = true, level = 4),
+ network = WifiNetworkModel.Active.of(isValidated = true, level = 4),
expected = null,
),
)
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/TestScopeProvider.kt b/packages/SystemUI/tests/utils/src/com/android/keyguard/TestScopeProvider.kt
index 6c35734c6eb4..6c35734c6eb4 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/TestScopeProvider.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/keyguard/TestScopeProvider.kt
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/SideFpsOverlayInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/SideFpsOverlayInteractorKosmos.kt
new file mode 100644
index 000000000000..15c7e25f8a5c
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/SideFpsOverlayInteractorKosmos.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.domain.interactor
+
+import com.android.systemui.keyguard.domain.interactor.deviceEntrySideFpsOverlayInteractor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+@OptIn(ExperimentalCoroutinesApi::class)
+val Kosmos.sideFpsOverlayInteractor by Fixture {
+ SideFpsOverlayInteractorImpl(
+ biometricStatusInteractor,
+ displayStateInteractor,
+ deviceEntrySideFpsOverlayInteractor,
+ sideFpsSensorInteractor,
+ )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderKosmos.kt
index 79d58a1d4e40..59809e3d253f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderKosmos.kt
@@ -19,27 +19,19 @@ package com.android.systemui.biometrics.ui.binder
import android.content.applicationContext
import android.view.layoutInflater
import android.view.windowManager
-import com.android.systemui.biometrics.domain.interactor.biometricStatusInteractor
-import com.android.systemui.biometrics.domain.interactor.displayStateInteractor
-import com.android.systemui.biometrics.domain.interactor.sideFpsSensorInteractor
-import com.android.systemui.keyguard.domain.interactor.deviceEntrySideFpsOverlayInteractor
-import com.android.systemui.keyguard.ui.viewmodel.sideFpsProgressBarViewModel
+import com.android.systemui.biometrics.domain.interactor.sideFpsOverlayInteractor
+import com.android.systemui.biometrics.ui.viewmodel.sideFpsOverlayViewModel
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.kosmos.applicationCoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-@OptIn(ExperimentalCoroutinesApi::class)
val Kosmos.sideFpsOverlayViewBinder by Fixture {
SideFpsOverlayViewBinder(
- applicationScope = applicationCoroutineScope,
- applicationContext = applicationContext,
- { biometricStatusInteractor },
- { displayStateInteractor },
- { deviceEntrySideFpsOverlayInteractor },
+ applicationCoroutineScope,
+ applicationContext,
{ layoutInflater },
- { sideFpsProgressBarViewModel },
- { sideFpsSensorInteractor },
+ { sideFpsOverlayInteractor },
+ { sideFpsOverlayViewModel },
{ windowManager }
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelKosmos.kt
index de038559fc38..e10b2dd6497d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelKosmos.kt
@@ -27,9 +27,9 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
@OptIn(ExperimentalCoroutinesApi::class)
val Kosmos.sideFpsOverlayViewModel by Fixture {
SideFpsOverlayViewModel(
- applicationContext = applicationContext,
- deviceEntrySideFpsOverlayInteractor = deviceEntrySideFpsOverlayInteractor,
- displayStateInteractor = displayStateInteractor,
- sfpsSensorInteractor = sideFpsSensorInteractor,
+ applicationContext,
+ deviceEntrySideFpsOverlayInteractor,
+ displayStateInteractor,
+ sideFpsSensorInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorKosmos.kt
index 811c6533c656..251a6b10a0da 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorKosmos.kt
@@ -50,6 +50,13 @@ var Kosmos.keyboardTouchpadEduStatsInteractor by
Kosmos.Fixture {
KeyboardTouchpadEduStatsInteractorImpl(
backgroundScope = testScope.backgroundScope,
- contextualEducationInteractor = contextualEducationInteractor
+ contextualEducationInteractor = contextualEducationInteractor,
+ inputDeviceRepository =
+ UserInputDeviceRepository(
+ testDispatcher,
+ keyboardRepository,
+ touchpadRepository,
+ userRepository
+ )
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt
index 27eadb147055..d920c4f05b03 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt
@@ -25,6 +25,7 @@ import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.domain.resolver.notifShadeSceneFamilyResolver
import com.android.systemui.scene.domain.resolver.quickSettingsSceneFamilyResolver
+import com.android.systemui.shade.domain.interactor.shadeInteractor
import kotlinx.coroutines.ExperimentalCoroutinesApi
@ExperimentalCoroutinesApi
@@ -35,11 +36,13 @@ val Kosmos.keyguardDismissActionInteractor by
transitionInteractor = keyguardTransitionInteractor,
dismissInteractor = keyguardDismissInteractor,
applicationScope = testScope.backgroundScope,
- sceneInteractor = sceneInteractor,
- deviceEntryInteractor = deviceEntryInteractor,
- quickSettingsSceneFamilyResolver = quickSettingsSceneFamilyResolver,
- notifShadeSceneFamilyResolver = notifShadeSceneFamilyResolver,
+ sceneInteractor = { sceneInteractor },
+ deviceEntryInteractor = { deviceEntryInteractor },
+ quickSettingsSceneFamilyResolver = { quickSettingsSceneFamilyResolver },
+ notifShadeSceneFamilyResolver = { notifShadeSceneFamilyResolver },
powerInteractor = powerInteractor,
alternateBouncerInteractor = alternateBouncerInteractor,
+ keyguardInteractor = { keyguardInteractor },
+ shadeInteractor = { shadeInteractor },
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceLoggerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceLoggerKosmos.kt
new file mode 100644
index 000000000000..76d71dd05edd
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceLoggerKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.controls.domain.pipeline
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.log.logcatLogBuffer
+
+var Kosmos.mediaDeviceLogger by
+ Kosmos.Fixture { MediaDeviceLogger(logcatLogBuffer("MediaDeviceLoggerKosmos")) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceManagerKosmos.kt
index c479ce676761..11408d8a4b90 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceManagerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceManagerKosmos.kt
@@ -41,5 +41,6 @@ val Kosmos.mediaDeviceManager by
},
fgExecutor = fakeExecutor,
bgExecutor = fakeExecutor,
+ logger = mediaDeviceLogger,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelKosmos.kt
index b03542cb569e..33227a4fcc62 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelKosmos.kt
@@ -16,6 +16,8 @@
package com.android.systemui.qs.panels.ui.viewmodel
+import android.content.applicationContext
+import com.android.systemui.common.ui.domain.interactor.configurationInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.qs.panels.domain.interactor.editTilesListInteractor
@@ -33,6 +35,8 @@ val Kosmos.editModeViewModel by
currentTilesInteractor,
tilesAvailabilityInteractor,
minimumTilesInteractor,
+ configurationInteractor,
+ applicationContext,
infiniteGridLayout,
applicationCoroutineScope,
gridLayoutTypeInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt
index dceb8bff0ae7..f66125a6087e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt
@@ -20,6 +20,7 @@ import android.os.UserHandle
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.qs.instanceIdSequenceFake
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory
import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
import com.android.systemui.qs.tiles.viewmodel.QSTileState
@@ -47,6 +48,7 @@ val Kosmos.customTileViewModelFactory: QSTileViewModelFactory.Component by
tileSpec,
QSTileUIConfig.Empty,
instanceIdSequenceFake.newInstanceId(),
+ category = TileCategory.PROVIDED_BY_APP,
)
object : QSTileViewModel {
override val state: StateFlow<QSTileState?> =
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigTestBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigTestBuilder.kt
index 2a0ee888db35..73d9b3233375 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigTestBuilder.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigTestBuilder.kt
@@ -18,6 +18,7 @@ package com.android.systemui.qs.tiles.viewmodel
import com.android.internal.logging.InstanceId
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
object QSTileConfigTestBuilder {
@@ -30,12 +31,14 @@ object QSTileConfigTestBuilder {
var instanceId: InstanceId = InstanceId.fakeInstanceId(0)
var metricsSpec: String = tileSpec.spec
var policy: QSTilePolicy = QSTilePolicy.NoRestrictions
+ var category: TileCategory = TileCategory.UNKNOWN
fun build() =
QSTileConfig(
tileSpec,
uiConfig,
instanceId,
+ category,
metricsSpec,
policy,
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryHelper.java b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/NotificationEntryHelper.java
index 2420e573421a..2420e573421a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryHelper.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/NotificationEntryHelper.java
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt
index 709be5edf4c0..7ca90ea4bd7d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt
@@ -32,7 +32,7 @@ class FakeWifiRepository : WifiRepository {
override val isWifiDefault: StateFlow<Boolean> = _isWifiDefault
private val _wifiNetwork: MutableStateFlow<WifiNetworkModel> =
- MutableStateFlow(WifiNetworkModel.Inactive)
+ MutableStateFlow(WifiNetworkModel.Inactive())
override val wifiNetwork: StateFlow<WifiNetworkModel> = _wifiNetwork
override val secondaryNetworks = MutableStateFlow<List<WifiNetworkModel>>(emptyList())
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioRepository.kt
index 888351f0a882..ba6ffd742611 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioRepository.kt
@@ -33,11 +33,7 @@ import kotlinx.coroutines.flow.update
class FakeAudioRepository : AudioRepository {
- private val unMutableStreams =
- setOf(
- AudioManager.STREAM_VOICE_CALL,
- AudioManager.STREAM_ALARM,
- )
+ private val unMutableStreams = setOf(AudioManager.STREAM_VOICE_CALL, AudioManager.STREAM_ALARM)
private val mutableMode = MutableStateFlow(AudioManager.MODE_NORMAL)
override val mode: StateFlow<Int> = mutableMode.asStateFlow()
@@ -126,7 +122,7 @@ class FakeAudioRepository : AudioRepository {
lastAudibleVolumes[audioStream] = volume
}
- override suspend fun setRingerMode(audioStream: AudioStream, mode: RingerMode) {
+ override suspend fun setRingerModeInternal(audioStream: AudioStream, mode: RingerMode) {
mutableRingerMode.value = mode
}
diff --git a/ravenwood/TEST_MAPPING b/ravenwood/TEST_MAPPING
index 469759bc4b40..7f9d9c29484c 100644
--- a/ravenwood/TEST_MAPPING
+++ b/ravenwood/TEST_MAPPING
@@ -142,6 +142,10 @@
"host": true
},
{
+ "name": "RavenwoodCoreTest",
+ "host": true
+ },
+ {
"name": "RavenwoodMinimumTest",
"host": true
},
diff --git a/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java b/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java
new file mode 100644
index 000000000000..a5a16c14600b
--- /dev/null
+++ b/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ravenwoodtest.bivalenttest;
+
+import static android.platform.test.ravenwood.RavenwoodConfig.isOnRavenwood;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeTrue;
+
+import android.platform.test.ravenwood.RavenwoodConfig;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test to make sure the config field is used.
+ */
+@RunWith(AndroidJUnit4.class)
+public class RavenwoodConfigTest {
+ private static final String PACKAGE_NAME = "com.test";
+
+ @RavenwoodConfig.Config
+ public static RavenwoodConfig sConfig =
+ new RavenwoodConfig.Builder()
+ .setPackageName(PACKAGE_NAME)
+ .build();
+
+ @Test
+ public void testConfig() {
+ assumeTrue(isOnRavenwood());
+ assertEquals(PACKAGE_NAME,
+ InstrumentationRegistry.getInstrumentation().getContext().getPackageName());
+ }
+}
diff --git a/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodMultipleRuleTest.java b/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodMultipleRuleTest.java
new file mode 100644
index 000000000000..c25d2b4cbc4d
--- /dev/null
+++ b/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodMultipleRuleTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ravenwoodtest.bivalenttest;
+
+import android.platform.test.ravenwood.RavenwoodConfig;
+import android.platform.test.ravenwood.RavenwoodRule;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Assume;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+
+/**
+ * Make sure having multiple RavenwoodRule's is detected.
+ * (But only when running on ravenwod. Otherwise it'll be ignored.)
+ */
+@RunWith(AndroidJUnit4.class)
+public class RavenwoodMultipleRuleTest {
+
+ @Rule(order = Integer.MIN_VALUE)
+ public final ExpectedException mExpectedException = ExpectedException.none();
+
+ @Rule
+ public final RavenwoodRule mRavenwood1 = new RavenwoodRule();
+
+ @Rule
+ public final RavenwoodRule mRavenwood2 = new RavenwoodRule();
+
+ public RavenwoodMultipleRuleTest() {
+ // We can't call it within the test method because the exception happens before
+ // calling the method, so set it up here.
+ if (RavenwoodConfig.isOnRavenwood()) {
+ mExpectedException.expectMessage("Multiple nesting RavenwoodRule");
+ }
+ }
+
+ @Test
+ public void testMultipleRulesNotAllowed() {
+ Assume.assumeTrue(RavenwoodConfig.isOnRavenwood());
+ }
+}
diff --git a/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/listenertests/RavenwoodAfterClassFailureTest.java b/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/listenertests/RavenwoodAfterClassFailureTest.java
deleted file mode 100644
index f9794ad5941e..000000000000
--- a/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/listenertests/RavenwoodAfterClassFailureTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.ravenwoodtest.bivalenttest.listenertests;
-
-import static android.platform.test.ravenwood.RavenwoodRule.isOnRavenwood;
-
-import org.junit.AfterClass;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
-import platform.test.runner.parameterized.Parameters;
-
-/**
- * Test that throws from @AfterClass.
- *
- * Tradefed would ignore it, so instead RavenwoodAwareTestRunner would detect it and kill
- * the self (test) process.
- *
- * Unfortunately, this behavior can't easily be tested from within this class, so for now
- * it's only used for a manual test, which you can run by removing the @Ignore.
- *
- * TODO(b/364948126) Improve the tests and automate it.
- */
-@Ignore
-@RunWith(ParameterizedAndroidJunit4.class)
-public class RavenwoodAfterClassFailureTest {
- public RavenwoodAfterClassFailureTest(String param) {
- }
-
- @AfterClass
- public static void afterClass() {
- if (!isOnRavenwood()) return; // Don't do anything on real device.
-
- throw new RuntimeException("FAILURE");
- }
-
- @Parameters
- public static List<String> getParams() {
- var params = new ArrayList<String>();
- params.add("foo");
- params.add("bar");
- return params;
- }
-
- @Test
- public void test1() {
- }
-
- @Test
- public void test2() {
- }
-}
diff --git a/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/listenertests/RavenwoodBeforeClassAssumptionFailureTest.java b/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/listenertests/RavenwoodBeforeClassAssumptionFailureTest.java
deleted file mode 100644
index 61fb06865545..000000000000
--- a/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/listenertests/RavenwoodBeforeClassAssumptionFailureTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.ravenwoodtest.bivalenttest.listenertests;
-
-import static android.platform.test.ravenwood.RavenwoodRule.isOnRavenwood;
-
-import org.junit.Assume;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
-import platform.test.runner.parameterized.Parameters;
-
-/**
- * Test that fails in assumption in @BeforeClass.
- *
- * This is only used for manual tests. Make sure `atest` shows 4 test results with
- * "ASSUMPTION_FAILED".
- *
- * TODO(b/364948126) Improve the tests and automate it.
- */
-@RunWith(ParameterizedAndroidJunit4.class)
-public class RavenwoodBeforeClassAssumptionFailureTest {
- public RavenwoodBeforeClassAssumptionFailureTest(String param) {
- }
-
- @BeforeClass
- public static void beforeClass() {
- if (!isOnRavenwood()) return; // Don't do anything on real device.
-
- Assume.assumeTrue(false);
- }
-
- @Parameters
- public static List<String> getParams() {
- var params = new ArrayList<String>();
- params.add("foo");
- params.add("bar");
- return params;
- }
-
- @Test
- public void test1() {
- }
-
- @Test
- public void test2() {
- }
-}
diff --git a/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/listenertests/RavenwoodBeforeClassFailureTest.java b/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/listenertests/RavenwoodBeforeClassFailureTest.java
deleted file mode 100644
index 626ce8198eeb..000000000000
--- a/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/listenertests/RavenwoodBeforeClassFailureTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.ravenwoodtest.bivalenttest.listenertests;
-
-import static android.platform.test.ravenwood.RavenwoodRule.isOnRavenwood;
-
-import org.junit.BeforeClass;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
-import platform.test.runner.parameterized.Parameters;
-
-/**
- * Test that fails throws from @BeforeClass.
- *
- * This is only used for manual tests. Make sure `atest` shows 4 test results with
- * a "FAILURE" runtime exception.
- *
- * In order to run the test, you'll need to remove the @Ignore.
- *
- * TODO(b/364948126) Improve the tests and automate it.
- */
-@Ignore
-@RunWith(ParameterizedAndroidJunit4.class)
-public class RavenwoodBeforeClassFailureTest {
- public static final String TAG = "RavenwoodBeforeClassFailureTest";
-
- public RavenwoodBeforeClassFailureTest(String param) {
- }
-
- @BeforeClass
- public static void beforeClass() {
- if (!isOnRavenwood()) return; // Don't do anything on real device.
-
- throw new RuntimeException("FAILURE");
- }
-
- @Parameters
- public static List<String> getParams() {
- var params = new ArrayList<String>();
- params.add("foo");
- params.add("bar");
- return params;
- }
-
- @Test
- public void test1() {
- }
-
- @Test
- public void test2() {
- }
-}
diff --git a/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/listenertests/RavenwoodClassRuleAssumptionFailureTest.java b/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/listenertests/RavenwoodClassRuleAssumptionFailureTest.java
deleted file mode 100644
index dc949c466110..000000000000
--- a/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/listenertests/RavenwoodClassRuleAssumptionFailureTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.ravenwoodtest.bivalenttest.listenertests;
-
-import static android.platform.test.ravenwood.RavenwoodRule.isOnRavenwood;
-
-import static org.junit.Assume.assumeTrue;
-
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runner.RunWith;
-import org.junit.runners.model.Statement;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
-import platform.test.runner.parameterized.Parameters;
-
-/**
- * Test that fails in assumption from a class rule.
- *
- * This is only used for manual tests. Make sure `atest` shows 4 test results with
- * "ASSUMPTION_FAILED".
- *
- * TODO(b/364948126) Improve the tests and automate it.
- */
-@RunWith(ParameterizedAndroidJunit4.class)
-public class RavenwoodClassRuleAssumptionFailureTest {
- public static final String TAG = "RavenwoodClassRuleFailureTest";
-
- @ClassRule
- public static final TestRule sClassRule = new TestRule() {
- @Override
- public Statement apply(Statement base, Description description) {
- if (!isOnRavenwood()) {
- return base; // Just run the test as-is on a real device.
- }
-
- assumeTrue(false);
- return null; // unreachable
- }
- };
-
- public RavenwoodClassRuleAssumptionFailureTest(String param) {
- }
-
- @Parameters
- public static List<String> getParams() {
- var params = new ArrayList<String>();
- params.add("foo");
- params.add("bar");
- return params;
- }
-
- @Test
- public void test1() {
- }
-
- @Test
- public void test2() {
- }
-}
diff --git a/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/listenertests/RavenwoodClassRuleFailureTest.java b/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/listenertests/RavenwoodClassRuleFailureTest.java
deleted file mode 100644
index 9996bec41525..000000000000
--- a/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/listenertests/RavenwoodClassRuleFailureTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.ravenwoodtest.bivalenttest.listenertests;
-
-import static android.platform.test.ravenwood.RavenwoodRule.isOnRavenwood;
-
-import org.junit.ClassRule;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runner.RunWith;
-import org.junit.runners.model.Statement;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
-import platform.test.runner.parameterized.Parameters;
-
-/**
- * Test that fails throws from a class rule.
- *
- * This is only used for manual tests. Make sure `atest` shows 4 test results with
- * a "FAILURE" runtime exception.
- *
- * In order to run the test, you'll need to remove the @Ignore.
- *
- * TODO(b/364948126) Improve the tests and automate it.
- */
-@Ignore
-@RunWith(ParameterizedAndroidJunit4.class)
-public class RavenwoodClassRuleFailureTest {
- public static final String TAG = "RavenwoodClassRuleFailureTest";
-
- @ClassRule
- public static final TestRule sClassRule = new TestRule() {
- @Override
- public Statement apply(Statement base, Description description) {
- if (!isOnRavenwood()) {
- return base; // Just run the test as-is on a real device.
- }
-
- throw new RuntimeException("FAILURE");
- }
- };
-
- public RavenwoodClassRuleFailureTest(String param) {
- }
-
- @Parameters
- public static List<String> getParams() {
- var params = new ArrayList<String>();
- params.add("foo");
- params.add("bar");
- return params;
- }
-
- @Test
- public void test1() {
- }
-
- @Test
- public void test2() {
- }
-}
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerHook.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerHook.java
index 6d21e440e911..92a1cb7fc3bf 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerHook.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerHook.java
@@ -31,13 +31,16 @@ import com.android.internal.os.RuntimeInit;
import com.android.ravenwood.common.RavenwoodCommonUtils;
import org.junit.runner.Description;
-import org.junit.runner.Runner;
import org.junit.runners.model.TestClass;
-import java.util.Stack;
-
/**
* Provide hook points created by {@link RavenwoodAwareTestRunner}.
+ *
+ * States are associated with each {@link RavenwoodAwareTestRunner} are stored in
+ * {@link RavenwoodRunnerState}, rather than as members of {@link RavenwoodAwareTestRunner}.
+ * See its javadoc for the reasons.
+ *
+ * All methods in this class must be called from the test main thread.
*/
public class RavenwoodAwareTestRunnerHook {
private static final String TAG = RavenwoodAwareTestRunner.TAG;
@@ -45,27 +48,10 @@ public class RavenwoodAwareTestRunnerHook {
private RavenwoodAwareTestRunnerHook() {
}
- private static RavenwoodTestStats sStats; // lazy initialization.
-
- // Keep track of the current class description.
-
- // Test classes can be nested because of "Suite", so we need a stack to keep track.
- private static final Stack<Description> sClassDescriptions = new Stack<>();
- private static Description sCurrentClassDescription;
-
- private static RavenwoodTestStats getStats() {
- if (sStats == null) {
- // We don't want to throw in the static initializer, because tradefed may not report
- // it properly, so we initialize it here.
- sStats = new RavenwoodTestStats();
- }
- return sStats;
- }
-
/**
* Called when a runner starts, before the inner runner gets a chance to run.
*/
- public static void onRunnerInitializing(Runner runner, TestClass testClass) {
+ public static void onRunnerInitializing(RavenwoodAwareTestRunner runner, TestClass testClass) {
// TODO: Move the initialization code to a better place.
initOnce();
@@ -103,7 +89,29 @@ public class RavenwoodAwareTestRunnerHook {
*/
public static void onClassSkipped(Description description) {
Log.i(TAG, "onClassSkipped: description=" + description);
- getStats().onClassSkipped(description);
+ RavenwoodTestStats.getInstance().onClassSkipped(description);
+ }
+
+ /**
+ * Called before the inner runner starts.
+ */
+ public static void onBeforeInnerRunnerStart(
+ RavenwoodAwareTestRunner runner, Description description) throws Throwable {
+ Log.v(TAG, "onBeforeInnerRunnerStart: description=" + description);
+
+ // Prepare the environment before the inner runner starts.
+ RavenwoodRunnerState.forRunner(runner).enterTestClass(description);
+ }
+
+ /**
+ * Called after the inner runner finished.
+ */
+ public static void onAfterInnerRunnerFinished(
+ RavenwoodAwareTestRunner runner, Description description) throws Throwable {
+ Log.v(TAG, "onAfterInnerRunnerFinished: description=" + description);
+
+ RavenwoodTestStats.getInstance().onClassFinished(description);
+ RavenwoodRunnerState.forRunner(runner).exitTestClass();
}
/**
@@ -112,21 +120,23 @@ public class RavenwoodAwareTestRunnerHook {
* Return false if it should be skipped.
*/
public static boolean onBefore(RavenwoodAwareTestRunner runner, Description description,
- Scope scope, Order order) {
+ Scope scope, Order order) throws Throwable {
Log.v(TAG, "onBefore: description=" + description + ", " + scope + ", " + order);
- if (scope == Scope.Class && order == Order.Outer) {
- // Keep track of the current class.
- sCurrentClassDescription = description;
- sClassDescriptions.push(description);
+ if (scope == Scope.Instance && order == Order.Outer) {
+ // Start of a test method.
+ RavenwoodRunnerState.forRunner(runner).enterTestMethod(description);
}
+ final var classDescription = RavenwoodRunnerState.forRunner(runner).getClassDescription();
+
// Class-level annotations are checked by the runner already, so we only check
// method-level annotations here.
if (scope == Scope.Instance && order == Order.Outer) {
if (!RavenwoodEnablementChecker.shouldEnableOnRavenwood(
description, true)) {
- getStats().onTestFinished(sCurrentClassDescription, description, Result.Skipped);
+ RavenwoodTestStats.getInstance().onTestFinished(
+ classDescription, description, Result.Skipped);
return false;
}
}
@@ -142,15 +152,13 @@ public class RavenwoodAwareTestRunnerHook {
Scope scope, Order order, Throwable th) {
Log.v(TAG, "onAfter: description=" + description + ", " + scope + ", " + order + ", " + th);
+ final var classDescription = RavenwoodRunnerState.forRunner(runner).getClassDescription();
+
if (scope == Scope.Instance && order == Order.Outer) {
- getStats().onTestFinished(sCurrentClassDescription, description,
+ // End of a test method.
+ RavenwoodRunnerState.forRunner(runner).exitTestMethod();
+ RavenwoodTestStats.getInstance().onTestFinished(classDescription, description,
th == null ? Result.Passed : Result.Failed);
-
- } else if (scope == Scope.Class && order == Order.Outer) {
- getStats().onClassFinished(sCurrentClassDescription);
- sClassDescriptions.pop();
- sCurrentClassDescription =
- sClassDescriptions.size() == 0 ? null : sClassDescriptions.peek();
}
// If RUN_DISABLED_TESTS is set, and the method did _not_ throw, make it an error.
@@ -190,4 +198,25 @@ public class RavenwoodAwareTestRunnerHook {
public static boolean shouldRunClassOnRavenwood(Class<?> clazz) {
return RavenwoodEnablementChecker.shouldRunClassOnRavenwood(clazz, true);
}
-}
+
+ /**
+ * Called by RavenwoodRule.
+ */
+ public static void onRavenwoodRuleEnter(RavenwoodAwareTestRunner runner,
+ Description description, RavenwoodRule rule) throws Throwable {
+ Log.v(TAG, "onRavenwoodRuleEnter: description=" + description);
+
+ RavenwoodRunnerState.forRunner(runner).enterRavenwoodRule(rule);
+ }
+
+
+ /**
+ * Called by RavenwoodRule.
+ */
+ public static void onRavenwoodRuleExit(RavenwoodAwareTestRunner runner,
+ Description description, RavenwoodRule rule) throws Throwable {
+ Log.v(TAG, "onRavenwoodRuleExit: description=" + description);
+
+ RavenwoodRunnerState.forRunner(runner).exitRavenwoodRule(rule);
+ }
+} \ No newline at end of file
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java
new file mode 100644
index 000000000000..d73afd4c391b
--- /dev/null
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.platform.test.ravenwood;
+
+import static com.android.ravenwood.common.RavenwoodCommonUtils.ensureIsPublicMember;
+
+import static org.junit.Assert.fail;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.ravenwood.common.RavenwoodRuntimeException;
+
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.WeakHashMap;
+
+/**
+ * Used to store various states associated with the current test runner.
+ *
+ * This class could be added to {@link RavenwoodAwareTestRunner} as a field, but we don't
+ * want to put it in junit-src/ (for one, that'll cause all the downstream dependencies to be
+ * rebuilt when this file is updated), so we manage it separately using a Map from each
+ * {@link RavenwoodAwareTestRunner} instance to a {@link RavenwoodRunnerState}.
+ *
+ * All members must be called from the runner's main thread.
+ */
+public final class RavenwoodRunnerState {
+ private static final String TAG = "RavenwoodRunnerState";
+
+ @GuardedBy("sStates")
+ private static final WeakHashMap<RavenwoodAwareTestRunner, RavenwoodRunnerState> sStates =
+ new WeakHashMap<>();
+
+ /**
+ * Get the instance for a given runner.
+ */
+ public static RavenwoodRunnerState forRunner(@NonNull RavenwoodAwareTestRunner runner) {
+ synchronized (sStates) {
+ var ret = sStates.get(runner);
+ if (ret == null) {
+ ret = new RavenwoodRunnerState(runner);
+ sStates.put(runner, ret);
+ }
+ return ret;
+ }
+ }
+
+ private final RavenwoodAwareTestRunner mRunner;
+
+ private RavenwoodRunnerState(RavenwoodAwareTestRunner runner) {
+ mRunner = runner;
+ }
+
+ private Description mClassDescription;
+ private Description mMethodDescription;
+
+ private RavenwoodConfig mCurrentConfig;
+ private RavenwoodRule mCurrentRule;
+
+ public Description getClassDescription() {
+ return mClassDescription;
+ }
+
+ public void enterTestClass(Description classDescription) throws IOException {
+ mClassDescription = classDescription;
+
+ mCurrentConfig = extractConfiguration(mRunner.getTestClass().getJavaClass());
+
+ if (mCurrentConfig != null) {
+ RavenwoodRuntimeEnvironmentController.init(mCurrentConfig);
+ }
+ }
+
+ public void exitTestClass() {
+ if (mCurrentConfig != null) {
+ try {
+ RavenwoodRuntimeEnvironmentController.reset();
+ } finally {
+ mClassDescription = null;
+ }
+ }
+ }
+
+ public void enterTestMethod(Description description) {
+ mMethodDescription = description;
+ }
+
+ public void exitTestMethod() {
+ mMethodDescription = null;
+ }
+
+ public void enterRavenwoodRule(RavenwoodRule rule) throws IOException {
+ if (mCurrentConfig != null) {
+ fail("RavenwoodConfiguration and RavenwoodRule cannot be used in the same class."
+ + " Suggest migrating to RavenwoodConfiguration.");
+ }
+ if (mCurrentRule != null) {
+ fail("Multiple nesting RavenwoodRule's are detected in the same class,"
+ + " which is not supported.");
+ }
+ mCurrentRule = rule;
+ RavenwoodRuntimeEnvironmentController.init(rule.getConfiguration());
+ }
+
+ public void exitRavenwoodRule(RavenwoodRule rule) {
+ if (mCurrentRule != rule) {
+ return; // This happens if the rule did _not_ take effect somehow.
+ }
+
+ try {
+ RavenwoodRuntimeEnvironmentController.reset();
+ } finally {
+ mCurrentRule = null;
+ }
+ }
+
+ /**
+ * @return a configuration from a test class, if any.
+ */
+ @Nullable
+ private static RavenwoodConfig extractConfiguration(Class<?> testClass) {
+ final boolean hasRavenwoodRule = hasRavenwoodRule(testClass);
+
+ var field = findConfigurationField(testClass);
+ if (field == null) {
+ return null;
+ }
+ if (hasRavenwoodRule) {
+ fail("RavenwoodConfiguration and RavenwoodRule cannot be used in the same class."
+ + " Suggest migrating to RavenwoodConfiguration.");
+ }
+
+ try {
+ return (RavenwoodConfig) field.get(null);
+ } catch (IllegalAccessException e) {
+ throw new RavenwoodRuntimeException("Failed to fetch from the configuration field", e);
+ }
+ }
+
+ /**
+ * @return true if the current target class (or its super classes) has any @Rule / @ClassRule
+ * fields of type RavenwoodRule.
+ *
+ * Note, this check won't detect cases where a Rule is of type
+ * {@link TestRule} and still be a {@link RavenwoodRule}. But that'll be detected at runtime
+ * as a failure, in {@link #enterRavenwoodRule}.
+ */
+ private static boolean hasRavenwoodRule(Class<?> testClass) {
+ for (var field : testClass.getDeclaredFields()) {
+ if (!field.isAnnotationPresent(Rule.class)
+ && field.isAnnotationPresent(ClassRule.class)) {
+ continue;
+ }
+ if (field.getType().equals(RavenwoodRule.class)) {
+ return true;
+ }
+ }
+ // JUnit supports rules as methods, so we need to check them too.
+ for (var method : testClass.getDeclaredMethods()) {
+ if (!method.isAnnotationPresent(Rule.class)
+ && method.isAnnotationPresent(ClassRule.class)) {
+ continue;
+ }
+ if (method.getReturnType().equals(RavenwoodRule.class)) {
+ return true;
+ }
+ }
+ // Look into the super class.
+ if (!testClass.getSuperclass().equals(Object.class)) {
+ return hasRavenwoodRule(testClass.getSuperclass());
+ }
+ return false;
+ }
+
+ /**
+ * Find and return a field with @RavenwoodConfiguration.Config, which must be of type
+ * RavenwoodConfiguration.
+ */
+ @Nullable
+ private static Field findConfigurationField(Class<?> testClass) {
+ Field foundField = null;
+
+ for (var field : testClass.getDeclaredFields()) {
+ final var hasAnot = field.isAnnotationPresent(RavenwoodConfig.Config.class);
+ final var isType = field.getType().equals(RavenwoodConfig.class);
+
+ if (hasAnot) {
+ if (isType) {
+ // Good, use this field.
+ if (foundField != null) {
+ fail(String.format(
+ "Class %s has multiple fields with %s",
+ testClass.getCanonicalName(),
+ "@RavenwoodConfiguration.Config"));
+ }
+ // Make sure it's static public
+ ensureIsPublicMember(field, true);
+
+ foundField = field;
+ } else {
+ fail(String.format(
+ "Field %s.%s has %s but type is not %s",
+ testClass.getCanonicalName(),
+ field.getName(),
+ "@RavenwoodConfiguration.Config",
+ "RavenwoodConfiguration"));
+ return null; // unreachable
+ }
+ } else {
+ if (isType) {
+ fail(String.format(
+ "Field %s.%s does not have %s but type is %s",
+ testClass.getCanonicalName(),
+ field.getName(),
+ "@RavenwoodConfiguration.Config",
+ "RavenwoodConfiguration"));
+ return null; // unreachable
+ } else {
+ // Unrelated field, ignore.
+ continue;
+ }
+ }
+ }
+ if (foundField != null) {
+ return foundField;
+ }
+ if (!testClass.getSuperclass().equals(Object.class)) {
+ return findConfigurationField(testClass.getSuperclass());
+ }
+ return null;
+ }
+}
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
index c4336762c0b8..03c9001366e9 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
@@ -18,6 +18,7 @@ package android.platform.test.ravenwood;
import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_EMPTY_RESOURCES_APK;
import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_RESOURCE_APK;
+import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERBOSE_LOGGING;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -37,6 +38,8 @@ import android.view.DisplayAdjustments;
import androidx.test.platform.app.InstrumentationRegistry;
+import com.android.ravenwood.common.RavenwoodRuntimeException;
+import com.android.ravenwood.common.SneakyThrow;
import com.android.server.LocalServices;
import org.junit.runner.Description;
@@ -53,14 +56,25 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
-public class RavenwoodRuleImpl {
+/**
+ * Responsible for initializing and de-initializing the environment, according to a
+ * {@link RavenwoodConfig}.
+ */
+public class RavenwoodRuntimeEnvironmentController {
+ private static final String TAG = "RavenwoodRuntimeEnvironmentController";
+
+ private RavenwoodRuntimeEnvironmentController() {
+ }
+
private static final String MAIN_THREAD_NAME = "RavenwoodMain";
/**
* When enabled, attempt to dump all thread stacks just before we hit the
* overall Tradefed timeout, to aid in debugging deadlocks.
*/
- private static final boolean ENABLE_TIMEOUT_STACKS = false;
+ private static final boolean ENABLE_TIMEOUT_STACKS =
+ "1".equals(System.getenv("RAVENWOOD_ENABLE_TIMEOUT_STACKS"));
+
private static final int TIMEOUT_MILLIS = 9_000;
private static final ScheduledExecutorService sTimeoutExecutor =
@@ -73,7 +87,8 @@ public class RavenwoodRuleImpl {
/**
* When enabled, attempt to detect uncaught exceptions from background threads.
*/
- private static final boolean ENABLE_UNCAUGHT_EXCEPTION_DETECTION = false;
+ private static final boolean ENABLE_UNCAUGHT_EXCEPTION_DETECTION =
+ "1".equals(System.getenv("RAVENWOOD_ENABLE_UNCAUGHT_EXCEPTION_DETECTION"));
/**
* When set, an unhandled exception was discovered (typically on a background thread), and we
@@ -101,24 +116,46 @@ public class RavenwoodRuleImpl {
return res;
}
- public static void init(RavenwoodRule rule) throws IOException {
+ private static RavenwoodConfig sConfig;
+
+ /**
+ * Initialize the environment.
+ */
+ public static void init(RavenwoodConfig config) throws IOException {
+ if (RAVENWOOD_VERBOSE_LOGGING) {
+ Log.i(TAG, "init() called here", new RuntimeException("STACKTRACE"));
+ }
+ try {
+ initInner(config);
+ } catch (Exception th) {
+ Log.e(TAG, "init() failed", th);
+ reset();
+ SneakyThrow.sneakyThrow(th);
+ }
+ }
+
+ private static void initInner(RavenwoodConfig config) throws IOException {
+ if (sConfig != null) {
+ throw new RavenwoodRuntimeException("Internal error: init() called without reset()");
+ }
+ sConfig = config;
if (ENABLE_UNCAUGHT_EXCEPTION_DETECTION) {
maybeThrowPendingUncaughtException(false);
Thread.setDefaultUncaughtExceptionHandler(sUncaughtExceptionHandler);
}
- android.os.Process.init$ravenwood(rule.mUid, rule.mPid);
+ android.os.Process.init$ravenwood(config.mUid, config.mPid);
sOriginalIdentityToken = Binder.clearCallingIdentity();
- Binder.restoreCallingIdentity(packBinderIdentityToken(false, rule.mUid, rule.mPid));
- setSystemProperties(rule.mSystemProperties);
+ Binder.restoreCallingIdentity(packBinderIdentityToken(false, config.mUid, config.mPid));
+ setSystemProperties(config.mSystemProperties);
ServiceManager.init$ravenwood();
LocalServices.removeAllServicesForTest();
- ActivityManager.init$ravenwood(rule.mCurrentUser);
+ ActivityManager.init$ravenwood(config.mCurrentUser);
final HandlerThread main;
- if (rule.mProvideMainThread) {
+ if (config.mProvideMainThread) {
main = new HandlerThread(MAIN_THREAD_NAME);
main.start();
Looper.setMainLooperForTest(main.getLooper());
@@ -142,21 +179,22 @@ public class RavenwoodRuleImpl {
emptyPaths, emptyPaths, emptyPaths,
emptyPaths, null, null,
new DisplayAdjustments().getCompatibilityInfo(),
- RavenwoodRuleImpl.class.getClassLoader(), null);
+ RavenwoodRuntimeEnvironmentController.class.getClassLoader(), null);
assertNotNull(ret);
return ret;
};
- rule.mContext = new RavenwoodContext(rule.mPackageName, main, resourcesSupplier);
- rule.mInstrumentation = new Instrumentation();
- rule.mInstrumentation.basicInit(rule.mContext);
- InstrumentationRegistry.registerInstance(rule.mInstrumentation, Bundle.EMPTY);
+ config.mContext = new RavenwoodContext(config.mPackageName, main, resourcesSupplier);
+ config.mInstrumentation = new Instrumentation();
+ config.mInstrumentation.basicInit(config.mContext);
+ InstrumentationRegistry.registerInstance(config.mInstrumentation, Bundle.EMPTY);
- RavenwoodSystemServer.init(rule);
+ RavenwoodSystemServer.init(config);
if (ENABLE_TIMEOUT_STACKS) {
- sPendingTimeout = sTimeoutExecutor.schedule(RavenwoodRuleImpl::dumpStacks,
+ sPendingTimeout = sTimeoutExecutor.schedule(
+ RavenwoodRuntimeEnvironmentController::dumpStacks,
TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
}
@@ -165,21 +203,33 @@ public class RavenwoodRuleImpl {
Objects.requireNonNull(Build.VERSION.SDK);
}
- public static void reset(RavenwoodRule rule) {
+ /**
+ * De-initialize.
+ */
+ public static void reset() {
+ if (RAVENWOOD_VERBOSE_LOGGING) {
+ Log.i(TAG, "reset() called here", new RuntimeException("STACKTRACE"));
+ }
+ if (sConfig == null) {
+ throw new RavenwoodRuntimeException("Internal error: reset() already called");
+ }
+ var config = sConfig;
+ sConfig = null;
+
if (ENABLE_TIMEOUT_STACKS) {
sPendingTimeout.cancel(false);
}
- RavenwoodSystemServer.reset(rule);
+ RavenwoodSystemServer.reset(config);
InstrumentationRegistry.registerInstance(null, Bundle.EMPTY);
- rule.mInstrumentation = null;
- if (rule.mContext != null) {
- ((RavenwoodContext) rule.mContext).cleanUp();
+ config.mInstrumentation = null;
+ if (config.mContext != null) {
+ ((RavenwoodContext) config.mContext).cleanUp();
}
- rule.mContext = null;
+ config.mContext = null;
- if (rule.mProvideMainThread) {
+ if (config.mProvideMainThread) {
Looper.getMainLooper().quit();
Looper.clearMainLooperForTest();
}
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java
index cd6b61df392f..f3a93c1dacad 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java
@@ -61,19 +61,19 @@ public class RavenwoodSystemServer {
private static TimingsTraceAndSlog sTimings;
private static SystemServiceManager sServiceManager;
- public static void init(RavenwoodRule rule) {
+ public static void init(RavenwoodConfig config) {
// Avoid overhead if no services required
- if (rule.mServicesRequired.isEmpty()) return;
+ if (config.mServicesRequired.isEmpty()) return;
sStartedServices = new ArraySet<>();
sTimings = new TimingsTraceAndSlog();
- sServiceManager = new SystemServiceManager(rule.mContext);
+ sServiceManager = new SystemServiceManager(config.mContext);
sServiceManager.setStartInfo(false,
SystemClock.elapsedRealtime(),
SystemClock.uptimeMillis());
LocalServices.addService(SystemServiceManager.class, sServiceManager);
- startServices(rule.mServicesRequired);
+ startServices(config.mServicesRequired);
sServiceManager.sealStartedServices();
// TODO: expand to include additional boot phases when relevant
@@ -81,7 +81,7 @@ public class RavenwoodSystemServer {
sServiceManager.startBootPhase(sTimings, SystemService.PHASE_BOOT_COMPLETED);
}
- public static void reset(RavenwoodRule rule) {
+ public static void reset(RavenwoodConfig config) {
// TODO: consider introducing shutdown boot phases
LocalServices.removeServiceForTest(SystemServiceManager.class);
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java
index 3ffabefb7681..428eb57f20bf 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java
@@ -31,7 +31,7 @@ import java.util.HashMap;
import java.util.Map;
/**
- * Creats a "stats" CSV file containing the test results.
+ * Collect test result stats and write them into a CSV file containing the test results.
*
* The output file is created as `/tmp/Ravenwood-stats_[TEST-MODULE=NAME]_[TIMESTAMP].csv`.
* A symlink to the latest result will be created as
@@ -41,6 +41,21 @@ public class RavenwoodTestStats {
private static final String TAG = "RavenwoodTestStats";
private static final String HEADER = "Module,Class,ClassDesc,Passed,Failed,Skipped";
+ private static RavenwoodTestStats sInstance;
+
+ /**
+ * @return a singleton instance.
+ */
+ public static RavenwoodTestStats getInstance() {
+ if (sInstance == null) {
+ sInstance = new RavenwoodTestStats();
+ }
+ return sInstance;
+ }
+
+ /**
+ * Represents a test result.
+ */
public enum Result {
Passed,
Failed,
@@ -113,16 +128,25 @@ public class RavenwoodTestStats {
});
}
+ /**
+ * Call it when a test class is skipped.
+ */
public void onClassSkipped(Description classDescription) {
addResult(classDescription, Description.EMPTY, Result.Skipped);
onClassFinished(classDescription);
}
+ /**
+ * Call it when a test method is finished.
+ */
public void onTestFinished(Description classDescription, Description testDescription,
Result result) {
addResult(classDescription, testDescription, result);
}
+ /**
+ * Call it when a test class is finished.
+ */
public void onClassFinished(Description classDescription) {
int passed = 0;
int skipped = 0;
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
index dffb263e77cb..bc944d76018d 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
@@ -26,8 +26,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.Log;
-import com.android.ravenwood.common.SneakyThrow;
-
import org.junit.Assume;
import org.junit.AssumptionViolatedException;
import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
@@ -61,6 +59,7 @@ import java.lang.annotation.Target;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Stack;
+import java.util.function.BiConsumer;
/**
* A test runner used for Ravenwood.
@@ -83,7 +82,7 @@ import java.util.Stack;
* it will basically just delegate to the inner wrapper, and won't do anything special.
* (no hooks, etc.)
*/
-public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orderable {
+public final class RavenwoodAwareTestRunner extends Runner implements Filterable, Orderable {
public static final String TAG = "Ravenwood";
@Inherited
@@ -105,7 +104,6 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde
/** Scope of a hook. */
public enum Scope {
- Runner,
Class,
Instance,
}
@@ -120,21 +118,21 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde
private static class RavenwoodClassOuterRule implements TestRule {
@Override
public Statement apply(Statement base, Description description) {
- return getCurrentRunner().updateStatement(base, description, Scope.Class, Order.Outer);
+ return getCurrentRunner().wrapWithHooks(base, description, Scope.Class, Order.Outer);
}
}
private static class RavenwoodClassInnerRule implements TestRule {
@Override
public Statement apply(Statement base, Description description) {
- return getCurrentRunner().updateStatement(base, description, Scope.Class, Order.Inner);
+ return getCurrentRunner().wrapWithHooks(base, description, Scope.Class, Order.Inner);
}
}
private static class RavenwoodInstanceOuterRule implements TestRule {
@Override
public Statement apply(Statement base, Description description) {
- return getCurrentRunner().updateStatement(
+ return getCurrentRunner().wrapWithHooks(
base, description, Scope.Instance, Order.Outer);
}
}
@@ -142,7 +140,7 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde
private static class RavenwoodInstanceInnerRule implements TestRule {
@Override
public Statement apply(Statement base, Description description) {
- return getCurrentRunner().updateStatement(
+ return getCurrentRunner().wrapWithHooks(
base, description, Scope.Instance, Order.Inner);
}
}
@@ -160,7 +158,7 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde
/** Keeps track of the runner on the current thread. */
private static final ThreadLocal<RavenwoodAwareTestRunner> sCurrentRunner = new ThreadLocal<>();
- private static RavenwoodAwareTestRunner getCurrentRunner() {
+ static RavenwoodAwareTestRunner getCurrentRunner() {
var runner = sCurrentRunner.get();
if (runner == null) {
throw new RuntimeException("Current test runner not set!");
@@ -296,7 +294,7 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde
@Override
public void run(RunNotifier realNotifier) {
- final RunNotifier notifier = new RavenwoodRunNotifier(realNotifier);
+ final RavenwoodRunNotifier notifier = new RavenwoodRunNotifier(realNotifier);
if (mRealRunner instanceof ClassSkippingTestRunner) {
mRealRunner.run(notifier);
@@ -315,10 +313,26 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde
sCurrentRunner.set(this);
try {
- runWithHooks(getDescription(), Scope.Runner, Order.Outer,
- () -> mRealRunner.run(notifier));
+ try {
+ RavenwoodAwareTestRunnerHook.onBeforeInnerRunnerStart(
+ this, getDescription());
+ } catch (Throwable th) {
+ notifier.reportBeforeTestFailure(getDescription(), th);
+ return;
+ }
+
+ // Delegate to the inner runner.
+ mRealRunner.run(notifier);
} finally {
sCurrentRunner.remove();
+
+ try {
+ RavenwoodAwareTestRunnerHook.onAfterInnerRunnerFinished(
+ this, getDescription());
+ } catch (Throwable th) {
+ notifier.reportAfterTestFailure(th);
+ return;
+ }
}
}
@@ -355,7 +369,7 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde
}
}
- private Statement updateStatement(Statement base, Description description, Scope scope,
+ private Statement wrapWithHooks(Statement base, Description description, Scope scope,
Order order) {
if (!isOnRavenwood()) {
return base;
@@ -368,7 +382,8 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde
};
}
- private void runWithHooks(Description description, Scope scope, Order order, Runnable r) {
+ private void runWithHooks(Description description, Scope scope, Order order, Runnable r)
+ throws Throwable {
runWithHooks(description, scope, order, new Statement() {
@Override
public void evaluate() throws Throwable {
@@ -377,7 +392,8 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde
});
}
- private void runWithHooks(Description description, Scope scope, Order order, Statement s) {
+ private void runWithHooks(Description description, Scope scope, Order order, Statement s)
+ throws Throwable {
if (isOnRavenwood()) {
Assume.assumeTrue(
RavenwoodAwareTestRunnerHook.onBefore(this, description, scope, order));
@@ -394,7 +410,7 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde
this, description, scope, order, t);
}
if (shouldThrow) {
- SneakyThrow.sneakyThrow(t);
+ throw t;
}
}
}
@@ -615,16 +631,13 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde
return true;
}
if (mAfterTest) {
- // Unfortunately, there's no good way to report it, so kill the own process.
- onCriticalError(
- "Failures detected in @AfterClass, which would be swalloed by tradefed",
- th);
- return true; // unreachable
+ reportAfterTestFailure(th);
+ return true;
}
return false;
}
- private void reportBeforeTestFailure(Description suiteDesc, Throwable th) {
+ public void reportBeforeTestFailure(Description suiteDesc, Throwable th) {
// If a failure happens befere running any tests, we'll need to pretend
// as if each test in the suite reported the failure, to work around b/364395552.
for (var child : suiteDesc.getChildren()) {
@@ -646,11 +659,51 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde
}
}
}
+
+ public void reportAfterTestFailure(Throwable th) {
+ // Unfortunately, there's no good way to report it, so kill the own process.
+ onCriticalError(
+ "Failures detected in @AfterClass, which would be swallowed by tradefed",
+ th);
+ }
}
+ private static volatile BiConsumer<String, Throwable> sCriticalErrorHanler;
+
private void onCriticalError(@NonNull String message, @Nullable Throwable th) {
- Log.e(TAG, "Critical error! Ravenwood cannot continue. Killing self process: "
- + message, th);
+ Log.e(TAG, "Critical error! " + message, th);
+ var handler = sCriticalErrorHanler;
+ if (handler == null) {
+ handler = sDefaultCriticalErrorHandler;
+ }
+ handler.accept(message, th);
+ }
+
+ private static BiConsumer<String, Throwable> sDefaultCriticalErrorHandler = (message, th) -> {
+ Log.e(TAG, "Ravenwood cannot continue. Killing self process.", th);
System.exit(1);
+ };
+
+ /**
+ * Contains Ravenwood private APIs.
+ */
+ public static class RavenwoodPrivate {
+ private RavenwoodPrivate() {
+ }
+
+ /**
+ * Set a listener for onCriticalError(), for testing. If a listener is set, we won't call
+ * System.exit().
+ */
+ public void setCriticalErrorHandler(
+ @Nullable BiConsumer<String, Throwable> handler) {
+ sCriticalErrorHanler = handler;
+ }
+ }
+
+ private static final RavenwoodPrivate sRavenwoodPrivate = new RavenwoodPrivate();
+
+ public static RavenwoodPrivate private$ravenwood() {
+ return sRavenwoodPrivate;
}
}
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java
new file mode 100644
index 000000000000..04e0bedc8aab
--- /dev/null
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.platform.test.ravenwood;
+
+import static android.os.Process.FIRST_APPLICATION_UID;
+import static android.os.Process.SYSTEM_UID;
+import static android.os.UserHandle.SYSTEM;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.Instrumentation;
+import android.content.Context;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Represents how to configure the ravenwood environment for a test class.
+ *
+ * If a ravenwood test class has a public static field with the {@link Config} annotation,
+ * Ravenwood will extract the config from it and initializes the environment. The type of the
+ * field must be of {@link RavenwoodConfig}.
+ */
+public final class RavenwoodConfig {
+ /**
+ * Use this to mark a field as the configuration.
+ * @hide
+ */
+ @Target({ElementType.FIELD})
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface Config {
+ }
+
+ private static final int NOBODY_UID = 9999;
+
+ private static final AtomicInteger sNextPid = new AtomicInteger(100);
+
+ int mCurrentUser = SYSTEM.getIdentifier();
+
+ /**
+ * Unless the test author requests differently, run as "nobody", and give each collection of
+ * tests its own unique PID.
+ */
+ int mUid = NOBODY_UID;
+ int mPid = sNextPid.getAndIncrement();
+
+ String mPackageName;
+
+ boolean mProvideMainThread = false;
+
+ final RavenwoodSystemProperties mSystemProperties = new RavenwoodSystemProperties();
+
+ final List<Class<?>> mServicesRequired = new ArrayList<>();
+
+ volatile Context mContext;
+ volatile Instrumentation mInstrumentation;
+
+ private RavenwoodConfig() {
+ }
+
+ /**
+ * Return if the current process is running on a Ravenwood test environment.
+ */
+ public static boolean isOnRavenwood() {
+ return RavenwoodRule.isOnRavenwood();
+ }
+
+ public static class Builder {
+ private final RavenwoodConfig mConfig = new RavenwoodConfig();
+
+ public Builder() {
+ }
+
+ /**
+ * Configure the identity of this process to be the system UID for the duration of the
+ * test. Has no effect on non-Ravenwood environments.
+ */
+ public Builder setProcessSystem() {
+ mConfig.mUid = SYSTEM_UID;
+ return this;
+ }
+
+ /**
+ * Configure the identity of this process to be an app UID for the duration of the
+ * test. Has no effect on non-Ravenwood environments.
+ */
+ public Builder setProcessApp() {
+ mConfig.mUid = FIRST_APPLICATION_UID;
+ return this;
+ }
+
+ /**
+ * Configure the identity of this process to be the given package name for the duration
+ * of the test. Has no effect on non-Ravenwood environments.
+ */
+ public Builder setPackageName(@NonNull String packageName) {
+ mConfig.mPackageName = Objects.requireNonNull(packageName);
+ return this;
+ }
+
+ /**
+ * Configure a "main" thread to be available for the duration of the test, as defined
+ * by {@code Looper.getMainLooper()}. Has no effect on non-Ravenwood environments.
+ */
+ public Builder setProvideMainThread(boolean provideMainThread) {
+ mConfig.mProvideMainThread = provideMainThread;
+ return this;
+ }
+
+ /**
+ * Configure the given system property as immutable for the duration of the test.
+ * Read access to the key is allowed, and write access will fail. When {@code value} is
+ * {@code null}, the value is left as undefined.
+ *
+ * All properties in the {@code debug.*} namespace are automatically mutable, with no
+ * developer action required.
+ *
+ * Has no effect on non-Ravenwood environments.
+ */
+ public Builder setSystemPropertyImmutable(@NonNull String key,
+ @Nullable Object value) {
+ mConfig.mSystemProperties.setValue(key, value);
+ mConfig.mSystemProperties.setAccessReadOnly(key);
+ return this;
+ }
+
+ /**
+ * Configure the given system property as mutable for the duration of the test.
+ * Both read and write access to the key is allowed, and its value will be reset between
+ * each test. When {@code value} is {@code null}, the value is left as undefined.
+ *
+ * All properties in the {@code debug.*} namespace are automatically mutable, with no
+ * developer action required.
+ *
+ * Has no effect on non-Ravenwood environments.
+ */
+ public Builder setSystemPropertyMutable(@NonNull String key,
+ @Nullable Object value) {
+ mConfig.mSystemProperties.setValue(key, value);
+ mConfig.mSystemProperties.setAccessReadWrite(key);
+ return this;
+ }
+
+ /**
+ * Configure the set of system services that are required for this test to operate.
+ *
+ * For example, passing {@code android.hardware.SerialManager.class} as an argument will
+ * ensure that the underlying service is created, initialized, and ready to use for the
+ * duration of the test. The {@code SerialManager} instance can be obtained via
+ * {@code RavenwoodRule.getContext()} and {@code Context.getSystemService()}, and
+ * {@code SerialManagerInternal} can be obtained via {@code LocalServices.getService()}.
+ */
+ public Builder setServicesRequired(@NonNull Class<?>... services) {
+ mConfig.mServicesRequired.clear();
+ for (Class<?> service : services) {
+ mConfig.mServicesRequired.add(service);
+ }
+ return this;
+ }
+
+ public RavenwoodConfig build() {
+ return mConfig;
+ }
+ }
+}
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
index d569896421eb..7847e7cb5463 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
@@ -16,17 +16,13 @@
package android.platform.test.ravenwood;
-import static android.os.Process.FIRST_APPLICATION_UID;
-import static android.os.Process.SYSTEM_UID;
-import static android.os.UserHandle.SYSTEM;
-
import static com.android.ravenwood.common.RavenwoodCommonUtils.log;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Instrumentation;
import android.content.Context;
import android.platform.test.annotations.DisabledOnRavenwood;
-import android.platform.test.annotations.EnabledOnRavenwood;
import com.android.ravenwood.common.RavenwoodCommonUtils;
@@ -34,26 +30,17 @@ 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.Objects;
-import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
/**
- * {@code @Rule} that configures the Ravenwood test environment. This rule has no effect when
- * tests are run on non-Ravenwood test environments.
- *
- * This rule initializes and resets the Ravenwood environment between each test method to offer a
- * hermetic testing environment.
- *
- * By default, all tests are executed on Ravenwood, but annotations such as
- * {@link DisabledOnRavenwood} and {@link EnabledOnRavenwood} can be used at both the method
- * and class level to "ignore" tests that may not be ready. When needed, a
- * {@link RavenwoodClassRule} can be used in addition to a {@link RavenwoodRule} to ignore tests
- * before a test class is fully initialized.
+ * @deprecated Use {@link RavenwoodConfig} to configure the ravenwood environment instead.
+ * A {@link RavenwoodRule} is no longer needed for {@link DisabledOnRavenwood}. To get the
+ * {@link Context} and {@link Instrumentation}, use
+ * {@link androidx.test.platform.app.InstrumentationRegistry} instead.
*/
-public class RavenwoodRule implements TestRule {
+@Deprecated
+public final class RavenwoodRule implements TestRule {
private static final String TAG = "RavenwoodRule";
static final boolean IS_ON_RAVENWOOD = RavenwoodCommonUtils.isOnRavenwood();
@@ -105,35 +92,19 @@ public class RavenwoodRule implements TestRule {
}
}
- private static final int NOBODY_UID = 9999;
-
- private static final AtomicInteger sNextPid = new AtomicInteger(100);
-
- int mCurrentUser = SYSTEM.getIdentifier();
-
- /**
- * Unless the test author requests differently, run as "nobody", and give each collection of
- * tests its own unique PID.
- */
- int mUid = NOBODY_UID;
- int mPid = sNextPid.getAndIncrement();
-
- String mPackageName;
-
- boolean mProvideMainThread = false;
-
- final RavenwoodSystemProperties mSystemProperties = new RavenwoodSystemProperties();
-
- final List<Class<?>> mServicesRequired = new ArrayList<>();
-
- volatile Context mContext;
- volatile Instrumentation mInstrumentation;
+ private final RavenwoodConfig mConfiguration;
public RavenwoodRule() {
+ mConfiguration = new RavenwoodConfig.Builder().build();
+ }
+
+ private RavenwoodRule(RavenwoodConfig config) {
+ mConfiguration = config;
}
public static class Builder {
- private RavenwoodRule mRule = new RavenwoodRule();
+ private final RavenwoodConfig.Builder mBuilder =
+ new RavenwoodConfig.Builder();
public Builder() {
}
@@ -143,7 +114,7 @@ public class RavenwoodRule implements TestRule {
* test. Has no effect on non-Ravenwood environments.
*/
public Builder setProcessSystem() {
- mRule.mUid = SYSTEM_UID;
+ mBuilder.setProcessSystem();
return this;
}
@@ -152,7 +123,7 @@ public class RavenwoodRule implements TestRule {
* test. Has no effect on non-Ravenwood environments.
*/
public Builder setProcessApp() {
- mRule.mUid = FIRST_APPLICATION_UID;
+ mBuilder.setProcessApp();
return this;
}
@@ -160,8 +131,8 @@ public class RavenwoodRule implements TestRule {
* Configure the identity of this process to be the given package name for the duration
* of the test. Has no effect on non-Ravenwood environments.
*/
- public Builder setPackageName(/* @NonNull */ String packageName) {
- mRule.mPackageName = Objects.requireNonNull(packageName);
+ public Builder setPackageName(@NonNull String packageName) {
+ mBuilder.setPackageName(packageName);
return this;
}
@@ -170,7 +141,7 @@ public class RavenwoodRule implements TestRule {
* by {@code Looper.getMainLooper()}. Has no effect on non-Ravenwood environments.
*/
public Builder setProvideMainThread(boolean provideMainThread) {
- mRule.mProvideMainThread = provideMainThread;
+ mBuilder.setProvideMainThread(provideMainThread);
return this;
}
@@ -184,10 +155,8 @@ public class RavenwoodRule implements TestRule {
*
* Has no effect on non-Ravenwood environments.
*/
- public Builder setSystemPropertyImmutable(/* @NonNull */ String key,
- /* @Nullable */ Object value) {
- mRule.mSystemProperties.setValue(key, value);
- mRule.mSystemProperties.setAccessReadOnly(key);
+ public Builder setSystemPropertyImmutable(@NonNull String key, @Nullable Object value) {
+ mBuilder.setSystemPropertyImmutable(key, value);
return this;
}
@@ -201,10 +170,8 @@ public class RavenwoodRule implements TestRule {
*
* Has no effect on non-Ravenwood environments.
*/
- public Builder setSystemPropertyMutable(/* @NonNull */ String key,
- /* @Nullable */ Object value) {
- mRule.mSystemProperties.setValue(key, value);
- mRule.mSystemProperties.setAccessReadWrite(key);
+ public Builder setSystemPropertyMutable(@NonNull String key, @Nullable Object value) {
+ mBuilder.setSystemPropertyMutable(key, value);
return this;
}
@@ -217,16 +184,13 @@ public class RavenwoodRule implements TestRule {
* {@code RavenwoodRule.getContext()} and {@code Context.getSystemService()}, and
* {@code SerialManagerInternal} can be obtained via {@code LocalServices.getService()}.
*/
- public Builder setServicesRequired(Class<?>... services) {
- mRule.mServicesRequired.clear();
- for (Class<?> service : services) {
- mRule.mServicesRequired.add(service);
- }
+ public Builder setServicesRequired(@NonNull Class<?>... services) {
+ mBuilder.setServicesRequired(services);
return this;
}
public RavenwoodRule build() {
- return mRule;
+ return new RavenwoodRule(mBuilder.build());
}
}
@@ -246,41 +210,44 @@ public class RavenwoodRule implements TestRule {
}
/**
- * Return a {@code Context} available for usage during the currently running test case.
- *
- * Each test should obtain needed information or references via this method;
- * references must not be stored beyond the scope of a test case.
+ * @deprecated Use
+ * {@code androidx.test.platform.app.InstrumentationRegistry.getInstrumentation().getContext()}
+ * instead.
*/
+ @Deprecated
public Context getContext() {
- return Objects.requireNonNull(mContext,
+ return Objects.requireNonNull(mConfiguration.mContext,
"Context is only available during @Test execution");
}
/**
- * Return a {@code Instrumentation} available for usage during the currently running test case.
- *
- * Each test should obtain needed information or references via this method;
- * references must not be stored beyond the scope of a test case.
+ * @deprecated Use
+ * {@code androidx.test.platform.app.InstrumentationRegistry.getInstrumentation()}
+ * instead.
*/
+ @Deprecated
public Instrumentation getInstrumentation() {
- return Objects.requireNonNull(mInstrumentation,
+ return Objects.requireNonNull(mConfiguration.mInstrumentation,
"Instrumentation is only available during @Test execution");
}
-
@Override
public Statement apply(Statement base, Description description) {
- // TODO: Here, we're calling init() / reset() once for each rule.
- // That means if a test class has multiple rules -- even if they refer to the same
- // rule instance -- we're calling them multiple times. We need to fix it.
+ if (!RavenwoodConfig.isOnRavenwood()) {
+ return base;
+ }
return new Statement() {
@Override
public void evaluate() throws Throwable {
- RavenwoodRuleImpl.init(RavenwoodRule.this);
+ RavenwoodAwareTestRunnerHook.onRavenwoodRuleEnter(
+ RavenwoodAwareTestRunner.getCurrentRunner(), description,
+ RavenwoodRule.this);
try {
base.evaluate();
} finally {
- RavenwoodRuleImpl.reset(RavenwoodRule.this);
+ RavenwoodAwareTestRunnerHook.onRavenwoodRuleExit(
+ RavenwoodAwareTestRunner.getCurrentRunner(), description,
+ RavenwoodRule.this);
}
}
};
@@ -339,4 +306,8 @@ public class RavenwoodRule implements TestRule {
public static RavenwoodPrivate private$ravenwood() {
return sRavenwoodPrivate;
}
+
+ RavenwoodConfig getConfiguration() {
+ return mConfiguration;
+ }
}
diff --git a/ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerHook.java b/ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerHook.java
index 1e4889ce0678..0178b934a649 100644
--- a/ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerHook.java
+++ b/ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerHook.java
@@ -19,7 +19,6 @@ import android.platform.test.ravenwood.RavenwoodAwareTestRunner.Order;
import android.platform.test.ravenwood.RavenwoodAwareTestRunner.Scope;
import org.junit.runner.Description;
-import org.junit.runner.Runner;
import org.junit.runners.model.TestClass;
/**
@@ -38,7 +37,7 @@ public class RavenwoodAwareTestRunnerHook {
/**
* Called when a runner starts, before the inner runner gets a chance to run.
*/
- public static void onRunnerInitializing(Runner runner, TestClass testClass) {
+ public static void onRunnerInitializing(RavenwoodAwareTestRunner runner, TestClass testClass) {
}
/**
@@ -48,15 +47,38 @@ public class RavenwoodAwareTestRunnerHook {
}
/**
+ * Called before the inner runner starts.
+ */
+ public static void onBeforeInnerRunnerStart(
+ RavenwoodAwareTestRunner runner, Description description) throws Throwable {
+ }
+
+ /**
+ * Called after the inner runner finished.
+ */
+ public static void onAfterInnerRunnerFinished(
+ RavenwoodAwareTestRunner runner, Description description) throws Throwable {
+ }
+
+ /**
* Called before a test / class.
*
* Return false if it should be skipped.
*/
public static boolean onBefore(RavenwoodAwareTestRunner runner, Description description,
- Scope scope, Order order) {
+ Scope scope, Order order) throws Throwable {
return true;
}
+ public static void onRavenwoodRuleEnter(RavenwoodAwareTestRunner runner,
+ Description description, RavenwoodRule rule) throws Throwable {
+ }
+
+ public static void onRavenwoodRuleExit(RavenwoodAwareTestRunner runner,
+ Description description, RavenwoodRule rule) throws Throwable {
+ }
+
+
/**
* Called after a test / class.
*
diff --git a/ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java b/ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java
deleted file mode 100644
index a470626dcbe7..000000000000
--- a/ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java
+++ /dev/null
@@ -1,37 +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 android.platform.test.ravenwood;
-
-import org.junit.runner.Description;
-
-public class RavenwoodRuleImpl {
- public static void init(RavenwoodRule rule) {
- // No-op when running on a real device
- }
-
- public static void reset(RavenwoodRule rule) {
- // No-op when running on a real device
- }
-
- public static void logTestRunner(String label, Description description) {
- // No-op when running on a real device
- }
-
- public static long realCurrentTimeMillis() {
- return System.currentTimeMillis();
- }
-}
diff --git a/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java b/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java
index 875ce71149cd..96746c679020 100644
--- a/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java
+++ b/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java
@@ -26,6 +26,7 @@ import java.io.FileInputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
@@ -279,6 +280,18 @@ public class RavenwoodCommonUtils {
(isStatic ? "static " : "")));
}
+ public static void ensureIsPublicMember(Member member, boolean isStatic) {
+ var ok = Modifier.isPublic(member.getModifiers())
+ && (Modifier.isStatic(member.getModifiers()) == isStatic);
+ if (ok) {
+ return; // okay
+ }
+ throw new AssertionError(String.format(
+ "%s.%s expected to be public %s",
+ member.getDeclaringClass().getName(), member.getName(),
+ (isStatic ? "static" : "")));
+ }
+
@NonNull
public static String getStackTraceString(@Nullable Throwable th) {
StringWriter stringWriter = new StringWriter();
diff --git a/ravenwood/tests/coretest/Android.bp b/ravenwood/tests/coretest/Android.bp
new file mode 100644
index 000000000000..d94475c00240
--- /dev/null
+++ b/ravenwood/tests/coretest/Android.bp
@@ -0,0 +1,25 @@
+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_ravenwood_test {
+ name: "RavenwoodCoreTest",
+
+ static_libs: [
+ "androidx.annotation_annotation",
+ "androidx.test.ext.junit",
+ "androidx.test.rules",
+ "junit-params",
+ "platform-parametric-runner-lib",
+ "truth",
+ ],
+ srcs: [
+ "test/**/*.java",
+ ],
+ auto_gen_config: true,
+}
diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerCallbackTest.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerCallbackTest.java
new file mode 100644
index 000000000000..6d8fb983504b
--- /dev/null
+++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerCallbackTest.java
@@ -0,0 +1,356 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ravenwoodtest.runnercallbacktests;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.platform.test.annotations.NoRavenizer;
+import android.platform.test.ravenwood.RavenwoodAwareTestRunner;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.AfterClass;
+import org.junit.Assume;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.Statement;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
+
+/**
+ * Tests to make sure {@link RavenwoodAwareTestRunner} produces expected callbacks in various
+ * error situations in places such as @BeforeClass / @AfterClass / Constructors, which are
+ * out of test method bodies.
+ */
+@NoRavenizer // This class shouldn't be executed with RavenwoodAwareTestRunner.
+public class RavenwoodRunnerCallbackTest extends RavenwoodRunnerTestBase {
+
+ /**
+ * Throws an exception in @AfterClass. This should produce a critical error.
+ */
+ @RunWith(BlockJUnit4ClassRunner.class)
+ // CHECKSTYLE:OFF Generated code
+ @Expected("""
+ testRunStarted: classes
+ testSuiteStarted: classes
+ testSuiteStarted: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$AfterClassFailureTest
+ testStarted: test1(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$AfterClassFailureTest)
+ testFinished: test1(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$AfterClassFailureTest)
+ testStarted: test2(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$AfterClassFailureTest)
+ testFinished: test2(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$AfterClassFailureTest)
+ testSuiteFinished: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$AfterClassFailureTest
+ criticalError: Failures detected in @AfterClass, which would be swallowed by tradefed: FAILURE
+ testSuiteFinished: classes
+ testRunFinished: 2,0,0,0
+ """)
+ // CHECKSTYLE:ON
+ public static class AfterClassFailureTest {
+ public AfterClassFailureTest() {
+ }
+
+ @AfterClass
+ public static void afterClass() {
+ throw new RuntimeException("FAILURE");
+ }
+
+ @Test
+ public void test1() {
+ }
+
+ @Test
+ public void test2() {
+ }
+
+ }
+
+ /**
+ * Assumption failure in @BeforeClass.
+ */
+ @RunWith(ParameterizedAndroidJunit4.class)
+ // Because the test uses ParameterizedAndroidJunit4 with two parameters,
+ // the whole class is executed twice.
+ // CHECKSTYLE:OFF
+ @Expected("""
+ testRunStarted: classes
+ testSuiteStarted: classes
+ testSuiteStarted: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$BeforeClassAssumptionFailureTest
+ testSuiteFinished: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$BeforeClassAssumptionFailureTest
+ testSuiteStarted: [0]
+ testStarted: test1[0](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$BeforeClassAssumptionFailureTest)
+ testAssumptionFailure: got: <false>, expected: is <true>
+ testFinished: test1[0](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$BeforeClassAssumptionFailureTest)
+ testStarted: test2[0](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$BeforeClassAssumptionFailureTest)
+ testAssumptionFailure: got: <false>, expected: is <true>
+ testFinished: test2[0](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$BeforeClassAssumptionFailureTest)
+ testSuiteFinished: [0]
+ testSuiteStarted: [1]
+ testStarted: test1[1](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$BeforeClassAssumptionFailureTest)
+ testAssumptionFailure: got: <false>, expected: is <true>
+ testFinished: test1[1](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$BeforeClassAssumptionFailureTest)
+ testStarted: test2[1](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$BeforeClassAssumptionFailureTest)
+ testAssumptionFailure: got: <false>, expected: is <true>
+ testFinished: test2[1](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$BeforeClassAssumptionFailureTest)
+ testSuiteFinished: [1]
+ testSuiteFinished: classes
+ testRunFinished: 4,0,4,0
+ """)
+ // CHECKSTYLE:ON
+ public static class BeforeClassAssumptionFailureTest {
+ public BeforeClassAssumptionFailureTest(String param) {
+ }
+
+ @BeforeClass
+ public static void beforeClass() {
+ Assume.assumeTrue(false);
+ }
+
+ @Parameters
+ public static List<String> getParams() {
+ var params = new ArrayList<String>();
+ params.add("foo");
+ params.add("bar");
+ return params;
+ }
+
+ @Test
+ public void test1() {
+ }
+
+ @Test
+ public void test2() {
+ }
+ }
+
+ /**
+ * General exception in @BeforeClass.
+ */
+ @RunWith(ParameterizedAndroidJunit4.class)
+ // Because the test uses ParameterizedAndroidJunit4 with two parameters,
+ // the whole class is executed twice.
+ // CHECKSTYLE:OFF
+ @Expected("""
+ testRunStarted: classes
+ testSuiteStarted: classes
+ testSuiteStarted: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$BeforeClassExceptionTest
+ testSuiteFinished: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$BeforeClassExceptionTest
+ testSuiteStarted: [0]
+ testStarted: test1[0](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$BeforeClassExceptionTest)
+ testFailure: FAILURE
+ testFinished: test1[0](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$BeforeClassExceptionTest)
+ testStarted: test2[0](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$BeforeClassExceptionTest)
+ testFailure: FAILURE
+ testFinished: test2[0](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$BeforeClassExceptionTest)
+ testSuiteFinished: [0]
+ testSuiteStarted: [1]
+ testStarted: test1[1](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$BeforeClassExceptionTest)
+ testFailure: FAILURE
+ testFinished: test1[1](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$BeforeClassExceptionTest)
+ testStarted: test2[1](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$BeforeClassExceptionTest)
+ testFailure: FAILURE
+ testFinished: test2[1](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$BeforeClassExceptionTest)
+ testSuiteFinished: [1]
+ testSuiteFinished: classes
+ testRunFinished: 4,4,0,0
+ """)
+ // CHECKSTYLE:ON
+ public static class BeforeClassExceptionTest {
+ public BeforeClassExceptionTest(String param) {
+ }
+
+ @BeforeClass
+ public static void beforeClass() {
+ throw new RuntimeException("FAILURE");
+ }
+
+ @Parameters
+ public static List<String> getParams() {
+ var params = new ArrayList<String>();
+ params.add("foo");
+ params.add("bar");
+ return params;
+ }
+
+ @Test
+ public void test1() {
+ }
+
+ @Test
+ public void test2() {
+ }
+ }
+
+ /**
+ * Assumption failure from a @ClassRule.
+ */
+ @RunWith(ParameterizedAndroidJunit4.class)
+ // Because the test uses ParameterizedAndroidJunit4 with two parameters,
+ // the whole class is executed twice.
+ // CHECKSTYLE:OFF
+ @Expected("""
+ testRunStarted: classes
+ testSuiteStarted: classes
+ testSuiteStarted: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassRuleAssumptionFailureTest
+ testSuiteFinished: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassRuleAssumptionFailureTest
+ testSuiteStarted: [0]
+ testStarted: test1[0](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassRuleAssumptionFailureTest)
+ testAssumptionFailure: got: <false>, expected: is <true>
+ testFinished: test1[0](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassRuleAssumptionFailureTest)
+ testStarted: test2[0](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassRuleAssumptionFailureTest)
+ testAssumptionFailure: got: <false>, expected: is <true>
+ testFinished: test2[0](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassRuleAssumptionFailureTest)
+ testSuiteFinished: [0]
+ testSuiteStarted: [1]
+ testStarted: test1[1](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassRuleAssumptionFailureTest)
+ testAssumptionFailure: got: <false>, expected: is <true>
+ testFinished: test1[1](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassRuleAssumptionFailureTest)
+ testStarted: test2[1](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassRuleAssumptionFailureTest)
+ testAssumptionFailure: got: <false>, expected: is <true>
+ testFinished: test2[1](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassRuleAssumptionFailureTest)
+ testSuiteFinished: [1]
+ testSuiteFinished: classes
+ testRunFinished: 4,0,4,0
+ """)
+ // CHECKSTYLE:ON
+ public static class ClassRuleAssumptionFailureTest {
+ @ClassRule
+ public static final TestRule sClassRule = new TestRule() {
+ @Override
+ public Statement apply(Statement base, Description description) {
+ assumeTrue(false);
+ return null; // unreachable
+ }
+ };
+
+ public ClassRuleAssumptionFailureTest(String param) {
+ }
+
+ @Parameters
+ public static List<String> getParams() {
+ var params = new ArrayList<String>();
+ params.add("foo");
+ params.add("bar");
+ return params;
+ }
+
+ @Test
+ public void test1() {
+ }
+
+ @Test
+ public void test2() {
+ }
+ }
+
+ /**
+ * General exception from a @ClassRule.
+ */
+ @RunWith(ParameterizedAndroidJunit4.class)
+ // Because the test uses ParameterizedAndroidJunit4 with two parameters,
+ // the whole class is executed twice.
+ // CHECKSTYLE:OFF
+ @Expected("""
+ testRunStarted: classes
+ testSuiteStarted: classes
+ testSuiteStarted: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassRuleExceptionTest
+ testSuiteFinished: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassRuleExceptionTest
+ testSuiteStarted: [0]
+ testStarted: test1[0](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassRuleExceptionTest)
+ testAssumptionFailure: got: <false>, expected: is <true>
+ testFinished: test1[0](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassRuleExceptionTest)
+ testStarted: test2[0](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassRuleExceptionTest)
+ testAssumptionFailure: got: <false>, expected: is <true>
+ testFinished: test2[0](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassRuleExceptionTest)
+ testSuiteFinished: [0]
+ testSuiteStarted: [1]
+ testStarted: test1[1](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassRuleExceptionTest)
+ testAssumptionFailure: got: <false>, expected: is <true>
+ testFinished: test1[1](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassRuleExceptionTest)
+ testStarted: test2[1](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassRuleExceptionTest)
+ testAssumptionFailure: got: <false>, expected: is <true>
+ testFinished: test2[1](com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassRuleExceptionTest)
+ testSuiteFinished: [1]
+ testSuiteFinished: classes
+ testRunFinished: 4,0,4,0
+ """)
+ // CHECKSTYLE:ON
+ public static class ClassRuleExceptionTest {
+ @ClassRule
+ public static final TestRule sClassRule = new TestRule() {
+ @Override
+ public Statement apply(Statement base, Description description) {
+ assumeTrue(false);
+ return null; // unreachable
+ }
+ };
+
+ public ClassRuleExceptionTest(String param) {
+ }
+
+ @Parameters
+ public static List<String> getParams() {
+ var params = new ArrayList<String>();
+ params.add("foo");
+ params.add("bar");
+ return params;
+ }
+
+ @Test
+ public void test1() {
+ }
+
+ @Test
+ public void test2() {
+ }
+ }
+
+ /**
+ * General exception from a @ClassRule.
+ */
+ @RunWith(AndroidJUnit4.class)
+ // CHECKSTYLE:OFF
+ @Expected("""
+ testRunStarted: classes
+ testSuiteStarted: classes
+ testStarted: Constructor(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ExceptionFromInnerRunnerConstructorTest)
+ testFailure: Exception detected in constructor
+ testFinished: Constructor(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ExceptionFromInnerRunnerConstructorTest)
+ testSuiteFinished: classes
+ testRunFinished: 1,1,0,0
+ """)
+ // CHECKSTYLE:ON
+ public static class ExceptionFromInnerRunnerConstructorTest {
+ public ExceptionFromInnerRunnerConstructorTest(String arg1, String arg2) {
+ }
+
+ @Test
+ public void test1() {
+ }
+
+ @Test
+ public void test2() {
+ }
+ }
+}
diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java
new file mode 100644
index 000000000000..6ee443fac874
--- /dev/null
+++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java
@@ -0,0 +1,452 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ravenwoodtest.runnercallbacktests;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.NoRavenizer;
+import android.platform.test.ravenwood.RavenwoodConfig;
+import android.platform.test.ravenwood.RavenwoodRule;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+
+
+/**
+ * Test for @Config field extraction and validation.
+ */
+@NoRavenizer // This class shouldn't be executed with RavenwoodAwareTestRunner.
+public class RavenwoodRunnerConfigValidationTest extends RavenwoodRunnerTestBase {
+ public abstract static class ConfigInBaseClass {
+ static String PACKAGE_NAME = "com.ConfigInBaseClass";
+
+ @RavenwoodConfig.Config
+ public static RavenwoodConfig sConfig = new RavenwoodConfig.Builder()
+ .setPackageName(PACKAGE_NAME).build();
+ }
+
+ /**
+ * Make sure a config in the base class is detected.
+ */
+ @RunWith(AndroidJUnit4.class)
+ // CHECKSTYLE:OFF
+ @Expected("""
+ testRunStarted: classes
+ testSuiteStarted: classes
+ testSuiteStarted: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigInBaseClassTest
+ testStarted: test(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigInBaseClassTest)
+ testFinished: test(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigInBaseClassTest)
+ testSuiteFinished: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigInBaseClassTest
+ testSuiteFinished: classes
+ testRunFinished: 1,0,0,0
+ """)
+ // CHECKSTYLE:ON
+ public static class ConfigInBaseClassTest extends ConfigInBaseClass {
+ @Test
+ public void test() {
+ assertThat(InstrumentationRegistry.getInstrumentation().getContext().getPackageName())
+ .isEqualTo(PACKAGE_NAME);
+ }
+ }
+
+ /**
+ * Make sure a config in the base class is detected.
+ */
+ @RunWith(AndroidJUnit4.class)
+ // CHECKSTYLE:OFF
+ @Expected("""
+ testRunStarted: classes
+ testSuiteStarted: classes
+ testSuiteStarted: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigOverridingTest
+ testStarted: test(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigOverridingTest)
+ testFinished: test(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigOverridingTest)
+ testSuiteFinished: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigOverridingTest
+ testSuiteFinished: classes
+ testRunFinished: 1,0,0,0
+ """)
+ // CHECKSTYLE:ON
+ public static class ConfigOverridingTest extends ConfigInBaseClass {
+ static String PACKAGE_NAME_OVERRIDE = "com.ConfigOverridingTest";
+
+ @RavenwoodConfig.Config
+ public static RavenwoodConfig sConfig = new RavenwoodConfig.Builder()
+ .setPackageName(PACKAGE_NAME_OVERRIDE).build();
+
+ @Test
+ public void test() {
+ assertThat(InstrumentationRegistry.getInstrumentation().getContext().getPackageName())
+ .isEqualTo(PACKAGE_NAME_OVERRIDE);
+ }
+ }
+
+ /**
+ * Test to make sure that if a test has a config error, the failure would be reported from
+ * each test method.
+ */
+ @RunWith(AndroidJUnit4.class)
+ // CHECKSTYLE:OFF
+ @Expected("""
+ testRunStarted: classes
+ testSuiteStarted: classes
+ testStarted: testMethod1(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ErrorMustBeReportedFromEachTest)
+ testFailure: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ErrorMustBeReportedFromEachTest.sConfig expected to be public static
+ testFinished: testMethod1(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ErrorMustBeReportedFromEachTest)
+ testStarted: testMethod2(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ErrorMustBeReportedFromEachTest)
+ testFailure: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ErrorMustBeReportedFromEachTest.sConfig expected to be public static
+ testFinished: testMethod2(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ErrorMustBeReportedFromEachTest)
+ testStarted: testMethod3(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ErrorMustBeReportedFromEachTest)
+ testFailure: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ErrorMustBeReportedFromEachTest.sConfig expected to be public static
+ testFinished: testMethod3(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ErrorMustBeReportedFromEachTest)
+ testSuiteFinished: classes
+ testRunFinished: 3,3,0,0
+ """)
+ // CHECKSTYLE:ON
+ public static class ErrorMustBeReportedFromEachTest {
+ @RavenwoodConfig.Config
+ private static RavenwoodConfig sConfig = // Invalid because it's private.
+ new RavenwoodConfig.Builder().build();
+
+ @Test
+ public void testMethod1() {
+ }
+
+ @Test
+ public void testMethod2() {
+ }
+
+ @Test
+ public void testMethod3() {
+ }
+ }
+
+ /**
+ * Invalid because there are two @Config's.
+ */
+ @RunWith(AndroidJUnit4.class)
+ // CHECKSTYLE:OFF
+ @Expected("""
+ testRunStarted: classes
+ testSuiteStarted: classes
+ testStarted: testConfig(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$DuplicateConfigTest)
+ testFailure: Class com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest.DuplicateConfigTest has multiple fields with @RavenwoodConfiguration.Config
+ testFinished: testConfig(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$DuplicateConfigTest)
+ testSuiteFinished: classes
+ testRunFinished: 1,1,0,0
+ """)
+ // CHECKSTYLE:ON
+ public static class DuplicateConfigTest {
+
+ @RavenwoodConfig.Config
+ public static RavenwoodConfig sConfig1 =
+ new RavenwoodConfig.Builder().build();
+
+ @RavenwoodConfig.Config
+ public static RavenwoodConfig sConfig2 =
+ new RavenwoodConfig.Builder().build();
+
+ @Test
+ public void testConfig() {
+ }
+ }
+
+ /**
+ * @Config's must be static.
+ */
+ @RunWith(AndroidJUnit4.class)
+ // CHECKSTYLE:OFF
+ @Expected("""
+ testRunStarted: classes
+ testSuiteStarted: classes
+ testStarted: testConfig(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$NonStaticConfigTest)
+ testFailure: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$NonStaticConfigTest.sConfig expected to be public static
+ testFinished: testConfig(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$NonStaticConfigTest)
+ testSuiteFinished: classes
+ testRunFinished: 1,1,0,0
+ """)
+ // CHECKSTYLE:ON
+ public static class NonStaticConfigTest {
+
+ @RavenwoodConfig.Config
+ public RavenwoodConfig sConfig =
+ new RavenwoodConfig.Builder().build();
+
+ @Test
+ public void testConfig() {
+ }
+ }
+
+ /**
+ * @Config's must be public.
+ */
+ @RunWith(AndroidJUnit4.class)
+ // CHECKSTYLE:OFF
+ @Expected("""
+ testRunStarted: classes
+ testSuiteStarted: classes
+ testStarted: testConfig(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$NonPublicConfigTest)
+ testFailure: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$NonPublicConfigTest.sConfig expected to be public static
+ testFinished: testConfig(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$NonPublicConfigTest)
+ testSuiteFinished: classes
+ testRunFinished: 1,1,0,0
+ """)
+ // CHECKSTYLE:ON
+ public static class NonPublicConfigTest {
+
+ @RavenwoodConfig.Config
+ RavenwoodConfig sConfig =
+ new RavenwoodConfig.Builder().build();
+
+ @Test
+ public void testConfig() {
+ }
+ }
+
+ /**
+ * @Config's must be of type RavenwoodConfiguration.
+ */
+ @RunWith(AndroidJUnit4.class)
+ // CHECKSTYLE:OFF
+ @Expected("""
+ testRunStarted: classes
+ testSuiteStarted: classes
+ testStarted: testConfig(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$WrongTypeConfigTest)
+ testFailure: Field com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest.WrongTypeConfigTest.sConfig has @RavenwoodConfiguration.Config but type is not RavenwoodConfiguration
+ testFinished: testConfig(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$WrongTypeConfigTest)
+ testSuiteFinished: classes
+ testRunFinished: 1,1,0,0
+ """)
+ // CHECKSTYLE:ON
+ public static class WrongTypeConfigTest {
+
+ @RavenwoodConfig.Config
+ public Object sConfig =
+ new RavenwoodConfig.Builder().build();
+
+ @Test
+ public void testConfig() {
+ }
+
+ }
+
+ /**
+ * Config can't be used with a (instance) Rule.
+ */
+ @RunWith(AndroidJUnit4.class)
+ // CHECKSTYLE:OFF
+ @Expected("""
+ testRunStarted: classes
+ testSuiteStarted: classes
+ testStarted: testConfig(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$WithInstanceRuleTest)
+ testFailure: RavenwoodConfiguration and RavenwoodRule cannot be used in the same class. Suggest migrating to RavenwoodConfiguration.
+ testFinished: testConfig(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$WithInstanceRuleTest)
+ testSuiteFinished: classes
+ testRunFinished: 1,1,0,0
+ """)
+ // CHECKSTYLE:ON
+ public static class WithInstanceRuleTest {
+
+ @RavenwoodConfig.Config
+ public static RavenwoodConfig sConfig =
+ new RavenwoodConfig.Builder().build();
+
+ @Rule
+ public RavenwoodRule mRule = new RavenwoodRule.Builder().build();
+
+ @Test
+ public void testConfig() {
+ }
+ }
+
+ /**
+ * Config can't be used with a (static) Rule.
+ */
+ @RunWith(AndroidJUnit4.class)
+ // CHECKSTYLE:OFF
+ @Expected("""
+ testRunStarted: classes
+ testSuiteStarted: classes
+ testStarted: Constructor(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$WithStaticRuleTest)
+ testFailure: Exception detected in constructor
+ testFinished: Constructor(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$WithStaticRuleTest)
+ testSuiteFinished: classes
+ testRunFinished: 1,1,0,0
+ """)
+ // CHECKSTYLE:ON
+ public static class WithStaticRuleTest {
+
+ @RavenwoodConfig.Config
+ public static RavenwoodConfig sConfig =
+ new RavenwoodConfig.Builder().build();
+
+ @Rule
+ public static RavenwoodRule sRule = new RavenwoodRule.Builder().build();
+
+ @Test
+ public void testConfig() {
+ }
+ }
+
+ @RunWith(AndroidJUnit4.class)
+ // CHECKSTYLE:OFF
+ @Expected("""
+ testRunStarted: classes
+ testSuiteStarted: classes
+ testSuiteStarted: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$DuplicateRulesTest
+ testStarted: testMultipleRulesNotAllowed(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$DuplicateRulesTest)
+ testFailure: Multiple nesting RavenwoodRule's are detected in the same class, which is not supported.
+ testFinished: testMultipleRulesNotAllowed(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$DuplicateRulesTest)
+ testSuiteFinished: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$DuplicateRulesTest
+ testSuiteFinished: classes
+ testRunFinished: 1,1,0,0
+ """)
+ // CHECKSTYLE:ON
+ public static class DuplicateRulesTest {
+
+ @Rule
+ public final RavenwoodRule mRavenwood1 = new RavenwoodRule();
+
+ @Rule
+ public final RavenwoodRule mRavenwood2 = new RavenwoodRule();
+
+ @Test
+ public void testMultipleRulesNotAllowed() {
+ }
+ }
+
+ public static class RuleInBaseClass {
+ static String PACKAGE_NAME = "com.RuleInBaseClass";
+ @Rule
+ public final RavenwoodRule mRavenwood1 = new RavenwoodRule.Builder()
+ .setPackageName(PACKAGE_NAME).build();
+ }
+
+ /**
+ * Make sure that RavenwoodRule in a base class takes effect.
+ */
+ @RunWith(AndroidJUnit4.class)
+ // CHECKSTYLE:OFF
+ @Expected("""
+ testRunStarted: classes
+ testSuiteStarted: classes
+ testSuiteStarted: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$RuleInBaseClassSuccessTest
+ testStarted: testRuleInBaseClass(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$RuleInBaseClassSuccessTest)
+ testFinished: testRuleInBaseClass(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$RuleInBaseClassSuccessTest)
+ testSuiteFinished: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$RuleInBaseClassSuccessTest
+ testSuiteFinished: classes
+ testRunFinished: 1,0,0,0
+ """)
+ // CHECKSTYLE:ON
+ public static class RuleInBaseClassSuccessTest extends RuleInBaseClass {
+
+ @Test
+ public void testRuleInBaseClass() {
+ assertThat(InstrumentationRegistry.getInstrumentation().getContext().getPackageName())
+ .isEqualTo(PACKAGE_NAME);
+ }
+ }
+
+ /**
+ * Make sure that having a config and a rule in a base class should fail.
+ * RavenwoodRule.
+ */
+ @RunWith(AndroidJUnit4.class)
+ // CHECKSTYLE:OFF
+ @Expected("""
+ testRunStarted: classes
+ testSuiteStarted: classes
+ testStarted: test(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigWithRuleInBaseClassTest)
+ testFailure: RavenwoodConfiguration and RavenwoodRule cannot be used in the same class. Suggest migrating to RavenwoodConfiguration.
+ testFinished: test(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigWithRuleInBaseClassTest)
+ testSuiteFinished: classes
+ testRunFinished: 1,1,0,0
+ """)
+ // CHECKSTYLE:ON
+ public static class ConfigWithRuleInBaseClassTest extends RuleInBaseClass {
+ @RavenwoodConfig.Config
+ public static RavenwoodConfig sConfig = new RavenwoodConfig.Builder().build();
+
+ @Test
+ public void test() {
+ }
+ }
+
+ /**
+ * Same as {@link RuleInBaseClass}, but the type of the rule field is not {@link RavenwoodRule}.
+ */
+ public abstract static class RuleWithDifferentTypeInBaseClass {
+ static String PACKAGE_NAME = "com.RuleWithDifferentTypeInBaseClass";
+ @Rule
+ public final TestRule mRavenwood1 = new RavenwoodRule.Builder()
+ .setPackageName(PACKAGE_NAME).build();
+ }
+
+ /**
+ * Make sure that RavenwoodRule in a base class takes effect, even if the field type is not
+ */
+ @RunWith(AndroidJUnit4.class)
+ // CHECKSTYLE:OFF
+ @Expected("""
+ testRunStarted: classes
+ testSuiteStarted: classes
+ testSuiteStarted: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$RuleWithDifferentTypeInBaseClassSuccessTest
+ testStarted: testRuleInBaseClass(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$RuleWithDifferentTypeInBaseClassSuccessTest)
+ testFinished: testRuleInBaseClass(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$RuleWithDifferentTypeInBaseClassSuccessTest)
+ testSuiteFinished: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$RuleWithDifferentTypeInBaseClassSuccessTest
+ testSuiteFinished: classes
+ testRunFinished: 1,0,0,0
+ """)
+ // CHECKSTYLE:ON
+ public static class RuleWithDifferentTypeInBaseClassSuccessTest extends RuleWithDifferentTypeInBaseClass {
+
+ @Test
+ public void testRuleInBaseClass() {
+ assertThat(InstrumentationRegistry.getInstrumentation().getContext().getPackageName())
+ .isEqualTo(PACKAGE_NAME);
+ }
+ }
+
+ /**
+ * Make sure that having a config and a rule in a base class should fail, even if the field type is not
+ * RavenwoodRule.
+ */
+ @RunWith(AndroidJUnit4.class)
+ // CHECKSTYLE:OFF
+ @Expected("""
+ testRunStarted: classes
+ testSuiteStarted: classes
+ testSuiteStarted: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigWithRuleWithDifferentTypeInBaseClassTest
+ testStarted: test(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigWithRuleWithDifferentTypeInBaseClassTest)
+ testFailure: RavenwoodConfiguration and RavenwoodRule cannot be used in the same class. Suggest migrating to RavenwoodConfiguration.
+ testFinished: test(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigWithRuleWithDifferentTypeInBaseClassTest)
+ testSuiteFinished: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigWithRuleWithDifferentTypeInBaseClassTest
+ testSuiteFinished: classes
+ testRunFinished: 1,1,0,0
+ """)
+ // CHECKSTYLE:ON
+ public static class ConfigWithRuleWithDifferentTypeInBaseClassTest extends RuleWithDifferentTypeInBaseClass {
+ @RavenwoodConfig.Config
+ public static RavenwoodConfig sConfig = new RavenwoodConfig.Builder().build();
+
+ @Test
+ public void test() {
+ }
+ }
+}
diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerTestBase.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerTestBase.java
new file mode 100644
index 000000000000..9a6934bf17c5
--- /dev/null
+++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerTestBase.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ravenwoodtest.runnercallbacktests;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.platform.test.annotations.NoRavenizer;
+import android.platform.test.ravenwood.RavenwoodAwareTestRunner;
+import android.util.Log;
+
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.function.BiConsumer;
+
+
+/**
+ * Base class for tests to make sure {@link RavenwoodAwareTestRunner} produces expected callbacks
+ * in various situations. (most of them are error situations.)
+ *
+ * Subclasses must contain test classes as static inner classes with an {@link Expected} annotation.
+ * This class finds them using reflections and run them one by one directly using {@link JUnitCore},
+ * and check the callbacks.
+ *
+ * Subclasses do no need to have any test methods.
+ *
+ * The {@link Expected} annotation must contain the expected result as a string.
+ *
+ * This test abuses the fact that atest + tradefed + junit won't run nested classes automatically.
+ * (So atest won't show any results directly from the nested classes.)
+ *
+ * The actual test method is {@link #doTest}, which is executed for each target test class, using
+ * junit-params.
+ */
+@RunWith(JUnitParamsRunner.class)
+@NoRavenizer // This class shouldn't be executed with RavenwoodAwareTestRunner.
+public abstract class RavenwoodRunnerTestBase {
+ private static final String TAG = "RavenwoodRunnerTestBase";
+
+ /**
+ * Annotation to specify the expected result for a class.
+ */
+ @Target({ElementType.TYPE})
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface Expected {
+ String value();
+ }
+
+ /**
+ * Take a multiline string, strip all of them, remove empty lines, and return it.
+ */
+ private static String stripMultiLines(String resultString) {
+ var list = new ArrayList<String>();
+ for (var line : resultString.split("\n")) {
+ var s = line.strip();
+ if (s.length() > 0) {
+ list.add(s);
+ }
+ }
+ return String.join("\n", list);
+ }
+
+ /**
+ * Extract the expected result from @Expected.
+ */
+ private String getExpectedResult(Class<?> testClazz) {
+ var expect = testClazz.getAnnotation(Expected.class);
+ return stripMultiLines(expect.value());
+ }
+
+ /**
+ * List all the nested classrs with an {@link Expected} annotation in a given class.
+ */
+ public Class<?>[] getTestClasses() {
+ var thisClass = this.getClass();
+ var ret = Arrays.stream(thisClass.getNestMembers())
+ .filter((c) -> c.getAnnotation(Expected.class) != null)
+ .toArray(Class[]::new);
+
+ assertThat(ret.length).isGreaterThan(0);
+
+ return ret;
+ }
+
+ /**
+ * This is the actual test method. We use junit-params to run this method for each target
+ * test class, which are returned by {@link #getTestClasses}.
+ *
+ * It runs each test class, and compare the result collected with
+ * {@link ResultCollectingListener} to expected results (as strings).
+ */
+ @Test
+ @Parameters(method = "getTestClasses")
+ public void doTest(Class<?> testClazz) {
+ doTest(testClazz, getExpectedResult(testClazz));
+ }
+
+ /**
+ * Run a given test class, and compare the result collected with
+ * {@link ResultCollectingListener} to expected results (as a string).
+ */
+ private void doTest(Class<?> testClazz, String expectedResult) {
+ Log.i(TAG, "Running test for " + testClazz);
+ var junitCore = new JUnitCore();
+
+ // Create a listener.
+ var listener = new ResultCollectingListener();
+ junitCore.addListener(listener);
+
+ // Set a listener to critical errors. This will also prevent
+ // {@link RavenwoodAwareTestRunner} from calling System.exit() when there's
+ // a critical error.
+ RavenwoodAwareTestRunner.private$ravenwood().setCriticalErrorHandler(
+ listener.sCriticalErrorListener);
+
+ try {
+ // Run the test class.
+ junitCore.run(testClazz);
+ } finally {
+ // Clear the critical error listener.
+ RavenwoodAwareTestRunner.private$ravenwood().setCriticalErrorHandler(null);
+ }
+
+ // Check the result.
+ assertWithMessage("Failure in test class: " + testClazz.getCanonicalName() + "]")
+ .that(listener.getResult())
+ .isEqualTo(expectedResult);
+ }
+
+ /**
+ * A JUnit RunListener that collects all the callbacks as a single string.
+ */
+ private static class ResultCollectingListener extends RunListener {
+ private final ArrayList<String> mResult = new ArrayList<>();
+
+ public final BiConsumer<String, Throwable> sCriticalErrorListener = (message, th) -> {
+ mResult.add("criticalError: " + message + ": " + th.getMessage());
+ };
+
+ @Override
+ public void testRunStarted(Description description) throws Exception {
+ mResult.add("testRunStarted: " + description);
+ }
+
+ @Override
+ public void testRunFinished(Result result) throws Exception {
+ mResult.add("testRunFinished: "
+ + result.getRunCount() + ","
+ + result.getFailureCount() + ","
+ + result.getAssumptionFailureCount() + ","
+ + result.getIgnoreCount());
+ }
+
+ @Override
+ public void testSuiteStarted(Description description) throws Exception {
+ mResult.add("testSuiteStarted: " + description);
+ }
+
+ @Override
+ public void testSuiteFinished(Description description) throws Exception {
+ mResult.add("testSuiteFinished: " + description);
+ }
+
+ @Override
+ public void testStarted(Description description) throws Exception {
+ mResult.add("testStarted: " + description);
+ }
+
+ @Override
+ public void testFinished(Description description) throws Exception {
+ mResult.add("testFinished: " + description);
+ }
+
+ @Override
+ public void testFailure(Failure failure) throws Exception {
+ mResult.add("testFailure: " + failure.getException().getMessage());
+ }
+
+ @Override
+ public void testAssumptionFailure(Failure failure) {
+ mResult.add("testAssumptionFailure: " + failure.getException().getMessage());
+ }
+
+ @Override
+ public void testIgnored(Description description) throws Exception {
+ mResult.add("testIgnored: " + description);
+ }
+
+ public String getResult() {
+ return String.join("\n", mResult);
+ }
+ }
+}
diff --git a/services/accessibility/Android.bp b/services/accessibility/Android.bp
index 3d7ad0b94d1b..b97ff6217403 100644
--- a/services/accessibility/Android.bp
+++ b/services/accessibility/Android.bp
@@ -10,6 +10,7 @@ package {
filegroup {
name: "services.accessibility-sources",
srcs: ["java/**/*.java"],
+ exclude_srcs: ["java/**/a11ychecker/*.java"],
path: "java",
visibility: ["//frameworks/base/services"],
}
@@ -26,16 +27,13 @@ java_library_static {
},
srcs: [
":services.accessibility-sources",
- ":statslog-accessibility-java-gen",
"//frameworks/base/packages/SettingsLib/RestrictedLockUtils:SettingsLibRestrictedLockUtilsSrc",
],
libs: [
- "aatf",
"services.core",
"androidx.annotation_annotation",
],
static_libs: [
- "accessibility_protos_lite",
"com_android_server_accessibility_flags_lib",
"//frameworks/base/packages/SystemUI/aconfig:com_android_systemui_flags_lib",
],
@@ -70,12 +68,3 @@ java_aconfig_library {
name: "com_android_server_accessibility_flags_lib",
aconfig_declarations: "com_android_server_accessibility_flags",
}
-
-genrule {
- name: "statslog-accessibility-java-gen",
- tools: ["stats-log-api-gen"],
- cmd: "$(location stats-log-api-gen) --java $(out) --module accessibility" +
- " --javaPackage com.android.server.accessibility.a11ychecker" +
- " --javaClass AccessibilityCheckerStatsLog --minApiLevel 34",
- out: ["java/com/android/server/accessibility/a11ychecker/AccessibilityCheckerStatsLog.java"],
-}
diff --git a/services/accessibility/TEST_MAPPING b/services/accessibility/TEST_MAPPING
index 3f85a9005582..0bc25e2dd3c4 100644
--- a/services/accessibility/TEST_MAPPING
+++ b/services/accessibility/TEST_MAPPING
@@ -1,34 +1,19 @@
{
"presubmit": [
{
- "name": "CtsAccessibilityServiceTestCases",
- "options": [
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- }
- ]
+ "name": "CtsAccessibilityServiceTestCases"
},
{
- "name": "CtsAccessibilityTestCases",
- "options": [
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- }
- ]
+ "name": "CtsAccessibilityTestCases"
},
{
- "name": "CtsUiAutomationTestCases",
- "options": [
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- }
- ]
+ "name": "CtsUiAutomationTestCases"
},
{
- "name": "FrameworksServicesTests_accessibility_Presubmit"
+ "name": "FrameworksServicesTests_accessibility"
},
{
- "name": "FrameworksCoreTests_accessibility_NO_FLAKES"
+ "name": "FrameworksCoreTests_accessibility"
}
],
"postsubmit": [
@@ -45,12 +30,7 @@
"name": "CtsUiAutomationTestCases"
},
{
- "name": "FrameworksServicesTests",
- "options": [
- {
- "include-filter": "com.android.server.accessibility"
- }
- ]
+ "name": "FrameworksServicesTests_accessibility"
},
{
"name": "FrameworksCoreTests_accessibility"
diff --git a/services/accessibility/java/com/android/server/accessibility/a11ychecker/Android.bp b/services/accessibility/java/com/android/server/accessibility/a11ychecker/Android.bp
new file mode 100644
index 000000000000..e9ed202f3a49
--- /dev/null
+++ b/services/accessibility/java/com/android/server/accessibility/a11ychecker/Android.bp
@@ -0,0 +1,31 @@
+package {
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+// TODO(http://b/364326163): a11ychecker depends on aatf which currently can't be used in the system
+// server as it pulls in test deps. We moved a11ychecker sources from services.accessibility to an
+// isolated library while this is resolved.
+java_library_static {
+ name: "a11ychecker",
+ srcs: [
+ "*.java",
+ ":statslog-accessibility-java-gen",
+ ],
+ libs: [
+ "aatf",
+ "androidx.annotation_annotation",
+ ],
+ static_libs: [
+ "accessibility_protos_lite",
+ "com_android_server_accessibility_flags_lib",
+ ],
+}
+
+genrule {
+ name: "statslog-accessibility-java-gen",
+ tools: ["stats-log-api-gen"],
+ cmd: "$(location stats-log-api-gen) --java $(out) --module accessibility" +
+ " --javaPackage com.android.server.accessibility.a11ychecker" +
+ " --javaClass AccessibilityCheckerStatsLog --minApiLevel 34",
+ out: ["java/com/android/server/accessibility/a11ychecker/AccessibilityCheckerStatsLog.java"],
+}
diff --git a/services/appfunctions/TEST_MAPPING b/services/appfunctions/TEST_MAPPING
index c7f5eeef8fa0..91e82ec0e95b 100644
--- a/services/appfunctions/TEST_MAPPING
+++ b/services/appfunctions/TEST_MAPPING
@@ -2,6 +2,9 @@
"postsubmit": [
{
"name": "FrameworksAppFunctionsTests"
+ },
+ {
+ "name": "CtsAppFunctionTestCases"
}
]
} \ No newline at end of file
diff --git a/services/appfunctions/java/com/android/server/appfunctions/FutureAppSearchSession.java b/services/appfunctions/java/com/android/server/appfunctions/FutureAppSearchSession.java
index 094723814e17..39aa27ae794e 100644
--- a/services/appfunctions/java/com/android/server/appfunctions/FutureAppSearchSession.java
+++ b/services/appfunctions/java/com/android/server/appfunctions/FutureAppSearchSession.java
@@ -27,6 +27,7 @@ import android.app.appsearch.GenericDocument;
import android.app.appsearch.GetByDocumentIdRequest;
import android.app.appsearch.GetSchemaResponse;
import android.app.appsearch.PutDocumentsRequest;
+import android.app.appsearch.RemoveByDocumentIdRequest;
import android.app.appsearch.SearchResult;
import android.app.appsearch.SearchResults;
import android.app.appsearch.SearchSpec;
@@ -146,6 +147,22 @@ public class FutureAppSearchSession implements Closeable {
});
}
+ /** Removes documents from the AppSearchSession database. */
+ public AndroidFuture<AppSearchBatchResult<String, Void>> remove(
+ @NonNull RemoveByDocumentIdRequest removeRequest) {
+ return getSessionAsync()
+ .thenCompose(
+ session -> {
+ AndroidFuture<AppSearchBatchResult<String, Void>>
+ settableBatchResultFuture = new AndroidFuture<>();
+ session.remove(
+ removeRequest,
+ mExecutor,
+ new BatchResultCallbackAdapter<>(settableBatchResultFuture));
+ return settableBatchResultFuture;
+ });
+ }
+
/**
* Retrieves documents from the open AppSearchSession that match a given query string and type
* of search provided.
@@ -200,9 +217,7 @@ public class FutureAppSearchSession implements Closeable {
Objects.requireNonNull(namespace);
GetByDocumentIdRequest request =
- new GetByDocumentIdRequest.Builder(namespace)
- .addIds(documentId)
- .build();
+ new GetByDocumentIdRequest.Builder(namespace).addIds(documentId).build();
return getSessionAsync()
.thenCompose(
session -> {
diff --git a/services/appfunctions/java/com/android/server/appfunctions/MetadataSyncAdapter.java b/services/appfunctions/java/com/android/server/appfunctions/MetadataSyncAdapter.java
index be5770b280dc..01e10086a03a 100644
--- a/services/appfunctions/java/com/android/server/appfunctions/MetadataSyncAdapter.java
+++ b/services/appfunctions/java/com/android/server/appfunctions/MetadataSyncAdapter.java
@@ -18,6 +18,7 @@ package com.android.server.appfunctions;
import android.annotation.NonNull;
import android.annotation.WorkerThread;
+import android.app.appsearch.PropertyPath;
import android.app.appsearch.SearchResult;
import android.app.appsearch.SearchSpec;
import android.util.ArrayMap;
@@ -60,8 +61,11 @@ public class MetadataSyncAdapter {
@NonNull
@VisibleForTesting
static ArrayMap<String, ArraySet<String>> getAddedFunctionsDiffMap(
- ArrayMap<String, ArraySet<String>> staticPackageToFunctionMap,
- ArrayMap<String, ArraySet<String>> runtimePackageToFunctionMap) {
+ @NonNull ArrayMap<String, ArraySet<String>> staticPackageToFunctionMap,
+ @NonNull ArrayMap<String, ArraySet<String>> runtimePackageToFunctionMap) {
+ Objects.requireNonNull(staticPackageToFunctionMap);
+ Objects.requireNonNull(runtimePackageToFunctionMap);
+
return getFunctionsDiffMap(staticPackageToFunctionMap, runtimePackageToFunctionMap);
}
@@ -79,15 +83,21 @@ public class MetadataSyncAdapter {
@NonNull
@VisibleForTesting
static ArrayMap<String, ArraySet<String>> getRemovedFunctionsDiffMap(
- ArrayMap<String, ArraySet<String>> staticPackageToFunctionMap,
- ArrayMap<String, ArraySet<String>> runtimePackageToFunctionMap) {
+ @NonNull ArrayMap<String, ArraySet<String>> staticPackageToFunctionMap,
+ @NonNull ArrayMap<String, ArraySet<String>> runtimePackageToFunctionMap) {
+ Objects.requireNonNull(staticPackageToFunctionMap);
+ Objects.requireNonNull(runtimePackageToFunctionMap);
+
return getFunctionsDiffMap(runtimePackageToFunctionMap, staticPackageToFunctionMap);
}
@NonNull
private static ArrayMap<String, ArraySet<String>> getFunctionsDiffMap(
- ArrayMap<String, ArraySet<String>> packageToFunctionMapA,
- ArrayMap<String, ArraySet<String>> packageToFunctionMapB) {
+ @NonNull ArrayMap<String, ArraySet<String>> packageToFunctionMapA,
+ @NonNull ArrayMap<String, ArraySet<String>> packageToFunctionMapB) {
+ Objects.requireNonNull(packageToFunctionMapA);
+ Objects.requireNonNull(packageToFunctionMapB);
+
ArrayMap<String, ArraySet<String>> diffMap = new ArrayMap<>();
for (String packageName : packageToFunctionMapA.keySet()) {
if (!packageToFunctionMapB.containsKey(packageName)) {
@@ -110,26 +120,32 @@ public class MetadataSyncAdapter {
}
/**
- * This method returns a map of package names to a set of function ids.
+ * This method returns a map of package names to a set of function ids from the AppFunction
+ * metadata.
*
- * @param queryExpression The query expression to use when searching for AppFunction metadata.
- * @param metadataSearchSpec The search spec to use when searching for AppFunction metadata.
- * @return A map of package names to a set of function ids.
- * @throws ExecutionException If the future search results fail to execute.
- * @throws InterruptedException If the future search results are interrupted.
+ * @param schemaType The name space of the AppFunction metadata.
+ * @return A map of package names to a set of function ids from the AppFunction metadata.
*/
@NonNull
@VisibleForTesting
@WorkerThread
ArrayMap<String, ArraySet<String>> getPackageToFunctionIdMap(
- @NonNull String queryExpression,
- @NonNull SearchSpec metadataSearchSpec,
+ @NonNull String schemaType,
@NonNull String propertyFunctionId,
@NonNull String propertyPackageName)
throws ExecutionException, InterruptedException {
+ Objects.requireNonNull(schemaType);
+ Objects.requireNonNull(propertyFunctionId);
+ Objects.requireNonNull(propertyPackageName);
ArrayMap<String, ArraySet<String>> packageToFunctionIds = new ArrayMap<>();
+
FutureSearchResults futureSearchResults =
- mFutureAppSearchSession.search(queryExpression, metadataSearchSpec).get();
+ mFutureAppSearchSession
+ .search(
+ "",
+ buildMetadataSearchSpec(
+ schemaType, propertyFunctionId, propertyPackageName))
+ .get();
List<SearchResult> searchResultsList = futureSearchResults.getNextPage().get();
// TODO(b/357551503): This could be expensive if we have more functions
while (!searchResultsList.isEmpty()) {
@@ -146,4 +162,30 @@ public class MetadataSyncAdapter {
}
return packageToFunctionIds;
}
+
+ /**
+ * This method returns a {@link SearchSpec} for searching the AppFunction metadata.
+ *
+ * @param schemaType The schema type of the AppFunction metadata.
+ * @param propertyFunctionId The property name of the function id in the AppFunction metadata.
+ * @param propertyPackageName The property name of the package name in the AppFunction metadata.
+ * @return A {@link SearchSpec} for searching the AppFunction metadata.
+ */
+ @NonNull
+ private static SearchSpec buildMetadataSearchSpec(
+ @NonNull String schemaType,
+ @NonNull String propertyFunctionId,
+ @NonNull String propertyPackageName) {
+ Objects.requireNonNull(schemaType);
+ Objects.requireNonNull(propertyFunctionId);
+ Objects.requireNonNull(propertyPackageName);
+ return new SearchSpec.Builder()
+ .addFilterSchemas(schemaType)
+ .addProjectionPaths(
+ schemaType,
+ List.of(
+ new PropertyPath(propertyFunctionId),
+ new PropertyPath(propertyPackageName)))
+ .build();
+ }
}
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 1470e9a9d925..6657c1c1ba89 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -238,13 +238,16 @@ public final class BatteryService extends SystemService {
final SomeArgs args = (SomeArgs) msg.obj;
final Context context;
final Intent intent;
+ final boolean forceUpdate;
try {
context = (Context) args.arg1;
intent = (Intent) args.arg2;
+ forceUpdate = (Boolean) args.arg3;
} finally {
args.recycle();
}
- broadcastBatteryChangedIntent(context, intent, BATTERY_CHANGED_OPTIONS);
+ broadcastBatteryChangedIntent(context, intent, BATTERY_CHANGED_OPTIONS,
+ forceUpdate);
return true;
}
case MSG_BROADCAST_POWER_CONNECTION_CHANGED: {
@@ -798,7 +801,7 @@ public final class BatteryService extends SystemService {
// We are doing this after sending the above broadcasts, so anything processing
// them will get the new sequence number at that point. (See for example how testing
// of JobScheduler's BatteryController works.)
- sendBatteryChangedIntentLocked();
+ sendBatteryChangedIntentLocked(force);
if (mLastBatteryLevel != mHealthInfo.batteryLevel || mLastPlugType != mPlugType) {
sendBatteryLevelChangedIntentLocked();
}
@@ -829,7 +832,7 @@ public final class BatteryService extends SystemService {
}
}
- private void sendBatteryChangedIntentLocked() {
+ private void sendBatteryChangedIntentLocked(boolean forceUpdate) {
// Pack up the values and broadcast them to everyone
final Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
@@ -869,15 +872,17 @@ public final class BatteryService extends SystemService {
final SomeArgs args = SomeArgs.obtain();
args.arg1 = mContext;
args.arg2 = intent;
+ args.arg3 = forceUpdate;
mHandler.obtainMessage(MSG_BROADCAST_BATTERY_CHANGED, args).sendToTarget();
} else {
mHandler.post(() -> broadcastBatteryChangedIntent(mContext,
- intent, BATTERY_CHANGED_OPTIONS));
+ intent, BATTERY_CHANGED_OPTIONS, forceUpdate));
}
}
private static void broadcastBatteryChangedIntent(Context context, Intent intent,
- Bundle options) {
+ Bundle options, boolean forceUpdate) {
+ traceBatteryChangedBroadcastEvent(intent, forceUpdate);
// TODO (293959093): It is important that SystemUI receives this broadcast as soon as
// possible. Ideally, it should be using binder callbacks but until then, dispatch this
// as a foreground broadcast to SystemUI.
@@ -895,6 +900,53 @@ public final class BatteryService extends SystemService {
AppOpsManager.OP_NONE, options, UserHandle.USER_ALL);
}
+ private static void traceBatteryChangedBroadcastEvent(Intent intent, boolean forceUpdate) {
+ if (!com.android.server.flags.Flags.traceBatteryChangedBroadcastEvent()) {
+ return;
+ }
+ if (!Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) return;
+
+ final StringBuilder builder = new StringBuilder();
+ builder.append("broadcastBatteryChanged; ");
+ builder.append("force="); builder.append(forceUpdate);
+ builder.append(",seq="); builder.append(intent.getIntExtra(
+ BatteryManager.EXTRA_SEQUENCE, -1));
+ builder.append(",s="); builder.append(intent.getIntExtra(
+ BatteryManager.EXTRA_STATUS, -1));
+ builder.append(",h="); builder.append(intent.getIntExtra(
+ BatteryManager.EXTRA_HEALTH, -1));
+ builder.append(",p="); builder.append(intent.getBooleanExtra(
+ BatteryManager.EXTRA_PRESENT, false));
+ builder.append(",l="); builder.append(intent.getIntExtra(
+ BatteryManager.EXTRA_LEVEL, -1));
+ builder.append(",bl="); builder.append(intent.getBooleanExtra(
+ BatteryManager.EXTRA_BATTERY_LOW, false));
+ builder.append(",sc="); builder.append(intent.getIntExtra(
+ BatteryManager.EXTRA_SCALE, -1));
+ builder.append(",pt="); builder.append(intent.getIntExtra(
+ BatteryManager.EXTRA_PLUGGED, -1));
+ builder.append(",v="); builder.append(intent.getIntExtra(
+ BatteryManager.EXTRA_VOLTAGE, -1));
+ builder.append(",t="); builder.append(intent.getIntExtra(
+ BatteryManager.EXTRA_TEMPERATURE, -1));
+ builder.append(",tech="); builder.append(intent.getStringExtra(
+ BatteryManager.EXTRA_TECHNOLOGY));
+ builder.append(",invc="); builder.append(intent.getIntExtra(
+ BatteryManager.EXTRA_INVALID_CHARGER, -1));
+ builder.append(",mcc="); builder.append(intent.getIntExtra(
+ BatteryManager.EXTRA_MAX_CHARGING_CURRENT, -1));
+ builder.append(",mcv="); builder.append(intent.getIntExtra(
+ BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE, -1));
+ builder.append(",chc="); builder.append(intent.getIntExtra(
+ BatteryManager.EXTRA_CHARGE_COUNTER, -1));
+ builder.append(",cc="); builder.append(intent.getIntExtra(
+ BatteryManager.EXTRA_CYCLE_COUNT, -1));
+ builder.append(",chs="); builder.append(intent.getIntExtra(
+ BatteryManager.EXTRA_CHARGING_STATUS, -1));
+
+ Trace.instant(Trace.TRACE_TAG_SYSTEM_SERVER, builder.toString());
+ }
+
private void sendBatteryLevelChangedIntentLocked() {
Bundle event = new Bundle();
long now = SystemClock.elapsedRealtime();
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 3f54cfc03114..f0cc09f7c232 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -1923,7 +1923,6 @@ public class OomAdjuster {
int procState;
int capability = cycleReEval ? getInitialCapability(app) : 0;
- boolean foregroundActivities = false;
boolean hasVisibleActivities = false;
if (app == topApp && PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP) {
// The last app on the list is the foreground app.
@@ -1937,7 +1936,6 @@ public class OomAdjuster {
schedGroup = SCHED_GROUP_DEFAULT;
state.setAdjType("intermediate-top-activity");
}
- foregroundActivities = true;
hasVisibleActivities = true;
procState = PROCESS_STATE_TOP;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
@@ -1988,7 +1986,6 @@ public class OomAdjuster {
adj = FOREGROUND_APP_ADJ;
schedGroup = SCHED_GROUP_BACKGROUND;
state.setAdjType("top-sleeping");
- foregroundActivities = true;
procState = PROCESS_STATE_CUR_TOP;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top (sleeping): " + app);
@@ -2008,7 +2005,8 @@ public class OomAdjuster {
}
}
- // Examine all activities if not already foreground.
+ // Examine all non-top activities.
+ boolean foregroundActivities = app == topApp;
if (!foregroundActivities && state.getCachedHasActivities()) {
state.computeOomAdjFromActivitiesIfNecessary(mTmpComputeOomAdjWindowCallback,
adj, foregroundActivities, hasVisibleActivities, procState, schedGroup,
@@ -2532,25 +2530,6 @@ public class OomAdjuster {
}
}
- state.setCurRawAdj(adj);
- adj = psr.modifyRawOomAdj(adj);
- if (adj > state.getMaxAdj()) {
- adj = state.getMaxAdj();
- if (adj <= PERCEPTIBLE_LOW_APP_ADJ) {
- schedGroup = SCHED_GROUP_DEFAULT;
- }
- }
-
- // Put bound foreground services in a special sched group for additional
- // restrictions on screen off
- if (procState >= PROCESS_STATE_BOUND_FOREGROUND_SERVICE
- && mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE
- && !state.shouldScheduleLikeTopApp()) {
- if (schedGroup > SCHED_GROUP_RESTRICTED) {
- schedGroup = SCHED_GROUP_RESTRICTED;
- }
- }
-
// apply capability from FGS.
if (psr.hasForegroundServices()) {
capability |= capabilityFromFGS;
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 5b4e57350c40..29a17f51b0af 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -3397,12 +3397,16 @@ public final class ProcessList {
final boolean wasStopped = info.isStopped();
// Check if we should mark the processrecord for first launch after force-stopping
if (wasStopped) {
- boolean wasEverLaunched;
+ boolean wasEverLaunched = false;
if (android.app.Flags.useAppInfoNotLaunched()) {
wasEverLaunched = !info.isNotLaunched();
} else {
- wasEverLaunched = mService.getPackageManagerInternal()
- .wasPackageEverLaunched(r.getApplicationInfo().packageName, r.userId);
+ try {
+ wasEverLaunched = mService.getPackageManagerInternal()
+ .wasPackageEverLaunched(r.getApplicationInfo().packageName, r.userId);
+ } catch (IllegalArgumentException e) {
+ // Package doesn't have state yet, assume not launched
+ }
}
// Check if the hosting record is for an activity or not. Since the stopped
// state tracking is handled differently to avoid WM calling back into AM,
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 99c3ecaba2e0..439bca0ea36a 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -453,7 +453,9 @@ public class SettingsToPropertiesMapper {
proto.write(StorageRequestMessage.FlagOverrideMessage.PACKAGE_NAME, packageName);
proto.write(StorageRequestMessage.FlagOverrideMessage.FLAG_NAME, flagName);
proto.write(StorageRequestMessage.FlagOverrideMessage.FLAG_VALUE, flagValue);
- proto.write(StorageRequestMessage.FlagOverrideMessage.IS_LOCAL, isLocal);
+ proto.write(StorageRequestMessage.FlagOverrideMessage.OVERRIDE_TYPE, isLocal
+ ? StorageRequestMessage.LOCAL_ON_REBOOT
+ : StorageRequestMessage.SERVER_ON_REBOOT);
proto.end(msgToken);
proto.end(msgsToken);
}
diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java
index 2a1687209aad..dba6c3372ae7 100644
--- a/services/core/java/com/android/server/biometrics/AuthService.java
+++ b/services/core/java/com/android/server/biometrics/AuthService.java
@@ -50,7 +50,6 @@ import android.hardware.biometrics.PromptInfo;
import android.hardware.biometrics.SensorLocationInternal;
import android.hardware.biometrics.SensorPropertiesInternal;
import android.hardware.biometrics.face.IFace;
-import android.hardware.biometrics.fingerprint.IFingerprint;
import android.hardware.face.FaceSensorConfigurations;
import android.hardware.face.FaceSensorProperties;
import android.hardware.face.FaceSensorPropertiesInternal;
@@ -74,6 +73,7 @@ import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.server.SystemService;
+import com.android.server.biometrics.sensors.fingerprint.FingerprintService;
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
import java.util.ArrayList;
@@ -203,7 +203,7 @@ public class AuthService extends SystemService {
*/
@VisibleForTesting
public String[] getFingerprintAidlInstances() {
- return ServiceManager.getDeclaredInstances(IFingerprint.DESCRIPTOR);
+ return FingerprintService.getDeclaredInstances();
}
/**
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index 60cfd5a5a6ae..2f6ba0b852ee 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -26,6 +26,7 @@ import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPR
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_USER_CANCELED;
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_VENDOR;
import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG;
+import static android.hardware.fingerprint.FingerprintSensorConfigurations.getIFingerprint;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -78,6 +79,7 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.SystemService;
@@ -1015,7 +1017,7 @@ public class FingerprintService extends SystemService {
this(context, BiometricContext.getInstance(context),
() -> IBiometricService.Stub.asInterface(
ServiceManager.getService(Context.BIOMETRIC_SERVICE)),
- () -> ServiceManager.getDeclaredInstances(IFingerprint.DESCRIPTOR),
+ () -> getDeclaredInstances(),
null /* fingerprintProvider */,
null /* fingerprintProviderFunction */);
}
@@ -1039,8 +1041,7 @@ public class FingerprintService extends SystemService {
mFingerprintProvider = fingerprintProvider != null ? fingerprintProvider :
(name) -> {
final String fqName = IFingerprint.DESCRIPTOR + "/" + name;
- final IFingerprint fp = IFingerprint.Stub.asInterface(
- Binder.allowBlocking(ServiceManager.waitForDeclaredService(fqName)));
+ final IFingerprint fp = getIFingerprint(fqName);
if (fp != null) {
try {
return new FingerprintProvider(getContext(),
@@ -1129,6 +1130,24 @@ public class FingerprintService extends SystemService {
publishBinderService(Context.FINGERPRINT_SERVICE, mServiceWrapper);
}
+ /**
+ * Get all fingerprint hal instances declared in manifest
+ * @return instance names
+ */
+ public static String[] getDeclaredInstances() {
+ String[] a = ServiceManager.getDeclaredInstances(IFingerprint.DESCRIPTOR);
+ Slog.i(TAG, "Before:getDeclaredInstances: IFingerprint instance found, a.length="
+ + a.length);
+ if (!ArrayUtils.contains(a, "virtual")) {
+ // Now, the virtual hal is registered with IVirtualHal interface and it is also
+ // moved from vendor to system_ext partition without a device manifest. So
+ // if the old vhal is not declared, add here.
+ a = ArrayUtils.appendElement(String.class, a, "virtual");
+ }
+ Slog.i(TAG, "After:getDeclaredInstances: a.length=" + a.length);
+ return a;
+ }
+
@NonNull
private List<Fingerprint> getEnrolledFingerprintsDeprecated(int userId, String opPackageName) {
final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java
index caa2c1c34ff7..fd3d9963c5e3 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java
@@ -20,9 +20,9 @@ import android.annotation.NonNull;
import android.content.Context;
import android.hardware.biometrics.ITestSession;
import android.hardware.biometrics.ITestSessionCallback;
-import android.hardware.biometrics.fingerprint.AcquiredInfoAndVendorCode;
-import android.hardware.biometrics.fingerprint.EnrollmentProgressStep;
-import android.hardware.biometrics.fingerprint.NextEnrollment;
+import android.hardware.biometrics.fingerprint.virtualhal.AcquiredInfoAndVendorCode;
+import android.hardware.biometrics.fingerprint.virtualhal.EnrollmentProgressStep;
+import android.hardware.biometrics.fingerprint.virtualhal.NextEnrollment;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintEnrollOptions;
import android.hardware.fingerprint.FingerprintManager;
@@ -300,4 +300,4 @@ class BiometricTestSessionImpl extends ITestSession.Stub {
super.getSensorId_enforcePermission();
return mSensorId;
}
-} \ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
index 9edaa4e6d818..8195efe6a56a 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
@@ -17,6 +17,8 @@
package com.android.server.biometrics.sensors.fingerprint.aidl;
import static android.hardware.fingerprint.FingerprintManager.SENSOR_ID_ANY;
+import static android.hardware.fingerprint.FingerprintSensorConfigurations.getIFingerprint;
+import static android.hardware.fingerprint.FingerprintSensorConfigurations.remapFqName;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -34,9 +36,9 @@ import android.hardware.biometrics.ITestSession;
import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.SensorLocationInternal;
import android.hardware.biometrics.fingerprint.IFingerprint;
-import android.hardware.biometrics.fingerprint.IVirtualHal;
import android.hardware.biometrics.fingerprint.PointerContext;
import android.hardware.biometrics.fingerprint.SensorProps;
+import android.hardware.biometrics.fingerprint.virtualhal.IVirtualHal;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
import android.hardware.fingerprint.FingerprintEnrollOptions;
@@ -291,7 +293,8 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
if (mTestHalEnabled) {
return true;
}
- return (ServiceManager.checkService(IFingerprint.DESCRIPTOR + "/" + mHalInstanceName)
+ return (ServiceManager.checkService(
+ remapFqName(IFingerprint.DESCRIPTOR + "/" + mHalInstanceName))
!= null);
}
@@ -330,10 +333,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
Slog.d(getTag(), "Daemon was null, reconnecting");
- mDaemon = IFingerprint.Stub.asInterface(
- Binder.allowBlocking(
- ServiceManager.waitForDeclaredService(
- IFingerprint.DESCRIPTOR + "/" + mHalInstanceNameCurrent)));
+ mDaemon = getIFingerprint(IFingerprint.DESCRIPTOR + "/" + mHalInstanceNameCurrent);
if (mDaemon == null) {
Slog.e(getTag(), "Unable to get daemon");
return null;
@@ -905,8 +905,8 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
void setTestHalEnabled(boolean enabled) {
final boolean changed = enabled != mTestHalEnabled;
mTestHalEnabled = enabled;
- Slog.i(getTag(), "setTestHalEnabled(): useVhalForTesting=" + Flags.useVhalForTesting()
- + "mTestHalEnabled=" + mTestHalEnabled + " changed=" + changed);
+ Slog.i(getTag(), "setTestHalEnabled(): useVhalForTestingFlags=" + Flags.useVhalForTesting()
+ + " mTestHalEnabled=" + mTestHalEnabled + " changed=" + changed);
if (changed && useVhalForTesting()) {
getHalInstance();
}
@@ -999,12 +999,13 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
*/
public IVirtualHal getVhal() throws RemoteException {
if (mVhal == null && useVhalForTesting()) {
- mVhal = IVirtualHal.Stub.asInterface(mDaemon.asBinder().getExtension());
- if (mVhal == null) {
- Slog.e(getTag(), "Unable to get fingerprint virtualhal interface");
- }
+ mVhal = IVirtualHal.Stub.asInterface(
+ Binder.allowBlocking(
+ ServiceManager.waitForService(
+ IVirtualHal.DESCRIPTOR + "/"
+ + mHalInstanceNameCurrent)));
+ Slog.d(getTag(), "getVhal " + mHalInstanceNameCurrent);
}
-
return mVhal;
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
index d12d7b2dc89a..25d1fe7d32ba 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
@@ -16,6 +16,8 @@
package com.android.server.biometrics.sensors.fingerprint.aidl;
+import static android.hardware.fingerprint.FingerprintSensorConfigurations.remapFqName;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -356,8 +358,8 @@ public class Sensor {
if (mTestHalEnabled) {
return true;
}
- return (ServiceManager.checkService(IFingerprint.DESCRIPTOR + "/" + halInstance)
- != null);
+ return (ServiceManager.checkService(
+ remapFqName(IFingerprint.DESCRIPTOR + "/" + halInstance)) != null);
}
@NonNull protected BiometricContext getBiometricContext() {
diff --git a/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java
index 028b9b0bcbc0..fcbcb0262c95 100644
--- a/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java
+++ b/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java
@@ -32,8 +32,9 @@ public final class BroadcastRadioService extends SystemService {
public BroadcastRadioService(Context context) {
super(context);
ArrayList<String> serviceNameList = IRadioServiceAidlImpl.getServicesNames();
- mServiceImpl = serviceNameList.isEmpty() ? new IRadioServiceHidlImpl(this)
- : new IRadioServiceAidlImpl(this, serviceNameList);
+ RadioServiceUserController userController = new RadioServiceUserControllerImpl();
+ mServiceImpl = serviceNameList.isEmpty() ? new IRadioServiceHidlImpl(this, userController)
+ : new IRadioServiceAidlImpl(this, serviceNameList, userController);
}
@Override
diff --git a/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java b/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java
index 16514fa813dc..332958d39a8c 100644
--- a/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java
+++ b/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java
@@ -69,8 +69,9 @@ final class IRadioServiceAidlImpl extends IRadioService.Stub {
return serviceList;
}
- IRadioServiceAidlImpl(BroadcastRadioService service, ArrayList<String> serviceList) {
- this(service, new BroadcastRadioServiceImpl(serviceList));
+ IRadioServiceAidlImpl(BroadcastRadioService service, List<String> serviceList,
+ RadioServiceUserController userController) {
+ this(service, new BroadcastRadioServiceImpl(serviceList, userController));
Slogf.i(TAG, "Initialize BroadcastRadioServiceAidl(%s)", service);
}
diff --git a/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java b/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java
index ab083429a200..67d3c95f3a23 100644
--- a/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java
+++ b/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java
@@ -59,13 +59,16 @@ final class IRadioServiceHidlImpl extends IRadioService.Stub {
@GuardedBy("mLock")
private final List<RadioManager.ModuleProperties> mV1Modules;
- IRadioServiceHidlImpl(BroadcastRadioService service) {
+ IRadioServiceHidlImpl(BroadcastRadioService service,
+ RadioServiceUserController userController) {
mService = Objects.requireNonNull(service, "broadcast radio service cannot be null");
- mHal1Client = new com.android.server.broadcastradio.hal1.BroadcastRadioService();
+ Objects.requireNonNull(userController, "user controller cannot be null");
+ mHal1Client = new com.android.server.broadcastradio.hal1.BroadcastRadioService(
+ userController);
mV1Modules = mHal1Client.loadModules();
OptionalInt max = mV1Modules.stream().mapToInt(RadioManager.ModuleProperties::getId).max();
mHal2Client = new com.android.server.broadcastradio.hal2.BroadcastRadioService(
- max.isPresent() ? max.getAsInt() + 1 : 0);
+ max.isPresent() ? max.getAsInt() + 1 : 0, userController);
}
@VisibleForTesting
diff --git a/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java b/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java
index c705ebe686f2..c15ccf193563 100644
--- a/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java
+++ b/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java
@@ -16,19 +16,11 @@
package com.android.server.broadcastradio;
-import android.app.ActivityManager;
-import android.os.Binder;
-import android.os.UserHandle;
-
/**
- * Controller to handle users in {@link com.android.server.broadcastradio.BroadcastRadioService}
+ * Controller interface to handle users in
+ * {@link com.android.server.broadcastradio.BroadcastRadioService}
*/
-public final class RadioServiceUserController {
-
- private RadioServiceUserController() {
- throw new UnsupportedOperationException(
- "RadioServiceUserController class is noninstantiable");
- }
+public interface RadioServiceUserController {
/**
* Check if the user calling the method in Broadcast Radio Service is the current user or the
@@ -37,26 +29,20 @@ public final class RadioServiceUserController {
* @return {@code true} if the user calling this method is the current user of system user,
* {@code false} otherwise.
*/
- public static boolean isCurrentOrSystemUser() {
- int callingUser = Binder.getCallingUserHandle().getIdentifier();
- return callingUser == getCurrentUser() || callingUser == UserHandle.USER_SYSTEM;
- }
+ boolean isCurrentOrSystemUser();
/**
* Get current foreground user for Broadcast Radio Service
*
* @return foreground user id.
*/
- public static int getCurrentUser() {
- int userId = UserHandle.USER_NULL;
- final long identity = Binder.clearCallingIdentity();
- try {
- userId = ActivityManager.getCurrentUser();
- } catch (RuntimeException e) {
- // Activity manager not running, nothing we can do assume user 0.
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- return userId;
- }
-}
+ int getCurrentUser();
+
+ /**
+ * Get id of the user handle assigned to the process that sent the binder transaction that is
+ * being processed
+ *
+ * @return Id of the user handle
+ */
+ int getCallingUserId();
+} \ No newline at end of file
diff --git a/services/core/java/com/android/server/broadcastradio/RadioServiceUserControllerImpl.java b/services/core/java/com/android/server/broadcastradio/RadioServiceUserControllerImpl.java
new file mode 100644
index 000000000000..e305d208000c
--- /dev/null
+++ b/services/core/java/com/android/server/broadcastradio/RadioServiceUserControllerImpl.java
@@ -0,0 +1,62 @@
+/**
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.broadcastradio;
+
+import android.app.ActivityManager;
+import android.os.Binder;
+import android.os.UserHandle;
+
+/**
+ * Implementation for the controller to handle users in
+ * {@link com.android.server.broadcastradio.BroadcastRadioService}
+ */
+public final class RadioServiceUserControllerImpl implements RadioServiceUserController {
+
+ /**
+ * @see RadioServiceUserController#isCurrentOrSystemUser()
+ */
+ @Override
+ public boolean isCurrentOrSystemUser() {
+ int callingUser = getCallingUserId();
+ return callingUser == getCurrentUser() || callingUser == UserHandle.USER_SYSTEM;
+ }
+
+ /**
+ * @see RadioServiceUserController#getCurrentUser()
+ */
+ @Override
+ public int getCurrentUser() {
+ int userId = UserHandle.USER_NULL;
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ userId = ActivityManager.getCurrentUser();
+ } catch (RuntimeException e) {
+ // Activity manager not running, nothing we can do assume user 0.
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ return userId;
+ }
+
+ /**
+ * @see RadioServiceUserController#getCallingUserId()
+ */
+ @Override
+ public int getCallingUserId() {
+ return Binder.getCallingUserHandle().getIdentifier();
+ }
+}
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java b/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java
index 7b504659c197..06024b57e45f 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java
@@ -51,6 +51,7 @@ public final class BroadcastRadioServiceImpl {
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private final Object mLock = new Object();
+ private final RadioServiceUserController mUserController;
@GuardedBy("mLock")
private int mNextModuleId;
@@ -77,7 +78,7 @@ public final class BroadcastRadioServiceImpl {
}
RadioModule radioModule =
- RadioModule.tryLoadingModule(moduleId, name, newBinder);
+ RadioModule.tryLoadingModule(moduleId, name, newBinder, mUserController);
if (radioModule == null) {
Slogf.w(TAG, "No module %s with id %d (HAL AIDL)", name, moduleId);
return;
@@ -141,9 +142,12 @@ public final class BroadcastRadioServiceImpl {
* BroadcastRadio HAL services
*
* @param serviceNameList list of names of AIDL BroadcastRadio HAL services
+ * @param userController User controller implementation
*/
- public BroadcastRadioServiceImpl(ArrayList<String> serviceNameList) {
+ public BroadcastRadioServiceImpl(List<String> serviceNameList,
+ RadioServiceUserController userController) {
mNextModuleId = 0;
+ mUserController = Objects.requireNonNull(userController, "User controller can not be null");
if (DEBUG) {
Slogf.d(TAG, "Initializing BroadcastRadioServiceImpl %s", IBroadcastRadio.DESCRIPTOR);
}
@@ -202,7 +206,7 @@ public final class BroadcastRadioServiceImpl {
if (DEBUG) {
Slogf.d(TAG, "Open AIDL radio session");
}
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.e(TAG, "Cannot open tuner on AIDL HAL client for non-current user");
throw new IllegalStateException("Cannot open session for non-current user");
}
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
index a176a3275ee9..20ee49e25dc2 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
@@ -62,6 +62,7 @@ final class RadioModule {
private final Handler mHandler;
private final RadioEventLogger mLogger;
private final RadioManager.ModuleProperties mProperties;
+ private final RadioServiceUserController mUserController;
/**
* Tracks antenna state reported by HAL (if any).
@@ -194,15 +195,18 @@ final class RadioModule {
};
@VisibleForTesting
- RadioModule(IBroadcastRadio service, RadioManager.ModuleProperties properties) {
+ RadioModule(IBroadcastRadio service, RadioManager.ModuleProperties properties,
+ RadioServiceUserController userController) {
mProperties = Objects.requireNonNull(properties, "properties cannot be null");
mService = Objects.requireNonNull(service, "service cannot be null");
mHandler = new Handler(Looper.getMainLooper());
+ mUserController = Objects.requireNonNull(userController, "User controller can not be null");
mLogger = new RadioEventLogger(TAG, RADIO_EVENT_LOGGER_QUEUE_SIZE);
}
@Nullable
- static RadioModule tryLoadingModule(int moduleId, String moduleName, IBinder serviceBinder) {
+ static RadioModule tryLoadingModule(int moduleId, String moduleName, IBinder serviceBinder,
+ RadioServiceUserController userController) {
try {
Slogf.i(TAG, "Try loading module for module id = %d, module name = %s",
moduleId, moduleName);
@@ -232,7 +236,7 @@ final class RadioModule {
RadioManager.ModuleProperties prop = ConversionUtils.propertiesFromHalProperties(
moduleId, moduleName, service.getProperties(), amfmConfig, dabConfig);
- return new RadioModule(service, prop);
+ return new RadioModule(service, prop, userController);
} catch (RemoteException ex) {
Slogf.e(TAG, ex, "Failed to load module %s", moduleName);
return null;
@@ -256,7 +260,7 @@ final class RadioModule {
RadioManager.ProgramInfo currentProgramInfo;
synchronized (mLock) {
boolean isFirstTunerSession = mAidlTunerSessions.isEmpty();
- tunerSession = new TunerSession(this, mService, userCb);
+ tunerSession = new TunerSession(this, mService, userCb, mUserController);
mAidlTunerSessions.add(tunerSession);
antennaConnected = mAntennaConnected;
currentProgramInfo = mCurrentProgramInfo;
@@ -440,7 +444,7 @@ final class RadioModule {
@GuardedBy("mLock")
private void fanoutAidlCallbackLocked(AidlCallbackRunnable runnable) {
- int currentUserId = RadioServiceUserController.getCurrentUser();
+ int currentUserId = mUserController.getCurrentUser();
List<TunerSession> deadSessions = null;
for (int i = 0; i < mAidlTunerSessions.size(); i++) {
if (mAidlTunerSessions.valueAt(i).mUserId != currentUserId
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java b/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java
index e90a1dda6cf5..f22661b72da1 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java
@@ -52,6 +52,7 @@ final class TunerSession extends ITuner.Stub {
final android.hardware.radio.ITunerCallback mCallback;
private final int mUid;
private final IBroadcastRadio mService;
+ private final RadioServiceUserController mUserController;
@GuardedBy("mLock")
private boolean mIsClosed;
@@ -65,11 +66,13 @@ final class TunerSession extends ITuner.Stub {
private RadioManager.BandConfig mPlaceHolderConfig;
TunerSession(RadioModule radioModule, IBroadcastRadio service,
- android.hardware.radio.ITunerCallback callback) {
+ android.hardware.radio.ITunerCallback callback,
+ RadioServiceUserController userController) {
mModule = Objects.requireNonNull(radioModule, "radioModule cannot be null");
mService = Objects.requireNonNull(service, "service cannot be null");
- mUserId = Binder.getCallingUserHandle().getIdentifier();
mCallback = Objects.requireNonNull(callback, "callback cannot be null");
+ mUserController = Objects.requireNonNull(userController, "User controller can not be null");
+ mUserId = mUserController.getCallingUserId();
mUid = Binder.getCallingUid();
mLogger = new RadioEventLogger(TAG, TUNER_EVENT_LOGGER_QUEUE_SIZE);
}
@@ -126,7 +129,7 @@ final class TunerSession extends ITuner.Stub {
@Override
public void setConfiguration(RadioManager.BandConfig config) {
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG, "Cannot set configuration for AIDL HAL client from non-current user");
return;
}
@@ -169,7 +172,7 @@ final class TunerSession extends ITuner.Stub {
public void step(boolean directionDown, boolean skipSubChannel) throws RemoteException {
mLogger.logRadioEvent("Step with direction %s, skipSubChannel? %s",
directionDown ? "down" : "up", skipSubChannel ? "yes" : "no");
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG, "Cannot step on AIDL HAL client from non-current user");
return;
}
@@ -187,7 +190,7 @@ final class TunerSession extends ITuner.Stub {
public void seek(boolean directionDown, boolean skipSubChannel) throws RemoteException {
mLogger.logRadioEvent("Seek with direction %s, skipSubChannel? %s",
directionDown ? "down" : "up", skipSubChannel ? "yes" : "no");
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG, "Cannot scan on AIDL HAL client from non-current user");
return;
}
@@ -204,7 +207,7 @@ final class TunerSession extends ITuner.Stub {
@Override
public void tune(ProgramSelector selector) throws RemoteException {
mLogger.logRadioEvent("Tune with selector %s", selector);
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG, "Cannot tune on AIDL HAL client from non-current user");
return;
}
@@ -226,7 +229,7 @@ final class TunerSession extends ITuner.Stub {
@Override
public void cancel() {
Slogf.i(TAG, "Cancel");
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG, "Cannot cancel on AIDL HAL client from non-current user");
return;
}
@@ -255,7 +258,7 @@ final class TunerSession extends ITuner.Stub {
@Override
public boolean startBackgroundScan() {
Slogf.w(TAG, "Explicit background scan trigger is not supported with HAL AIDL");
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG, "Cannot start background scan on AIDL HAL client from non-current user");
return false;
}
@@ -268,7 +271,7 @@ final class TunerSession extends ITuner.Stub {
@Override
public void startProgramListUpdates(ProgramList.Filter filter) throws RemoteException {
mLogger.logRadioEvent("Start programList updates %s", filter);
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG,
"Cannot start program list updates on AIDL HAL client from non-current user");
return;
@@ -344,7 +347,7 @@ final class TunerSession extends ITuner.Stub {
@Override
public void stopProgramListUpdates() throws RemoteException {
mLogger.logRadioEvent("Stop programList updates");
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG,
"Cannot stop program list updates on AIDL HAL client from non-current user");
return;
@@ -389,7 +392,7 @@ final class TunerSession extends ITuner.Stub {
public void setConfigFlag(int flag, boolean value) throws RemoteException {
mLogger.logRadioEvent("set ConfigFlag %s to %b ",
ConfigFlag.$.toString(flag), value);
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG, "Cannot set config flag for AIDL HAL client from non-current user");
return;
}
@@ -406,7 +409,7 @@ final class TunerSession extends ITuner.Stub {
@Override
public Map<String, String> setParameters(Map<String, String> parameters) {
mLogger.logRadioEvent("Set parameters ");
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG, "Cannot set parameters for AIDL HAL client from non-current user");
return new ArrayMap<>();
}
diff --git a/services/core/java/com/android/server/broadcastradio/hal1/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/hal1/BroadcastRadioService.java
index fb42c94b56f4..6a6a3ae44c8b 100644
--- a/services/core/java/com/android/server/broadcastradio/hal1/BroadcastRadioService.java
+++ b/services/core/java/com/android/server/broadcastradio/hal1/BroadcastRadioService.java
@@ -35,6 +35,7 @@ public class BroadcastRadioService {
* This field is used by native code, do not access or modify.
*/
private final long mNativeContext = nativeInit();
+ private final RadioServiceUserController mUserController;
private final Object mLock = new Object();
@@ -50,6 +51,10 @@ public class BroadcastRadioService {
private native Tuner nativeOpenTuner(long nativeContext, int moduleId,
RadioManager.BandConfig config, boolean withAudio, ITunerCallback callback);
+ public BroadcastRadioService(RadioServiceUserController userController) {
+ mUserController = Objects.requireNonNull(userController, "User controller can not be null");
+ }
+
public @NonNull List<RadioManager.ModuleProperties> loadModules() {
synchronized (mLock) {
return Objects.requireNonNull(nativeLoadModules(mNativeContext));
@@ -58,7 +63,7 @@ public class BroadcastRadioService {
public ITuner openTuner(int moduleId, RadioManager.BandConfig bandConfig,
boolean withAudio, ITunerCallback callback) {
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.e(TAG, "Cannot open tuner on HAL 1.x client for non-current user");
throw new IllegalStateException("Cannot open tuner for non-current user");
}
diff --git a/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java b/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java
index 7cac4091c583..8e64600d2694 100644
--- a/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java
+++ b/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java
@@ -28,6 +28,7 @@ import android.os.IBinder;
import android.os.RemoteException;
import com.android.server.broadcastradio.RadioServiceUserController;
+import com.android.server.broadcastradio.RadioServiceUserControllerImpl;
import com.android.server.utils.Slogf;
import java.util.List;
@@ -51,6 +52,7 @@ class Tuner extends ITuner.Stub {
private boolean mIsMuted = false;
private int mRegion;
private final boolean mWithAudio;
+ private final RadioServiceUserController mUserController = new RadioServiceUserControllerImpl();
Tuner(@NonNull ITunerCallback clientCallback, int halRev,
int region, boolean withAudio, int band) {
@@ -127,7 +129,7 @@ class Tuner extends ITuner.Stub {
@Override
public void setConfiguration(RadioManager.BandConfig config) {
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG, "Cannot set configuration for HAL 1.x client from non-current user");
return;
}
@@ -176,7 +178,7 @@ class Tuner extends ITuner.Stub {
@Override
public void step(boolean directionDown, boolean skipSubChannel) {
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG, "Cannot step on HAL 1.x client from non-current user");
return;
}
@@ -189,7 +191,7 @@ class Tuner extends ITuner.Stub {
@Override
public void seek(boolean directionDown, boolean skipSubChannel) {
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG, "Cannot seek on HAL 1.x client from non-current user");
return;
}
@@ -202,7 +204,7 @@ class Tuner extends ITuner.Stub {
@Override
public void tune(ProgramSelector selector) {
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG, "Cannot tune on HAL 1.x client from non-current user");
return;
}
@@ -219,7 +221,7 @@ class Tuner extends ITuner.Stub {
@Override
public void cancel() {
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG, "Cannot cancel on HAL 1.x client from non-current user");
return;
}
@@ -231,7 +233,7 @@ class Tuner extends ITuner.Stub {
@Override
public void cancelAnnouncement() {
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG, "Cannot cancel announcement on HAL 1.x client from non-current user");
return;
}
@@ -260,7 +262,7 @@ class Tuner extends ITuner.Stub {
@Override
public boolean startBackgroundScan() {
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG,
"Cannot start background scan on HAL 1.x client from non-current user");
return false;
@@ -285,7 +287,7 @@ class Tuner extends ITuner.Stub {
@Override
public void startProgramListUpdates(ProgramList.Filter filter) {
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG,
"Cannot start program list updates on HAL 1.x client from non-current user");
return;
@@ -295,7 +297,7 @@ class Tuner extends ITuner.Stub {
@Override
public void stopProgramListUpdates() {
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG,
"Cannot stop program list updates on HAL 1.x client from non-current user");
return;
@@ -321,7 +323,7 @@ class Tuner extends ITuner.Stub {
@Override
public void setConfigFlag(int flag, boolean value) {
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG, "Cannot set config flag for HAL 1.x client from non-current user");
return;
}
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
index a4efa2e330f8..3227afd82dbd 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
@@ -50,6 +50,8 @@ public final class BroadcastRadioService {
private final Object mLock = new Object();
+ private final RadioServiceUserController mUserController;
+
@GuardedBy("mLock")
private int mNextModuleId;
@@ -75,7 +77,8 @@ public final class BroadcastRadioService {
moduleId = mNextModuleId;
}
- RadioModule radioModule = RadioModule.tryLoadingModule(moduleId, serviceName);
+ RadioModule radioModule = RadioModule.tryLoadingModule(moduleId, serviceName,
+ mUserController);
if (radioModule == null) {
return;
}
@@ -123,8 +126,9 @@ public final class BroadcastRadioService {
}
};
- public BroadcastRadioService(int nextModuleId) {
+ public BroadcastRadioService(int nextModuleId, RadioServiceUserController userController) {
mNextModuleId = nextModuleId;
+ mUserController = Objects.requireNonNull(userController, "User controller can not be null");
try {
IServiceManager manager = IServiceManager.getService();
if (manager == null) {
@@ -138,8 +142,10 @@ public final class BroadcastRadioService {
}
@VisibleForTesting
- BroadcastRadioService(int nextModuleId, IServiceManager manager) {
+ BroadcastRadioService(int nextModuleId, IServiceManager manager,
+ RadioServiceUserController userController) {
mNextModuleId = nextModuleId;
+ mUserController = Objects.requireNonNull(userController, "User controller can not be null");
Objects.requireNonNull(manager, "Service manager cannot be null");
try {
manager.registerForNotifications(IBroadcastRadio.kInterfaceName, "", mServiceListener);
@@ -171,7 +177,7 @@ public final class BroadcastRadioService {
public ITuner openSession(int moduleId, @Nullable RadioManager.BandConfig legacyConfig,
boolean withAudio, @NonNull ITunerCallback callback) throws RemoteException {
Slogf.v(TAG, "Open HIDL 2.0 session with module id " + moduleId);
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.e(TAG, "Cannot open tuner on HAL 2.0 client for non-current user");
throw new IllegalStateException("Cannot open session for non-current user");
}
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
index d3b244886a64..a0d6cc2c75b0 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
@@ -66,6 +66,7 @@ final class RadioModule {
private final Object mLock = new Object();
private final Handler mHandler;
private final RadioEventLogger mEventLogger;
+ private final RadioServiceUserController mUserController;
@GuardedBy("mLock")
private ITunerSession mHalTunerSession;
@@ -148,16 +149,18 @@ final class RadioModule {
private final Set<TunerSession> mAidlTunerSessions = new ArraySet<>();
@VisibleForTesting
- RadioModule(@NonNull IBroadcastRadio service,
- @NonNull RadioManager.ModuleProperties properties) {
+ RadioModule(IBroadcastRadio service, RadioManager.ModuleProperties properties,
+ RadioServiceUserController userController) {
mProperties = Objects.requireNonNull(properties);
mService = Objects.requireNonNull(service);
mHandler = new Handler(Looper.getMainLooper());
+ mUserController = Objects.requireNonNull(userController, "User controller can not be null");
mEventLogger = new RadioEventLogger(TAG, RADIO_EVENT_LOGGER_QUEUE_SIZE);
}
@Nullable
- static RadioModule tryLoadingModule(int idx, @NonNull String fqName) {
+ static RadioModule tryLoadingModule(int idx, String fqName,
+ RadioServiceUserController controller) {
try {
Slogf.i(TAG, "Try loading module for idx " + idx + ", fqName " + fqName);
IBroadcastRadio service = IBroadcastRadio.getService(fqName);
@@ -179,7 +182,7 @@ final class RadioModule {
RadioManager.ModuleProperties prop = Convert.propertiesFromHal(idx, fqName,
service.getProperties(), amfmConfig.value, dabConfig.value);
- return new RadioModule(service, prop);
+ return new RadioModule(service, prop, controller);
} catch (RemoteException ex) {
Slogf.e(TAG, "Failed to load module " + fqName, ex);
return null;
@@ -208,7 +211,8 @@ final class RadioModule {
});
mHalTunerSession = Objects.requireNonNull(hwSession.value);
}
- TunerSession tunerSession = new TunerSession(this, mHalTunerSession, userCb);
+ TunerSession tunerSession = new TunerSession(this, mHalTunerSession, userCb,
+ mUserController);
mAidlTunerSessions.add(tunerSession);
// Propagate state to new client. Note: These callbacks are invoked while holding mLock
@@ -375,7 +379,7 @@ final class RadioModule {
@GuardedBy("mLock")
private void fanoutAidlCallbackLocked(AidlCallbackRunnable runnable) {
- int currentUserId = RadioServiceUserController.getCurrentUser();
+ int currentUserId = mUserController.getCurrentUser();
List<TunerSession> deadSessions = null;
for (TunerSession tunerSession : mAidlTunerSessions) {
if (tunerSession.mUserId != currentUserId && tunerSession.mUserId
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
index 80efacdb12ee..dc164b1e6eff 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
@@ -16,7 +16,6 @@
package com.android.server.broadcastradio.hal2;
-import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Bitmap;
import android.hardware.broadcastradio.V2_0.ConfigFlag;
@@ -27,7 +26,6 @@ import android.hardware.radio.ITuner;
import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
-import android.os.Binder;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -55,6 +53,7 @@ final class TunerSession extends ITuner.Stub {
private final ITunerSession mHwSession;
final int mUserId;
final android.hardware.radio.ITunerCallback mCallback;
+ private final RadioServiceUserController mUserController;
@GuardedBy("mLock")
private boolean mIsClosed = false;
@@ -66,12 +65,14 @@ final class TunerSession extends ITuner.Stub {
// necessary only for older APIs compatibility
private RadioManager.BandConfig mDummyConfig = null;
- TunerSession(@NonNull RadioModule module, @NonNull ITunerSession hwSession,
- @NonNull android.hardware.radio.ITunerCallback callback) {
+ TunerSession(RadioModule module, ITunerSession hwSession,
+ android.hardware.radio.ITunerCallback callback,
+ RadioServiceUserController userController) {
mModule = Objects.requireNonNull(module);
mHwSession = Objects.requireNonNull(hwSession);
- mUserId = Binder.getCallingUserHandle().getIdentifier();
mCallback = Objects.requireNonNull(callback);
+ mUserController = Objects.requireNonNull(userController, "User controller can not be null");
+ mUserId = mUserController.getCallingUserId();
mEventLogger = new RadioEventLogger(TAG, TUNER_EVENT_LOGGER_QUEUE_SIZE);
}
@@ -120,7 +121,7 @@ final class TunerSession extends ITuner.Stub {
@Override
public void setConfiguration(RadioManager.BandConfig config) {
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG, "Cannot set configuration for HAL 2.0 client from non-current user");
return;
}
@@ -162,7 +163,7 @@ final class TunerSession extends ITuner.Stub {
public void step(boolean directionDown, boolean skipSubChannel) throws RemoteException {
mEventLogger.logRadioEvent("Step with direction %s, skipSubChannel? %s",
directionDown ? "down" : "up", skipSubChannel ? "yes" : "no");
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG, "Cannot step on HAL 2.0 client from non-current user");
return;
}
@@ -177,7 +178,7 @@ final class TunerSession extends ITuner.Stub {
public void seek(boolean directionDown, boolean skipSubChannel) throws RemoteException {
mEventLogger.logRadioEvent("Seek with direction %s, skipSubChannel? %s",
directionDown ? "down" : "up", skipSubChannel ? "yes" : "no");
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG, "Cannot scan on HAL 2.0 client from non-current user");
return;
}
@@ -191,7 +192,7 @@ final class TunerSession extends ITuner.Stub {
@Override
public void tune(ProgramSelector selector) throws RemoteException {
mEventLogger.logRadioEvent("Tune with selector %s", selector);
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG, "Cannot tune on HAL 2.0 client from non-current user");
return;
}
@@ -205,7 +206,7 @@ final class TunerSession extends ITuner.Stub {
@Override
public void cancel() {
Slogf.i(TAG, "Cancel");
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG, "Cannot cancel on HAL 2.0 client from non-current user");
return;
}
@@ -230,7 +231,7 @@ final class TunerSession extends ITuner.Stub {
@Override
public boolean startBackgroundScan() {
Slogf.w(TAG, "Explicit background scan trigger is not supported with HAL 2.0");
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG,
"Cannot start background scan on HAL 2.0 client from non-current user");
return false;
@@ -242,7 +243,7 @@ final class TunerSession extends ITuner.Stub {
@Override
public void startProgramListUpdates(ProgramList.Filter filter) {
mEventLogger.logRadioEvent("start programList updates %s", filter);
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG,
"Cannot start program list updates on HAL 2.0 client from non-current user");
return;
@@ -306,7 +307,7 @@ final class TunerSession extends ITuner.Stub {
@Override
public void stopProgramListUpdates() throws RemoteException {
mEventLogger.logRadioEvent("Stop programList updates");
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG,
"Cannot stop program list updates on HAL 2.0 client from non-current user");
return;
@@ -355,7 +356,7 @@ final class TunerSession extends ITuner.Stub {
@Override
public void setConfigFlag(int flag, boolean value) throws RemoteException {
mEventLogger.logRadioEvent("Set ConfigFlag %s = %b", ConfigFlag.toString(flag), value);
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG, "Cannot set config flag for HAL 2.0 client from non-current user");
return;
}
@@ -368,7 +369,7 @@ final class TunerSession extends ITuner.Stub {
@Override
public Map<String, String> setParameters(Map<String, String> parameters) {
- if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ if (!mUserController.isCurrentOrSystemUser()) {
Slogf.w(TAG, "Cannot set parameters for HAL 2.0 client from non-current user");
return new ArrayMap<>();
}
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index ec61d4d39aa0..05fc6bc869ca 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -380,9 +380,7 @@ public class CameraServiceProxy extends SystemService
}
if (CameraServiceProxy.DEBUG) {
String ultrawideDebug = ", wideAngleUsage " + mUsedUltraWide;
- String zoomOverrideDebug = Flags.logZoomOverrideUsage()
- ? ", zoomOverrideUsage " + mUsedZoomOverride
- : "";
+ String zoomOverrideDebug = ", zoomOverrideUsage " + mUsedZoomOverride;
String mostRequestedFpsRangeDebug = Flags.analytics24q3()
? ", mostRequestedFpsRange " + mMostRequestedFpsRange
: "";
@@ -1337,8 +1335,7 @@ public class CameraServiceProxy extends SystemService
String userTag = cameraState.getUserTag();
int videoStabilizationMode = cameraState.getVideoStabilizationMode();
boolean usedUltraWide = cameraState.getUsedUltraWide();
- boolean usedZoomOverride =
- Flags.logZoomOverrideUsage() ? cameraState.getUsedZoomOverride() : false;
+ boolean usedZoomOverride = cameraState.getUsedZoomOverride();
long logId = cameraState.getLogId();
int sessionIdx = cameraState.getSessionIndex();
CameraExtensionSessionStats extSessionStats = cameraState.getExtensionSessionStats();
diff --git a/services/core/java/com/android/server/display/BrightnessRangeController.java b/services/core/java/com/android/server/display/BrightnessRangeController.java
index 8a3e39257145..1d68ee54d96c 100644
--- a/services/core/java/com/android/server/display/BrightnessRangeController.java
+++ b/services/core/java/com/android/server/display/BrightnessRangeController.java
@@ -16,6 +16,7 @@
package com.android.server.display;
+import android.annotation.Nullable;
import android.hardware.display.BrightnessInfo;
import android.os.Handler;
import android.os.IBinder;
@@ -92,7 +93,7 @@ class BrightnessRangeController {
return mHbmController.getNormalBrightnessMax();
}
- void loadFromConfig(HighBrightnessModeMetadata hbmMetadata, IBinder token,
+ void loadFromConfig(@Nullable HighBrightnessModeMetadata hbmMetadata, IBinder token,
DisplayDeviceInfo info, DisplayDeviceConfig displayDeviceConfig) {
applyChanges(
() -> mNormalBrightnessModeController.resetNbmData(
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index ed16b1472ee5..9644b1dbb977 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -2170,9 +2170,7 @@ public final class DisplayManagerService extends SystemService {
HighBrightnessModeMetadata hbmMetadata =
mHighBrightnessModeMetadataMapper.getHighBrightnessModeMetadataLocked(display);
- if (hbmMetadata != null) {
- dpc.onDisplayChanged(hbmMetadata, leadDisplayId);
- }
+ dpc.onDisplayChanged(hbmMetadata, leadDisplayId);
}
}
@@ -2291,9 +2289,7 @@ public final class DisplayManagerService extends SystemService {
HighBrightnessModeMetadata hbmMetadata =
mHighBrightnessModeMetadataMapper.getHighBrightnessModeMetadataLocked(display);
- if (hbmMetadata != null) {
- dpc.onDisplayChanged(hbmMetadata, leadDisplayId);
- }
+ dpc.onDisplayChanged(hbmMetadata, leadDisplayId);
}
}
@@ -3560,6 +3556,18 @@ public final class DisplayManagerService extends SystemService {
DisplayManagerFlags getFlags() {
return new DisplayManagerFlags();
}
+
+ DisplayPowerController getDisplayPowerController(Context context,
+ DisplayPowerController.Injector injector,
+ DisplayManagerInternal.DisplayPowerCallbacks callbacks, Handler handler,
+ SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay,
+ BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting,
+ Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata,
+ boolean bootCompleted, DisplayManagerFlags flags) {
+ return new DisplayPowerController(context, injector, callbacks, handler, sensorManager,
+ blanker, logicalDisplay, brightnessTracker, brightnessSetting,
+ onBrightnessChangeRunnable, hbmMetadata, bootCompleted, flags);
+ }
}
@VisibleForTesting
@@ -3612,7 +3620,7 @@ public final class DisplayManagerService extends SystemService {
// with the corresponding displaydevice.
HighBrightnessModeMetadata hbmMetadata =
mHighBrightnessModeMetadataMapper.getHighBrightnessModeMetadataLocked(display);
- displayPowerController = new DisplayPowerController(
+ displayPowerController = mInjector.getDisplayPowerController(
mContext, /* injector= */ null, mDisplayPowerCallbacks, mPowerHandler,
mSensorManager, mDisplayBlanker, display, mBrightnessTracker, brightnessSetting,
() -> handleBrightnessChange(display), hbmMetadata, mBootCompleted, mFlags);
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 7c591e3a2c03..c3faec007552 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -849,7 +849,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
*
* Make sure DisplayManagerService.mSyncRoot lock is held when this is called
*/
- public void onDisplayChanged(HighBrightnessModeMetadata hbmMetadata, int leadDisplayId) {
+ public void onDisplayChanged(@Nullable HighBrightnessModeMetadata hbmMetadata,
+ int leadDisplayId) {
mLeadDisplayId = leadDisplayId;
final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
if (device == null) {
@@ -949,7 +950,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info,
- HighBrightnessModeMetadata hbmMetadata) {
+ @Nullable HighBrightnessModeMetadata hbmMetadata) {
// All properties that depend on the associated DisplayDevice and the DDC must be
// updated here.
mScreenBrightnessDozeConfig = BrightnessUtils.clampAbsoluteBrightness(
diff --git a/services/core/java/com/android/server/display/HighBrightnessModeController.java b/services/core/java/com/android/server/display/HighBrightnessModeController.java
index da9eef2d7459..135cab6d0614 100644
--- a/services/core/java/com/android/server/display/HighBrightnessModeController.java
+++ b/services/core/java/com/android/server/display/HighBrightnessModeController.java
@@ -266,7 +266,7 @@ class HighBrightnessModeController {
mSettingsObserver.stopObserving();
}
- void setHighBrightnessModeMetadata(HighBrightnessModeMetadata hbmInfo) {
+ void setHighBrightnessModeMetadata(@Nullable HighBrightnessModeMetadata hbmInfo) {
mHighBrightnessModeMetadata = hbmInfo;
}
diff --git a/services/core/java/com/android/server/flags/services.aconfig b/services/core/java/com/android/server/flags/services.aconfig
index 649678c13a00..69ba785b3b4f 100644
--- a/services/core/java/com/android/server/flags/services.aconfig
+++ b/services/core/java/com/android/server/flags/services.aconfig
@@ -56,3 +56,14 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ namespace: "backstage_power"
+ name: "trace_battery_changed_broadcast_event"
+ description: "Add tracing to record battery changed broadcast event"
+ bug: "365410144"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 1285a61d08f2..dfcea9f8e46f 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -2269,14 +2269,8 @@ public class InputManagerService extends IInputManager.Stub
// Native callback.
@SuppressWarnings("unused")
private void notifyTouchpadHardwareState(TouchpadHardwareState hardwareStates, int deviceId) {
- Slog.d(TAG, "notifyTouchpadHardwareState: Time: "
- + hardwareStates.getTimestamp() + ", No. Buttons: "
- + hardwareStates.getButtonsDown() + ", No. Fingers: "
- + hardwareStates.getFingerCount() + ", No. Touch: "
- + hardwareStates.getTouchCount() + ", Id: "
- + deviceId);
if (mTouchpadDebugViewController != null) {
- mTouchpadDebugViewController.updateTouchpadHardwareState(hardwareStates);
+ mTouchpadDebugViewController.updateTouchpadHardwareState(hardwareStates, deviceId);
}
}
diff --git a/services/core/java/com/android/server/input/debug/TouchpadDebugView.java b/services/core/java/com/android/server/input/debug/TouchpadDebugView.java
index ba56ad073e6a..7d8ce5fdb918 100644
--- a/services/core/java/com/android/server/input/debug/TouchpadDebugView.java
+++ b/services/core/java/com/android/server/input/debug/TouchpadDebugView.java
@@ -22,6 +22,7 @@ import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Rect;
+import android.hardware.input.InputManager;
import android.util.Slog;
import android.view.Gravity;
import android.view.MotionEvent;
@@ -65,7 +66,7 @@ public class TouchpadDebugView extends LinearLayout {
mTouchpadId = touchpadId;
mWindowManager =
Objects.requireNonNull(getContext().getSystemService(WindowManager.class));
- init(context);
+ init(context, touchpadId);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
// TODO(b/360137366): Use the hardware properties to initialise layout parameters.
@@ -88,32 +89,40 @@ public class TouchpadDebugView extends LinearLayout {
mWindowLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
}
- private void init(Context context) {
+ private void init(Context context, int touchpadId) {
setOrientation(VERTICAL);
setLayoutParams(new LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
- setBackgroundColor(Color.RED);
-
- // TODO(b/286551975): Replace this content with the touchpad debug view.
- TextView textView1 = new TextView(context);
- textView1.setBackgroundColor(Color.TRANSPARENT);
- textView1.setTextSize(20);
- textView1.setText("Touchpad Debug View 1");
- textView1.setGravity(Gravity.CENTER);
- textView1.setTextColor(Color.WHITE);
- textView1.setLayoutParams(new LayoutParams(1000, 200));
-
- TextView textView2 = new TextView(context);
- textView2.setBackgroundColor(Color.TRANSPARENT);
- textView2.setTextSize(20);
- textView2.setText("Touchpad Debug View 2");
- textView2.setGravity(Gravity.CENTER);
- textView2.setTextColor(Color.WHITE);
- textView2.setLayoutParams(new LayoutParams(1000, 200));
-
- addView(textView1);
- addView(textView2);
+ setBackgroundColor(Color.TRANSPARENT);
+
+ TextView nameView = new TextView(context);
+ nameView.setBackgroundColor(Color.RED);
+ nameView.setTextSize(20);
+ nameView.setText(Objects.requireNonNull(Objects.requireNonNull(
+ mContext.getSystemService(InputManager.class))
+ .getInputDevice(touchpadId)).getName());
+ nameView.setGravity(Gravity.CENTER);
+ nameView.setTextColor(Color.WHITE);
+ nameView.setLayoutParams(new LayoutParams(1000, 200));
+
+ TouchpadVisualisationView touchpadVisualisationView =
+ new TouchpadVisualisationView(context);
+ touchpadVisualisationView.setBackgroundColor(Color.WHITE);
+ touchpadVisualisationView.setLayoutParams(new LayoutParams(1000, 200));
+
+ //TODO(b/365562952): Add a display for recognized gesture info here
+ TextView gestureInfoView = new TextView(context);
+ gestureInfoView.setBackgroundColor(Color.GRAY);
+ gestureInfoView.setTextSize(20);
+ gestureInfoView.setText("Touchpad Debug View 3");
+ gestureInfoView.setGravity(Gravity.CENTER);
+ gestureInfoView.setTextColor(Color.BLACK);
+ gestureInfoView.setLayoutParams(new LayoutParams(1000, 200));
+
+ addView(nameView);
+ addView(touchpadVisualisationView);
+ addView(gestureInfoView);
updateScreenDimensions();
}
@@ -204,7 +213,15 @@ public class TouchpadDebugView extends LinearLayout {
return mWindowLayoutParams;
}
- public void updateHardwareState(TouchpadHardwareState touchpadHardwareState) {
+ /**
+ * Notify the view of a change in TouchpadHardwareState and changing the
+ * color of the view based on the status of the button click.
+ */
+ public void updateHardwareState(TouchpadHardwareState touchpadHardwareState, int deviceId) {
+ if (deviceId != mTouchpadId) {
+ return;
+ }
+
if (mLastTouchpadState.getButtonsDown() == 0) {
if (touchpadHardwareState.getButtonsDown() > 0) {
onTouchpadButtonPress();
@@ -219,18 +236,11 @@ public class TouchpadDebugView extends LinearLayout {
private void onTouchpadButtonPress() {
Slog.d("TouchpadDebugView", "You clicked me!");
-
- // Iterate through all child views
- // Temporary demonstration for testing
- for (int i = 0; i < getChildCount(); i++) {
- getChildAt(i).setBackgroundColor(Color.BLUE);
- }
+ getChildAt(0).setBackgroundColor(Color.BLUE);
}
private void onTouchpadButtonRelease() {
Slog.d("TouchpadDebugView", "You released the click");
- for (int i = 0; i < getChildCount(); i++) {
- getChildAt(i).setBackgroundColor(Color.RED);
- }
+ getChildAt(0).setBackgroundColor(Color.RED);
}
}
diff --git a/services/core/java/com/android/server/input/debug/TouchpadDebugViewController.java b/services/core/java/com/android/server/input/debug/TouchpadDebugViewController.java
index bc53c4947a71..4d527bdff0d3 100644
--- a/services/core/java/com/android/server/input/debug/TouchpadDebugViewController.java
+++ b/services/core/java/com/android/server/input/debug/TouchpadDebugViewController.java
@@ -68,6 +68,13 @@ public class TouchpadDebugViewController implements InputManager.InputDeviceList
@Override
public void onInputDeviceRemoved(int deviceId) {
hideDebugView(deviceId);
+ if (mTouchpadDebugView == null) {
+ final InputManager inputManager = Objects.requireNonNull(
+ mContext.getSystemService(InputManager.class));
+ for (int id : inputManager.getInputDeviceIds()) {
+ onInputDeviceAdded(id);
+ }
+ }
}
@Override
@@ -134,9 +141,13 @@ public class TouchpadDebugViewController implements InputManager.InputDeviceList
Slog.d(TAG, "Touchpad debug view removed.");
}
- public void updateTouchpadHardwareState(TouchpadHardwareState touchpadHardwareState) {
+ /**
+ * Notify the TouchpadDebugView with the new TouchpadHardwareState.
+ */
+ public void updateTouchpadHardwareState(TouchpadHardwareState touchpadHardwareState,
+ int deviceId) {
if (mTouchpadDebugView != null) {
- mTouchpadDebugView.updateHardwareState(touchpadHardwareState);
+ mTouchpadDebugView.updateHardwareState(touchpadHardwareState, deviceId);
}
}
}
diff --git a/services/core/java/com/android/server/input/debug/TouchpadVisualisationView.java b/services/core/java/com/android/server/input/debug/TouchpadVisualisationView.java
new file mode 100644
index 000000000000..38442bcc0292
--- /dev/null
+++ b/services/core/java/com/android/server/input/debug/TouchpadVisualisationView.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.input.debug;
+
+import android.content.Context;
+import android.view.View;
+
+public class TouchpadVisualisationView extends View {
+ public TouchpadVisualisationView(Context context) {
+ super(context);
+ }
+}
diff --git a/services/core/java/com/android/server/logcat/TEST_MAPPING b/services/core/java/com/android/server/logcat/TEST_MAPPING
index 5b07cd960fbe..688dbe9ec444 100644
--- a/services/core/java/com/android/server/logcat/TEST_MAPPING
+++ b/services/core/java/com/android/server/logcat/TEST_MAPPING
@@ -1,15 +1,12 @@
{
"presubmit": [
{
- "name": "FrameworksServicesTests_android_server_logcat_Presubmit"
+ "name": "FrameworksServicesTests_android_server_logcat"
}
],
"postsubmit": [
{
- "name": "FrameworksServicesTests",
- "options": [
- {"include-filter": "com.android.server.logcat"}
- ]
+ "name": "FrameworksServicesTests_android_server_logcat"
}
]
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index e54124608a26..b9f0968b5864 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -330,10 +330,19 @@ public final class NotificationRecord {
}
final long[] vibrationPattern = channel.getVibrationPattern();
- if (vibrationPattern == null) {
- return helper.createDefaultVibration(insistent);
+ if (vibrationPattern != null) {
+ return helper.createWaveformVibration(vibrationPattern, insistent);
}
- return helper.createWaveformVibration(vibrationPattern, insistent);
+
+ if (com.android.server.notification.Flags.notificationVibrationInSoundUri()) {
+ final VibrationEffect vibrationEffectFromSoundUri =
+ helper.createVibrationEffectFromSoundUri(channel.getSound());
+ if (vibrationEffectFromSoundUri != null) {
+ return vibrationEffectFromSoundUri;
+ }
+ }
+
+ return helper.createDefaultVibration(insistent);
}
private VibrationEffect calculateVibration() {
diff --git a/services/core/java/com/android/server/notification/VibratorHelper.java b/services/core/java/com/android/server/notification/VibratorHelper.java
index 8a0e595176ec..fbe77720b9fc 100644
--- a/services/core/java/com/android/server/notification/VibratorHelper.java
+++ b/services/core/java/com/android/server/notification/VibratorHelper.java
@@ -24,6 +24,9 @@ import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.media.AudioAttributes;
+import android.media.RingtoneManager;
+import android.media.Utils;
+import android.net.Uri;
import android.os.Process;
import android.os.VibrationAttributes;
import android.os.VibrationEffect;
@@ -51,6 +54,7 @@ public final class VibratorHelper {
@Nullable private final float[] mDefaultPwlePattern;
@Nullable private final float[] mFallbackPwlePattern;
private final int mDefaultVibrationAmplitude;
+ private final Context mContext;
public VibratorHelper(Context context) {
mVibrator = context.getSystemService(Vibrator.class);
@@ -68,6 +72,7 @@ public final class VibratorHelper {
com.android.internal.R.array.config_notificationFallbackVibeWaveform);
mDefaultVibrationAmplitude = context.getResources().getInteger(
com.android.internal.R.integer.config_defaultVibrationAmplitude);
+ mContext = context;
}
/**
@@ -184,6 +189,16 @@ public final class VibratorHelper {
* @param insistent {@code true} if the vibration should loop until it is cancelled.
*/
public VibrationEffect createDefaultVibration(boolean insistent) {
+ if (com.android.server.notification.Flags.notificationVibrationInSoundUri()) {
+ final Uri defaultRingtoneUri = RingtoneManager.getActualDefaultRingtoneUri(mContext,
+ RingtoneManager.TYPE_NOTIFICATION);
+ final VibrationEffect vibrationEffectFromSoundUri =
+ createVibrationEffectFromSoundUri(defaultRingtoneUri);
+ if (vibrationEffectFromSoundUri != null) {
+ return vibrationEffectFromSoundUri;
+ }
+ }
+
if (mVibrator.hasFrequencyControl()) {
VibrationEffect effect = createPwleWaveformVibration(mDefaultPwlePattern, insistent);
if (effect != null) {
@@ -193,6 +208,22 @@ public final class VibratorHelper {
return createWaveformVibration(mDefaultPattern, insistent);
}
+ /**
+ * Safely create a {@link VibrationEffect} from given an uri {@code Uri}.
+ * with query parameter "vibration_uri"
+ *
+ * Use this function if the {@code Uri} is with a query parameter "vibration_uri" and the
+ * vibration_uri represents a valid vibration effect in xml
+ *
+ * @param uri {@code Uri} an uri including query parameter "vibraiton_uri"
+ */
+ public @Nullable VibrationEffect createVibrationEffectFromSoundUri(Uri uri) {
+ if (uri == null) {
+ return null;
+ }
+ return Utils.parseVibrationEffect(mVibrator, Utils.getVibrationUri(uri));
+ }
+
/** Returns if a given vibration can be played by the vibrator that does notification buzz. */
public boolean areEffectComponentsSupported(VibrationEffect effect) {
return mVibrator.areVibrationFeaturesSupported(effect);
diff --git a/services/core/java/com/android/server/notification/flags.aconfig b/services/core/java/com/android/server/notification/flags.aconfig
index aac2c404fd38..be3adc142fa4 100644
--- a/services/core/java/com/android/server/notification/flags.aconfig
+++ b/services/core/java/com/android/server/notification/flags.aconfig
@@ -156,3 +156,10 @@ flag {
description: "This flag enables forced auto-grouping conversations"
bug: "336488844"
}
+
+flag {
+ name: "notification_vibration_in_sound_uri"
+ namespace: "systemui"
+ description: "This flag enables sound uri with vibration source"
+ bug: "358524009"
+}
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 6303ecd53dbb..a41675a4aac5 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -298,12 +298,13 @@ public final class OverlayManagerService extends SystemService {
restoreSettings();
- // Wipe all shell overlays on boot, to recover from a potentially broken device
- String shellPkgName = TextUtils.emptyIfNull(
- getContext().getString(android.R.string.config_systemShell));
- mSettings.removeIf(overlayInfo -> overlayInfo.isFabricated
- && shellPkgName.equals(overlayInfo.packageName));
-
+ if (Build.IS_USER) {
+ // Wipe all shell overlays on boot, to recover from a potentially broken device
+ String shellPkgName = TextUtils.emptyIfNull(
+ getContext().getString(android.R.string.config_systemShell));
+ mSettings.removeIf(overlayInfo -> overlayInfo.isFabricated
+ && shellPkgName.equals(overlayInfo.packageName));
+ }
initIfNeeded();
onStartUser(UserHandle.USER_SYSTEM);
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 2856eb45ebd1..f449126af0f9 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -1019,9 +1019,7 @@ final class InstallPackageHelper {
&& scanInstallPackages(requests, createdAppId, versionInfos)) {
List<ReconciledPackage> reconciledPackages =
reconcileInstallPackages(requests, versionInfos);
- if (reconciledPackages != null
- && renameAndUpdatePaths(requests)
- && commitInstallPackages(reconciledPackages)) {
+ if (reconciledPackages != null && commitInstallPackages(reconciledPackages)) {
success = true;
}
}
@@ -1031,49 +1029,24 @@ final class InstallPackageHelper {
}
}
- private boolean renameAndUpdatePaths(List<InstallRequest> requests) {
+ private boolean prepareInstallPackages(List<InstallRequest> requests) {
+ // TODO: will remove the locking after doRename is moved out of prepare
try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
for (InstallRequest request : requests) {
- ParsedPackage parsedPackage = request.getParsedPackage();
- final boolean isApex = (request.getScanFlags() & SCAN_AS_APEX) != 0;
- if (isApex) {
- continue;
- }
try {
- doRenameLI(request, parsedPackage);
- setUpFsVerity(parsedPackage);
- } catch (Installer.InstallerException | IOException | DigestException
- | NoSuchAlgorithmException | PrepareFailure e) {
- request.setError(PackageManagerException.INTERNAL_ERROR_VERITY_SETUP,
- "Failed to set up verity: " + e);
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage");
+ request.onPrepareStarted();
+ preparePackageLI(request);
+ } catch (PrepareFailure prepareFailure) {
+ request.setError(prepareFailure.error,
+ prepareFailure.getMessage());
+ request.setOriginPackage(prepareFailure.mConflictingPackage);
+ request.setOriginPermission(prepareFailure.mConflictingPermission);
return false;
+ } finally {
+ request.onPrepareFinished();
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
-
- // update paths that are set before renaming
- PackageSetting scannedPackageSetting = request.getScannedPackageSetting();
- scannedPackageSetting.setPath(new File(parsedPackage.getPath()));
- scannedPackageSetting.setLegacyNativeLibraryPath(
- parsedPackage.getNativeLibraryRootDir());
- }
- return true;
- }
- }
-
- private boolean prepareInstallPackages(List<InstallRequest> requests) {
- for (InstallRequest request : requests) {
- try {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage");
- request.onPrepareStarted();
- preparePackage(request);
- } catch (PrepareFailure prepareFailure) {
- request.setError(prepareFailure.error,
- prepareFailure.getMessage());
- request.setOriginPackage(prepareFailure.mConflictingPackage);
- request.setOriginPermission(prepareFailure.mConflictingPermission);
- return false;
- } finally {
- request.onPrepareFinished();
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
return true;
@@ -1258,7 +1231,8 @@ final class InstallPackageHelper {
return newProp != null && newProp.getBoolean();
}
- private void preparePackage(InstallRequest request) throws PrepareFailure {
+ @GuardedBy("mPm.mInstallLock")
+ private void preparePackageLI(InstallRequest request) throws PrepareFailure {
final int[] allUsers = mPm.mUserManager.getUserIds();
final int installFlags = request.getInstallFlags();
final boolean onExternal = request.getVolumeUuid() != null;
@@ -1765,7 +1739,18 @@ final class InstallPackageHelper {
}
}
- if (isApex) {
+ if (!isApex) {
+ doRenameLI(request, parsedPackage);
+
+ try {
+ setUpFsVerity(parsedPackage);
+ } catch (Installer.InstallerException | IOException | DigestException
+ | NoSuchAlgorithmException e) {
+ throw PrepareFailure.ofInternalError(
+ "Failed to set up verity: " + e,
+ PackageManagerException.INTERNAL_ERROR_VERITY_SETUP);
+ }
+ } else {
// Use the path returned by apexd
parsedPackage.setPath(request.getApexInfo().modulePath);
parsedPackage.setBaseApkPath(request.getApexInfo().modulePath);
@@ -2107,21 +2092,7 @@ final class InstallPackageHelper {
// Reflect the rename in scanned details
try {
- String afterCanonicalPath = afterCodeFile.getCanonicalPath();
- String beforeCanonicalPath = beforeCodeFile.getCanonicalPath();
- parsedPackage.setPath(afterCanonicalPath);
-
- parsedPackage.setNativeLibraryDir(
- parsedPackage.getNativeLibraryDir()
- .replace(beforeCanonicalPath, afterCanonicalPath));
- parsedPackage.setNativeLibraryRootDir(
- parsedPackage.getNativeLibraryRootDir()
- .replace(beforeCanonicalPath, afterCanonicalPath));
- String secondaryNativeLibraryDir = parsedPackage.getSecondaryNativeLibraryDir();
- if (secondaryNativeLibraryDir != null) {
- parsedPackage.setSecondaryNativeLibraryDir(
- secondaryNativeLibraryDir.replace(beforeCanonicalPath, afterCanonicalPath));
- }
+ parsedPackage.setPath(afterCodeFile.getCanonicalPath());
} catch (IOException e) {
Slog.e(TAG, "Failed to get path: " + afterCodeFile, e);
throw new PrepareFailure(PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE,
diff --git a/services/core/java/com/android/server/pm/PackageArchiver.java b/services/core/java/com/android/server/pm/PackageArchiver.java
index f53234215fc6..76ea0b963036 100644
--- a/services/core/java/com/android/server/pm/PackageArchiver.java
+++ b/services/core/java/com/android/server/pm/PackageArchiver.java
@@ -283,10 +283,7 @@ public class PackageArchiver {
return START_CLASS_NOT_FOUND;
}
- String currentLauncherPackageName = getCurrentLauncherPackageName(getParentUserId(userId));
- if ((currentLauncherPackageName == null || !TextUtils.equals(callerPackageName,
- currentLauncherPackageName)) && callingUid != Process.SHELL_UID) {
- // TODO(b/311619990): Remove dependency on SHELL_UID for testing
+ if (!isCallerQualifiedForUnarchival(callerPackageName, callingUid, userId)) {
Slog.e(TAG, TextUtils.formatSimple(
"callerPackageName: %s does not qualify for unarchival of package: " + "%s!",
callerPackageName, packageName));
@@ -335,6 +332,37 @@ public class PackageArchiver {
return START_ABORTED;
}
+ private boolean isCallerQualifiedForUnarchival(String callerPackageName, int callingUid,
+ int userId) {
+ // TODO(b/311619990): Remove dependency on SHELL_UID for testing
+ if (callingUid == Process.SHELL_UID) {
+ return true;
+ }
+ String currentLauncherPackageName = getCurrentLauncherPackageName(getParentUserId(userId));
+ if (currentLauncherPackageName != null && TextUtils.equals(
+ callerPackageName, currentLauncherPackageName)) {
+ return true;
+ }
+ Slog.w(TAG, TextUtils.formatSimple(
+ "Requester of unarchival: %s is not the default launcher package: %s.",
+ callerPackageName, currentLauncherPackageName));
+ // When the default launcher is not set, or when the current caller is not the default
+ // launcher, allow the caller to directly request unarchive if it is a launcher app
+ // that is a pre-installed system app.
+ final Computer snapshot = mPm.snapshotComputer();
+ final PackageStateInternal ps = snapshot.getPackageStateInternal(callerPackageName);
+ final boolean isSystem = ps != null && ps.isSystem();
+ return isSystem && isLauncherApp(snapshot, callerPackageName, userId);
+ }
+
+ private boolean isLauncherApp(Computer snapshot, String packageName, int userId) {
+ final Intent intent = snapshot.getHomeIntent();
+ intent.setPackage(packageName);
+ List<ResolveInfo> launcherActivities = snapshot.queryIntentActivitiesInternal(
+ intent, null /* resolvedType */, 0 /* flags */, userId);
+ return !launcherActivities.isEmpty();
+ }
+
// Profiles share their UI and default apps, so we have to get the profile parent before
// fetching the default launcher.
private int getParentUserId(int userId) {
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index 09d2a0263f2e..83cb72e1df1f 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -35,7 +35,8 @@ import com.android.server.notification.NotificationDelegate;
public interface StatusBarManagerInternal {
void setNotificationDelegate(NotificationDelegate delegate);
- void showScreenPinningRequest(int taskId);
+ /** Show a screen pinning request for a specific task. */
+ void showScreenPinningRequest(int taskId, int userId);
void showAssistDisclosure();
void preloadRecentApps();
@@ -136,7 +137,7 @@ public interface StatusBarManagerInternal {
*
* @param hidesStatusBar whether it is being hidden
*/
- void setTopAppHidesStatusBar(boolean hidesStatusBar);
+ void setTopAppHidesStatusBar(int displayId, boolean hidesStatusBar);
boolean showShutdownUi(boolean isReboot, String requestString);
@@ -149,17 +150,18 @@ public interface StatusBarManagerInternal {
/**
* Notify System UI that the system get into or exit immersive mode.
+ * @param displayId The changed display Id.
* @param rootDisplayAreaId The changed display area Id.
* @param isImmersiveMode {@code true} if the display area get into immersive mode.
*/
- void immersiveModeChanged(int rootDisplayAreaId, boolean isImmersiveMode);
+ void immersiveModeChanged(int displayId, int rootDisplayAreaId, boolean isImmersiveMode);
/**
* Show a rotation suggestion that a user may approve to rotate the screen.
*
* @param rotation rotation suggestion
*/
- void onProposedRotationChanged(int rotation, boolean isValid);
+ void onProposedRotationChanged(int displayId, int rotation, boolean isValid);
/**
* Notifies System UI that the display is ready to show system decorations.
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 0fd59670436e..908f51b9cba9 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -119,6 +119,7 @@ import com.android.server.LocalServices;
import com.android.server.UiThread;
import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.server.notification.NotificationDelegate;
+import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.UserManagerService;
import com.android.server.policy.GlobalActionsProvider;
import com.android.server.power.ShutdownCheckPoints;
@@ -185,6 +186,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
private final ActivityManagerInternal mActivityManagerInternal;
private final ActivityTaskManagerInternal mActivityTaskManager;
private final PackageManagerInternal mPackageManagerInternal;
+ private final UserManagerInternal mUserManagerInternal;
private final SessionMonitor mSessionMonitor;
private int mCurrentUserId;
private boolean mTracingEnabled;
@@ -304,6 +306,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
mActivityTaskManager = LocalServices.getService(ActivityTaskManagerInternal.class);
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
+ mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
mTileRequestTracker = new TileRequestTracker(mContext);
mSessionMonitor = new SessionMonitor(mContext);
@@ -360,7 +363,14 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
}
@Override
- public void showScreenPinningRequest(int taskId) {
+ public void showScreenPinningRequest(int taskId, int userId) {
+ if (isVisibleBackgroundUser(userId)) {
+ if (SPEW) {
+ Slog.d(TAG, "Skipping showScreenPinningRequest for visible background user "
+ + userId);
+ }
+ return;
+ }
IStatusBar bar = mBar;
if (bar != null) {
try {
@@ -439,6 +449,13 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
@Override
public void appTransitionFinished(int displayId) {
+ if (isVisibleBackgroundUserOnDisplay(displayId)) {
+ if (SPEW) {
+ Slog.d(TAG, "Skipping appTransitionFinished for visible background user "
+ + mUserManagerInternal.getUserAssignedToDisplay(displayId));
+ }
+ return;
+ }
enforceStatusBarService();
IStatusBar bar = mBar;
if (bar != null) {
@@ -588,6 +605,13 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
@Override
public void setWindowState(int displayId, int window, int state) {
+ if (isVisibleBackgroundUserOnDisplay(displayId)) {
+ if (SPEW) {
+ Slog.d(TAG, "Skipping setWindowState for visible background user "
+ + mUserManagerInternal.getUserAssignedToDisplay(displayId));
+ }
+ return;
+ }
IStatusBar bar = mBar;
if (bar != null) {
try {
@@ -598,6 +622,13 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
@Override
public void appTransitionPending(int displayId) {
+ if (isVisibleBackgroundUserOnDisplay(displayId)) {
+ if (SPEW) {
+ Slog.d(TAG, "Skipping appTransitionPending for visible background user "
+ + mUserManagerInternal.getUserAssignedToDisplay(displayId));
+ }
+ return;
+ }
IStatusBar bar = mBar;
if (bar != null) {
try {
@@ -608,6 +639,13 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
@Override
public void appTransitionCancelled(int displayId) {
+ if (isVisibleBackgroundUserOnDisplay(displayId)) {
+ if (SPEW) {
+ Slog.d(TAG, "Skipping appTransitionCancelled for visible background user "
+ + mUserManagerInternal.getUserAssignedToDisplay(displayId));
+ }
+ return;
+ }
IStatusBar bar = mBar;
if (bar != null) {
try {
@@ -619,6 +657,13 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
@Override
public void appTransitionStarting(int displayId, long statusBarAnimationsStartTime,
long statusBarAnimationsDuration) {
+ if (isVisibleBackgroundUserOnDisplay(displayId)) {
+ if (SPEW) {
+ Slog.d(TAG, "Skipping appTransitionStarting for visible background user "
+ + mUserManagerInternal.getUserAssignedToDisplay(displayId));
+ }
+ return;
+ }
IStatusBar bar = mBar;
if (bar != null) {
try {
@@ -629,7 +674,14 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
}
@Override
- public void setTopAppHidesStatusBar(boolean hidesStatusBar) {
+ public void setTopAppHidesStatusBar(int displayId, boolean hidesStatusBar) {
+ if (isVisibleBackgroundUserOnDisplay(displayId)) {
+ if (SPEW) {
+ Slog.d(TAG, "Skipping setTopAppHidesStatusBar for visible background user "
+ + mUserManagerInternal.getUserAssignedToDisplay(displayId));
+ }
+ return;
+ }
IStatusBar bar = mBar;
if (bar != null) {
try {
@@ -665,10 +717,18 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
}
@Override
- public void immersiveModeChanged(int rootDisplayAreaId, boolean isImmersiveMode) {
+ public void immersiveModeChanged(int displayId, int rootDisplayAreaId,
+ boolean isImmersiveMode) {
if (mBar == null) {
return;
}
+ if (isVisibleBackgroundUserOnDisplay(displayId)) {
+ if (SPEW) {
+ Slog.d(TAG, "Skipping immersiveModeChanged for visible background user "
+ + mUserManagerInternal.getUserAssignedToDisplay(displayId));
+ }
+ return;
+ }
if (!CLIENT_TRANSIENT) {
// Only call from here when the client transient is not enabled.
try {
@@ -680,7 +740,14 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
// TODO(b/118592525): support it per display if necessary.
@Override
- public void onProposedRotationChanged(int rotation, boolean isValid) {
+ public void onProposedRotationChanged(int displayId, int rotation, boolean isValid) {
+ if (isVisibleBackgroundUserOnDisplay(displayId)) {
+ if (SPEW) {
+ Slog.d(TAG, "Skipping onProposedRotationChanged for visible background user "
+ + mUserManagerInternal.getUserAssignedToDisplay(displayId));
+ }
+ return;
+ }
if (mBar != null){
try {
mBar.onProposedRotationChanged(rotation, isValid);
@@ -690,6 +757,13 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
@Override
public void onDisplayReady(int displayId) {
+ if (isVisibleBackgroundUserOnDisplay(displayId)) {
+ if (SPEW) {
+ Slog.d(TAG, "Skipping onDisplayReady for visible background user "
+ + mUserManagerInternal.getUserAssignedToDisplay(displayId));
+ }
+ return;
+ }
IStatusBar bar = mBar;
if (bar != null) {
try {
@@ -703,6 +777,13 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme,
@Behavior int behavior, @InsetsType int requestedVisibleTypes,
String packageName, LetterboxDetails[] letterboxDetails) {
+ if (isVisibleBackgroundUserOnDisplay(displayId)) {
+ if (SPEW) {
+ Slog.d(TAG, "Skipping onSystemBarAttributesChanged for visible background user "
+ + mUserManagerInternal.getUserAssignedToDisplay(displayId));
+ }
+ return;
+ }
getUiState(displayId).setBarAttributes(appearance, appearanceRegions,
navbarColorManagedByIme, behavior, requestedVisibleTypes, packageName,
letterboxDetails);
@@ -719,6 +800,13 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
@Override
public void showTransient(int displayId, @InsetsType int types,
boolean isGestureOnSystemBar) {
+ if (isVisibleBackgroundUserOnDisplay(displayId)) {
+ if (SPEW) {
+ Slog.d(TAG, "Skipping showTransient for visible background user "
+ + mUserManagerInternal.getUserAssignedToDisplay(displayId));
+ }
+ return;
+ }
getUiState(displayId).showTransient(types);
IStatusBar bar = mBar;
if (bar != null) {
@@ -730,6 +818,13 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
@Override
public void abortTransient(int displayId, @InsetsType int types) {
+ if (isVisibleBackgroundUserOnDisplay(displayId)) {
+ if (SPEW) {
+ Slog.d(TAG, "Skipping abortTransient for visible background user "
+ + mUserManagerInternal.getUserAssignedToDisplay(displayId));
+ }
+ return;
+ }
getUiState(displayId).clearTransient(types);
IStatusBar bar = mBar;
if (bar != null) {
@@ -776,6 +871,15 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
@Override
public void setNavigationBarLumaSamplingEnabled(int displayId, boolean enable) {
+ if (isVisibleBackgroundUserOnDisplay(displayId)) {
+ if (SPEW) {
+ Slog.d(TAG,
+ "Skipping setNavigationBarLumaSamplingEnabled for visible background "
+ + "user "
+ + mUserManagerInternal.getUserAssignedToDisplay(displayId));
+ }
+ return;
+ }
IStatusBar bar = mBar;
if (bar != null) {
try {
@@ -1416,6 +1520,13 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
}
private void setDisableFlags(int displayId, int flags, String cause) {
+ if (isVisibleBackgroundUserOnDisplay(displayId)) {
+ if (SPEW) {
+ Slog.d(TAG, "Skipping setDisableFlags for visible background user "
+ + mUserManagerInternal.getUserAssignedToDisplay(displayId));
+ }
+ return;
+ }
// also allows calls from window manager which is in this process.
enforceStatusBarService();
@@ -2713,16 +2824,30 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
if (callingUserId == USER_SYSTEM || callingUserId == mCurrentUserId) {
return;
}
- final long ident = Binder.clearCallingIdentity();
- try {
- if (mUserManager.isSameProfileGroup(callingUserId, mCurrentUserId)) {
- return;
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
+ if (!isVisibleBackgroundUser(callingUserId)) {
+ return;
}
throw new SecurityException("User " + callingUserId
+ " is not permitted to use this method");
}
-}
+
+ private boolean isVisibleBackgroundUser(int userId) {
+ if (!mVisibleBackgroundUsersEnabled) {
+ return false;
+ }
+ // The main use case for visible background users is the Automotive multi-display
+ // configuration where a passenger can use a secondary display while the driver is
+ // using the main display.
+ // TODO(b/341604160) - Support visible background users properly and remove carve outs
+ return mUserManagerInternal.isVisibleBackgroundFullUser(userId);
+ }
+
+ private boolean isVisibleBackgroundUserOnDisplay(int displayId) {
+ if (!mVisibleBackgroundUsersEnabled) {
+ return false;
+ }
+ int userId = mUserManagerInternal.getUserAssignedToDisplay(displayId);
+ return isVisibleBackgroundUser(userId);
+ }
+} \ No newline at end of file
diff --git a/services/core/java/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java b/services/core/java/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java
index 474253223628..5f704a002a33 100644
--- a/services/core/java/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java
+++ b/services/core/java/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java
@@ -276,7 +276,7 @@ public class IpSecPacketLossDetector extends NetworkMetricMonitor {
// enabled on the last one as a sample
mInboundTransform = inboundTransform;
- if (!Flags.allowDisableIpsecLossDetector() || canStart()) {
+ if (canStart()) {
start();
}
}
@@ -292,7 +292,7 @@ public class IpSecPacketLossDetector extends NetworkMetricMonitor {
mMaxSeqNumIncreasePerSecond = getMaxSeqNumIncreasePerSecond(carrierConfig);
}
- if (Flags.allowDisableIpsecLossDetector() && canStart() != isStarted()) {
+ if (canStart() != isStarted()) {
if (canStart()) {
start();
} else {
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 4dcc6e112ecc..78359bd15717 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -2224,15 +2224,21 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
public ParcelFileDescriptor getWallpaperWithFeature(String callingPkg, String callingFeatureId,
IWallpaperManagerCallback cb, final int which, Bundle outParams, int wallpaperUserId,
boolean getCropped) {
- final boolean hasPrivilege = hasPermission(READ_WALLPAPER_INTERNAL)
- || hasPermission(MANAGE_EXTERNAL_STORAGE);
+ final int callingPid = Binder.getCallingPid();
+ final int callingUid = Binder.getCallingUid();
+ final boolean hasPrivilege = hasPermission(READ_WALLPAPER_INTERNAL);
if (!hasPrivilege) {
- mContext.getSystemService(StorageManager.class).checkPermissionReadImages(true,
- Binder.getCallingPid(), Binder.getCallingUid(), callingPkg, callingFeatureId);
+ boolean hasManageExternalStorage = hasPermission(MANAGE_EXTERNAL_STORAGE)
+ || hasAppOpPermission(MANAGE_EXTERNAL_STORAGE, callingUid, callingPkg,
+ callingFeatureId, "getWallpaperWithFeature from package: " + callingPkg);
+ if (!hasManageExternalStorage) {
+ mContext.getSystemService(StorageManager.class).checkPermissionReadImages(true,
+ callingPid, callingUid, callingPkg, callingFeatureId);
+ }
}
- wallpaperUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
- Binder.getCallingUid(), wallpaperUserId, false, true, "getWallpaper", null);
+ wallpaperUserId = ActivityManager.handleIncomingUser(callingPid, callingUid,
+ wallpaperUserId, false, true, "getWallpaper", null);
if (which != FLAG_SYSTEM && which != FLAG_LOCK) {
throw new IllegalArgumentException("Must specify exactly one kind of wallpaper to read");
@@ -2348,6 +2354,22 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
return mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED;
}
+ private boolean hasAppOpPermission(String permission, int callingUid, String callingPackage,
+ String attributionTag, String message) {
+ final String op = AppOpsManager.permissionToOp(permission);
+ final int opMode = mAppOpsManager.noteOpNoThrow(op, callingUid, callingPackage,
+ attributionTag, message);
+ switch (opMode) {
+ case AppOpsManager.MODE_ALLOWED:
+ case AppOpsManager.MODE_FOREGROUND:
+ return true;
+ case AppOpsManager.MODE_DEFAULT:
+ return hasPermission(permission);
+ default:
+ return false;
+ }
+ }
+
@Override
public WallpaperInfo getWallpaperInfo(int userId) {
return getWallpaperInfoWithFlags(FLAG_SYSTEM, userId);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 0be6471f189e..ff6f021f52a7 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -2848,7 +2848,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
final boolean hasImeSurface;
if (mStartingData != null) {
if (mStartingData.mWaitForSyncTransactionCommit
- || mTransitionController.isCollecting(this)) {
+ || mSyncState != SYNC_STATE_NONE) {
mStartingData.mRemoveAfterTransaction = AFTER_TRANSACTION_REMOVE_DIRECTLY;
mStartingData.mPrepareRemoveAnimation = prepareAnimation;
return;
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index 4e4616dcaa3f..0646fb74ddfd 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -1072,8 +1072,10 @@ class BackNavigationController {
return close.asWindowState() != null;
}
- private void initiate(@NonNull WindowContainer close, @NonNull WindowContainer[] open,
+ private void initiate(ScheduleAnimationBuilder builder,
@NonNull ActivityRecord[] openingActivities) {
+ WindowContainer close = builder.mCloseTarget;
+ WindowContainer[] open = builder.mOpenTargets;
if (isActivitySwitch(close, open)) {
mSwitchType = ACTIVITY_SWITCH;
if (Flags.migratePredictiveBackTransition()) {
@@ -1091,9 +1093,17 @@ class BackNavigationController {
return;
}
- mCloseAdaptor = createAdaptor(close, false, mSwitchType);
+ final Transition prepareTransition = builder.prepareTransitionIfNeeded(
+ openingActivities);
+ final SurfaceControl.Transaction st = openingActivities[0].getSyncTransaction();
+ final SurfaceControl.Transaction ct = prepareTransition != null
+ ? st : close.getPendingTransaction();
+ mCloseAdaptor = createAdaptor(close, false, mSwitchType, ct);
if (mCloseAdaptor.mAnimationTarget == null) {
Slog.w(TAG, "composeNewAnimations fail, skip");
+ if (prepareTransition != null) {
+ prepareTransition.abort();
+ }
clearBackAnimateTarget(true /* cancel */);
return;
}
@@ -1110,12 +1120,17 @@ class BackNavigationController {
next.getWindowConfiguration().getRotation());
}
}
- mOpenAnimAdaptor = new BackWindowAnimationAdaptorWrapper(true, mSwitchType, open);
+ mOpenAnimAdaptor = new BackWindowAnimationAdaptorWrapper(
+ true, mSwitchType, st, open);
if (!mOpenAnimAdaptor.isValid()) {
Slog.w(TAG, "compose animations fail, skip");
+ if (prepareTransition != null) {
+ prepareTransition.abort();
+ }
clearBackAnimateTarget(true /* cancel */);
return;
}
+ mOpenAnimAdaptor.mPreparedOpenTransition = prepareTransition;
mOpenActivities = openingActivities;
}
@@ -1147,19 +1162,21 @@ class BackNavigationController {
return new Pair<>(replaceClose, replaceOpen);
}
- private boolean composeAnimations(@NonNull WindowContainer close,
- @NonNull WindowContainer[] open, @NonNull ActivityRecord[] openingActivities) {
+ private boolean composeAnimations(@NonNull ScheduleAnimationBuilder builder,
+ @NonNull ActivityRecord[] openingActivities) {
if (mComposed || mWaitTransition) {
Slog.e(TAG, "Previous animation is running " + this);
return false;
}
clearBackAnimateTarget(true /* cancel */);
- if (close == null || open == null || open.length == 0 || open.length > 2) {
+ final WindowContainer[] open = builder.mOpenTargets;
+ if (builder.mCloseTarget == null || open == null || open.length == 0
+ || open.length > 2) {
Slog.e(TAG, "reset animation with null target close: "
- + close + " open: " + Arrays.toString(open));
+ + builder.mCloseTarget + " open: " + Arrays.toString(open));
return false;
}
- initiate(close, open, openingActivities);
+ initiate(builder, openingActivities);
if (mSwitchType == UNKNOWN) {
return false;
}
@@ -1384,10 +1401,10 @@ class BackNavigationController {
}
@NonNull private static BackWindowAnimationAdaptor createAdaptor(
- @NonNull WindowContainer target, boolean isOpen, int switchType) {
+ @NonNull WindowContainer target, boolean isOpen, int switchType,
+ SurfaceControl.Transaction st) {
final BackWindowAnimationAdaptor adaptor =
new BackWindowAnimationAdaptor(target, isOpen, switchType);
- final SurfaceControl.Transaction pt = target.getPendingTransaction();
// Workaround to show TaskFragment which can be hide in Transitions and won't show
// during isAnimating.
if (isOpen && target.asActivityRecord() != null) {
@@ -1395,10 +1412,10 @@ class BackNavigationController {
if (fragment != null) {
// Ensure task fragment surface has updated, in case configuration has changed.
fragment.updateOrganizedTaskFragmentSurface();
- pt.show(fragment.mSurfaceControl);
+ st.show(fragment.mSurfaceControl);
}
}
- target.startAnimation(pt, adaptor, false /* hidden */, ANIMATION_TYPE_PREDICT_BACK);
+ target.startAnimation(st, adaptor, false /* hidden */, ANIMATION_TYPE_PREDICT_BACK);
return adaptor;
}
@@ -1417,12 +1434,12 @@ class BackNavigationController {
private Transition mPreparedOpenTransition;
BackWindowAnimationAdaptorWrapper(boolean isOpen, int switchType,
- @NonNull WindowContainer... targets) {
+ SurfaceControl.Transaction st, @NonNull WindowContainer... targets) {
mAdaptors = new BackWindowAnimationAdaptor[targets.length];
for (int i = targets.length - 1; i >= 0; --i) {
- mAdaptors[i] = createAdaptor(targets[i], isOpen, switchType);
+ mAdaptors[i] = createAdaptor(targets[i], isOpen, switchType, st);
}
- mRemoteAnimationTarget = targets.length > 1 ? createWrapTarget()
+ mRemoteAnimationTarget = targets.length > 1 ? createWrapTarget(st)
: mAdaptors[0].mAnimationTarget;
}
@@ -1448,7 +1465,7 @@ class BackNavigationController {
mPreparedOpenTransition = null;
}
- private RemoteAnimationTarget createWrapTarget() {
+ private RemoteAnimationTarget createWrapTarget(SurfaceControl.Transaction st) {
// Special handle for opening two activities together.
// If we animate both activities separately, the animation area and rounded corner
// would also being handled separately. To make them seem like "open" together, wrap
@@ -1470,12 +1487,11 @@ class BackNavigationController {
.build();
mCloseTransaction = new SurfaceControl.Transaction();
mCloseTransaction.reparent(leashSurface, null);
- final SurfaceControl.Transaction pt = wc.getPendingTransaction();
- pt.setLayer(leashSurface, wc.getLastLayer());
+ st.setLayer(leashSurface, wc.getLastLayer());
for (int i = mAdaptors.length - 1; i >= 0; --i) {
BackWindowAnimationAdaptor adaptor = mAdaptors[i];
- pt.reparent(adaptor.mAnimationTarget.leash, leashSurface);
- pt.setPosition(adaptor.mAnimationTarget.leash,
+ st.reparent(adaptor.mAnimationTarget.leash, leashSurface);
+ st.setPosition(adaptor.mAnimationTarget.leash,
adaptor.mAnimationTarget.localBounds.left,
adaptor.mAnimationTarget.localBounds.top);
// For adjacent activity embedded, reparent Activity to TaskFragment when
@@ -1738,6 +1754,7 @@ class BackNavigationController {
WindowContainer mCloseTarget;
WindowContainer[] mOpenTargets;
boolean mIsLaunchBehind;
+ TaskSnapshot mSnapshot;
ScheduleAnimationBuilder(int type, BackAnimationAdapter adapter,
NavigationMonitor monitor) {
@@ -1771,6 +1788,13 @@ class BackNavigationController {
return wc == mCloseTarget || mCloseTarget.hasChild(wc) || wc.hasChild(mCloseTarget);
}
+ private Transition prepareTransitionIfNeeded(ActivityRecord[] visibleOpenActivities) {
+ if (mSnapshot == null) {
+ return setLaunchBehind(visibleOpenActivities);
+ }
+ return null;
+ }
+
/**
* Apply preview strategy on the opening target
*
@@ -1780,26 +1804,17 @@ class BackNavigationController {
private void applyPreviewStrategy(
@NonNull BackWindowAnimationAdaptorWrapper openAnimationAdaptor,
@NonNull ActivityRecord[] visibleOpenActivities) {
- boolean needsLaunchBehind = true;
if (isSupportWindowlessSurface() && mShowWindowlessSurface && !mIsLaunchBehind) {
boolean activitiesAreDrawn = false;
for (int i = visibleOpenActivities.length - 1; i >= 0; --i) {
// If the activity hasn't stopped, it's window should remain drawn.
activitiesAreDrawn |= visibleOpenActivities[i].firstWindowDrawn;
}
- final WindowContainer mainOpen = openAnimationAdaptor.mAdaptors[0].mTarget;
- final TaskSnapshot snapshot = getSnapshot(mainOpen, visibleOpenActivities);
// Don't create starting surface if previous activities haven't stopped or
// the snapshot does not exist.
- if (snapshot != null || !activitiesAreDrawn) {
- openAnimationAdaptor.createStartingSurface(snapshot);
+ if (mSnapshot != null || !activitiesAreDrawn) {
+ openAnimationAdaptor.createStartingSurface(mSnapshot);
}
- // Only use LaunchBehind if snapshot does not exist.
- needsLaunchBehind = snapshot == null;
- }
- if (needsLaunchBehind) {
- openAnimationAdaptor.mPreparedOpenTransition =
- setLaunchBehind(visibleOpenActivities);
}
// Force update mLastSurfaceShowing for opening activity and its task.
if (mWindowManagerService.mRoot.mTransitionController.isShellTransitionsEnabled()) {
@@ -1821,7 +1836,11 @@ class BackNavigationController {
return null;
}
- if (!composeAnimations(mCloseTarget, mOpenTargets, openingActivities)) {
+ if (!shouldLaunchBehind && mShowWindowlessSurface) {
+ mSnapshot = getSnapshot(mOpenTargets[0], openingActivities);
+ }
+
+ if (!composeAnimations(this, openingActivities)) {
return null;
}
mCloseTarget.mTransitionController.mSnapshotController
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 107d31e4e25c..0fa1a2138e35 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -2517,7 +2517,7 @@ public class DisplayPolicy {
if (getStatusBar() != null) {
final StatusBarManagerInternal statusBar = getStatusBarManagerInternal();
if (statusBar != null) {
- statusBar.setTopAppHidesStatusBar(topAppHidesStatusBar);
+ statusBar.setTopAppHidesStatusBar(getDisplayId(), topAppHidesStatusBar);
}
}
@@ -2544,9 +2544,9 @@ public class DisplayPolicy {
mService.mPolicy.isUserSetupComplete(),
isNavBarEmpty(disableFlags));
} else {
- // TODO (b/277290737): Move this to the client side, instead of using a proxy.
- callStatusBarSafely(statusBar -> statusBar.immersiveModeChanged(rootDisplayAreaId,
- isImmersiveMode));
+ // TODO(b/277290737): Move this to the client side, instead of using a proxy.
+ callStatusBarSafely(statusBar -> statusBar.immersiveModeChanged(getDisplayId(),
+ rootDisplayAreaId, isImmersiveMode));
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 5200e820fc02..8c06cfecdc40 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -81,7 +81,6 @@ import android.window.WindowContainerTransaction;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.ProtoLog;
-import com.android.server.LocalServices;
import com.android.server.UiThread;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.statusbar.StatusBarManagerInternal;
@@ -136,7 +135,6 @@ public class DisplayRotation {
private final RotationLockHistory mRotationLockHistory = new RotationLockHistory();
private OrientationListener mOrientationListener;
- private StatusBarManagerInternal mStatusBarManagerInternal;
private SettingsObserver mSettingsObserver;
@NonNull
private final DeviceStateController mDeviceStateController;
@@ -1559,11 +1557,9 @@ public class DisplayRotation {
/** Notify the StatusBar that system rotation suggestion has changed. */
private void sendProposedRotationChangeToStatusBarInternal(int rotation, boolean isValid) {
- if (mStatusBarManagerInternal == null) {
- mStatusBarManagerInternal = LocalServices.getService(StatusBarManagerInternal.class);
- }
- if (mStatusBarManagerInternal != null) {
- mStatusBarManagerInternal.onProposedRotationChanged(rotation, isValid);
+ final StatusBarManagerInternal bar = mDisplayPolicy.getStatusBarManagerInternal();
+ if (bar != null) {
+ bar.onProposedRotationChanged(mDisplayContent.getDisplayId(), rotation, isValid);
}
}
diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java
index 0dadade38ddb..e65396e00b20 100644
--- a/services/core/java/com/android/server/wm/LockTaskController.java
+++ b/services/core/java/com/android/server/wm/LockTaskController.java
@@ -659,7 +659,7 @@ public class LockTaskController {
StatusBarManagerInternal statusBarManager = LocalServices.getService(
StatusBarManagerInternal.class);
if (statusBarManager != null) {
- statusBarManager.showScreenPinningRequest(task.mTaskId);
+ statusBarManager.showScreenPinningRequest(task.mTaskId, task.mUserId);
}
return;
} else if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index e6226ab6786d..1e3de12b6d4e 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -73,6 +73,7 @@ import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_W
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_PREDICT_BACK;
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowState.BLAST_TIMEOUT_DURATION;
+import static com.android.window.flags.Flags.enableDisplayFocusInShellTransitions;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -223,6 +224,13 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
private final ArrayList<Task> mOnTopTasksAtReady = new ArrayList<>();
/**
+ * Tracks the top display like top tasks so we can trigger a MOVED_TO_TOP transition even when
+ * a display gets moved to front but there's no change in per-display focused tasks.
+ */
+ private DisplayContent mOnTopDisplayStart = null;
+ private DisplayContent mOnTopDisplayAtReady = null;
+
+ /**
* Set of participating windowtokens (activity/wallpaper) which are visible at the end of
* the transition animation.
*/
@@ -772,6 +780,10 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
if (dc == null || mTargetDisplays.contains(dc)) return;
mTargetDisplays.add(dc);
addOnTopTasks(dc, mOnTopTasksStart);
+ if (mOnTopDisplayStart == null) {
+ mOnTopDisplayStart =
+ mController.mAtm.mRootWindowContainer.getTopFocusedDisplayContent();
+ }
// Handle the case {transition.start(); applyTransaction(wct);} that the animating state
// is set before collecting participants.
if (mController.isAnimating()) {
@@ -995,6 +1007,8 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
for (int i = 0; i < mTargetDisplays.size(); ++i) {
addOnTopTasks(mTargetDisplays.get(i), mOnTopTasksAtReady);
}
+ mOnTopDisplayAtReady =
+ mController.mAtm.mRootWindowContainer.getTopFocusedDisplayContent();
mController.onTransitionPopulated(this);
}
}
@@ -2079,6 +2093,10 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
return true;
}
}
+ if (enableDisplayFocusInShellTransitions() && mOnTopDisplayStart
+ != mController.mAtm.mRootWindowContainer.getTopFocusedDisplayContent()) {
+ return true;
+ }
return false;
}
@@ -2110,6 +2128,8 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
includesOrderChange = true;
break;
}
+ includesOrderChange |= enableDisplayFocusInShellTransitions()
+ && mOnTopDisplayStart != mOnTopDisplayAtReady;
if (!includesOrderChange && !reportCurrent) {
// This transition doesn't include an order change, so if it isn't required to report
// the current focus (eg. it's the last of a cluster of transitions), then don't
@@ -2120,6 +2140,8 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
// latest state and compare with the last reported state (or our start state if no
// reported state exists).
ArrayList<Task> onTopTasksEnd = new ArrayList<>();
+ final DisplayContent onTopDisplayEnd =
+ mController.mAtm.mRootWindowContainer.getTopFocusedDisplayContent();
for (int d = 0; d < mTargetDisplays.size(); ++d) {
addOnTopTasks(mTargetDisplays.get(d), onTopTasksEnd);
final int displayId = mTargetDisplays.get(d).mDisplayId;
@@ -2127,11 +2149,15 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
for (int i = onTopTasksEnd.size() - 1; i >= 0; --i) {
final Task task = onTopTasksEnd.get(i);
if (task.getDisplayId() != displayId) continue;
- // If it didn't change since last report, don't report
- if (reportedOnTop == null) {
- if (mOnTopTasksStart.contains(task)) continue;
- } else if (reportedOnTop.contains(task)) {
- continue;
+ if (!enableDisplayFocusInShellTransitions()
+ || mOnTopDisplayStart == onTopDisplayEnd
+ || displayId != onTopDisplayEnd.mDisplayId) {
+ // If it didn't change since last report, don't report
+ if (reportedOnTop == null) {
+ if (mOnTopTasksStart.contains(task)) continue;
+ } else if (reportedOnTop.contains(task)) {
+ continue;
+ }
}
// Need to report it.
mParticipants.add(task);
@@ -2333,10 +2359,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
// Place the nav bar on top of anything else in the top activity.
t.setLayer(navSurfaceControl, Integer.MAX_VALUE);
}
- final StatusBarManagerInternal bar = dc.getDisplayPolicy().getStatusBarManagerInternal();
- if (bar != null) {
- bar.setNavigationBarLumaSamplingEnabled(mRecentsDisplayId, false);
- }
+ sendLumaSamplingEnabledToStatusBarInternal(dc, false);
}
/** @see RecentsAnimationController#restoreNavigationBarFromApp */
@@ -2354,10 +2377,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
final DisplayContent dc =
mController.mAtm.mRootWindowContainer.getDisplayContent(recentsDisplayId);
- final StatusBarManagerInternal bar = dc.getDisplayPolicy().getStatusBarManagerInternal();
- if (bar != null) {
- bar.setNavigationBarLumaSamplingEnabled(recentsDisplayId, true);
- }
+ sendLumaSamplingEnabledToStatusBarInternal(dc, true);
final WindowState navWindow = dc.getDisplayPolicy().getNavigationBar();
if (navWindow == null) return;
navWindow.setSurfaceTranslationY(0);
@@ -2391,6 +2411,14 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
dc.mWmService.scheduleAnimationLocked();
}
+ private void sendLumaSamplingEnabledToStatusBarInternal(@NonNull DisplayContent dc,
+ boolean enabled) {
+ final StatusBarManagerInternal bar = dc.getDisplayPolicy().getStatusBarManagerInternal();
+ if (bar != null) {
+ bar.setNavigationBarLumaSamplingEnabled(dc.getDisplayId(), enabled);
+ }
+ }
+
private void reportStartReasonsToLogger() {
// Record transition start in metrics logger. We just assume everything is "DRAWN"
// at this point since splash-screen is a presentation (shell) detail.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index fb57a1bb94c1..d63cdcd4e32a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -90,6 +90,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManager.REMOVE_CONTENT_MODE_UNDEFINED;
import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_OPEN;
+import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.view.WindowManager.fixScale;
import static android.view.WindowManagerGlobal.ADD_OKAY;
import static android.view.WindowManagerGlobal.RELAYOUT_RES_CANCEL_AND_REDRAW;
@@ -158,6 +159,7 @@ import static com.android.server.wm.WindowManagerServiceDumpProto.ROOT_WINDOW_CO
import static com.android.server.wm.WindowManagerServiceDumpProto.WINDOW_FRAMES_VALID;
import static com.android.window.flags.Flags.multiCrop;
import static com.android.window.flags.Flags.setScPropertiesInClient;
+import static com.android.window.flags.Flags.enableDisplayFocusInShellTransitions;
import android.Manifest;
import android.Manifest.permission;
@@ -3238,9 +3240,28 @@ public class WindowManagerService extends IWindowManager.Stub
return;
}
+ Transition transition = null;
+ boolean transitionNewlyCreated = false;
+ if (enableDisplayFocusInShellTransitions()) {
+ transition = mAtmService.getTransitionController().requestTransitionIfNeeded(
+ TRANSIT_TO_FRONT, 0 /* flags */, null /* trigger */,
+ displayContent);
+ if (transition != null) {
+ transitionNewlyCreated = true;
+ } else {
+ transition =
+ mAtmService.getTransitionController().getCollectingTransition();
+ }
+ if (transition != null) {
+ transition.recordTaskOrder(displayContent);
+ }
+ }
// Nothing prevented us from moving the display to the top. Let's do it!
displayContent.getParent().positionChildAt(WindowContainer.POSITION_TOP,
displayContent, true /* includingParents */);
+ if (transitionNewlyCreated) {
+ transition.setReady(displayContent, true /* ready */);
+ }
}
}
}
diff --git a/services/tests/appfunctions/src/android/app/appfunctions/AppFunctionRuntimeMetadataTest.kt b/services/tests/appfunctions/src/android/app/appfunctions/AppFunctionRuntimeMetadataTest.kt
new file mode 100644
index 000000000000..650e520ebb7d
--- /dev/null
+++ b/services/tests/appfunctions/src/android/app/appfunctions/AppFunctionRuntimeMetadataTest.kt
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.app.appfunctions
+
+import android.app.appsearch.AppSearchSchema
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class AppFunctionRuntimeMetadataTest {
+
+ @Test
+ fun getRuntimeSchemaNameForPackage() {
+ val actualSchemaName =
+ AppFunctionRuntimeMetadata.getRuntimeSchemaNameForPackage("com.example.app")
+
+ assertThat(actualSchemaName).isEqualTo("AppFunctionRuntimeMetadata-com.example.app")
+ }
+
+ @Test
+ fun testCreateChildRuntimeSchema() {
+ val runtimeSchema: AppSearchSchema =
+ AppFunctionRuntimeMetadata.createAppFunctionRuntimeSchema("com.example.app")
+
+ assertThat(runtimeSchema.schemaType).isEqualTo("AppFunctionRuntimeMetadata-com.example.app")
+ val propertyNameSet = runtimeSchema.properties.map { it.name }.toSet()
+ assertThat(propertyNameSet.contains(AppFunctionRuntimeMetadata.PROPERTY_FUNCTION_ID))
+ .isTrue()
+ assertThat(propertyNameSet.contains(AppFunctionRuntimeMetadata.PROPERTY_PACKAGE_NAME))
+ .isTrue()
+ assertThat(propertyNameSet.contains(AppFunctionRuntimeMetadata.PROPERTY_ENABLED)).isTrue()
+ assertThat(
+ propertyNameSet.contains(
+ AppFunctionRuntimeMetadata.PROPERTY_APP_FUNCTION_STATIC_METADATA_QUALIFIED_ID
+ )
+ )
+ .isTrue()
+ }
+
+ @Test
+ fun testCreateParentRuntimeSchema() {
+ val runtimeSchema: AppSearchSchema =
+ AppFunctionRuntimeMetadata.createParentAppFunctionRuntimeSchema()
+
+ assertThat(runtimeSchema.schemaType).isEqualTo("AppFunctionRuntimeMetadata")
+ val propertyNameSet = runtimeSchema.properties.map { it.name }.toSet()
+ assertThat(propertyNameSet.contains(AppFunctionRuntimeMetadata.PROPERTY_FUNCTION_ID))
+ .isTrue()
+ assertThat(propertyNameSet.contains(AppFunctionRuntimeMetadata.PROPERTY_PACKAGE_NAME))
+ .isTrue()
+ assertThat(propertyNameSet.contains(AppFunctionRuntimeMetadata.PROPERTY_ENABLED)).isTrue()
+ assertThat(
+ propertyNameSet.contains(
+ AppFunctionRuntimeMetadata.PROPERTY_APP_FUNCTION_STATIC_METADATA_QUALIFIED_ID
+ )
+ )
+ .isTrue()
+ }
+
+ @Test
+ fun testGetPackageNameFromSchema() {
+ val expectedPackageName = "com.foo.test"
+ val expectedPackageName2 = "com.bar.test"
+ val testSchemaType =
+ AppFunctionRuntimeMetadata.createAppFunctionRuntimeSchema(expectedPackageName)
+ .schemaType
+ val testSchemaType2 =
+ AppFunctionRuntimeMetadata.createAppFunctionRuntimeSchema(expectedPackageName2)
+ .schemaType
+
+ val actualPackageName = AppFunctionRuntimeMetadata.getPackageNameFromSchema(testSchemaType)
+ val actualPackageName2 =
+ AppFunctionRuntimeMetadata.getPackageNameFromSchema(testSchemaType2)
+
+ assertThat(actualPackageName).isEqualTo(expectedPackageName)
+ assertThat(actualPackageName2).isEqualTo(expectedPackageName2)
+ }
+
+ @Test
+ fun testGetPackageNameFromParentSchema() {
+ val expectedPackageName = AppFunctionRuntimeMetadata.APP_FUNCTION_INDEXER_PACKAGE
+ val testSchemaType =
+ AppFunctionRuntimeMetadata.createParentAppFunctionRuntimeSchema().schemaType
+
+ val actualPackageName = AppFunctionRuntimeMetadata.getPackageNameFromSchema(testSchemaType)
+
+ assertThat(actualPackageName).isEqualTo(expectedPackageName)
+ }
+}
diff --git a/services/tests/appfunctions/src/com/android/server/appfunctions/FutureAppSearchSessionTest.kt b/services/tests/appfunctions/src/com/android/server/appfunctions/FutureAppSearchSessionTest.kt
index a0f1a559bb52..3bc44111ba08 100644
--- a/services/tests/appfunctions/src/com/android/server/appfunctions/FutureAppSearchSessionTest.kt
+++ b/services/tests/appfunctions/src/com/android/server/appfunctions/FutureAppSearchSessionTest.kt
@@ -19,8 +19,10 @@ import android.app.appfunctions.AppFunctionRuntimeMetadata
import android.app.appfunctions.AppFunctionRuntimeMetadata.APP_FUNCTION_RUNTIME_NAMESPACE
import android.app.appfunctions.AppFunctionRuntimeMetadata.createAppFunctionRuntimeSchema
import android.app.appfunctions.AppFunctionRuntimeMetadata.createParentAppFunctionRuntimeSchema
+import android.app.appsearch.AppSearchBatchResult
import android.app.appsearch.AppSearchManager
import android.app.appsearch.PutDocumentsRequest
+import android.app.appsearch.RemoveByDocumentIdRequest
import android.app.appsearch.SearchSpec
import android.app.appsearch.SetSchemaRequest
import androidx.test.platform.app.InstrumentationRegistry
@@ -56,7 +58,7 @@ class FutureAppSearchSessionTest {
SetSchemaRequest.Builder()
.addSchemas(
createParentAppFunctionRuntimeSchema(),
- createAppFunctionRuntimeSchema(TEST_PACKAGE_NAME)
+ createAppFunctionRuntimeSchema(TEST_PACKAGE_NAME),
)
.build()
@@ -74,7 +76,7 @@ class FutureAppSearchSessionTest {
SetSchemaRequest.Builder()
.addSchemas(
createParentAppFunctionRuntimeSchema(),
- createAppFunctionRuntimeSchema(TEST_PACKAGE_NAME)
+ createAppFunctionRuntimeSchema(TEST_PACKAGE_NAME),
)
.build()
val schema = session.setSchema(setSchemaRequest)
@@ -93,6 +95,40 @@ class FutureAppSearchSessionTest {
}
@Test
+ fun remove() {
+ val searchContext = AppSearchManager.SearchContext.Builder(TEST_DB).build()
+ FutureAppSearchSession(appSearchManager, testExecutor, searchContext).use { session ->
+ val setSchemaRequest =
+ SetSchemaRequest.Builder()
+ .addSchemas(
+ createParentAppFunctionRuntimeSchema(),
+ createAppFunctionRuntimeSchema(TEST_PACKAGE_NAME),
+ )
+ .build()
+ val schema = session.setSchema(setSchemaRequest)
+ assertThat(schema.get()).isNotNull()
+ val appFunctionRuntimeMetadata =
+ AppFunctionRuntimeMetadata.Builder(TEST_PACKAGE_NAME, TEST_FUNCTION_ID, "").build()
+ val putDocumentsRequest: PutDocumentsRequest =
+ PutDocumentsRequest.Builder()
+ .addGenericDocuments(appFunctionRuntimeMetadata)
+ .build()
+ val putResult = session.put(putDocumentsRequest)
+ assertThat(putResult.get().isSuccess).isTrue()
+ val removeDocumentRequest =
+ RemoveByDocumentIdRequest.Builder(APP_FUNCTION_RUNTIME_NAMESPACE)
+ .addIds(appFunctionRuntimeMetadata.id)
+ .build()
+
+ val removeResult: AppSearchBatchResult<String, Void> =
+ session.remove(removeDocumentRequest).get()
+
+ assertThat(removeResult).isNotNull()
+ assertThat(removeResult.isSuccess).isTrue()
+ }
+ }
+
+ @Test
fun search() {
val searchContext = AppSearchManager.SearchContext.Builder(TEST_DB).build()
FutureAppSearchSession(appSearchManager, testExecutor, searchContext).use { session ->
@@ -100,7 +136,7 @@ class FutureAppSearchSessionTest {
SetSchemaRequest.Builder()
.addSchemas(
createParentAppFunctionRuntimeSchema(),
- createAppFunctionRuntimeSchema(TEST_PACKAGE_NAME)
+ createAppFunctionRuntimeSchema(TEST_PACKAGE_NAME),
)
.build()
val schema = session.setSchema(setSchemaRequest)
@@ -132,7 +168,7 @@ class FutureAppSearchSessionTest {
SetSchemaRequest.Builder()
.addSchemas(
createParentAppFunctionRuntimeSchema(),
- createAppFunctionRuntimeSchema(TEST_PACKAGE_NAME)
+ createAppFunctionRuntimeSchema(TEST_PACKAGE_NAME),
)
.build()
val schema = session.setSchema(setSchemaRequest)
@@ -144,12 +180,13 @@ class FutureAppSearchSessionTest {
.build()
val putResult = session.put(putDocumentsRequest)
- val genricDocument = session
- .getByDocumentId(
- /* documentId= */ "${TEST_PACKAGE_NAME}/${TEST_FUNCTION_ID}",
- APP_FUNCTION_RUNTIME_NAMESPACE
- )
- .get()
+ val genricDocument =
+ session
+ .getByDocumentId(
+ /* documentId= */ "${TEST_PACKAGE_NAME}/${TEST_FUNCTION_ID}",
+ APP_FUNCTION_RUNTIME_NAMESPACE,
+ )
+ .get()
val foundAppFunctionRuntimeMetadata = AppFunctionRuntimeMetadata(genricDocument)
assertThat(foundAppFunctionRuntimeMetadata.functionId).isEqualTo(TEST_FUNCTION_ID)
diff --git a/services/tests/appfunctions/src/com/android/server/appfunctions/MetadataSyncAdapterTest.kt b/services/tests/appfunctions/src/com/android/server/appfunctions/MetadataSyncAdapterTest.kt
index 1061da28f799..5769e07ee58d 100644
--- a/services/tests/appfunctions/src/com/android/server/appfunctions/MetadataSyncAdapterTest.kt
+++ b/services/tests/appfunctions/src/com/android/server/appfunctions/MetadataSyncAdapterTest.kt
@@ -16,12 +16,9 @@
package com.android.server.appfunctions
import android.app.appfunctions.AppFunctionRuntimeMetadata
-import android.app.appfunctions.AppFunctionRuntimeMetadata.PROPERTY_FUNCTION_ID
-import android.app.appfunctions.AppFunctionRuntimeMetadata.PROPERTY_PACKAGE_NAME
import android.app.appsearch.AppSearchManager
import android.app.appsearch.AppSearchManager.SearchContext
import android.app.appsearch.PutDocumentsRequest
-import android.app.appsearch.SearchSpec
import android.app.appsearch.SetSchemaRequest
import android.util.ArrayMap
import android.util.ArraySet
@@ -76,20 +73,11 @@ class MetadataSyncAdapterTest {
testExecutor,
FutureAppSearchSession(appSearchManager, testExecutor, searchContext),
)
- val searchSpec: SearchSpec =
- SearchSpec.Builder()
- .addFilterSchemas(
- AppFunctionRuntimeMetadata.RUNTIME_SCHEMA_TYPE,
- AppFunctionRuntimeMetadata.createAppFunctionRuntimeSchema(TEST_TARGET_PKG_NAME)
- .schemaType,
- )
- .build()
val packageToFunctionIdMap =
metadataSyncAdapter.getPackageToFunctionIdMap(
- "",
- searchSpec,
- PROPERTY_FUNCTION_ID,
- PROPERTY_PACKAGE_NAME,
+ AppFunctionRuntimeMetadata.RUNTIME_SCHEMA_TYPE,
+ AppFunctionRuntimeMetadata.PROPERTY_FUNCTION_ID,
+ AppFunctionRuntimeMetadata.PROPERTY_PACKAGE_NAME,
)
assertThat(packageToFunctionIdMap).isNotNull()
@@ -135,21 +123,11 @@ class MetadataSyncAdapterTest {
testExecutor,
FutureAppSearchSession(appSearchManager, testExecutor, searchContext),
)
- val searchSpec: SearchSpec =
- SearchSpec.Builder()
- .setResultCountPerPage(1)
- .addFilterSchemas(
- AppFunctionRuntimeMetadata.RUNTIME_SCHEMA_TYPE,
- AppFunctionRuntimeMetadata.createAppFunctionRuntimeSchema(TEST_TARGET_PKG_NAME)
- .schemaType,
- )
- .build()
val packageToFunctionIdMap =
metadataSyncAdapter.getPackageToFunctionIdMap(
- "",
- searchSpec,
- PROPERTY_FUNCTION_ID,
- PROPERTY_PACKAGE_NAME,
+ AppFunctionRuntimeMetadata.RUNTIME_SCHEMA_TYPE,
+ AppFunctionRuntimeMetadata.PROPERTY_FUNCTION_ID,
+ AppFunctionRuntimeMetadata.PROPERTY_PACKAGE_NAME,
)
assertThat(packageToFunctionIdMap).isNotNull()
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
index 52f1cbd89e13..76c8e6862211 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -143,6 +143,7 @@ import com.android.server.display.DisplayManagerService.DeviceStateListener;
import com.android.server.display.DisplayManagerService.SyncRoot;
import com.android.server.display.config.SensorData;
import com.android.server.display.feature.DisplayManagerFlags;
+import com.android.server.display.layout.Layout;
import com.android.server.display.notifications.DisplayNotificationManager;
import com.android.server.input.InputManagerInternal;
import com.android.server.lights.LightsManager;
@@ -3201,6 +3202,45 @@ public class DisplayManagerServiceTest {
argThat(matchesFilter));
}
+ @Test
+ public void testOnDisplayChanged_HbmMetadataNull() {
+ DisplayPowerController dpc = mock(DisplayPowerController.class);
+ DisplayManagerService.Injector injector = new BasicInjector() {
+ @Override
+ DisplayPowerController getDisplayPowerController(Context context,
+ DisplayPowerController.Injector injector,
+ DisplayManagerInternal.DisplayPowerCallbacks callbacks, Handler handler,
+ SensorManager sensorManager, DisplayBlanker blanker,
+ LogicalDisplay logicalDisplay, BrightnessTracker brightnessTracker,
+ BrightnessSetting brightnessSetting, Runnable onBrightnessChangeRunnable,
+ HighBrightnessModeMetadata hbmMetadata, boolean bootCompleted,
+ DisplayManagerFlags flags) {
+ return dpc;
+ }
+ };
+ DisplayManagerService displayManager = new DisplayManagerService(mContext, injector);
+ DisplayManagerInternal localService = displayManager.new LocalService();
+ registerDefaultDisplays(displayManager);
+ displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
+
+ // Add the FakeDisplayDevice
+ FakeDisplayDevice displayDevice = new FakeDisplayDevice();
+ DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo();
+ displayDeviceInfo.state = Display.STATE_ON;
+ displayDevice.setDisplayDeviceInfo(displayDeviceInfo);
+ displayManager.getDisplayDeviceRepository()
+ .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED);
+ initDisplayPowerController(localService);
+
+ // Simulate DisplayDevice change
+ DisplayDeviceInfo displayDeviceInfo2 = new DisplayDeviceInfo();
+ displayDeviceInfo2.copyFrom(displayDeviceInfo);
+ displayDeviceInfo2.state = Display.STATE_DOZE;
+ updateDisplayDeviceInfo(displayManager, displayDevice, displayDeviceInfo2);
+
+ verify(dpc).onDisplayChanged(/* hbmMetadata= */ null, Layout.NO_LEAD_DISPLAY);
+ }
+
private void initDisplayPowerController(DisplayManagerInternal localService) {
localService.initPowerManagement(new DisplayManagerInternal.DisplayPowerCallbacks() {
@Override
diff --git a/services/tests/mockingservicestests/Android.bp b/services/tests/mockingservicestests/Android.bp
index 5a7693194d88..01435ff7f253 100644
--- a/services/tests/mockingservicestests/Android.bp
+++ b/services/tests/mockingservicestests/Android.bp
@@ -138,8 +138,6 @@ android_ravenwood_test {
auto_gen_config: true,
}
-FLAKY = ["androidx.test.filters.FlakyTest"]
-
test_module_config {
name: "FrameworksMockingServicesTests_blob",
base: "FrameworksMockingServicesTests",
@@ -152,7 +150,6 @@ test_module_config {
base: "FrameworksMockingServicesTests",
test_suites: ["device-tests"],
include_filters: ["com.android.server.DeviceIdleControllerTest"],
- exclude_annotations: FLAKY,
}
test_module_config {
@@ -161,7 +158,6 @@ test_module_config {
test_suites: ["device-tests"],
include_filters: ["com.android.server.AppStateTrackerTest"],
include_annotations: ["android.platform.test.annotations.Presubmit"],
- exclude_annotations: FLAKY,
}
test_module_config {
@@ -177,7 +173,6 @@ test_module_config {
test_suites: ["device-tests"],
include_filters: ["com.android.server.alarm"],
include_annotations: ["android.platform.test.annotations.Presubmit"],
- exclude_annotations: FLAKY,
}
test_module_config {
@@ -185,7 +180,7 @@ test_module_config {
base: "FrameworksMockingServicesTests",
test_suites: ["device-tests"],
include_filters: ["com.android.server.job"],
- exclude_annotations: FLAKY + ["androidx.test.filters.LargeTest"],
+ exclude_annotations: ["androidx.test.filters.LargeTest"],
}
test_module_config {
@@ -200,7 +195,6 @@ test_module_config {
base: "FrameworksMockingServicesTests",
test_suites: ["device-tests"],
include_filters: ["com.android.server.tare"],
- exclude_annotations: FLAKY,
}
test_module_config {
@@ -215,7 +209,6 @@ test_module_config {
base: "FrameworksMockingServicesTests",
test_suites: ["device-tests"],
include_filters: ["android.service.games"],
- exclude_annotations: FLAKY,
}
test_module_config {
@@ -245,7 +238,6 @@ test_module_config {
test_suites: ["device-tests"],
include_filters: ["com.android.server.am."],
include_annotations: ["android.platform.test.annotations.Presubmit"],
- exclude_annotations: FLAKY,
}
test_module_config {
@@ -265,7 +257,6 @@ test_module_config {
test_suites: ["device-tests"],
// Matches appop too
include_filters: ["com.android.server.app"],
- exclude_annotations: FLAKY,
}
test_module_config {
@@ -301,7 +292,6 @@ test_module_config {
base: "FrameworksMockingServicesTests",
test_suites: ["device-tests"],
include_filters: ["com.android.server.pm"],
- exclude_annotations: FLAKY + ["org.junit.Ignore"],
}
test_module_config {
@@ -309,7 +299,6 @@ test_module_config {
base: "FrameworksMockingServicesTests",
test_suites: ["device-tests"],
include_filters: ["com.android.server.power"],
- exclude_annotations: FLAKY,
}
test_module_config {
@@ -324,7 +313,6 @@ test_module_config {
base: "FrameworksMockingServicesTests",
test_suites: ["device-tests"],
include_filters: ["com.android.server.trust"],
- exclude_annotations: FLAKY,
}
test_module_config {
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index d9573559fa8d..5ec53023dc67 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -438,6 +438,28 @@ public class MockingOomAdjusterTests {
@SuppressWarnings("GuardedBy")
@Test
+ public void testUpdateOomAdj_DoOne_TopSleepingReceivingBroadcast() {
+ ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
+ doReturn(PROCESS_STATE_TOP_SLEEPING).when(mService.mAtmInternal).getTopProcessState();
+ doReturn(app).when(mService).getTopApp();
+ updateOomAdj(app);
+
+ assertProcStates(app, PROCESS_STATE_TOP_SLEEPING, FOREGROUND_APP_ADJ,
+ SCHED_GROUP_BACKGROUND);
+ assertTrue(app.mState.hasForegroundActivities());
+
+ doReturn(true).when(mService).isReceivingBroadcastLocked(any(ProcessRecord.class),
+ any(int[].class));
+ updateOomAdj(app);
+
+ assertProcStates(app, PROCESS_STATE_RECEIVER, FOREGROUND_APP_ADJ, SCHED_GROUP_BACKGROUND);
+ assertTrue(app.mState.hasForegroundActivities());
+
+ }
+
+ @SuppressWarnings("GuardedBy")
+ @Test
public void testUpdateOomAdj_DoOne_ExecutingService() {
ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
@@ -1182,6 +1204,25 @@ public class MockingOomAdjusterTests {
@SuppressWarnings("GuardedBy")
@Test
+ public void testUpdateOomAdj_DoOne_BoundFgService_Sleeping() {
+ ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
+ ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
+ MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
+ bindService(app, client, null, null, Context.BIND_FOREGROUND_SERVICE, mock(IBinder.class));
+ client.mState.setMaxAdj(PERSISTENT_PROC_ADJ);
+ mService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_ASLEEP);
+ updateOomAdj(client, app);
+ mService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
+
+ assertProcStates(app, PROCESS_STATE_BOUND_FOREGROUND_SERVICE, VISIBLE_APP_ADJ,
+ SCHED_GROUP_RESTRICTED);
+ assertProcStates(client, PROCESS_STATE_PERSISTENT, PERSISTENT_PROC_ADJ,
+ SCHED_GROUP_DEFAULT);
+ }
+
+ @SuppressWarnings("GuardedBy")
+ @Test
public void testUpdateOomAdj_DoOne_Service_BoundNotForeground() {
ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
@@ -2766,6 +2807,30 @@ public class MockingOomAdjusterTests {
@SuppressWarnings("GuardedBy")
@Test
+ public void testUpdateOomAdj_DoOne_AboveClient() {
+ ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
+ ProcessRecord service = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
+ MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, true));
+ doReturn(PROCESS_STATE_TOP).when(mService.mAtmInternal).getTopProcessState();
+ doReturn(app).when(mService).getTopApp();
+ mService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
+ updateOomAdj(app);
+
+ assertEquals(FOREGROUND_APP_ADJ, app.mState.getSetAdj());
+
+ // Simulate binding to a service in the same process using BIND_ABOVE_CLIENT and
+ // verify that its OOM adjustment level is unaffected.
+ bindService(service, app, null, null, Context.BIND_ABOVE_CLIENT, mock(IBinder.class));
+ app.mServices.updateHasAboveClientLocked();
+ assertTrue(app.mServices.hasAboveClient());
+
+ updateOomAdj(app);
+ assertEquals(VISIBLE_APP_ADJ, app.mState.getSetAdj());
+ }
+
+ @SuppressWarnings("GuardedBy")
+ @Test
public void testUpdateOomAdj_DoOne_AboveClient_SameProcess() {
ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index a862c43fd841..914b29f44bb1 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -36,6 +36,7 @@ android_test {
"-Werror",
],
static_libs: [
+ "a11ychecker",
"aatf",
"accessibility_protos_lite",
"cts-input-lib",
@@ -273,21 +274,12 @@ java_genrule {
"$(location soong_zip) -o $(out) -C $(genDir)/res -D $(genDir)/res",
}
-FLAKY = [
- "androidx.test.filters.FlakyTest",
-]
-
-FLAKY_AND_IGNORED = [
- "androidx.test.filters.FlakyTest",
- "org.junit.Ignore",
-]
// Used by content protection TEST_MAPPING
test_module_config {
name: "FrameworksServicesTests_contentprotection",
base: "FrameworksServicesTests",
test_suites: ["device-tests"],
include_filters: ["com.android.server.contentprotection"],
- exclude_annotations: FLAKY_AND_IGNORED,
}
test_module_config {
@@ -295,7 +287,6 @@ test_module_config {
base: "FrameworksServicesTests",
test_suites: ["device-tests"],
include_filters: ["com.android.server.om."],
- exclude_annotations: FLAKY_AND_IGNORED,
}
// Used by contexthub TEST_MAPPING
@@ -306,7 +297,6 @@ test_module_config {
include_filters: ["com.android.server.location.contexthub."],
// TODO(ron): are these right, does it run anything?
include_annotations: ["android.platform.test.annotations.Presubmit"],
- exclude_annotations: FLAKY_AND_IGNORED,
}
test_module_config {
@@ -316,7 +306,6 @@ test_module_config {
include_filters: ["com.android.server.location.contexthub."],
// TODO(ron): are these right, does it run anything?
include_annotations: ["android.platform.test.annotations.Postsubmit"],
- exclude_annotations: FLAKY_AND_IGNORED,
}
// Used by contentcapture
@@ -325,7 +314,6 @@ test_module_config {
base: "FrameworksServicesTests",
test_suites: ["device-tests"],
include_filters: ["com.android.server.contentcapture"],
- exclude_annotations: FLAKY_AND_IGNORED,
}
test_module_config {
@@ -333,7 +321,6 @@ test_module_config {
base: "FrameworksServicesTests",
test_suites: ["device-tests"],
include_filters: ["com.android.server.recoverysystem."],
- exclude_annotations: FLAKY,
}
// server pm TEST_MAPPING
@@ -343,7 +330,6 @@ test_module_config {
test_suites: ["device-tests"],
include_annotations: ["android.platform.test.annotations.Presubmit"],
include_filters: ["com.android.server.pm."],
- exclude_annotations: FLAKY_AND_IGNORED,
}
test_module_config {
@@ -352,7 +338,6 @@ test_module_config {
test_suites: ["device-tests"],
include_annotations: ["android.platform.test.annotations.Postsubmit"],
include_filters: ["com.android.server.pm."],
- exclude_annotations: FLAKY_AND_IGNORED,
}
// server os TEST_MAPPING
@@ -368,7 +353,6 @@ test_module_config {
base: "FrameworksServicesTests",
test_suites: ["device-tests"],
include_annotations: ["android.platform.test.annotations.Presubmit"],
- exclude_annotations: FLAKY_AND_IGNORED,
}
test_module_config {
@@ -390,14 +374,6 @@ test_module_config {
}
test_module_config {
- name: "FrameworksServicesTests_com_android_server_tare_Presubmit",
- base: "FrameworksServicesTests",
- test_suites: ["device-tests"],
- include_filters: ["com.android.server.tare"],
- exclude_annotations: FLAKY,
-}
-
-test_module_config {
name: "FrameworksServicesTests_com_android_server_tare",
base: "FrameworksServicesTests",
test_suites: ["device-tests"],
@@ -405,14 +381,6 @@ test_module_config {
}
test_module_config {
- name: "FrameworksServicesTests_com_android_server_usage_Presubmit",
- base: "FrameworksServicesTests",
- test_suites: ["device-tests"],
- include_filters: ["com.android.server.usage"],
- exclude_annotations: FLAKY,
-}
-
-test_module_config {
name: "FrameworksServicesTests_com_android_server_usage",
base: "FrameworksServicesTests",
test_suites: ["device-tests"],
@@ -427,14 +395,6 @@ test_module_config {
}
test_module_config {
- name: "FrameworksServicesTests_accessibility_Presubmit",
- base: "FrameworksServicesTests",
- test_suites: ["device-tests"],
- include_filters: ["com.android.server.accessibility"],
- exclude_annotations: FLAKY,
-}
-
-test_module_config {
name: "FrameworksServicesTests_accessibility",
base: "FrameworksServicesTests",
test_suites: ["device-tests"],
@@ -462,7 +422,6 @@ test_module_config {
test_suites: ["device-tests"],
include_filters: ["com.android.server.am."],
include_annotations: ["android.platform.test.annotations.Presubmit"],
- exclude_annotations: FLAKY,
}
test_module_config {
@@ -485,7 +444,6 @@ test_module_config {
test_suites: ["device-tests"],
include_filters: ["com.android.server.audio"],
include_annotations: ["android.platform.test.annotations.Presubmit"],
- exclude_annotations: FLAKY_AND_IGNORED,
}
test_module_config {
@@ -501,7 +459,6 @@ test_module_config {
test_suites: ["device-tests"],
include_filters: ["com.android.server.hdmi"],
include_annotations: ["android.platform.test.annotations.Presubmit"],
- exclude_annotations: FLAKY_AND_IGNORED,
}
test_module_config {
@@ -509,7 +466,6 @@ test_module_config {
base: "FrameworksServicesTests",
test_suites: ["device-tests"],
include_filters: ["com.android.server.hdmi"],
- exclude_annotations: ["org.junit.Ignore"],
}
test_module_config {
@@ -524,7 +480,6 @@ test_module_config {
base: "FrameworksServicesTests",
test_suites: ["device-tests"],
include_filters: ["com.android.server.lights"],
- exclude_annotations: FLAKY,
}
test_module_config {
@@ -540,7 +495,6 @@ test_module_config {
test_suites: ["device-tests"],
include_filters: ["com.android.server.location.contexthub."],
include_annotations: ["android.platform.test.annotations.Presubmit"],
- exclude_annotations: FLAKY_AND_IGNORED,
}
test_module_config {
@@ -548,15 +502,6 @@ test_module_config {
base: "FrameworksServicesTests",
test_suites: ["device-tests"],
include_filters: ["com.android.server.locksettings."],
- exclude_annotations: FLAKY,
-}
-
-test_module_config {
- name: "FrameworksServicesTests_android_server_logcat_Presubmit",
- base: "FrameworksServicesTests",
- test_suites: ["device-tests"],
- include_filters: ["com.android.server.logcat"],
- exclude_annotations: FLAKY,
}
test_module_config {
@@ -572,7 +517,6 @@ test_module_config {
test_suites: ["device-tests"],
include_filters: ["com.android.server.net."],
include_annotations: ["android.platform.test.annotations.Presubmit"],
- exclude_annotations: FLAKY,
}
test_module_config {
@@ -602,7 +546,6 @@ test_module_config {
test_suites: ["device-tests"],
include_filters: ["com.android.server.policy."],
include_annotations: ["android.platform.test.annotations.Presubmit"],
- exclude_annotations: FLAKY,
}
test_module_config {
@@ -624,7 +567,6 @@ test_module_config {
base: "FrameworksServicesTests",
test_suites: ["device-tests"],
include_filters: ["com.android.server.power.hint"],
- exclude_annotations: FLAKY,
}
test_module_config {
@@ -654,7 +596,6 @@ test_module_config {
test_suites: ["device-tests"],
include_filters: ["com.android.server.location.contexthub."],
include_annotations: ["android.platform.test.annotations.Postsubmit"],
- exclude_annotations: FLAKY_AND_IGNORED,
}
test_module_config {
diff --git a/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java b/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java
index cbf79356e9c4..def33551a820 100644
--- a/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java
+++ b/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java
@@ -19,7 +19,7 @@ package com.android.server.webkit;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.UserInfo;
+import android.os.UserHandle;
import android.webkit.UserPackage;
import android.webkit.WebViewProviderInfo;
@@ -137,16 +137,12 @@ public class TestSystemImpl implements SystemInterface {
List<UserPackage> ret = new ArrayList();
// Loop over defined users, and find the corresponding package for each user.
for (int userId : mUsers) {
- ret.add(new UserPackage(createUserInfo(userId),
+ ret.add(new UserPackage(UserHandle.of(userId),
userPackages == null ? null : userPackages.get(userId)));
}
return ret;
}
- private static UserInfo createUserInfo(int userId) {
- return new UserInfo(userId, "User nr. " + userId, 0 /* flags */);
- }
-
/**
* Set package for primary user.
*/
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
index f572e7aa1706..50a5f658f059 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
@@ -62,6 +62,8 @@ import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.drawable.Icon;
import android.media.AudioAttributes;
+import android.media.RingtoneManager;
+import android.media.Utils;
import android.metrics.LogMaker;
import android.net.Uri;
import android.os.Build;
@@ -69,6 +71,7 @@ import android.os.Bundle;
import android.os.UserHandle;
import android.os.VibrationEffect;
import android.os.Vibrator;
+import android.os.VibratorInfo;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
@@ -93,6 +96,9 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
import java.util.ArrayList;
@SmallTest
@@ -141,6 +147,7 @@ public class NotificationRecordTest extends UiServiceTestCase {
when(mMockContext.getSystemService(eq(Vibrator.class))).thenReturn(mVibrator);
when(mVibrator.areVibrationFeaturesSupported(any())).thenReturn(true);
+ when(mVibrator.getInfo()).thenReturn(VibratorInfo.EMPTY_VIBRATOR_INFO);
final Resources res = mContext.getResources();
when(mMockContext.getResources()).thenReturn(res);
when(mMockContext.getPackageManager()).thenReturn(mPm);
@@ -511,6 +518,51 @@ public class NotificationRecordTest extends UiServiceTestCase {
}
@Test
+ @EnableFlags(com.android.server.notification.Flags.FLAG_NOTIFICATION_VIBRATION_IN_SOUND_URI)
+ public void testVibration_customVibrationForSound_withoutVibrationUri() {
+ // prepare testing data
+ Uri backupDefaultUri = RingtoneManager.getActualDefaultRingtoneUri(mMockContext,
+ RingtoneManager.TYPE_NOTIFICATION);
+ RingtoneManager.setActualDefaultRingtoneUri(mMockContext, RingtoneManager.TYPE_NOTIFICATION,
+ Settings.System.DEFAULT_NOTIFICATION_URI);
+ defaultChannel.enableVibration(true);
+ defaultChannel.setSound(Settings.System.DEFAULT_NOTIFICATION_URI, CUSTOM_ATTRIBUTES);
+ StatusBarNotification sbn = getNotification(
+ /* channelVibrationPattern= */ null,
+ /* channelVibrationEffect= */ null,
+ /* insistent= */ false);
+ NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
+
+ try {
+ assertEquals(
+ new VibratorHelper(mMockContext).createDefaultVibration(false),
+ record.getVibration());
+ } finally {
+ // restore the data
+ RingtoneManager.setActualDefaultRingtoneUri(mMockContext,
+ RingtoneManager.TYPE_NOTIFICATION,
+ backupDefaultUri);
+ }
+ }
+
+ @Test
+ @EnableFlags(com.android.server.notification.Flags.FLAG_NOTIFICATION_VIBRATION_IN_SOUND_URI)
+ public void testVibration_customVibrationForSound_withVibrationUri() throws IOException {
+ defaultChannel.enableVibration(true);
+ VibrationInfo vibration = getTestingVibration(mVibrator);
+ Uri uriWithVibration = getVibrationUriAppended(
+ Settings.System.DEFAULT_NOTIFICATION_URI, vibration.mUri);
+ defaultChannel.setSound(uriWithVibration, CUSTOM_ATTRIBUTES);
+ StatusBarNotification sbn = getNotification(
+ /* channelVibrationPattern= */ null,
+ /* channelVibrationEffect= */ null,
+ /* insistent= */ false);
+ NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
+
+ assertEquals(vibration.mVibrationEffect, record.getVibration());
+ }
+
+ @Test
public void testImportance_preUpgrade() {
StatusBarNotification sbn = getNotification(PKG_N_MR1, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
@@ -1594,4 +1646,39 @@ public class NotificationRecordTest extends UiServiceTestCase {
assertThat(record.getAudioAttributes().getUsage()).isEqualTo(USAGE_ALARM);
}
+
+ static class VibrationInfo {
+ public VibrationEffect mVibrationEffect;
+ public Uri mUri;
+ VibrationInfo(VibrationEffect vibrationEffect, Uri uri) {
+ mVibrationEffect = vibrationEffect;
+ mUri = uri;
+ }
+ }
+
+ private static VibrationInfo getTestingVibration(Vibrator vibrator) throws IOException {
+ File tempVibrationFile = File.createTempFile("test_vibration_file", ".xml");
+ FileWriter writer = new FileWriter(tempVibrationFile);
+ writer.write("<vibration-effect>\n"
+ + " <waveform-effect>\n"
+ + " <!-- PRIMING -->\n"
+ + " <waveform-entry durationMs=\"0\" amplitude=\"0\"/>\n"
+ + " <waveform-entry durationMs=\"12\" amplitude=\"255\"/>\n"
+ + " <waveform-entry durationMs=\"250\" amplitude=\"0\"/>\n"
+ + " <waveform-entry durationMs=\"12\" amplitude=\"255\"/>\n"
+ + " <waveform-entry durationMs=\"500\" amplitude=\"0\"/>\n"
+ + " </waveform-effect>\n"
+ + "</vibration-effect>"); // Your test XML content
+ writer.close();
+ Uri vibrationUri = Uri.parse(tempVibrationFile.toURI().toString());
+
+ VibrationEffect vibrationEffect = Utils.parseVibrationEffect(vibrator, vibrationUri);
+ return new VibrationInfo(vibrationEffect, vibrationUri);
+ }
+
+ private static Uri getVibrationUriAppended(Uri audioUri, Uri vibrationUri) {
+ Uri.Builder builder = audioUri.buildUpon();
+ builder.appendQueryParameter(Utils.VIBRATION_URI_PARAM, vibrationUri.toString());
+ return builder.build();
+ }
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/VibratorHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/VibratorHelperTest.java
index 0993bec42c6a..4d2396c78d16 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/VibratorHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/VibratorHelperTest.java
@@ -22,8 +22,12 @@ import static junit.framework.Assert.assertTrue;
import static org.mockito.Mockito.when;
+import android.media.Utils;
+import android.net.Uri;
import android.os.VibrationEffect;
import android.os.Vibrator;
+import android.os.VibratorInfo;
+import android.provider.Settings;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -36,6 +40,10 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
@SmallTest
@RunWith(AndroidJUnit4.class)
public class VibratorHelperTest extends UiServiceTestCase {
@@ -86,7 +94,34 @@ public class VibratorHelperTest extends UiServiceTestCase {
}
@Test
+ public void createVibrationEffectFromSoundUri_nullInput() {
+ assertNull(mVibratorHelper.createVibrationEffectFromSoundUri(null));
+ }
+
+ @Test
+ public void createVibrationEffectFromSoundUri_emptyUri() {
+ assertNull(mVibratorHelper.createVibrationEffectFromSoundUri(Uri.EMPTY));
+ }
+
+ @Test
+ public void createVibrationEffectFromSoundUri_uriWithoutRequiredQueryParameter() {
+ Uri uri = Settings.System.DEFAULT_NOTIFICATION_URI;
+ assertNull(mVibratorHelper.createVibrationEffectFromSoundUri(uri));
+ }
+
+ @Test
+ public void createVibrationEffectFromSoundUri_uriWithVibrationUri() throws IOException {
+ // prepare the uri with vibration
+ when(mVibrator.getInfo()).thenReturn(VibratorInfo.EMPTY_VIBRATOR_INFO);
+ Uri validUri = getVibrationUriAppended(Settings.System.DEFAULT_NOTIFICATION_URI);
+
+ assertSingleVibration(mVibratorHelper.createVibrationEffectFromSoundUri(validUri));
+ }
+
+ @Test
public void createVibration_insistent_createsRepeatingVibration() {
+ when(mVibrator.getInfo()).thenReturn(VibratorInfo.EMPTY_VIBRATOR_INFO);
+
when(mVibrator.hasFrequencyControl()).thenReturn(false);
assertRepeatingVibration(mVibratorHelper.createDefaultVibration(/* insistent= */ true));
assertRepeatingVibration(mVibratorHelper.createFallbackVibration(/* insistent= */ true));
@@ -98,6 +133,8 @@ public class VibratorHelperTest extends UiServiceTestCase {
@Test
public void createVibration_nonInsistent_createsSingleShotVibration() {
+ when(mVibrator.getInfo()).thenReturn(VibratorInfo.EMPTY_VIBRATOR_INFO);
+
when(mVibrator.hasFrequencyControl()).thenReturn(false);
assertSingleVibration(mVibratorHelper.createDefaultVibration(/* insistent= */ false));
assertSingleVibration(mVibratorHelper.createFallbackVibration(/* insistent= */ false));
@@ -120,4 +157,26 @@ public class VibratorHelperTest extends UiServiceTestCase {
effect instanceof VibrationEffect.Composed);
return ((VibrationEffect.Composed) effect).getRepeatIndex();
}
+
+ private static Uri getVibrationUriAppended(Uri baseUri) throws IOException {
+ File tempVibrationFile = File.createTempFile("test_vibration_file", ".xml");
+ FileWriter writer = new FileWriter(tempVibrationFile);
+ writer.write("<vibration-effect>\n"
+ + " <waveform-effect>\n"
+ + " <!-- PRIMING -->\n"
+ + " <waveform-entry durationMs=\"0\" amplitude=\"0\"/>\n"
+ + " <waveform-entry durationMs=\"12\" amplitude=\"255\"/>\n"
+ + " <waveform-entry durationMs=\"250\" amplitude=\"0\"/>\n"
+ + " <waveform-entry durationMs=\"12\" amplitude=\"255\"/>\n"
+ + " <waveform-entry durationMs=\"500\" amplitude=\"0\"/>\n"
+ + " </waveform-effect>\n"
+ + "</vibration-effect>"); // Your test XML content
+ writer.close();
+
+ Uri.Builder builder = baseUri.buildUpon();
+ builder.appendQueryParameter(
+ Utils.VIBRATION_URI_PARAM,
+ tempVibrationFile.toURI().toString());
+ return builder.build();
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
index 2e488d8127bb..09fe75da18cb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
@@ -22,6 +22,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_SENSOR;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.DisplayCutout.NO_CUTOUT;
import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_DEFAULT;
import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_DISABLED;
@@ -78,7 +79,6 @@ import androidx.test.filters.SmallTest;
import com.android.internal.R;
import com.android.internal.util.test.FakeSettingsProvider;
-import com.android.server.LocalServices;
import com.android.server.UiThread;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.statusbar.StatusBarManagerInternal;
@@ -86,7 +86,6 @@ import com.android.server.testutils.OffsettableClock;
import com.android.server.testutils.TestHandler;
import com.android.server.wm.DisplayContent.FixedRotationTransitionListener;
-import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
@@ -168,25 +167,10 @@ public class DisplayRotationTests {
public void setUp() {
FakeSettingsProvider.clearSettingsProvider();
- mPreviousStatusBarManagerInternal = LocalServices.getService(
- StatusBarManagerInternal.class);
- LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
- mMockStatusBarManagerInternal = mock(StatusBarManagerInternal.class);
- LocalServices.addService(StatusBarManagerInternal.class, mMockStatusBarManagerInternal);
mDisplayRotationImmersiveAppCompatPolicyMock = null;
mBuilder = new DisplayRotationBuilder();
}
- @After
- public void tearDown() {
- LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
- if (mPreviousStatusBarManagerInternal != null) {
- LocalServices.addService(StatusBarManagerInternal.class,
- mPreviousStatusBarManagerInternal);
- mPreviousStatusBarManagerInternal = null;
- }
- }
-
// ================================
// Display Settings Related Tests
// ================================
@@ -677,7 +661,8 @@ public class DisplayRotationTests {
mOrientationSensorListener.onSensorChanged(createSensorEvent(Surface.ROTATION_90));
assertTrue(waitForUiHandler());
- verify(mMockStatusBarManagerInternal).onProposedRotationChanged(Surface.ROTATION_90, true);
+ verify(mMockStatusBarManagerInternal).onProposedRotationChanged(DEFAULT_DISPLAY,
+ Surface.ROTATION_90, true);
}
@Test
@@ -697,7 +682,8 @@ public class DisplayRotationTests {
mOrientationSensorListener.onSensorChanged(createSensorEvent(Surface.ROTATION_90));
assertTrue(waitForUiHandler());
- verify(mMockStatusBarManagerInternal).onProposedRotationChanged(Surface.ROTATION_90, true);
+ verify(mMockStatusBarManagerInternal).onProposedRotationChanged(DEFAULT_DISPLAY,
+ Surface.ROTATION_90, true);
// An imaginary ActivityRecord.setRequestedOrientation call disables immersive mode:
when(mDisplayRotationImmersiveAppCompatPolicyMock.isRotationLockEnforced(
@@ -728,7 +714,7 @@ public class DisplayRotationTests {
assertTrue(waitForUiHandler());
verify(mMockStatusBarManagerInternal)
- .onProposedRotationChanged(Surface.ROTATION_180, true);
+ .onProposedRotationChanged(DEFAULT_DISPLAY, Surface.ROTATION_180, true);
}
@Test
@@ -746,7 +732,7 @@ public class DisplayRotationTests {
assertTrue(waitForUiHandler());
verify(mMockStatusBarManagerInternal)
- .onProposedRotationChanged(Surface.ROTATION_180, false);
+ .onProposedRotationChanged(DEFAULT_DISPLAY, Surface.ROTATION_180, false);
}
@Test
@@ -773,7 +759,7 @@ public class DisplayRotationTests {
assertTrue(waitForUiHandler());
verify(mMockStatusBarManagerInternal)
- .onProposedRotationChanged(Surface.ROTATION_180, false);
+ .onProposedRotationChanged(DEFAULT_DISPLAY, Surface.ROTATION_180, false);
}
@Test
@@ -1526,6 +1512,7 @@ public class DisplayRotationTests {
mMockDisplayContent = mock(DisplayContent.class);
when(mMockDisplayContent.getDisplay()).thenReturn(mock(Display.class));
+ when(mMockDisplayContent.getDisplayId()).thenReturn(DEFAULT_DISPLAY);
mMockDisplayContent.isDefaultDisplay = mIsDefaultDisplay;
when(mMockDisplayContent.calculateDisplayCutoutForRotation(anyInt()))
.thenReturn(NO_CUTOUT);
@@ -1541,6 +1528,9 @@ public class DisplayRotationTests {
field.set(mMockDisplayContent, mock(FixedRotationTransitionListener.class));
mMockDisplayPolicy = mock(DisplayPolicy.class);
+ mMockStatusBarManagerInternal = mock(StatusBarManagerInternal.class);
+ when(mMockDisplayPolicy.getStatusBarManagerInternal()).thenReturn(
+ mMockStatusBarManagerInternal);
mMockRes = mock(Resources.class);
when(mMockContext.getResources()).thenReturn((mMockRes));
diff --git a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
index 1d14dc31fa26..bef4531c9f28 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
@@ -219,7 +219,7 @@ public class LockTaskControllerTest {
mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
// THEN a pinning request should be shown
- verify(mStatusBarManagerInternal).showScreenPinningRequest(anyInt());
+ verify(mStatusBarManagerInternal).showScreenPinningRequest(anyInt(), anyInt());
}
@Test
@@ -769,9 +769,11 @@ public class LockTaskControllerTest {
private Task getTask(Intent intent, int lockTaskAuth) {
Task tr = mock(Task.class);
+ DisplayContent dc = mock(DisplayContent.class);
tr.mLockTaskAuth = lockTaskAuth;
tr.intent = intent;
tr.mUserId = TEST_USER_ID;
+ tr.mDisplayContent = dc;
return tr;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
index 52a80b01971d..f8e42d19f78f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -51,6 +51,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
+import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
import static com.android.window.flags.Flags.explicitRefreshRateHints;
import static org.junit.Assert.assertEquals;
@@ -140,8 +141,7 @@ public class TransitionTests extends WindowTestsBase {
}
private Transition createTestTransition(int transitType) {
- final TransitionController controller = new TestTransitionController(
- mock(ActivityTaskManagerService.class));
+ final TransitionController controller = new TestTransitionController(mAtm);
mSyncEngine = createTestBLASTSyncEngine();
controller.setSyncEngine(mSyncEngine);
@@ -2357,7 +2357,7 @@ public class TransitionTests extends WindowTestsBase {
}
@Test
- public void testMoveToTopWhileVisible() {
+ public void testMoveTaskToTopWhileVisible() {
final Transition transition = createTestTransition(TRANSIT_OPEN);
final ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges;
final ArraySet<WindowContainer> participants = transition.mParticipants;
@@ -2392,6 +2392,55 @@ public class TransitionTests extends WindowTestsBase {
assertEquals(TRANSIT_CHANGE, info.getChanges().get(0).getMode());
}
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DISPLAY_FOCUS_IN_SHELL_TRANSITIONS)
+ public void testMoveDisplayToTop() {
+ // Set up two displays, each of which has a task.
+ DisplayContent otherDisplay = createNewDisplay();
+ final Consumer<DisplayContent> setUpTask = (DisplayContent dc) -> {
+ final Task task = createTask(dc);
+ final ActivityRecord act = createActivityRecord(task);
+ final TestWindowState win = createWindowState(
+ new WindowManager.LayoutParams(TYPE_BASE_APPLICATION), act);
+ act.addWindow(win);
+ act.setVisibleRequested(true);
+ };
+ setUpTask.accept(mDisplayContent);
+ setUpTask.accept(otherDisplay);
+ mWm.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /* updateImWindows */);
+
+ final Transition transition = createTestTransition(TRANSIT_OPEN);
+ final ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges;
+ final ArraySet<WindowContainer> participants = transition.mParticipants;
+
+ // Emulate WindowManagerService#moveDisplayToTopInternal().
+ transition.recordTaskOrder(mDefaultDisplay);
+ mDefaultDisplay.getParent().positionChildAt(WindowContainer.POSITION_TOP,
+ mDefaultDisplay, true /* includingParents */);
+ mWm.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /* updateImWindows */);
+ transition.setReady(mDefaultDisplay, true /* ready */);
+
+ // Test has order changes, a shallow check of order changes.
+ assertTrue(transition.hasOrderChanges());
+
+ // We just moved a display to top, so there shouldn't be any changes.
+ ArrayList<Transition.ChangeInfo> targets = Transition.calculateTargets(
+ participants, changes);
+ assertTrue(targets.isEmpty());
+
+ // After collecting order changes, the task on the newly focused display should be
+ // considered to get moved to top.
+ transition.collectOrderChanges(true);
+ targets = Transition.calculateTargets(participants, changes);
+ assertEquals(1, targets.size());
+
+ // Make sure the flag is set
+ final TransitionInfo info = Transition.calculateTransitionInfo(
+ transition.mType, 0 /* flags */, targets, mMockT);
+ assertTrue((info.getChanges().get(0).getFlags() & TransitionInfo.FLAG_MOVED_TO_TOP) != 0);
+ assertEquals(TRANSIT_CHANGE, info.getChanges().get(0).getMode());
+ }
+
private class OrderChangeTestSetup {
final TransitionController mController;
final TestTransitionPlayer mPlayer;
diff --git a/tests/Input/src/com/android/server/input/debug/TouchpadDebugViewTest.java b/tests/Input/src/com/android/server/input/debug/TouchpadDebugViewTest.java
index 0f08be215033..2a49eb12c3ff 100644
--- a/tests/Input/src/com/android/server/input/debug/TouchpadDebugViewTest.java
+++ b/tests/Input/src/com/android/server/input/debug/TouchpadDebugViewTest.java
@@ -296,33 +296,31 @@ public class TouchpadDebugViewTest {
@Test
public void testTouchpadClick() {
- View child;
+ View child = mTouchpadDebugView.getChildAt(0);
mTouchpadDebugView.updateHardwareState(
new TouchpadHardwareState(0, 1 /* buttonsDown */, 0, 0,
- new TouchpadFingerState[0]));
+ new TouchpadFingerState[0]), TOUCHPAD_DEVICE_ID);
- for (int i = 0; i < mTouchpadDebugView.getChildCount(); i++) {
- child = mTouchpadDebugView.getChildAt(i);
- assertEquals(((ColorDrawable) child.getBackground()).getColor(), Color.BLUE);
- }
+ assertEquals(((ColorDrawable) child.getBackground()).getColor(), Color.BLUE);
mTouchpadDebugView.updateHardwareState(
new TouchpadHardwareState(0, 0 /* buttonsDown */, 0, 0,
- new TouchpadFingerState[0]));
+ new TouchpadFingerState[0]), TOUCHPAD_DEVICE_ID);
- for (int i = 0; i < mTouchpadDebugView.getChildCount(); i++) {
- child = mTouchpadDebugView.getChildAt(i);
- assertEquals(((ColorDrawable) child.getBackground()).getColor(), Color.RED);
- }
+ assertEquals(((ColorDrawable) child.getBackground()).getColor(), Color.RED);
mTouchpadDebugView.updateHardwareState(
new TouchpadHardwareState(0, 1 /* buttonsDown */, 0, 0,
- new TouchpadFingerState[0]));
+ new TouchpadFingerState[0]), TOUCHPAD_DEVICE_ID);
- for (int i = 0; i < mTouchpadDebugView.getChildCount(); i++) {
- child = mTouchpadDebugView.getChildAt(i);
- assertEquals(((ColorDrawable) child.getBackground()).getColor(), Color.BLUE);
- }
+ assertEquals(((ColorDrawable) child.getBackground()).getColor(), Color.BLUE);
+
+ // Color should not change because hardware state of a different touchpad
+ mTouchpadDebugView.updateHardwareState(
+ new TouchpadHardwareState(0, 0 /* buttonsDown */, 0, 0,
+ new TouchpadFingerState[0]), TOUCHPAD_DEVICE_ID + 1);
+
+ assertEquals(((ColorDrawable) child.getBackground()).getColor(), Color.BLUE);
}
}
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkEvaluationTestBase.java b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkEvaluationTestBase.java
index 0439d5f54e23..edad67896e8e 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkEvaluationTestBase.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkEvaluationTestBase.java
@@ -123,7 +123,6 @@ public abstract class NetworkEvaluationTestBase {
mSetFlagsRule.enableFlags(Flags.FLAG_VALIDATE_NETWORK_ON_IPSEC_LOSS);
mSetFlagsRule.enableFlags(Flags.FLAG_EVALUATE_IPSEC_LOSS_ON_LP_NC_CHANGE);
mSetFlagsRule.enableFlags(Flags.FLAG_HANDLE_SEQ_NUM_LEAP);
- mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_DISABLE_IPSEC_LOSS_DETECTOR);
when(mNetwork.getNetId()).thenReturn(-1);
diff --git a/tools/aapt/Package.cpp b/tools/aapt/Package.cpp
index 60c4bf5c4131..5e0f87f0dcaf 100644
--- a/tools/aapt/Package.cpp
+++ b/tools/aapt/Package.cpp
@@ -292,12 +292,13 @@ bool processFile(Bundle* bundle, ZipFile* zip,
}
if (!hasData) {
const String8& srcName = file->getSourceFile();
- auto fileModWhen = getFileModDate(srcName.c_str());
- if (fileModWhen == kInvalidModDate) { // file existence tested earlier,
- return false; // not expecting an error here
+ time_t fileModWhen;
+ fileModWhen = getFileModDate(srcName.c_str());
+ if (fileModWhen == (time_t) -1) { // file existence tested earlier,
+ return false; // not expecting an error here
}
-
- if (toTimeT(fileModWhen) > entry->getModWhen()) {
+
+ if (fileModWhen > entry->getModWhen()) {
// mark as deleted so add() will succeed
if (bundle->getVerbose()) {
printf(" (removing old '%s')\n", storageName.c_str());