summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java358
-rw-r--r--apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java85
-rw-r--r--apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java35
-rw-r--r--apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java101
-rw-r--r--core/api/current.txt53
-rw-r--r--core/api/system-current.txt23
-rw-r--r--core/java/android/app/ContextImpl.java17
-rw-r--r--core/java/android/app/ResourcesManager.java8
-rw-r--r--core/java/android/app/SystemServiceRegistry.java27
-rw-r--r--core/java/android/app/UiAutomationConnection.java5
-rw-r--r--core/java/android/app/usage/UsageEvents.java1
-rw-r--r--core/java/android/appwidget/AppWidgetManager.java2
-rw-r--r--core/java/android/content/AttributionSource.java3
-rw-r--r--core/java/android/content/Context.java23
-rw-r--r--core/java/android/content/Intent.java6
-rw-r--r--core/java/android/content/pm/PackageInfo.java3
-rw-r--r--core/java/android/content/pm/PackageInstaller.java48
-rw-r--r--core/java/android/content/pm/PackageItemInfo.java8
-rw-r--r--core/java/android/content/pm/PackageManager.java11
-rw-r--r--core/java/android/content/pm/flags.aconfig7
-rw-r--r--core/java/android/content/res/flags.aconfig9
-rw-r--r--core/java/android/hardware/SensorPrivacyManager.java7
-rw-r--r--core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java2
-rw-r--r--core/java/android/os/BatteryUsageStats.java22
-rw-r--r--core/java/android/os/ISecurityStateManager.aidl26
-rw-r--r--core/java/android/os/Message.java2
-rw-r--r--core/java/android/os/SecurityStateManager.java81
-rw-r--r--core/java/android/os/flags.aconfig7
-rw-r--r--core/java/android/os/storage/StorageManager.java17
-rw-r--r--core/java/android/provider/Settings.java32
-rw-r--r--core/java/android/view/ViewRootImpl.java2
-rw-r--r--core/java/android/view/accessibility/IWindowMagnificationConnection.aidl2
-rw-r--r--core/java/android/webkit/IWebViewUpdateService.aidl5
-rw-r--r--core/java/android/window/TaskFragmentOperation.java14
-rw-r--r--core/java/android/window/TaskFragmentParentInfo.java24
-rw-r--r--core/java/com/android/internal/display/RefreshRateSettingsUtils.java15
-rw-r--r--core/res/res/values/config.xml5
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java39
-rw-r--r--core/tests/coretests/src/android/content/res/ResourcesManagerTest.java8
-rw-r--r--keystore/java/android/security/KeyStore2.java19
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java3
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java3
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java24
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java22
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/csuiteDefaultTemplate.xml5
-rw-r--r--location/api/system-current.txt4
-rw-r--r--location/java/android/location/GnssMeasurementRequest.java4
-rw-r--r--location/java/android/location/flags/gnss.aconfig16
-rw-r--r--media/java/android/media/IAudioService.aidl2
-rw-r--r--media/java/android/media/LoudnessCodecConfigurator.java189
-rw-r--r--media/java/android/media/LoudnessCodecDispatcher.java92
-rw-r--r--media/java/android/media/LoudnessCodecInfo.aidl3
-rw-r--r--media/java/android/media/tv/ad/TvAdManager.java10
-rw-r--r--media/java/android/media/tv/flags/media_tv.aconfig7
-rw-r--r--media/tests/LoudnessCodecApiTest/src/com/android/loudnesscodecapitest/LoudnessCodecConfiguratorTest.java2
-rw-r--r--packages/CredentialManager/Android.bp2
-rw-r--r--packages/CredentialManager/shared/src/com/android/credentialmanager/IntentParser.kt11
-rw-r--r--packages/CredentialManager/shared/src/com/android/credentialmanager/client/impl/CredentialManagerClientImpl.kt7
-rw-r--r--packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/CredentialKtx.kt369
-rw-r--r--packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/PasswordKtx.kt32
-rw-r--r--packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestGetMapper.kt40
-rw-r--r--packages/CredentialManager/shared/src/com/android/credentialmanager/model/CredentialType.kt (renamed from packages/CredentialManager/src/com/android/credentialmanager/common/CredentialType.kt)2
-rw-r--r--packages/CredentialManager/shared/src/com/android/credentialmanager/model/EntryInfo.kt (renamed from packages/CredentialManager/src/com/android/credentialmanager/common/BaseEntry.kt)4
-rw-r--r--packages/CredentialManager/shared/src/com/android/credentialmanager/model/Request.kt7
-rw-r--r--packages/CredentialManager/shared/src/com/android/credentialmanager/model/creation/CreateOptionInfo.kt46
-rw-r--r--packages/CredentialManager/shared/src/com/android/credentialmanager/model/creation/RemoteInfo.kt36
-rw-r--r--packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/ActionEntryInfo.kt40
-rw-r--r--packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/AuthenticationEntryInfo.kt44
-rw-r--r--packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/CredentialEntryInfo.kt50
-rw-r--r--packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/ProviderInfo.kt33
-rw-r--r--packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/RemoteEntryInfo.kt36
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt13
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt241
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt27
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt86
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt67
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt29
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt130
-rw-r--r--packages/CredentialManager/wear/src/com/android/credentialmanager/di/AppModule.kt21
-rw-r--r--packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt4
-rw-r--r--packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt4
-rw-r--r--packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreenViewModel.kt21
-rw-r--r--packages/PackageInstaller/Android.bp3
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java18
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java18
-rw-r--r--packages/SettingsLib/Spa/build.gradle.kts4
-rw-r--r--packages/SettingsLib/Spa/spa/build.gradle.kts4
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTheme.kt22
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/PrimarySwitchPreference.java6
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java11
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/Utils.java10
-rw-r--r--packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java1
-rw-r--r--packages/SystemUI/Android.bp178
-rw-r--r--packages/SystemUI/aconfig/OWNERS1
-rw-r--r--packages/SystemUI/aconfig/biometrics_framework.aconfig10
-rw-r--r--packages/SystemUI/aconfig/systemui.aconfig6
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt69
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerTest.java (renamed from packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsShellTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsViewTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/data/repository/SimBouncerRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/bouncer/data/repository/SimBouncerRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt)4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt)16
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt)132
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinInputViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinInputViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dock/DockManagerFake.java (renamed from packages/SystemUI/tests/src/com/android/systemui/dock/DockManagerFake.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dump/LogBufferHelper.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferHelper.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/AutoAddSettingsRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/AutoAddSettingsRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/CustomTileAddedSharedPreferencesRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/CustomTileAddedSharedPreferencesRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredBroadcastRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredBroadcastRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/TilesSettingConverterTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TilesSettingConverterTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/UserAutoAddRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserAutoAddRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/UserTileSpecRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserTileSpecRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CallbackControllerAutoAddableTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CallbackControllerAutoAddableTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddableTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddableTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DataSaverAutoAddableTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DataSaverAutoAddableTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DeviceControlsAutoAddableTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DeviceControlsAutoAddableTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/HotspotAutoAddableTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/HotspotAutoAddableTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddableTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddableTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddableTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddableTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WalletAutoAddableTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WalletAutoAddableTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/AutoAddInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/AutoAddInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/FakeQSTile.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/FakeQSTile.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/RestoreReconciliationInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/RestoreReconciliationInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileDataInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileDataInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTileDefaultsRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/custom/CustomTileDefaultsRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTilePackageUpdatesRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/custom/CustomTilePackageUpdatesRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapperTest.kt18
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapperTest.kt13
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt)7
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/data/repository/WindowRootViewVisibilityRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/WindowRootViewVisibilityRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt)2
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/FakeAirplaneModeRepository.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/FakeAirplaneModeRepository.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/FakeConnectivityRepository.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/FakeConnectivityRepository.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt)0
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt)0
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java (renamed from packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationConnectionImpl.java)8
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt60
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt74
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingHostedToLockscreenTransitionViewModel.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToLockscreenTransitionViewModel.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt55
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt94
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt47
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingHostedTransitionViewModel.kt47
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModel.kt45
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/AirplaneModeMapper.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapper.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapper.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureControllerImpl.java41
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt115
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DevicePostureControllerImplTest.kt143
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/unfold/progress/MainThreadUnfoldTransitionProgressProviderTest.kt96
-rw-r--r--packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt52
-rw-r--r--packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldBgProgressFlag.kt (renamed from packages/CredentialManager/shared/src/com/android/credentialmanager/model/Password.kt)18
-rw-r--r--packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/MainThreadUnfoldTransitionProgressProvider.kt92
-rw-r--r--ravenwood/framework-minus-apex-ravenwood-policies.txt3
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java2
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java20
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java (renamed from services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java)53
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionWrapper.java6
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java115
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java38
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/PanningScalingHandler.java1
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java52
-rw-r--r--services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraController.java114
-rw-r--r--services/core/java/com/android/server/OWNERS4
-rw-r--r--services/core/java/com/android/server/SecurityStateManagerService.java109
-rw-r--r--services/core/java/com/android/server/Watchdog.java146
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java6
-rw-r--r--services/core/java/com/android/server/am/BatteryStatsService.java4
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java10
-rw-r--r--services/core/java/com/android/server/audio/AudioServiceEvents.java49
-rw-r--r--services/core/java/com/android/server/audio/LoudnessCodecHelper.java196
-rw-r--r--services/core/java/com/android/server/display/BrightnessMappingStrategy.java23
-rw-r--r--services/core/java/com/android/server/display/DisplayAdapter.java12
-rw-r--r--services/core/java/com/android/server/display/DisplayDevice.java3
-rw-r--r--services/core/java/com/android/server/display/DisplayDeviceConfig.java138
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java12
-rw-r--r--services/core/java/com/android/server/display/LocalDisplayAdapter.java14
-rw-r--r--services/core/java/com/android/server/display/OverlayDisplayAdapter.java6
-rw-r--r--services/core/java/com/android/server/display/VirtualDisplayAdapter.java10
-rw-r--r--services/core/java/com/android/server/display/WifiDisplayAdapter.java5
-rw-r--r--services/core/java/com/android/server/display/feature/DisplayManagerFlags.java12
-rw-r--r--services/core/java/com/android/server/display/feature/display_flags.aconfig8
-rw-r--r--services/core/java/com/android/server/display/mode/DisplayModeDirector.java42
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssLocationProvider.java52
-rw-r--r--services/core/java/com/android/server/media/AudioAttributesUtils.java125
-rw-r--r--services/core/java/com/android/server/media/AudioPoliciesBluetoothRouteController.java336
-rw-r--r--services/core/java/com/android/server/media/AudioPoliciesDeviceRouteController.java678
-rw-r--r--services/core/java/com/android/server/media/AudioRoutingUtils.java46
-rw-r--r--services/core/java/com/android/server/media/BluetoothRouteController.java29
-rw-r--r--services/core/java/com/android/server/media/DeviceRouteController.java93
-rw-r--r--services/core/java/com/android/server/media/LegacyBluetoothRouteController.java6
-rw-r--r--services/core/java/com/android/server/media/LegacyDeviceRouteController.java26
-rw-r--r--services/core/java/com/android/server/media/SystemMediaRoute2Provider.java145
-rw-r--r--services/core/java/com/android/server/pm/DeletePackageHelper.java6
-rw-r--r--services/core/java/com/android/server/pm/InstallRequest.java6
-rw-r--r--services/core/java/com/android/server/pm/SharedLibrariesImpl.java4
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java9
-rw-r--r--services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java109
-rw-r--r--services/core/java/com/android/server/power/hint/HintManagerService.java7
-rw-r--r--services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java25
-rw-r--r--services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java8
-rw-r--r--services/core/java/com/android/server/utils/UserSettingDeviceConfigMediator.java194
-rw-r--r--services/core/java/com/android/server/webkit/WebViewUpdateService.java5
-rw-r--r--services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java7
-rw-r--r--services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl2.java18
-rw-r--r--services/core/java/com/android/server/webkit/WebViewUpdateServiceInterface.java2
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java1
-rw-r--r--services/core/java/com/android/server/wm/BackgroundActivityStartController.java73
-rw-r--r--services/core/java/com/android/server/wm/Task.java145
-rw-r--r--services/core/java/com/android/server/wm/TaskFragment.java3
-rw-r--r--services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java2
-rw-r--r--services/core/java/com/android/server/wm/Transition.java21
-rw-r--r--services/core/java/com/android/server/wm/TransitionController.java6
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java25
-rw-r--r--services/core/xsd/display-device-config/display-device-config.xsd57
-rw-r--r--services/core/xsd/display-device-config/schema/current.txt15
-rw-r--r--services/java/com/android/server/SystemServer.java9
-rw-r--r--services/robotests/src/com/android/server/media/AudioPoliciesBluetoothRouteControllerTest.java293
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java82
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java77
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java23
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java14
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java4
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java7
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/PersistentDataStoreTest.java29
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/RefreshRateSettingsUtilsTest.java19
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java7
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java118
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java10
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/location/gnss/GnssLocationProviderTest.java179
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt11
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java9
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java37
-rw-r--r--services/tests/servicestests/src/com/android/server/SecurityStateTest.java118
-rw-r--r--services/tests/servicestests/src/com/android/server/WatchdogTest.java152
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java30
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java58
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java (renamed from services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java)433
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionWrapperTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java153
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java23
-rw-r--r--services/tests/servicestests/src/com/android/server/audio/LoudnessCodecHelperTest.java166
-rw-r--r--services/tests/servicestests/src/com/android/server/companion/virtual/camera/VirtualCameraControllerTest.java11
-rw-r--r--services/tests/servicestests/src/com/android/server/media/AudioPoliciesDeviceRouteControllerTest.java247
-rw-r--r--services/tests/servicestests/src/com/android/server/media/DeviceRouteControllerTest.java7
-rw-r--r--services/tests/servicestests/src/com/android/server/utils/UserSettingDeviceConfigMediatorTest.java235
-rw-r--r--services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java18
-rw-r--r--services/tests/wmtests/AndroidManifest.xml9
-rw-r--r--services/tests/wmtests/AndroidTest.xml4
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java18
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java7
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SurfaceControlViewHostTests.java79
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java39
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskTests.java181
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TransitionTests.java3
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/utils/TestActivity.java68
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt2
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt20
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt18
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt20
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt18
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt24
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/IPretendingAidl.java9
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java2
424 files changed, 7363 insertions, 4276 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index 158d914575c6..e6c94d896e50 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -32,6 +32,7 @@ import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
import android.app.BroadcastOptions;
import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.IIntentReceiver;
import android.content.Intent;
@@ -41,6 +42,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManagerInternal;
import android.content.res.Resources;
+import android.database.ContentObserver;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
@@ -81,6 +83,7 @@ import android.os.Trace;
import android.os.UserHandle;
import android.os.WearModeManagerInternal;
import android.provider.DeviceConfig;
+import android.provider.Settings;
import android.telephony.TelephonyCallback;
import android.telephony.TelephonyManager;
import android.telephony.emergency.EmergencyNumber;
@@ -109,6 +112,7 @@ import com.android.server.deviceidle.DeviceIdleConstraintTracker;
import com.android.server.deviceidle.IDeviceIdleConstraint;
import com.android.server.deviceidle.TvConstraintController;
import com.android.server.net.NetworkPolicyManagerInternal;
+import com.android.server.utils.UserSettingDeviceConfigMediator;
import com.android.server.wm.ActivityTaskManagerInternal;
import org.xmlpull.v1.XmlPullParser;
@@ -1020,7 +1024,8 @@ public class DeviceIdleController extends SystemService
* global Settings. Any access to this class or its fields should be done while
* holding the DeviceIdleController lock.
*/
- public final class Constants implements DeviceConfig.OnPropertiesChangedListener {
+ public final class Constants extends ContentObserver
+ implements DeviceConfig.OnPropertiesChangedListener {
// Key names stored in the settings value.
private static final String KEY_FLEX_TIME_SHORT = "flex_time_short";
private static final String KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT =
@@ -1396,6 +1401,7 @@ public class DeviceIdleController extends SystemService
/**
* Amount of time we would like to whitelist an app that is handling a
* {@link android.app.PendingIntent} triggered by a {@link android.app.Notification}.
+ *
* @see #KEY_NOTIFICATION_ALLOWLIST_DURATION_MS
*/
public long NOTIFICATION_ALLOWLIST_DURATION_MS = mDefaultNotificationAllowlistDurationMs;
@@ -1413,9 +1419,14 @@ public class DeviceIdleController extends SystemService
*/
public boolean USE_MODE_MANAGER = mDefaultUseModeManager;
+ private final ContentResolver mResolver;
private final boolean mSmallBatteryDevice;
+ private final UserSettingDeviceConfigMediator mUserSettingDeviceConfigMediator =
+ new UserSettingDeviceConfigMediator.SettingsOverridesIndividualMediator(',');
- public Constants() {
+ public Constants(Handler handler, ContentResolver resolver) {
+ super(handler);
+ mResolver = resolver;
initDefault();
mSmallBatteryDevice = ActivityManager.isSmallBatteryDevice();
if (mSmallBatteryDevice) {
@@ -1424,8 +1435,14 @@ public class DeviceIdleController extends SystemService
}
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_DEVICE_IDLE,
AppSchedulingModuleThread.getExecutor(), this);
+ mResolver.registerContentObserver(
+ Settings.Global.getUriFor(Settings.Global.DEVICE_IDLE_CONSTANTS),
+ false, this);
// Load all the constants.
- onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_DEVICE_IDLE));
+ updateSettingsConstantLocked();
+ mUserSettingDeviceConfigMediator.setDeviceConfigProperties(
+ DeviceConfig.getProperties(DeviceConfig.NAMESPACE_DEVICE_IDLE));
+ updateConstantsLocked();
}
private void initDefault() {
@@ -1574,188 +1591,166 @@ public class DeviceIdleController extends SystemService
return (!COMPRESS_TIME || defTimeout < compTimeout) ? defTimeout : compTimeout;
}
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ synchronized (DeviceIdleController.this) {
+ updateSettingsConstantLocked();
+ updateConstantsLocked();
+ }
+ }
+
+ private void updateSettingsConstantLocked() {
+ try {
+ mUserSettingDeviceConfigMediator.setSettingsString(
+ Settings.Global.getString(mResolver,
+ Settings.Global.DEVICE_IDLE_CONSTANTS));
+ } catch (IllegalArgumentException e) {
+ // Failed to parse the settings string, log this and move on with previous values.
+ Slog.e(TAG, "Bad device idle settings", e);
+ }
+ }
@Override
public void onPropertiesChanged(DeviceConfig.Properties properties) {
synchronized (DeviceIdleController.this) {
- for (String name : properties.getKeyset()) {
- if (name == null) {
- continue;
- }
- switch (name) {
- case KEY_FLEX_TIME_SHORT:
- FLEX_TIME_SHORT = properties.getLong(
- KEY_FLEX_TIME_SHORT, mDefaultFlexTimeShort);
- break;
- case KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT:
- LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = properties.getLong(
- KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT,
- mDefaultLightIdleAfterInactiveTimeout);
- break;
- case KEY_LIGHT_IDLE_TIMEOUT:
- LIGHT_IDLE_TIMEOUT = properties.getLong(
- KEY_LIGHT_IDLE_TIMEOUT, mDefaultLightIdleTimeout);
- break;
- case KEY_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX:
- LIGHT_IDLE_TIMEOUT_INITIAL_FLEX = properties.getLong(
- KEY_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX,
- mDefaultLightIdleTimeoutInitialFlex);
- break;
- case KEY_LIGHT_IDLE_TIMEOUT_MAX_FLEX:
- LIGHT_IDLE_TIMEOUT_MAX_FLEX = properties.getLong(
- KEY_LIGHT_IDLE_TIMEOUT_MAX_FLEX,
- mDefaultLightIdleTimeoutMaxFlex);
- break;
- case KEY_LIGHT_IDLE_FACTOR:
- LIGHT_IDLE_FACTOR = Math.max(1, properties.getFloat(
- KEY_LIGHT_IDLE_FACTOR, mDefaultLightIdleFactor));
- break;
- case KEY_LIGHT_IDLE_INCREASE_LINEARLY:
- LIGHT_IDLE_INCREASE_LINEARLY = properties.getBoolean(
- KEY_LIGHT_IDLE_INCREASE_LINEARLY,
- mDefaultLightIdleIncreaseLinearly);
- break;
- case KEY_LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS:
- LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS = properties.getLong(
- KEY_LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS,
- mDefaultLightIdleLinearIncreaseFactorMs);
- break;
- case KEY_LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS:
- LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS = properties.getLong(
- KEY_LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS,
- mDefaultLightIdleFlexLinearIncreaseFactorMs);
- break;
- case KEY_LIGHT_MAX_IDLE_TIMEOUT:
- LIGHT_MAX_IDLE_TIMEOUT = properties.getLong(
- KEY_LIGHT_MAX_IDLE_TIMEOUT, mDefaultLightMaxIdleTimeout);
- break;
- case KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET:
- LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = properties.getLong(
- KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET,
- mDefaultLightIdleMaintenanceMinBudget);
- break;
- case KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET:
- LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = properties.getLong(
- KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET,
- mDefaultLightIdleMaintenanceMaxBudget);
- break;
- case KEY_MIN_LIGHT_MAINTENANCE_TIME:
- MIN_LIGHT_MAINTENANCE_TIME = properties.getLong(
- KEY_MIN_LIGHT_MAINTENANCE_TIME,
- mDefaultMinLightMaintenanceTime);
- break;
- case KEY_MIN_DEEP_MAINTENANCE_TIME:
- MIN_DEEP_MAINTENANCE_TIME = properties.getLong(
- KEY_MIN_DEEP_MAINTENANCE_TIME,
- mDefaultMinDeepMaintenanceTime);
- break;
- case KEY_INACTIVE_TIMEOUT:
- final long defaultInactiveTimeout = mSmallBatteryDevice
- ? DEFAULT_INACTIVE_TIMEOUT_SMALL_BATTERY
- : mDefaultInactiveTimeout;
- INACTIVE_TIMEOUT = properties.getLong(
- KEY_INACTIVE_TIMEOUT, defaultInactiveTimeout);
- break;
- case KEY_SENSING_TIMEOUT:
- SENSING_TIMEOUT = properties.getLong(
- KEY_SENSING_TIMEOUT, mDefaultSensingTimeout);
- break;
- case KEY_LOCATING_TIMEOUT:
- LOCATING_TIMEOUT = properties.getLong(
- KEY_LOCATING_TIMEOUT, mDefaultLocatingTimeout);
- break;
- case KEY_LOCATION_ACCURACY:
- LOCATION_ACCURACY = properties.getFloat(
- KEY_LOCATION_ACCURACY, mDefaultLocationAccuracy);
- break;
- case KEY_MOTION_INACTIVE_TIMEOUT:
- MOTION_INACTIVE_TIMEOUT = properties.getLong(
- KEY_MOTION_INACTIVE_TIMEOUT, mDefaultMotionInactiveTimeout);
- break;
- case KEY_MOTION_INACTIVE_TIMEOUT_FLEX:
- MOTION_INACTIVE_TIMEOUT_FLEX = properties.getLong(
- KEY_MOTION_INACTIVE_TIMEOUT_FLEX,
- mDefaultMotionInactiveTimeoutFlex);
- break;
- case KEY_IDLE_AFTER_INACTIVE_TIMEOUT:
- final long defaultIdleAfterInactiveTimeout = mSmallBatteryDevice
- ? DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT_SMALL_BATTERY
- : mDefaultIdleAfterInactiveTimeout;
- IDLE_AFTER_INACTIVE_TIMEOUT = properties.getLong(
- KEY_IDLE_AFTER_INACTIVE_TIMEOUT,
- defaultIdleAfterInactiveTimeout);
- break;
- case KEY_IDLE_PENDING_TIMEOUT:
- IDLE_PENDING_TIMEOUT = properties.getLong(
- KEY_IDLE_PENDING_TIMEOUT, mDefaultIdlePendingTimeout);
- break;
- case KEY_MAX_IDLE_PENDING_TIMEOUT:
- MAX_IDLE_PENDING_TIMEOUT = properties.getLong(
- KEY_MAX_IDLE_PENDING_TIMEOUT, mDefaultMaxIdlePendingTimeout);
- break;
- case KEY_IDLE_PENDING_FACTOR:
- IDLE_PENDING_FACTOR = properties.getFloat(
- KEY_IDLE_PENDING_FACTOR, mDefaultIdlePendingFactor);
- break;
- case KEY_QUICK_DOZE_DELAY_TIMEOUT:
- QUICK_DOZE_DELAY_TIMEOUT = properties.getLong(
- KEY_QUICK_DOZE_DELAY_TIMEOUT, mDefaultQuickDozeDelayTimeout);
- break;
- case KEY_IDLE_TIMEOUT:
- IDLE_TIMEOUT = properties.getLong(
- KEY_IDLE_TIMEOUT, mDefaultIdleTimeout);
- break;
- case KEY_MAX_IDLE_TIMEOUT:
- MAX_IDLE_TIMEOUT = properties.getLong(
- KEY_MAX_IDLE_TIMEOUT, mDefaultMaxIdleTimeout);
- break;
- case KEY_IDLE_FACTOR:
- IDLE_FACTOR = properties.getFloat(KEY_IDLE_FACTOR, mDefaultIdleFactor);
- break;
- case KEY_MIN_TIME_TO_ALARM:
- MIN_TIME_TO_ALARM = properties.getLong(
- KEY_MIN_TIME_TO_ALARM, mDefaultMinTimeToAlarm);
- break;
- case KEY_MAX_TEMP_APP_ALLOWLIST_DURATION_MS:
- MAX_TEMP_APP_ALLOWLIST_DURATION_MS = properties.getLong(
- KEY_MAX_TEMP_APP_ALLOWLIST_DURATION_MS,
- mDefaultMaxTempAppAllowlistDurationMs);
- break;
- case KEY_MMS_TEMP_APP_ALLOWLIST_DURATION_MS:
- MMS_TEMP_APP_ALLOWLIST_DURATION_MS = properties.getLong(
- KEY_MMS_TEMP_APP_ALLOWLIST_DURATION_MS,
- mDefaultMmsTempAppAllowlistDurationMs);
- break;
- case KEY_SMS_TEMP_APP_ALLOWLIST_DURATION_MS:
- SMS_TEMP_APP_ALLOWLIST_DURATION_MS = properties.getLong(
- KEY_SMS_TEMP_APP_ALLOWLIST_DURATION_MS,
- mDefaultSmsTempAppAllowlistDurationMs);
- break;
- case KEY_NOTIFICATION_ALLOWLIST_DURATION_MS:
- NOTIFICATION_ALLOWLIST_DURATION_MS = properties.getLong(
- KEY_NOTIFICATION_ALLOWLIST_DURATION_MS,
- mDefaultNotificationAllowlistDurationMs);
- break;
- case KEY_WAIT_FOR_UNLOCK:
- WAIT_FOR_UNLOCK = properties.getBoolean(
- KEY_WAIT_FOR_UNLOCK, mDefaultWaitForUnlock);
- break;
- case KEY_USE_WINDOW_ALARMS:
- USE_WINDOW_ALARMS = properties.getBoolean(
- KEY_USE_WINDOW_ALARMS, mDefaultUseWindowAlarms);
- break;
- case KEY_USE_MODE_MANAGER:
- USE_MODE_MANAGER = properties.getBoolean(
- KEY_USE_MODE_MANAGER, mDefaultUseModeManager);
- break;
- default:
- Slog.e(TAG, "Unknown configuration key: " + name);
- break;
- }
- }
+ mUserSettingDeviceConfigMediator.setDeviceConfigProperties(properties);
+ updateConstantsLocked();
}
}
+ private void updateConstantsLocked() {
+ if (mSmallBatteryDevice) return;
+ FLEX_TIME_SHORT = mUserSettingDeviceConfigMediator.getLong(
+ KEY_FLEX_TIME_SHORT, mDefaultFlexTimeShort);
+
+ LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+ KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT,
+ mDefaultLightIdleAfterInactiveTimeout);
+
+ LIGHT_IDLE_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+ KEY_LIGHT_IDLE_TIMEOUT, mDefaultLightIdleTimeout);
+
+ LIGHT_IDLE_TIMEOUT_INITIAL_FLEX = mUserSettingDeviceConfigMediator.getLong(
+ KEY_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX,
+ mDefaultLightIdleTimeoutInitialFlex);
+
+ LIGHT_IDLE_TIMEOUT_MAX_FLEX = mUserSettingDeviceConfigMediator.getLong(
+ KEY_LIGHT_IDLE_TIMEOUT_MAX_FLEX,
+ mDefaultLightIdleTimeoutMaxFlex);
+
+ LIGHT_IDLE_FACTOR = Math.max(1, mUserSettingDeviceConfigMediator.getFloat(
+ KEY_LIGHT_IDLE_FACTOR, mDefaultLightIdleFactor));
+
+ LIGHT_IDLE_INCREASE_LINEARLY = mUserSettingDeviceConfigMediator.getBoolean(
+ KEY_LIGHT_IDLE_INCREASE_LINEARLY,
+ mDefaultLightIdleIncreaseLinearly);
+
+ LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS = mUserSettingDeviceConfigMediator.getLong(
+ KEY_LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS,
+ mDefaultLightIdleLinearIncreaseFactorMs);
+
+ LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS = mUserSettingDeviceConfigMediator.getLong(
+ KEY_LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS,
+ mDefaultLightIdleFlexLinearIncreaseFactorMs);
+
+ LIGHT_MAX_IDLE_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+ KEY_LIGHT_MAX_IDLE_TIMEOUT, mDefaultLightMaxIdleTimeout);
+
+ LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = mUserSettingDeviceConfigMediator.getLong(
+ KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET,
+ mDefaultLightIdleMaintenanceMinBudget);
+
+ LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = mUserSettingDeviceConfigMediator.getLong(
+ KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET,
+ mDefaultLightIdleMaintenanceMaxBudget);
+
+ MIN_LIGHT_MAINTENANCE_TIME = mUserSettingDeviceConfigMediator.getLong(
+ KEY_MIN_LIGHT_MAINTENANCE_TIME,
+ mDefaultMinLightMaintenanceTime);
+
+ MIN_DEEP_MAINTENANCE_TIME = mUserSettingDeviceConfigMediator.getLong(
+ KEY_MIN_DEEP_MAINTENANCE_TIME,
+ mDefaultMinDeepMaintenanceTime);
+
+ final long defaultInactiveTimeout = mSmallBatteryDevice
+ ? DEFAULT_INACTIVE_TIMEOUT_SMALL_BATTERY
+ : mDefaultInactiveTimeout;
+ INACTIVE_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+ KEY_INACTIVE_TIMEOUT, defaultInactiveTimeout);
+
+ SENSING_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+ KEY_SENSING_TIMEOUT, mDefaultSensingTimeout);
+
+ LOCATING_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+ KEY_LOCATING_TIMEOUT, mDefaultLocatingTimeout);
+
+ LOCATION_ACCURACY = mUserSettingDeviceConfigMediator.getFloat(
+ KEY_LOCATION_ACCURACY, mDefaultLocationAccuracy);
+
+ MOTION_INACTIVE_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+ KEY_MOTION_INACTIVE_TIMEOUT, mDefaultMotionInactiveTimeout);
+
+ MOTION_INACTIVE_TIMEOUT_FLEX = mUserSettingDeviceConfigMediator.getLong(
+ KEY_MOTION_INACTIVE_TIMEOUT_FLEX,
+ mDefaultMotionInactiveTimeoutFlex);
+
+ final long defaultIdleAfterInactiveTimeout = mSmallBatteryDevice
+ ? DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT_SMALL_BATTERY
+ : mDefaultIdleAfterInactiveTimeout;
+ IDLE_AFTER_INACTIVE_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+ KEY_IDLE_AFTER_INACTIVE_TIMEOUT,
+ defaultIdleAfterInactiveTimeout);
+
+ IDLE_PENDING_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+ KEY_IDLE_PENDING_TIMEOUT, mDefaultIdlePendingTimeout);
+
+ MAX_IDLE_PENDING_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+ KEY_MAX_IDLE_PENDING_TIMEOUT, mDefaultMaxIdlePendingTimeout);
+
+ IDLE_PENDING_FACTOR = mUserSettingDeviceConfigMediator.getFloat(
+ KEY_IDLE_PENDING_FACTOR, mDefaultIdlePendingFactor);
+
+ QUICK_DOZE_DELAY_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+ KEY_QUICK_DOZE_DELAY_TIMEOUT, mDefaultQuickDozeDelayTimeout);
+
+ IDLE_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+ KEY_IDLE_TIMEOUT, mDefaultIdleTimeout);
+
+ MAX_IDLE_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+ KEY_MAX_IDLE_TIMEOUT, mDefaultMaxIdleTimeout);
+
+ IDLE_FACTOR = mUserSettingDeviceConfigMediator.getFloat(KEY_IDLE_FACTOR,
+ mDefaultIdleFactor);
+
+ MIN_TIME_TO_ALARM = mUserSettingDeviceConfigMediator.getLong(
+ KEY_MIN_TIME_TO_ALARM, mDefaultMinTimeToAlarm);
+
+ MAX_TEMP_APP_ALLOWLIST_DURATION_MS = mUserSettingDeviceConfigMediator.getLong(
+ KEY_MAX_TEMP_APP_ALLOWLIST_DURATION_MS,
+ mDefaultMaxTempAppAllowlistDurationMs);
+
+ MMS_TEMP_APP_ALLOWLIST_DURATION_MS = mUserSettingDeviceConfigMediator.getLong(
+ KEY_MMS_TEMP_APP_ALLOWLIST_DURATION_MS,
+ mDefaultMmsTempAppAllowlistDurationMs);
+
+ SMS_TEMP_APP_ALLOWLIST_DURATION_MS = mUserSettingDeviceConfigMediator.getLong(
+ KEY_SMS_TEMP_APP_ALLOWLIST_DURATION_MS,
+ mDefaultSmsTempAppAllowlistDurationMs);
+
+ NOTIFICATION_ALLOWLIST_DURATION_MS = mUserSettingDeviceConfigMediator.getLong(
+ KEY_NOTIFICATION_ALLOWLIST_DURATION_MS,
+ mDefaultNotificationAllowlistDurationMs);
+
+ WAIT_FOR_UNLOCK = mUserSettingDeviceConfigMediator.getBoolean(
+ KEY_WAIT_FOR_UNLOCK, mDefaultWaitForUnlock);
+
+ USE_WINDOW_ALARMS = mUserSettingDeviceConfigMediator.getBoolean(
+ KEY_USE_WINDOW_ALARMS, mDefaultUseWindowAlarms);
+
+ USE_MODE_MANAGER = mUserSettingDeviceConfigMediator.getBoolean(
+ KEY_USE_MODE_MANAGER, mDefaultUseModeManager);
+ }
+
void dump(PrintWriter pw) {
pw.println(" Settings:");
@@ -2490,9 +2485,10 @@ public class DeviceIdleController extends SystemService
return mConnectivityManager;
}
- Constants getConstants(DeviceIdleController controller) {
+ Constants getConstants(DeviceIdleController controller, Handler handler,
+ ContentResolver resolver) {
if (mConstants == null) {
- mConstants = controller.new Constants();
+ mConstants = controller.new Constants(handler, resolver);
}
return mConstants;
}
@@ -2650,7 +2646,7 @@ public class DeviceIdleController extends SystemService
}
}
- mConstants = mInjector.getConstants(this);
+ mConstants = mInjector.getConstants(this, mHandler, getContext().getContentResolver());
readConfigFileLocked();
updateWhitelistAppIdsLocked();
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java
index d2150b80761f..8381d1a322e0 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java
@@ -109,7 +109,6 @@ import android.annotation.Nullable;
import android.content.ContentResolver;
import android.provider.DeviceConfig;
import android.util.IndentingPrintWriter;
-import android.util.KeyValueListParser;
import android.util.Slog;
import android.util.SparseArray;
@@ -154,7 +153,6 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy {
private long mMinSatiatedConsumptionLimit;
private long mMaxSatiatedConsumptionLimit;
- private final KeyValueListParser mParser = new KeyValueListParser(',');
private final Injector mInjector;
private final SparseArray<Action> mActions = new SparseArray<>();
@@ -241,35 +239,36 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy {
mRewards.clear();
try {
- mParser.setString(policyValuesString);
+ mUserSettingDeviceConfigMediator.setSettingsString(policyValuesString);
+ mUserSettingDeviceConfigMediator.setDeviceConfigProperties(properties);
} catch (IllegalArgumentException e) {
Slog.e(TAG, "Global setting key incorrect: ", e);
}
- mMinSatiatedBalanceOther = getConstantAsCake(mParser, properties,
+ mMinSatiatedBalanceOther = getConstantAsCake(
KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP, DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP_CAKES);
- mMinSatiatedBalanceHeadlessSystemApp = getConstantAsCake(mParser, properties,
+ mMinSatiatedBalanceHeadlessSystemApp = getConstantAsCake(
KEY_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
DEFAULT_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES,
mMinSatiatedBalanceOther);
- mMinSatiatedBalanceExempted = getConstantAsCake(mParser, properties,
+ mMinSatiatedBalanceExempted = getConstantAsCake(
KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED,
DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES,
mMinSatiatedBalanceHeadlessSystemApp);
- mMaxSatiatedBalance = getConstantAsCake(mParser, properties,
+ mMaxSatiatedBalance = getConstantAsCake(
KEY_AM_MAX_SATIATED_BALANCE, DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES,
Math.max(arcToCake(1), mMinSatiatedBalanceExempted));
- mMinSatiatedConsumptionLimit = getConstantAsCake(mParser, properties,
+ mMinSatiatedConsumptionLimit = getConstantAsCake(
KEY_AM_MIN_CONSUMPTION_LIMIT, DEFAULT_AM_MIN_CONSUMPTION_LIMIT_CAKES,
arcToCake(1));
- mInitialSatiatedConsumptionLimit = getConstantAsCake(mParser, properties,
+ mInitialSatiatedConsumptionLimit = getConstantAsCake(
KEY_AM_INITIAL_CONSUMPTION_LIMIT, DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT_CAKES,
mMinSatiatedConsumptionLimit);
- mMaxSatiatedConsumptionLimit = getConstantAsCake(mParser, properties,
+ mMaxSatiatedConsumptionLimit = getConstantAsCake(
KEY_AM_MAX_CONSUMPTION_LIMIT, DEFAULT_AM_MAX_CONSUMPTION_LIMIT_CAKES,
mInitialSatiatedConsumptionLimit);
- final long exactAllowWhileIdleWakeupBasePrice = getConstantAsCake(mParser, properties,
+ final long exactAllowWhileIdleWakeupBasePrice = getConstantAsCake(
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE,
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE_CAKES);
@@ -279,49 +278,49 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy {
// run out of credits, and not when the system has run out of stock.
mActions.put(ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE,
new Action(ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP,
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP_CAKES),
exactAllowWhileIdleWakeupBasePrice,
/* respectsStockLimit */ false));
mActions.put(ACTION_ALARM_WAKEUP_EXACT,
new Action(ACTION_ALARM_WAKEUP_EXACT,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_ACTION_ALARM_EXACT_WAKEUP_CTP,
DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_CTP_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE,
DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE_CAKES),
/* respectsStockLimit */ false));
final long inexactAllowWhileIdleWakeupBasePrice =
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE,
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE_CAKES);
mActions.put(ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE,
new Action(ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP,
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP_CAKES),
inexactAllowWhileIdleWakeupBasePrice,
/* respectsStockLimit */ false));
mActions.put(ACTION_ALARM_WAKEUP_INEXACT,
new Action(ACTION_ALARM_WAKEUP_INEXACT,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP,
DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE,
DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE_CAKES),
/* respectsStockLimit */ false));
- final long exactAllowWhileIdleNonWakeupBasePrice = getConstantAsCake(mParser, properties,
+ final long exactAllowWhileIdleNonWakeupBasePrice = getConstantAsCake(
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_BASE_PRICE,
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES);
mActions.put(ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE,
new Action(ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP,
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP_CAKES),
exactAllowWhileIdleNonWakeupBasePrice,
@@ -329,18 +328,18 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy {
mActions.put(ACTION_ALARM_NONWAKEUP_EXACT,
new Action(ACTION_ALARM_NONWAKEUP_EXACT,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP,
DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE,
DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE_CAKES),
/* respectsStockLimit */ false));
- final long inexactAllowWhileIdleNonWakeupBasePrice = getConstantAsCake(mParser, properties,
+ final long inexactAllowWhileIdleNonWakeupBasePrice = getConstantAsCake(
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE,
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES);
- final long inexactAllowWhileIdleNonWakeupCtp = getConstantAsCake(mParser, properties,
+ final long inexactAllowWhileIdleNonWakeupCtp = getConstantAsCake(
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP,
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP_CAKES);
mActions.put(ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE,
@@ -350,72 +349,72 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy {
mActions.put(ACTION_ALARM_NONWAKEUP_INEXACT,
new Action(ACTION_ALARM_NONWAKEUP_INEXACT,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP,
DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE,
DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE_CAKES)));
mActions.put(ACTION_ALARM_CLOCK,
new Action(ACTION_ALARM_CLOCK,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_ACTION_ALARM_ALARMCLOCK_CTP,
DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_CTP_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE,
DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE_CAKES),
/* respectsStockLimit */ false));
mRewards.put(REWARD_TOP_ACTIVITY, new Reward(REWARD_TOP_ACTIVITY,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_REWARD_TOP_ACTIVITY_INSTANT,
DEFAULT_AM_REWARD_TOP_ACTIVITY_INSTANT_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_REWARD_TOP_ACTIVITY_ONGOING,
DEFAULT_AM_REWARD_TOP_ACTIVITY_ONGOING_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_REWARD_TOP_ACTIVITY_MAX,
DEFAULT_AM_REWARD_TOP_ACTIVITY_MAX_CAKES)));
mRewards.put(REWARD_NOTIFICATION_SEEN, new Reward(REWARD_NOTIFICATION_SEEN,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_REWARD_NOTIFICATION_SEEN_INSTANT,
DEFAULT_AM_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_REWARD_NOTIFICATION_SEEN_ONGOING,
DEFAULT_AM_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_REWARD_NOTIFICATION_SEEN_MAX,
DEFAULT_AM_REWARD_NOTIFICATION_SEEN_MAX_CAKES)));
mRewards.put(REWARD_NOTIFICATION_INTERACTION,
new Reward(REWARD_NOTIFICATION_INTERACTION,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT,
DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING,
DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_REWARD_NOTIFICATION_INTERACTION_MAX,
DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES)));
mRewards.put(REWARD_WIDGET_INTERACTION, new Reward(REWARD_WIDGET_INTERACTION,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_REWARD_WIDGET_INTERACTION_INSTANT,
DEFAULT_AM_REWARD_WIDGET_INTERACTION_INSTANT_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_REWARD_WIDGET_INTERACTION_ONGOING,
DEFAULT_AM_REWARD_WIDGET_INTERACTION_ONGOING_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_REWARD_WIDGET_INTERACTION_MAX,
DEFAULT_AM_REWARD_WIDGET_INTERACTION_MAX_CAKES)));
mRewards.put(REWARD_OTHER_USER_INTERACTION,
new Reward(REWARD_OTHER_USER_INTERACTION,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_REWARD_OTHER_USER_INTERACTION_INSTANT,
DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_REWARD_OTHER_USER_INTERACTION_ONGOING,
DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_AM_REWARD_OTHER_USER_INTERACTION_MAX,
DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX_CAKES)));
}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java
index a4043dd8ba78..61096b9fa179 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java
@@ -33,9 +33,9 @@ import android.content.ContentResolver;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.util.IndentingPrintWriter;
-import android.util.KeyValueListParser;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.utils.UserSettingDeviceConfigMediator;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -197,10 +197,17 @@ public abstract class EconomicPolicy {
}
protected final InternalResourceService mIrs;
+ protected final UserSettingDeviceConfigMediator mUserSettingDeviceConfigMediator;
private static final Modifier[] COST_MODIFIER_BY_INDEX = new Modifier[NUM_COST_MODIFIERS];
EconomicPolicy(@NonNull InternalResourceService irs) {
mIrs = irs;
+ // Don't cross the streams! Mixing Settings/local user config changes with DeviceConfig
+ // config can cause issues since the scales may be different, so use one or the other.
+ // If user settings exist, then just stick with the Settings constants, even if there
+ // are invalid values.
+ mUserSettingDeviceConfigMediator =
+ new UserSettingDeviceConfigMediator.SettingsOverridesAllMediator(',');
for (int mId : getCostModifiers()) {
initModifier(mId, irs);
}
@@ -464,28 +471,14 @@ public abstract class EconomicPolicy {
return "UNKNOWN_REWARD:" + Integer.toHexString(eventId);
}
- protected long getConstantAsCake(@NonNull KeyValueListParser parser,
- @Nullable DeviceConfig.Properties properties, String key, long defaultValCake) {
- return getConstantAsCake(parser, properties, key, defaultValCake, 0);
+ protected long getConstantAsCake(String key, long defaultValCake) {
+ return getConstantAsCake(key, defaultValCake, 0);
}
- protected long getConstantAsCake(@NonNull KeyValueListParser parser,
- @Nullable DeviceConfig.Properties properties, String key, long defaultValCake,
- long minValCake) {
- // Don't cross the streams! Mixing Settings/local user config changes with DeviceConfig
- // config can cause issues since the scales may be different, so use one or the other.
- if (parser.size() > 0) {
- // User settings take precedence. Just stick with the Settings constants, even if there
- // are invalid values. It's not worth the time to evaluate all the key/value pairs to
- // make sure there are valid ones before deciding.
- return Math.max(minValCake,
- parseCreditValue(parser.getString(key, null), defaultValCake));
- }
- if (properties != null) {
- return Math.max(minValCake,
- parseCreditValue(properties.getString(key, null), defaultValCake));
- }
- return Math.max(minValCake, defaultValCake);
+ protected long getConstantAsCake(String key, long defaultValCake, long minValCake) {
+ return Math.max(minValCake,
+ parseCreditValue(
+ mUserSettingDeviceConfigMediator.getString(key, null), defaultValCake));
}
@VisibleForTesting
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java
index 91a291fe20db..69e57365b6e0 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java
@@ -127,7 +127,6 @@ import android.annotation.Nullable;
import android.content.ContentResolver;
import android.provider.DeviceConfig;
import android.util.IndentingPrintWriter;
-import android.util.KeyValueListParser;
import android.util.Slog;
import android.util.SparseArray;
@@ -168,7 +167,6 @@ public class JobSchedulerEconomicPolicy extends EconomicPolicy {
private long mMinSatiatedConsumptionLimit;
private long mMaxSatiatedConsumptionLimit;
- private final KeyValueListParser mParser = new KeyValueListParser(',');
private final Injector mInjector;
private final SparseArray<Action> mActions = new SparseArray<>();
@@ -274,176 +272,177 @@ public class JobSchedulerEconomicPolicy extends EconomicPolicy {
mRewards.clear();
try {
- mParser.setString(policyValuesString);
+ mUserSettingDeviceConfigMediator.setSettingsString(policyValuesString);
+ mUserSettingDeviceConfigMediator.setDeviceConfigProperties(properties);
} catch (IllegalArgumentException e) {
Slog.e(TAG, "Global setting key incorrect: ", e);
}
- mMinSatiatedBalanceOther = getConstantAsCake(mParser, properties,
+ mMinSatiatedBalanceOther = getConstantAsCake(
KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP, DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES);
- mMinSatiatedBalanceHeadlessSystemApp = getConstantAsCake(mParser, properties,
+ mMinSatiatedBalanceHeadlessSystemApp = getConstantAsCake(
KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
DEFAULT_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES,
mMinSatiatedBalanceOther);
- mMinSatiatedBalanceExempted = getConstantAsCake(mParser, properties,
+ mMinSatiatedBalanceExempted = getConstantAsCake(
KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED,
DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES,
mMinSatiatedBalanceHeadlessSystemApp);
- mMinSatiatedBalanceIncrementalAppUpdater = getConstantAsCake(mParser, properties,
+ mMinSatiatedBalanceIncrementalAppUpdater = getConstantAsCake(
KEY_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER,
DEFAULT_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER_CAKES);
- mMaxSatiatedBalance = getConstantAsCake(mParser, properties,
+ mMaxSatiatedBalance = getConstantAsCake(
KEY_JS_MAX_SATIATED_BALANCE, DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES,
Math.max(arcToCake(1), mMinSatiatedBalanceExempted));
- mMinSatiatedConsumptionLimit = getConstantAsCake(mParser, properties,
+ mMinSatiatedConsumptionLimit = getConstantAsCake(
KEY_JS_MIN_CONSUMPTION_LIMIT, DEFAULT_JS_MIN_CONSUMPTION_LIMIT_CAKES,
arcToCake(1));
- mInitialSatiatedConsumptionLimit = getConstantAsCake(mParser, properties,
+ mInitialSatiatedConsumptionLimit = getConstantAsCake(
KEY_JS_INITIAL_CONSUMPTION_LIMIT, DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT_CAKES,
mMinSatiatedConsumptionLimit);
- mMaxSatiatedConsumptionLimit = getConstantAsCake(mParser, properties,
+ mMaxSatiatedConsumptionLimit = getConstantAsCake(
KEY_JS_MAX_CONSUMPTION_LIMIT, DEFAULT_JS_MAX_CONSUMPTION_LIMIT_CAKES,
mInitialSatiatedConsumptionLimit);
mActions.put(ACTION_JOB_MAX_START, new Action(ACTION_JOB_MAX_START,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_ACTION_JOB_MAX_START_CTP,
DEFAULT_JS_ACTION_JOB_MAX_START_CTP_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_ACTION_JOB_MAX_START_BASE_PRICE,
DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE_CAKES)));
mActions.put(ACTION_JOB_MAX_RUNNING, new Action(ACTION_JOB_MAX_RUNNING,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_ACTION_JOB_MAX_RUNNING_CTP,
DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE,
DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE_CAKES)));
mActions.put(ACTION_JOB_HIGH_START, new Action(ACTION_JOB_HIGH_START,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_ACTION_JOB_HIGH_START_CTP,
DEFAULT_JS_ACTION_JOB_HIGH_START_CTP_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_ACTION_JOB_HIGH_START_BASE_PRICE,
DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE_CAKES)));
mActions.put(ACTION_JOB_HIGH_RUNNING, new Action(ACTION_JOB_HIGH_RUNNING,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_ACTION_JOB_HIGH_RUNNING_CTP,
DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE,
DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE_CAKES)));
mActions.put(ACTION_JOB_DEFAULT_START, new Action(ACTION_JOB_DEFAULT_START,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_ACTION_JOB_DEFAULT_START_CTP,
DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE,
DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE_CAKES)));
mActions.put(ACTION_JOB_DEFAULT_RUNNING, new Action(ACTION_JOB_DEFAULT_RUNNING,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_ACTION_JOB_DEFAULT_RUNNING_CTP,
DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE,
DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE_CAKES)));
mActions.put(ACTION_JOB_LOW_START, new Action(ACTION_JOB_LOW_START,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_ACTION_JOB_LOW_START_CTP,
DEFAULT_JS_ACTION_JOB_LOW_START_CTP_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_ACTION_JOB_LOW_START_BASE_PRICE,
DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE_CAKES)));
mActions.put(ACTION_JOB_LOW_RUNNING, new Action(ACTION_JOB_LOW_RUNNING,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_ACTION_JOB_LOW_RUNNING_CTP,
DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE,
DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE_CAKES)));
mActions.put(ACTION_JOB_MIN_START, new Action(ACTION_JOB_MIN_START,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_ACTION_JOB_MIN_START_CTP,
DEFAULT_JS_ACTION_JOB_MIN_START_CTP_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_ACTION_JOB_MIN_START_BASE_PRICE,
DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE_CAKES)));
mActions.put(ACTION_JOB_MIN_RUNNING, new Action(ACTION_JOB_MIN_RUNNING,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_ACTION_JOB_MIN_RUNNING_CTP,
DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE,
DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE_CAKES)));
mActions.put(ACTION_JOB_TIMEOUT, new Action(ACTION_JOB_TIMEOUT,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP,
DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE,
DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE_CAKES)));
mRewards.put(REWARD_TOP_ACTIVITY, new Reward(REWARD_TOP_ACTIVITY,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_REWARD_TOP_ACTIVITY_INSTANT,
DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_REWARD_TOP_ACTIVITY_ONGOING,
DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_REWARD_TOP_ACTIVITY_MAX,
DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX_CAKES)));
mRewards.put(REWARD_NOTIFICATION_SEEN, new Reward(REWARD_NOTIFICATION_SEEN,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_REWARD_NOTIFICATION_SEEN_INSTANT,
DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_REWARD_NOTIFICATION_SEEN_ONGOING,
DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_REWARD_NOTIFICATION_SEEN_MAX,
DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX_CAKES)));
mRewards.put(REWARD_NOTIFICATION_INTERACTION,
new Reward(REWARD_NOTIFICATION_INTERACTION,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT,
DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING,
DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_REWARD_NOTIFICATION_INTERACTION_MAX,
DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES)));
mRewards.put(REWARD_WIDGET_INTERACTION, new Reward(REWARD_WIDGET_INTERACTION,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_REWARD_WIDGET_INTERACTION_INSTANT,
DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_REWARD_WIDGET_INTERACTION_ONGOING,
DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_REWARD_WIDGET_INTERACTION_MAX,
DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX_CAKES)));
mRewards.put(REWARD_OTHER_USER_INTERACTION,
new Reward(REWARD_OTHER_USER_INTERACTION,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_REWARD_OTHER_USER_INTERACTION_INSTANT,
DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_REWARD_OTHER_USER_INTERACTION_ONGOING,
DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_REWARD_OTHER_USER_INTERACTION_MAX,
DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX_CAKES)));
mRewards.put(REWARD_APP_INSTALL,
new Reward(REWARD_APP_INSTALL,
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_REWARD_APP_INSTALL_INSTANT,
DEFAULT_JS_REWARD_APP_INSTALL_INSTANT_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_REWARD_APP_INSTALL_ONGOING,
DEFAULT_JS_REWARD_APP_INSTALL_ONGOING_CAKES),
- getConstantAsCake(mParser, properties,
+ getConstantAsCake(
KEY_JS_REWARD_APP_INSTALL_MAX,
DEFAULT_JS_REWARD_APP_INSTALL_MAX_CAKES)));
}
diff --git a/core/api/current.txt b/core/api/current.txt
index 309135411137..805ecd43e3c7 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -9854,7 +9854,7 @@ package android.content {
method @NonNull public android.content.AttributionSource build();
method @NonNull public android.content.AttributionSource.Builder setAttributionTag(@Nullable String);
method @FlaggedApi("android.permission.flags.device_aware_permission_apis") @NonNull public android.content.AttributionSource.Builder setDeviceId(int);
- method @Deprecated @NonNull public android.content.AttributionSource.Builder setNext(@Nullable android.content.AttributionSource);
+ method @NonNull public android.content.AttributionSource.Builder setNext(@Nullable android.content.AttributionSource);
method @FlaggedApi("android.permission.flags.set_next_attribution_source") @NonNull public android.content.AttributionSource.Builder setNextAttributionSource(@NonNull android.content.AttributionSource);
method @NonNull public android.content.AttributionSource.Builder setPackageName(@Nullable String);
method @NonNull public android.content.AttributionSource.Builder setPid(int);
@@ -10601,6 +10601,7 @@ package android.content {
field public static final String RESTRICTIONS_SERVICE = "restrictions";
field public static final String ROLE_SERVICE = "role";
field public static final String SEARCH_SERVICE = "search";
+ field @FlaggedApi("android.os.security_state_service") public static final String SECURITY_STATE_SERVICE = "security_state";
field public static final String SENSOR_SERVICE = "sensor";
field public static final String SHORTCUT_SERVICE = "shortcut";
field public static final String STATUS_BAR_SERVICE = "statusbar";
@@ -10613,6 +10614,7 @@ package android.content {
field public static final String TELEPHONY_SUBSCRIPTION_SERVICE = "telephony_subscription_service";
field public static final String TEXT_CLASSIFICATION_SERVICE = "textclassification";
field public static final String TEXT_SERVICES_MANAGER_SERVICE = "textservices";
+ field @FlaggedApi("android.media.tv.flags.enable_ad_service_fw") public static final String TV_AD_SERVICE = "tv_ad";
field public static final String TV_INPUT_SERVICE = "tv_input";
field public static final String TV_INTERACTIVE_APP_SERVICE = "tv_interactive_app";
field public static final String UI_MODE_SERVICE = "uimode";
@@ -11101,6 +11103,7 @@ package android.content {
field public static final String ACTION_UID_REMOVED = "android.intent.action.UID_REMOVED";
field @Deprecated public static final String ACTION_UMS_CONNECTED = "android.intent.action.UMS_CONNECTED";
field @Deprecated public static final String ACTION_UMS_DISCONNECTED = "android.intent.action.UMS_DISCONNECTED";
+ field @FlaggedApi("android.content.pm.archiving") public static final String ACTION_UNARCHIVE_PACKAGE = "android.intent.action.UNARCHIVE_PACKAGE";
field @Deprecated public static final String ACTION_UNINSTALL_PACKAGE = "android.intent.action.UNINSTALL_PACKAGE";
field public static final String ACTION_USER_BACKGROUND = "android.intent.action.USER_BACKGROUND";
field public static final String ACTION_USER_FOREGROUND = "android.intent.action.USER_FOREGROUND";
@@ -12366,6 +12369,7 @@ package android.content.pm {
public class PackageInfo implements android.os.Parcelable {
ctor public PackageInfo();
method public int describeContents();
+ method @FlaggedApi("android.content.pm.archiving") public long getArchiveTimeMillis();
method public long getLongVersionCode();
method public void setLongVersionCode(long);
method public void writeToParcel(android.os.Parcel, int);
@@ -12422,6 +12426,9 @@ package android.content.pm {
method @NonNull public android.content.pm.PackageInstaller.Session openSession(int) throws java.io.IOException;
method public void registerSessionCallback(@NonNull android.content.pm.PackageInstaller.SessionCallback);
method public void registerSessionCallback(@NonNull android.content.pm.PackageInstaller.SessionCallback, @NonNull android.os.Handler);
+ method @FlaggedApi("android.content.pm.archiving") @RequiresPermission(anyOf={android.Manifest.permission.INSTALL_PACKAGES, android.Manifest.permission.REQUEST_INSTALL_PACKAGES}) public void reportUnarchivalStatus(int, int, long, @Nullable android.app.PendingIntent) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @FlaggedApi("android.content.pm.archiving") @RequiresPermission(anyOf={android.Manifest.permission.DELETE_PACKAGES, android.Manifest.permission.REQUEST_DELETE_PACKAGES}) public void requestArchive(@NonNull String, @NonNull android.content.IntentSender) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @FlaggedApi("android.content.pm.archiving") @RequiresPermission(anyOf={android.Manifest.permission.INSTALL_PACKAGES, android.Manifest.permission.REQUEST_INSTALL_PACKAGES}) public void requestUnarchive(@NonNull String, @NonNull android.content.IntentSender) throws java.io.IOException, android.content.pm.PackageManager.NameNotFoundException;
method @RequiresPermission(anyOf={android.Manifest.permission.DELETE_PACKAGES, android.Manifest.permission.REQUEST_DELETE_PACKAGES}) public void uninstall(@NonNull String, @NonNull android.content.IntentSender);
method @RequiresPermission(anyOf={android.Manifest.permission.DELETE_PACKAGES, android.Manifest.permission.REQUEST_DELETE_PACKAGES}) public void uninstall(@NonNull android.content.pm.VersionedPackage, @NonNull android.content.IntentSender);
method @RequiresPermission(anyOf={android.Manifest.permission.DELETE_PACKAGES, android.Manifest.permission.REQUEST_DELETE_PACKAGES}) public void uninstall(@NonNull android.content.pm.VersionedPackage, int, @NonNull android.content.IntentSender);
@@ -12443,6 +12450,10 @@ package android.content.pm {
field public static final String EXTRA_STATUS = "android.content.pm.extra.STATUS";
field public static final String EXTRA_STATUS_MESSAGE = "android.content.pm.extra.STATUS_MESSAGE";
field public static final String EXTRA_STORAGE_PATH = "android.content.pm.extra.STORAGE_PATH";
+ field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_ALL_USERS = "android.content.pm.extra.UNARCHIVE_ALL_USERS";
+ field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_ID = "android.content.pm.extra.UNARCHIVE_ID";
+ field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_PACKAGE_NAME = "android.content.pm.extra.UNARCHIVE_PACKAGE_NAME";
+ field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_STATUS = "android.content.pm.extra.UNARCHIVE_STATUS";
field public static final int PACKAGE_SOURCE_DOWNLOADED_FILE = 4; // 0x4
field public static final int PACKAGE_SOURCE_LOCAL_FILE = 3; // 0x3
field public static final int PACKAGE_SOURCE_OTHER = 1; // 0x1
@@ -12458,6 +12469,13 @@ package android.content.pm {
field public static final int STATUS_FAILURE_TIMEOUT = 8; // 0x8
field public static final int STATUS_PENDING_USER_ACTION = -1; // 0xffffffff
field public static final int STATUS_SUCCESS = 0; // 0x0
+ field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_ERROR_INSTALLER_DISABLED = 4; // 0x4
+ field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_ERROR_INSTALLER_UNINSTALLED = 5; // 0x5
+ field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_ERROR_INSUFFICIENT_STORAGE = 2; // 0x2
+ field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_ERROR_NO_CONNECTIVITY = 3; // 0x3
+ field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_ERROR_USER_ACTION_NEEDED = 1; // 0x1
+ field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_GENERIC_ERROR = 100; // 0x64
+ field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_OK = 0; // 0x0
}
public static final class PackageInstaller.InstallConstraints implements android.os.Parcelable {
@@ -12621,6 +12639,7 @@ package android.content.pm {
method @RequiresPermission(android.Manifest.permission.ENFORCE_UPDATE_OWNERSHIP) public void setRequestUpdateOwnership(boolean);
method public void setRequireUserAction(int);
method public void setSize(long);
+ method @FlaggedApi("android.content.pm.archiving") public void setUnarchiveId(int);
method public void setWhitelistedRestrictedPermissions(@Nullable java.util.Set<java.lang.String>);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.content.pm.PackageInstaller.SessionParams> CREATOR;
@@ -12650,6 +12669,7 @@ package android.content.pm {
method public void writeToParcel(android.os.Parcel, int);
field public int banner;
field public int icon;
+ field @FlaggedApi("android.content.pm.archiving") public boolean isArchived;
field public int labelRes;
field public int logo;
field public android.os.Bundle metaData;
@@ -12772,6 +12792,7 @@ package android.content.pm {
method public boolean hasSigningCertificate(int, @NonNull byte[], int);
method public abstract boolean hasSystemFeature(@NonNull String);
method public abstract boolean hasSystemFeature(@NonNull String, int);
+ method @FlaggedApi("android.content.pm.archiving") public boolean isAppArchivable(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
method @RequiresPermission(value="android.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS", conditional=true) public boolean isAutoRevokeWhitelisted(@NonNull String);
method public boolean isAutoRevokeWhitelisted();
method public boolean isDefaultApplicationIcon(@NonNull android.graphics.drawable.Drawable);
@@ -13013,6 +13034,7 @@ package android.content.pm {
field public static final int INSTALL_SCENARIO_FAST = 1; // 0x1
field public static final int MATCH_ALL = 131072; // 0x20000
field public static final int MATCH_APEX = 1073741824; // 0x40000000
+ field @FlaggedApi("android.content.pm.archiving") public static final long MATCH_ARCHIVED_PACKAGES = 4294967296L; // 0x100000000L
field public static final int MATCH_DEFAULT_ONLY = 65536; // 0x10000
field public static final int MATCH_DIRECT_BOOT_AUTO = 268435456; // 0x10000000
field public static final int MATCH_DIRECT_BOOT_AWARE = 524288; // 0x80000
@@ -22034,6 +22056,19 @@ package android.media {
method public void onJetUserIdUpdate(android.media.JetPlayer, int, int);
}
+ @FlaggedApi("android.media.audio.loudness_configurator_api") public class LoudnessCodecConfigurator {
+ method @FlaggedApi("android.media.audio.loudness_configurator_api") public void addMediaCodec(@NonNull android.media.MediaCodec);
+ method @FlaggedApi("android.media.audio.loudness_configurator_api") @NonNull public static android.media.LoudnessCodecConfigurator create();
+ method @FlaggedApi("android.media.audio.loudness_configurator_api") @NonNull public static android.media.LoudnessCodecConfigurator create(@NonNull java.util.concurrent.Executor, @NonNull android.media.LoudnessCodecConfigurator.OnLoudnessCodecUpdateListener);
+ method @FlaggedApi("android.media.audio.loudness_configurator_api") @NonNull public android.os.Bundle getLoudnessCodecParams(@NonNull android.media.AudioTrack, @NonNull android.media.MediaCodec);
+ method @FlaggedApi("android.media.audio.loudness_configurator_api") public void removeMediaCodec(@NonNull android.media.MediaCodec);
+ method @FlaggedApi("android.media.audio.loudness_configurator_api") public void setAudioTrack(@Nullable android.media.AudioTrack);
+ }
+
+ @FlaggedApi("android.media.audio.loudness_configurator_api") public static interface LoudnessCodecConfigurator.OnLoudnessCodecUpdateListener {
+ method @FlaggedApi("android.media.audio.loudness_configurator_api") @NonNull public default android.os.Bundle onLoudnessCodecUpdate(@NonNull android.media.MediaCodec, @NonNull android.os.Bundle);
+ }
+
public class MediaActionSound {
ctor public MediaActionSound();
method public void load(int);
@@ -27302,6 +27337,13 @@ package android.media.tv {
}
+package android.media.tv.ad {
+
+ @FlaggedApi("android.media.tv.flags.enable_ad_service_fw") public class TvAdManager {
+ }
+
+}
+
package android.media.tv.interactive {
public final class AppLinkInfo implements android.os.Parcelable {
@@ -32840,7 +32882,7 @@ package android.os {
method public static android.os.Message obtain(android.os.Handler, int, Object);
method public static android.os.Message obtain(android.os.Handler, int, int, int);
method public static android.os.Message obtain(android.os.Handler, int, int, int, Object);
- method public android.os.Bundle peekData();
+ method @Nullable public android.os.Bundle peekData();
method public void recycle();
method public void sendToTarget();
method public void setAsynchronous(boolean);
@@ -33379,6 +33421,13 @@ package android.os {
field @NonNull public static final android.os.Parcelable.Creator<android.os.ResultReceiver> CREATOR;
}
+ @FlaggedApi("android.os.security_state_service") public class SecurityStateManager {
+ method @FlaggedApi("android.os.security_state_service") @NonNull public android.os.Bundle getGlobalSecurityState();
+ field public static final String KEY_KERNEL_VERSION = "kernel_version";
+ field public static final String KEY_SYSTEM_SPL = "system_spl";
+ field public static final String KEY_VENDOR_SPL = "vendor_spl";
+ }
+
public final class SharedMemory implements java.io.Closeable android.os.Parcelable {
method public void close();
method @NonNull public static android.os.SharedMemory create(@Nullable String, int) throws android.system.ErrnoException;
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index fc23f9bc43ff..e2b2879c1e42 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -3614,7 +3614,6 @@ package android.content {
field public static final String ACTION_SHOW_SUSPENDED_APP_DETAILS = "android.intent.action.SHOW_SUSPENDED_APP_DETAILS";
field @Deprecated public static final String ACTION_SIM_STATE_CHANGED = "android.intent.action.SIM_STATE_CHANGED";
field public static final String ACTION_SPLIT_CONFIGURATION_CHANGED = "android.intent.action.SPLIT_CONFIGURATION_CHANGED";
- field @FlaggedApi("android.content.pm.archiving") public static final String ACTION_UNARCHIVE_PACKAGE = "android.intent.action.UNARCHIVE_PACKAGE";
field public static final String ACTION_UPGRADE_SETUP = "android.intent.action.UPGRADE_SETUP";
field public static final String ACTION_USER_ADDED = "android.intent.action.USER_ADDED";
field public static final String ACTION_USER_REMOVED = "android.intent.action.USER_REMOVED";
@@ -3862,16 +3861,9 @@ package android.content.pm {
field @RequiresPermission(android.Manifest.permission.ACCESS_SHORTCUTS) public static final int FLAG_GET_PERSONS_DATA = 2048; // 0x800
}
- public class PackageInfo implements android.os.Parcelable {
- method @FlaggedApi("android.content.pm.archiving") public long getArchiveTimeMillis();
- }
-
public class PackageInstaller {
method @NonNull public android.content.pm.PackageInstaller.InstallInfo readInstallInfo(@NonNull java.io.File, int) throws android.content.pm.PackageInstaller.PackageParsingException;
method @FlaggedApi("android.content.pm.read_install_info") @NonNull public android.content.pm.PackageInstaller.InstallInfo readInstallInfo(@NonNull android.os.ParcelFileDescriptor, @Nullable String, int) throws android.content.pm.PackageInstaller.PackageParsingException;
- method @FlaggedApi("android.content.pm.archiving") @RequiresPermission(anyOf={android.Manifest.permission.INSTALL_PACKAGES, android.Manifest.permission.REQUEST_INSTALL_PACKAGES}) public void reportUnarchivalStatus(int, int, long, @Nullable android.app.PendingIntent) throws android.content.pm.PackageManager.NameNotFoundException;
- method @FlaggedApi("android.content.pm.archiving") @RequiresPermission(anyOf={android.Manifest.permission.DELETE_PACKAGES, android.Manifest.permission.REQUEST_DELETE_PACKAGES}) public void requestArchive(@NonNull String, @NonNull android.content.IntentSender) throws android.content.pm.PackageManager.NameNotFoundException;
- method @FlaggedApi("android.content.pm.archiving") @RequiresPermission(anyOf={android.Manifest.permission.INSTALL_PACKAGES, android.Manifest.permission.REQUEST_INSTALL_PACKAGES}) public void requestUnarchive(@NonNull String, @NonNull android.content.IntentSender) throws java.io.IOException, android.content.pm.PackageManager.NameNotFoundException;
method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setPermissionsResult(int, boolean);
field public static final String ACTION_CONFIRM_INSTALL = "android.content.pm.action.CONFIRM_INSTALL";
field public static final String ACTION_CONFIRM_PRE_APPROVAL = "android.content.pm.action.CONFIRM_PRE_APPROVAL";
@@ -3882,23 +3874,12 @@ package android.content.pm {
field public static final String EXTRA_DATA_LOADER_TYPE = "android.content.pm.extra.DATA_LOADER_TYPE";
field public static final String EXTRA_LEGACY_STATUS = "android.content.pm.extra.LEGACY_STATUS";
field @Deprecated public static final String EXTRA_RESOLVED_BASE_PATH = "android.content.pm.extra.RESOLVED_BASE_PATH";
- field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_ALL_USERS = "android.content.pm.extra.UNARCHIVE_ALL_USERS";
- field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_ID = "android.content.pm.extra.UNARCHIVE_ID";
- field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_PACKAGE_NAME = "android.content.pm.extra.UNARCHIVE_PACKAGE_NAME";
- field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_STATUS = "android.content.pm.extra.UNARCHIVE_STATUS";
field public static final int LOCATION_DATA_APP = 0; // 0x0
field public static final int LOCATION_MEDIA_DATA = 2; // 0x2
field public static final int LOCATION_MEDIA_OBB = 1; // 0x1
field public static final int REASON_CONFIRM_PACKAGE_CHANGE = 0; // 0x0
field public static final int REASON_OWNERSHIP_CHANGED = 1; // 0x1
field public static final int REASON_REMIND_OWNERSHIP = 2; // 0x2
- field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_ERROR_INSTALLER_DISABLED = 4; // 0x4
- field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_ERROR_INSTALLER_UNINSTALLED = 5; // 0x5
- field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_ERROR_INSUFFICIENT_STORAGE = 2; // 0x2
- field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_ERROR_NO_CONNECTIVITY = 3; // 0x3
- field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_ERROR_USER_ACTION_NEEDED = 1; // 0x1
- field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_GENERIC_ERROR = 100; // 0x64
- field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_OK = 0; // 0x0
}
public static class PackageInstaller.InstallInfo {
@@ -3948,14 +3929,12 @@ package android.content.pm {
method public void setRequestDowngrade(boolean);
method @FlaggedApi("android.content.pm.rollback_lifetime") @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS) public void setRollbackLifetimeMillis(long);
method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setStaged();
- method @FlaggedApi("android.content.pm.archiving") public void setUnarchiveId(int);
}
public class PackageItemInfo {
method public static void forceSafeLabels();
method @Deprecated @NonNull public CharSequence loadSafeLabel(@NonNull android.content.pm.PackageManager);
method @NonNull public CharSequence loadSafeLabel(@NonNull android.content.pm.PackageManager, @FloatRange(from=0) float, int);
- field @FlaggedApi("android.content.pm.archiving") public boolean isArchived;
}
public abstract class PackageManager {
@@ -3987,7 +3966,6 @@ package android.content.pm {
method @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) public abstract void grantRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
method @Deprecated public abstract int installExistingPackage(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
method @Deprecated public abstract int installExistingPackage(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
- method @FlaggedApi("android.content.pm.archiving") public boolean isAppArchivable(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceiversAsUser(@NonNull android.content.Intent, int, android.os.UserHandle);
method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceiversAsUser(@NonNull android.content.Intent, @NonNull android.content.pm.PackageManager.ResolveInfoFlags, @NonNull android.os.UserHandle);
method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List<android.content.pm.ResolveInfo> queryIntentActivitiesAsUser(@NonNull android.content.Intent, int, @NonNull android.os.UserHandle);
@@ -4105,7 +4083,6 @@ package android.content.pm {
field @Deprecated public static final int INTENT_FILTER_VERIFICATION_SUCCESS = 1; // 0x1
field @Deprecated public static final int MASK_PERMISSION_FLAGS = 255; // 0xff
field public static final int MATCH_ANY_USER = 4194304; // 0x400000
- field @FlaggedApi("android.content.pm.archiving") public static final long MATCH_ARCHIVED_PACKAGES = 4294967296L; // 0x100000000L
field public static final int MATCH_CLONE_PROFILE = 536870912; // 0x20000000
field public static final int MATCH_FACTORY_ONLY = 2097152; // 0x200000
field public static final int MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS = 536870912; // 0x20000000
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 4f8e8dd813a1..014ddd41f8d4 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -3484,9 +3484,20 @@ class ContextImpl extends Context {
// only do this if the user already has more than one preferred locale
if (android.content.res.Flags.defaultLocale()
&& r.getConfiguration().getLocales().size() > 1) {
- LocaleConfig lc = getUserId() < 0
- ? LocaleConfig.fromContextIgnoringOverride(this)
- : new LocaleConfig(this);
+ LocaleConfig lc;
+ if (getUserId() < 0) {
+ lc = LocaleConfig.fromContextIgnoringOverride(this);
+ } else {
+ // This is needed because the app might have locale config overrides that need to
+ // be read from disk in order for resources to correctly choose which values to
+ // load.
+ StrictMode.ThreadPolicy policy = StrictMode.allowThreadDiskReads();
+ try {
+ lc = new LocaleConfig(this);
+ } finally {
+ StrictMode.setThreadPolicy(policy);
+ }
+ }
mResourcesManager.setLocaleConfig(lc);
}
}
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 6009c29ae53c..24a51573b48a 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -159,7 +159,8 @@ public class ResourcesManager {
* Loads {@link ApkAssets} and caches them to prevent their garbage collection while the
* instance is alive and reachable.
*/
- private class ApkAssetsSupplier {
+ @VisibleForTesting
+ protected class ApkAssetsSupplier {
final ArrayMap<ApkKey, ApkAssets> mLocalCache = new ArrayMap<>();
/**
@@ -544,7 +545,10 @@ public class ResourcesManager {
* from an {@link ApkAssetsSupplier} if non-null; otherwise ApkAssets are loaded using
* {@link #loadApkAssets(ApkKey)}.
*/
- private @Nullable AssetManager createAssetManager(@NonNull final ResourcesKey key,
+
+ @VisibleForTesting
+ @UnsupportedAppUsage
+ protected @Nullable AssetManager createAssetManager(@NonNull final ResourcesKey key,
@Nullable ApkAssetsSupplier apkSupplier) {
final AssetManager.Builder builder = new AssetManager.Builder();
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 79a5879b5cc0..9cf732abb86a 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -137,6 +137,8 @@ import android.media.projection.MediaProjectionManager;
import android.media.soundtrigger.SoundTriggerManager;
import android.media.tv.ITvInputManager;
import android.media.tv.TvInputManager;
+import android.media.tv.ad.ITvAdManager;
+import android.media.tv.ad.TvAdManager;
import android.media.tv.interactive.ITvInteractiveAppManager;
import android.media.tv.interactive.TvInteractiveAppManager;
import android.media.tv.tunerresourcemanager.ITunerResourceManager;
@@ -174,6 +176,7 @@ import android.os.IHardwarePropertiesManager;
import android.os.IPowerManager;
import android.os.IPowerStatsService;
import android.os.IRecoverySystem;
+import android.os.ISecurityStateManager;
import android.os.ISystemUpdateManager;
import android.os.IThermalService;
import android.os.IUserManager;
@@ -182,6 +185,7 @@ import android.os.PerformanceHintManager;
import android.os.PermissionEnforcer;
import android.os.PowerManager;
import android.os.RecoverySystem;
+import android.os.SecurityStateManager;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
import android.os.StatsFrameworkInitializer;
@@ -628,6 +632,17 @@ public final class SystemServiceRegistry {
ctx.mMainThread.getHandler());
}});
+ registerService(Context.SECURITY_STATE_SERVICE, SecurityStateManager.class,
+ new CachedServiceFetcher<SecurityStateManager>() {
+ @Override
+ public SecurityStateManager createService(ContextImpl ctx)
+ throws ServiceNotFoundException {
+ IBinder b = ServiceManager.getServiceOrThrow(
+ Context.SECURITY_STATE_SERVICE);
+ ISecurityStateManager service = ISecurityStateManager.Stub.asInterface(b);
+ return new SecurityStateManager(service);
+ }});
+
registerService(Context.SENSOR_SERVICE, SensorManager.class,
new CachedServiceFetcher<SensorManager>() {
@Override
@@ -960,6 +975,18 @@ public final class SystemServiceRegistry {
return new TvInteractiveAppManager(service, ctx.getUserId());
}});
+ registerService(Context.TV_AD_SERVICE, TvAdManager.class,
+ new CachedServiceFetcher<TvAdManager>() {
+ @Override
+ public TvAdManager createService(ContextImpl ctx)
+ throws ServiceNotFoundException {
+ IBinder iBinder =
+ ServiceManager.getServiceOrThrow(Context.TV_AD_SERVICE);
+ ITvAdManager service =
+ ITvAdManager.Stub.asInterface(iBinder);
+ return new TvAdManager(service, ctx.getUserId());
+ }});
+
registerService(Context.TV_INPUT_SERVICE, TvInputManager.class,
new CachedServiceFetcher<TvInputManager>() {
@Override
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
index 6a03c17159d3..ce1d43d10c34 100644
--- a/core/java/android/app/UiAutomationConnection.java
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -180,6 +180,11 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
@Override
public void injectInputEventToInputFilter(InputEvent event) throws RemoteException {
+ synchronized (mLock) {
+ throwIfCalledByNotTrustedUidLocked();
+ throwIfShutdownLocked();
+ throwIfNotConnectedLocked();
+ }
mAccessibilityManager.injectInputEventToInputFilter(event);
}
diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java
index 0ae00cd7d133..9eb73b32a2a7 100644
--- a/core/java/android/app/usage/UsageEvents.java
+++ b/core/java/android/app/usage/UsageEvents.java
@@ -837,6 +837,7 @@ public final class UsageEvents implements Parcelable {
if (mEventCount != mEventsToWrite.size()) {
Log.w(TAG, "Partial usage event list received: " + mEventCount + " != "
+ mEventsToWrite.size());
+ mEventCount = mEventsToWrite.size();
}
}
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 51a7f1ce8c5f..6e451479c5a4 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -558,7 +558,7 @@ public class AppWidgetManager {
}
}).toArray(ComponentName[]::new));
} catch (Exception e) {
- Log.e(TAG, "Nofity service of inheritance info", e);
+ Log.e(TAG, "Notify service of inheritance info", e);
}
});
}
diff --git a/core/java/android/content/AttributionSource.java b/core/java/android/content/AttributionSource.java
index 4b2cee698df2..697c25c2a1ec 100644
--- a/core/java/android/content/AttributionSource.java
+++ b/core/java/android/content/AttributionSource.java
@@ -730,10 +730,7 @@ public final class AttributionSource implements Parcelable {
/**
* The next app to receive the permission protected data.
- *
- * @deprecated Use {@link #setNextAttributionSource} instead.
*/
- @Deprecated
public @NonNull Builder setNext(@Nullable AttributionSource value) {
checkNotUsed();
mBuilderFieldsSet |= 0x20;
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 1c6c7b5baa58..b75c64dcc3c1 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -72,6 +72,7 @@ import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
+import android.os.Flags;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.IBinder;
@@ -4214,6 +4215,7 @@ public abstract class Context {
DEVICE_LOCK_SERVICE,
VIRTUALIZATION_SERVICE,
GRAMMATICAL_INFLECTION_SERVICE,
+ SECURITY_STATE_SERVICE,
})
@Retention(RetentionPolicy.SOURCE)
@@ -5818,6 +5820,17 @@ public abstract class Context {
/**
* Use with {@link #getSystemService(String)} to retrieve a
+ * {@link android.media.tv.ad.TvAdManager} for interacting with TV client-side advertisement
+ * services on the device.
+ *
+ * @see #getSystemService(String)
+ * @see android.media.tv.ad.TvAdManager
+ */
+ @FlaggedApi(android.media.tv.flags.Flags.FLAG_ENABLE_AD_SERVICE_FW)
+ public static final String TV_AD_SERVICE = "tv_ad";
+
+ /**
+ * Use with {@link #getSystemService(String)} to retrieve a
* {@link android.media.tv.TunerResourceManager} for interacting with TV
* tuner resources on the device.
*
@@ -6478,6 +6491,16 @@ public abstract class Context {
public static final String SHARED_CONNECTIVITY_SERVICE = "shared_connectivity";
/**
+ * Use with {@link #getSystemService(String)} to retrieve a
+ * {@link android.os.SecurityStateManager} for accessing the security state manager service.
+ *
+ * @see #getSystemService(String)
+ * @see android.os.SecurityStateManager
+ */
+ @FlaggedApi(Flags.FLAG_SECURITY_STATE_SERVICE)
+ public static final String SECURITY_STATE_SERVICE = "security_state";
+
+ /**
* Determine whether the given permission is allowed for a particular
* process and user ID running in the system.
*
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index c7a86fbe0171..38bcfa220af4 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -5353,11 +5353,11 @@ public class Intent implements Parcelable, Cloneable {
* Broadcast Action: Sent to the responsible installer of an archived package when unarchival
* is requested.
*
- * @see android.content.pm.PackageInstaller#requestUnarchive(String)
- * @hide
+ * @see android.content.pm.PackageInstaller#requestUnarchive
*/
- @SystemApi
@FlaggedApi(android.content.pm.Flags.FLAG_ARCHIVING)
+ @BroadcastBehavior(explicitOnly = true)
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_UNARCHIVE_PACKAGE = "android.intent.action.UNARCHIVE_PACKAGE";
// ---------------------------------------------------------------------
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index 1cfdb8b37fcd..5736a6d8cb4a 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -20,7 +20,6 @@ import android.annotation.CurrentTimeMillisLong;
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
import android.os.Parcel;
@@ -522,9 +521,7 @@ public class PackageInfo implements Parcelable {
/**
* Returns the time at which the app was archived for the user. Units are as
* per {@link System#currentTimeMillis()}.
- * @hide
*/
- @SystemApi
@FlaggedApi(Flags.FLAG_ARCHIVING)
public @CurrentTimeMillisLong long getArchiveTimeMillis() {
return mArchiveTimeMillis;
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 6df1f600c3ef..d35c3922e9b7 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -354,10 +354,7 @@ public class PackageInstaller {
/**
* Extra field for the package name of a package that is requested to be unarchived. Sent as
* part of the {@link android.content.Intent#ACTION_UNARCHIVE_PACKAGE} intent.
- *
- * @hide
*/
- @SystemApi
@FlaggedApi(Flags.FLAG_ARCHIVING)
public static final String EXTRA_UNARCHIVE_PACKAGE_NAME =
"android.content.pm.extra.UNARCHIVE_PACKAGE_NAME";
@@ -366,22 +363,16 @@ public class PackageInstaller {
* Extra field for the unarchive ID. Sent as
* part of the {@link android.content.Intent#ACTION_UNARCHIVE_PACKAGE} intent.
*
- * @see Session#setUnarchiveId(int)
- *
- * @hide
+ * @see SessionParams#setUnarchiveId
*/
- @SystemApi
@FlaggedApi(Flags.FLAG_ARCHIVING)
public static final String EXTRA_UNARCHIVE_ID =
"android.content.pm.extra.UNARCHIVE_ID";
/**
* If true, the requestor of the unarchival has specified that the app should be unarchived
- * for {@link android.os.UserHandle#ALL}.
- *
- * @hide
+ * for all users.
*/
- @SystemApi
@FlaggedApi(Flags.FLAG_ARCHIVING)
public static final String EXTRA_UNARCHIVE_ALL_USERS =
"android.content.pm.extra.UNARCHIVE_ALL_USERS";
@@ -398,9 +389,7 @@ public class PackageInstaller {
* failure dialog.
*
* @see #requestUnarchive
- * @hide
*/
- @SystemApi
@FlaggedApi(Flags.FLAG_ARCHIVING)
public static final String EXTRA_UNARCHIVE_STATUS = "android.content.pm.extra.UNARCHIVE_STATUS";
@@ -675,10 +664,7 @@ public class PackageInstaller {
*
* <p> Note that this does not mean that the unarchival has completed. This status should be
* sent before any longer asynchronous action (e.g. app download) is started.
- *
- * @hide
*/
- @SystemApi
@FlaggedApi(Flags.FLAG_ARCHIVING)
public static final int UNARCHIVAL_OK = 0;
@@ -687,10 +673,7 @@ public class PackageInstaller {
*
* <p> An example use case for this could be that the user needs to login to allow the
* download for a paid app.
- *
- * @hide
*/
- @SystemApi
@FlaggedApi(Flags.FLAG_ARCHIVING)
public static final int UNARCHIVAL_ERROR_USER_ACTION_NEEDED = 1;
@@ -700,19 +683,13 @@ public class PackageInstaller {
* <p> The installer can optionally provide a {@code userActionIntent} for a space-clearing
* dialog. If no action is provided, then a generic intent
* {@link android.os.storage.StorageManager#ACTION_MANAGE_STORAGE} is started instead.
- *
- * @hide
*/
- @SystemApi
@FlaggedApi(Flags.FLAG_ARCHIVING)
public static final int UNARCHIVAL_ERROR_INSUFFICIENT_STORAGE = 2;
/**
* The device is not connected to the internet
- *
- * @hide
*/
- @SystemApi
@FlaggedApi(Flags.FLAG_ARCHIVING)
public static final int UNARCHIVAL_ERROR_NO_CONNECTIVITY = 3;
@@ -720,10 +697,7 @@ public class PackageInstaller {
* The installer responsible for the unarchival is disabled.
*
* <p> Should only be used by the system.
- *
- * @hide
*/
- @SystemApi
@FlaggedApi(Flags.FLAG_ARCHIVING)
public static final int UNARCHIVAL_ERROR_INSTALLER_DISABLED = 4;
@@ -731,19 +705,13 @@ public class PackageInstaller {
* The installer responsible for the unarchival has been uninstalled
*
* <p> Should only be used by the system.
- *
- * @hide
*/
- @SystemApi
@FlaggedApi(Flags.FLAG_ARCHIVING)
public static final int UNARCHIVAL_ERROR_INSTALLER_UNINSTALLED = 5;
/**
* Generic error: The app cannot be unarchived.
- *
- * @hide
*/
- @SystemApi
@FlaggedApi(Flags.FLAG_ARCHIVING)
public static final int UNARCHIVAL_GENERIC_ERROR = 100;
@@ -2364,12 +2332,10 @@ public class PackageInstaller {
* @param statusReceiver Callback used to notify when the operation is completed.
* @throws PackageManager.NameNotFoundException If {@code packageName} isn't found or not
* available to the caller or isn't archived.
- * @hide
*/
@RequiresPermission(anyOf = {
Manifest.permission.DELETE_PACKAGES,
Manifest.permission.REQUEST_DELETE_PACKAGES})
- @SystemApi
@FlaggedApi(Flags.FLAG_ARCHIVING)
public void requestArchive(@NonNull String packageName, @NonNull IntentSender statusReceiver)
throws PackageManager.NameNotFoundException {
@@ -2395,19 +2361,16 @@ public class PackageInstaller {
*
* @param statusReceiver Callback used to notify whether the installer has accepted the
* unarchival request or an error has occurred. The status update will be
- * sent though {@link EXTRA_UNARCHIVE_STATUS}. Only one status will be
+ * sent though {@link #EXTRA_UNARCHIVE_STATUS}. Only one status will be
* sent.
* @throws PackageManager.NameNotFoundException If {@code packageName} isn't found or not
* visible to the caller or if the package has no
* installer on the device anymore to unarchive it.
* @throws IOException If parameters were unsatisfiable, such as lack of disk space.
- *
- * @hide
*/
@RequiresPermission(anyOf = {
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.REQUEST_INSTALL_PACKAGES})
- @SystemApi
@FlaggedApi(Flags.FLAG_ARCHIVING)
public void requestUnarchive(@NonNull String packageName, @NonNull IntentSender statusReceiver)
throws IOException, PackageManager.NameNotFoundException {
@@ -2435,12 +2398,10 @@ public class PackageInstaller {
* @param userActionIntent Optional intent to start a follow up action required to
* facilitate the unarchival flow (e.g. user needs to log in).
* @throws PackageManager.NameNotFoundException if no unarchival with {@code unarchiveId} exists
- * @hide
*/
@RequiresPermission(anyOf = {
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.REQUEST_INSTALL_PACKAGES})
- @SystemApi
@FlaggedApi(Flags.FLAG_ARCHIVING)
public void reportUnarchivalStatus(int unarchiveId, @UnarchivalStatus int status,
long requiredStorageBytes, @Nullable PendingIntent userActionIntent)
@@ -3454,11 +3415,8 @@ public class PackageInstaller {
* <p> The ID should be retrieved from the unarchive intent and passed into the
* session that's being created to unarchive the app in question. Used to link the unarchive
* intent and the install session to disambiguate.
- *
- * @hide
*/
@FlaggedApi(Flags.FLAG_ARCHIVING)
- @SystemApi
public void setUnarchiveId(int unarchiveId) {
this.unarchiveId = unarchiveId;
}
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index c7091ad99199..70e6f9864eb6 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -177,12 +177,10 @@ public class PackageItemInfo {
/**
* Whether the package is currently in an archived state.
*
- * <p>Packages can be archived through {@link PackageArchiver} and do not have any APKs stored
- * on the device, but do keep the data directory.
- * @hide
+ * <p>Packages can be archived through {@link PackageInstaller#requestArchive} and do not have
+ * any APKs stored on the device, but do keep the data directory.
+ *
*/
- // TODO(b/278553670) Unhide and update @links before launch.
- @SystemApi
@FlaggedApi(Flags.FLAG_ARCHIVING)
public boolean isArchived;
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 6775f9b8d84d..a22fe3f1452b 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1263,18 +1263,14 @@ public abstract class PackageManager {
/**
* Flag parameter to also retrieve some information about archived packages.
- * Packages can be archived through
- * {@link PackageInstaller#requestArchive(String, IntentSender)} and do not have any APKs stored
- * on the device, but do keep the data directory.
+ * Packages can be archived through {@link PackageInstaller#requestArchive} and do not have any
+ * APKs stored on the device, but do keep the data directory.
* <p> Note: Archived apps are a subset of apps returned by {@link #MATCH_UNINSTALLED_PACKAGES}.
* <p> Note: this flag may cause less information about currently installed
* applications to be returned.
* <p> Note: use of this flag requires the android.permission.QUERY_ALL_PACKAGES
* permission to see uninstalled packages.
- * @hide
*/
- // TODO(b/278553670) Unhide and update @links before launch.
- @SystemApi
@FlaggedApi(android.content.pm.Flags.FLAG_ARCHIVING)
public static final long MATCH_ARCHIVED_PACKAGES = 1L << 32;
@@ -8969,10 +8965,7 @@ public abstract class PackageManager {
*
* @throws NameNotFoundException if the given package name is not available to the caller.
* @see PackageInstaller#requestArchive(String, IntentSender)
- *
- * @hide
*/
- @SystemApi
@FlaggedApi(android.content.pm.Flags.FLAG_ARCHIVING)
public boolean isAppArchivable(@NonNull String packageName) throws NameNotFoundException {
throw new UnsupportedOperationException("isAppArchivable not implemented");
diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig
index a565f6825e7a..d21b81854584 100644
--- a/core/java/android/content/pm/flags.aconfig
+++ b/core/java/android/content/pm/flags.aconfig
@@ -94,3 +94,10 @@ flag {
description: "Feature flag to read install related information from an APK."
bug: "275658500"
}
+
+flag {
+ name: "use_pia_v2"
+ namespace: "package_manager_service"
+ description: "Feature flag to enable the refactored Package Installer app with updated UI."
+ bug: "182205982"
+}
diff --git a/core/java/android/content/res/flags.aconfig b/core/java/android/content/res/flags.aconfig
index 1b8eb0748737..40592a151fa7 100644
--- a/core/java/android/content/res/flags.aconfig
+++ b/core/java/android/content/res/flags.aconfig
@@ -15,3 +15,12 @@ flag {
description: "Feature flag for passing in an AssetFileDescriptor to create an frro"
bug: "304478666"
}
+
+flag {
+ name: "manifest_flagging"
+ namespace: "resource_manager"
+ description: "Feature flag for flagging manifest entries"
+ bug: "297373084"
+ # This flag is read in PackageParser at boot time, and in aapt2 which is a build tool.
+ is_fixed_read_only: true
+}
diff --git a/core/java/android/hardware/SensorPrivacyManager.java b/core/java/android/hardware/SensorPrivacyManager.java
index d786d9a20189..18c95bfbb297 100644
--- a/core/java/android/hardware/SensorPrivacyManager.java
+++ b/core/java/android/hardware/SensorPrivacyManager.java
@@ -66,6 +66,13 @@ public final class SensorPrivacyManager {
+ ".extra.sensor";
/**
+ * An extra containing the notification id that triggered the intent
+ * @hide
+ */
+ public static final String EXTRA_NOTIFICATION_ID = SensorPrivacyManager.class.getName()
+ + ".extra.notification_id";
+
+ /**
* An extra indicating if all sensors are affected
* @hide
*/
diff --git a/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java b/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java
index d4ce0ebbc528..5cbb0bbadc4c 100644
--- a/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java
@@ -16,8 +16,6 @@
package android.hardware.camera2.params;
-import static com.android.internal.R.string.hardware;
-
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
diff --git a/core/java/android/os/BatteryUsageStats.java b/core/java/android/os/BatteryUsageStats.java
index ed3100251040..eabe13b0c54f 100644
--- a/core/java/android/os/BatteryUsageStats.java
+++ b/core/java/android/os/BatteryUsageStats.java
@@ -123,6 +123,12 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
private static final int STATSD_PULL_ATOM_MAX_BYTES = 45000;
+ private static final int[] UID_USAGE_TIME_PROCESS_STATES = {
+ BatteryConsumer.PROCESS_STATE_FOREGROUND,
+ BatteryConsumer.PROCESS_STATE_BACKGROUND,
+ BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE
+ };
+
private final int mDischargePercentage;
private final double mBatteryCapacityMah;
private final long mStatsStartTimestampMs;
@@ -516,6 +522,22 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
proto.write(
BatteryUsageStatsAtomsProto.UidBatteryConsumer.TIME_IN_BACKGROUND_MILLIS,
bgMs);
+ for (int processState : UID_USAGE_TIME_PROCESS_STATES) {
+ final long timeInStateMillis = consumer.getTimeInProcessStateMs(processState);
+ if (timeInStateMillis <= 0) {
+ continue;
+ }
+ final long timeInStateToken = proto.start(
+ BatteryUsageStatsAtomsProto.UidBatteryConsumer.TIME_IN_STATE);
+ proto.write(
+ BatteryUsageStatsAtomsProto.UidBatteryConsumer.TimeInState.PROCESS_STATE,
+ processState);
+ proto.write(
+ BatteryUsageStatsAtomsProto.UidBatteryConsumer.TimeInState
+ .TIME_IN_STATE_MILLIS,
+ timeInStateMillis);
+ proto.end(timeInStateToken);
+ }
proto.end(token);
if (proto.getRawSize() >= maxRawSize) {
diff --git a/core/java/android/os/ISecurityStateManager.aidl b/core/java/android/os/ISecurityStateManager.aidl
new file mode 100644
index 000000000000..8ae624d0371d
--- /dev/null
+++ b/core/java/android/os/ISecurityStateManager.aidl
@@ -0,0 +1,26 @@
+/* //device/java/android/android/os/ISecurityStateManager.aidl
+**
+** Copyright 2023, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.os;
+
+import android.os.Bundle;
+import android.os.PersistableBundle;
+
+/** @hide */
+interface ISecurityStateManager {
+ Bundle getGlobalSecurityState();
+}
diff --git a/core/java/android/os/Message.java b/core/java/android/os/Message.java
index da647e2b78cb..161951ead77f 100644
--- a/core/java/android/os/Message.java
+++ b/core/java/android/os/Message.java
@@ -16,6 +16,7 @@
package android.os;
+import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
@@ -437,6 +438,7 @@ public final class Message implements Parcelable {
* @see #getData()
* @see #setData(Bundle)
*/
+ @Nullable
public Bundle peekData() {
return data;
}
diff --git a/core/java/android/os/SecurityStateManager.java b/core/java/android/os/SecurityStateManager.java
new file mode 100644
index 000000000000..4fa61e0ca782
--- /dev/null
+++ b/core/java/android/os/SecurityStateManager.java
@@ -0,0 +1,81 @@
+/*
+ * 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.os;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.SystemService;
+import android.content.Context;
+
+/**
+ * SecurityStateManager provides the functionality to query the security status of the system and
+ * platform components. For example, this includes the system and vendor security patch level.
+ */
+@FlaggedApi(Flags.FLAG_SECURITY_STATE_SERVICE)
+@SystemService(Context.SECURITY_STATE_SERVICE)
+public class SecurityStateManager {
+
+ /**
+ * The system SPL key returned as part of the {@code Bundle} from
+ * {@code getGlobalSecurityState}.
+ */
+ public static final String KEY_SYSTEM_SPL = "system_spl";
+
+ /**
+ * The vendor SPL key returned as part of the {@code Bundle} from
+ * {@code getGlobalSecurityState}.
+ */
+ public static final String KEY_VENDOR_SPL = "vendor_spl";
+
+ /**
+ * The kernel version key returned as part of the {@code Bundle} from
+ * {@code getGlobalSecurityState}.
+ */
+ public static final String KEY_KERNEL_VERSION = "kernel_version";
+
+ private final ISecurityStateManager mService;
+
+ /**
+ * @hide
+ */
+ public SecurityStateManager(ISecurityStateManager service) {
+ mService = requireNonNull(service, "missing ISecurityStateManager");
+ }
+
+ /**
+ * Returns the current global security state. Each key-value pair is a mapping of a component
+ * of the global security state to its current version/SPL (security patch level). For example,
+ * the {@code KEY_SYSTEM_SPL} key will map to the SPL of the system as defined in
+ * {@link android.os.Build.VERSION}. The bundle will also include mappings from WebView packages
+ * and packages listed under config {@code config_securityStatePackages} to their respective
+ * versions as defined in {@link android.content.pm.PackageInfo#versionName}.
+ *
+ * @return A {@code Bundle} that contains the global security state information as
+ * string-to-string key-value pairs.
+ */
+ @FlaggedApi(Flags.FLAG_SECURITY_STATE_SERVICE)
+ @NonNull
+ public Bundle getGlobalSecurityState() {
+ try {
+ return mService.getGlobalSecurityState();
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+}
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index a78f221fc962..c085f334457a 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -57,6 +57,13 @@ flag {
}
flag {
+ name: "security_state_service"
+ namespace: "dynamic_spl"
+ description: "Guards the Security State API."
+ bug: "302189431"
+}
+
+flag {
name: "battery_saver_supported_check_api"
namespace: "backstage_power"
description: "Guards a new API in PowerManager to check if battery saver is supported or not."
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 6853892348d9..78a12f75a508 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -1738,23 +1738,6 @@ public class StorageManager {
return RoSystemProperties.CRYPTO_FILE_ENCRYPTED;
}
- /** {@hide}
- * @deprecated Use {@link #isFileEncrypted} instead, since emulated FBE is no longer supported.
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- @Deprecated
- public static boolean isFileEncryptedNativeOnly() {
- return isFileEncrypted();
- }
-
- /** {@hide}
- * @deprecated Use {@link #isFileEncrypted} instead, since emulated FBE is no longer supported.
- */
- @Deprecated
- public static boolean isFileEncryptedNativeOrEmulated() {
- return isFileEncrypted();
- }
-
/** {@hide} */
public static boolean hasAdoptable() {
switch (SystemProperties.get(PROP_ADOPTABLE)) {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ff6ec29bb8ac..8f18c5f58c7e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -14975,6 +14975,38 @@ public final class Settings {
public static final String APP_OPS_CONSTANTS = "app_ops_constants";
/**
+ * Device Idle (Doze) specific settings.
+ * This is encoded as a key=value list, separated by commas. Ex:
+ *
+ * "inactive_to=60000,sensing_to=400000"
+ *
+ * The following keys are supported:
+ *
+ * <pre>
+ * inactive_to (long)
+ * sensing_to (long)
+ * motion_inactive_to (long)
+ * idle_after_inactive_to (long)
+ * idle_pending_to (long)
+ * max_idle_pending_to (long)
+ * idle_pending_factor (float)
+ * quick_doze_delay_to (long)
+ * idle_to (long)
+ * max_idle_to (long)
+ * idle_factor (float)
+ * min_time_to_alarm (long)
+ * max_temp_app_whitelist_duration (long)
+ * notification_whitelist_duration (long)
+ * </pre>
+ *
+ * <p>
+ * Type: string
+ * @hide
+ * @see com.android.server.DeviceIdleController.Constants
+ */
+ public static final String DEVICE_IDLE_CONSTANTS = "device_idle_constants";
+
+ /**
* Battery Saver specific settings
* This is encoded as a key=value list, separated by commas. Ex:
*
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 7a6c2929c706..cac5387116a1 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -991,7 +991,7 @@ public final class ViewRootImpl implements ViewParent,
// for idleness handling.
private boolean mHasIdledMessage = false;
// time for touch boost period.
- private static final int FRAME_RATE_TOUCH_BOOST_TIME = 1500;
+ private static final int FRAME_RATE_TOUCH_BOOST_TIME = 3000;
// time for checking idle status periodically.
private static final int FRAME_RATE_IDLENESS_CHECK_TIME_MILLIS = 500;
// time for revaluating the idle status before lowering the frame rate.
diff --git a/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl b/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl
index a11c6d0ce956..a404bd6f8c97 100644
--- a/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl
+++ b/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl
@@ -54,7 +54,7 @@ oneway interface IWindowMagnificationConnection {
* @param displayId the logical display id.
* @param scale magnification scale.
*/
- void setScale(int displayId, float scale);
+ void setScaleForWindowMagnification(int displayId, float scale);
/**
* Disables window magnification on specified display with animation.
diff --git a/core/java/android/webkit/IWebViewUpdateService.aidl b/core/java/android/webkit/IWebViewUpdateService.aidl
index e17773159ec5..c6bd20cec07d 100644
--- a/core/java/android/webkit/IWebViewUpdateService.aidl
+++ b/core/java/android/webkit/IWebViewUpdateService.aidl
@@ -79,4 +79,9 @@ interface IWebViewUpdateService {
* Used by Settings to enable/disable multiprocess.
*/
void enableMultiProcess(boolean enable);
+
+ /**
+ * Used by Settings to get the default WebView package.
+ */
+ WebViewProviderInfo getDefaultWebViewPackage();
}
diff --git a/core/java/android/window/TaskFragmentOperation.java b/core/java/android/window/TaskFragmentOperation.java
index 4e0f9a51c0a0..0ec9ffe6390b 100644
--- a/core/java/android/window/TaskFragmentOperation.java
+++ b/core/java/android/window/TaskFragmentOperation.java
@@ -108,6 +108,18 @@ public final class TaskFragmentOperation implements Parcelable {
*/
public static final int OP_TYPE_REORDER_TO_TOP_OF_TASK = 13;
+ /**
+ * Creates a decor surface in the parent Task of the TaskFragment. The created decor surface
+ * will be provided in {@link TaskFragmentTransaction#TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED}
+ * event callback.
+ */
+ public static final int OP_TYPE_CREATE_TASK_FRAGMENT_DECOR_SURFACE = 14;
+
+ /**
+ * Removes the decor surface in the parent Task of the TaskFragment.
+ */
+ public static final int OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE = 15;
+
@IntDef(prefix = { "OP_TYPE_" }, value = {
OP_TYPE_UNKNOWN,
OP_TYPE_CREATE_TASK_FRAGMENT,
@@ -124,6 +136,8 @@ public final class TaskFragmentOperation implements Parcelable {
OP_TYPE_SET_ISOLATED_NAVIGATION,
OP_TYPE_REORDER_TO_BOTTOM_OF_TASK,
OP_TYPE_REORDER_TO_TOP_OF_TASK,
+ OP_TYPE_CREATE_TASK_FRAGMENT_DECOR_SURFACE,
+ OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface OperationType {}
diff --git a/core/java/android/window/TaskFragmentParentInfo.java b/core/java/android/window/TaskFragmentParentInfo.java
index e6eeca4b4801..a77c23475c60 100644
--- a/core/java/android/window/TaskFragmentParentInfo.java
+++ b/core/java/android/window/TaskFragmentParentInfo.java
@@ -22,6 +22,9 @@ import android.app.WindowConfiguration;
import android.content.res.Configuration;
import android.os.Parcel;
import android.os.Parcelable;
+import android.view.SurfaceControl;
+
+import java.util.Objects;
/**
* The information about the parent Task of a particular TaskFragment
@@ -37,12 +40,15 @@ public class TaskFragmentParentInfo implements Parcelable {
private final boolean mHasDirectActivity;
+ @Nullable private final SurfaceControl mDecorSurface;
+
public TaskFragmentParentInfo(@NonNull Configuration configuration, int displayId,
- boolean visible, boolean hasDirectActivity) {
+ boolean visible, boolean hasDirectActivity, @Nullable SurfaceControl decorSurface) {
mConfiguration.setTo(configuration);
mDisplayId = displayId;
mVisible = visible;
mHasDirectActivity = hasDirectActivity;
+ mDecorSurface = decorSurface;
}
public TaskFragmentParentInfo(@NonNull TaskFragmentParentInfo info) {
@@ -50,6 +56,7 @@ public class TaskFragmentParentInfo implements Parcelable {
mDisplayId = info.mDisplayId;
mVisible = info.mVisible;
mHasDirectActivity = info.mHasDirectActivity;
+ mDecorSurface = info.mDecorSurface;
}
/** The {@link Configuration} of the parent Task */
@@ -92,7 +99,13 @@ public class TaskFragmentParentInfo implements Parcelable {
return false;
}
return getWindowingMode() == that.getWindowingMode() && mDisplayId == that.mDisplayId
- && mVisible == that.mVisible && mHasDirectActivity == that.mHasDirectActivity;
+ && mVisible == that.mVisible && mHasDirectActivity == that.mHasDirectActivity
+ && mDecorSurface == that.mDecorSurface;
+ }
+
+ @Nullable
+ public SurfaceControl getDecorSurface() {
+ return mDecorSurface;
}
@WindowConfiguration.WindowingMode
@@ -107,6 +120,7 @@ public class TaskFragmentParentInfo implements Parcelable {
+ ", displayId=" + mDisplayId
+ ", visible=" + mVisible
+ ", hasDirectActivity=" + mHasDirectActivity
+ + ", decorSurface=" + mDecorSurface
+ "}";
}
@@ -128,7 +142,8 @@ public class TaskFragmentParentInfo implements Parcelable {
return mConfiguration.equals(that.mConfiguration)
&& mDisplayId == that.mDisplayId
&& mVisible == that.mVisible
- && mHasDirectActivity == that.mHasDirectActivity;
+ && mHasDirectActivity == that.mHasDirectActivity
+ && mDecorSurface == that.mDecorSurface;
}
@Override
@@ -137,6 +152,7 @@ public class TaskFragmentParentInfo implements Parcelable {
result = 31 * result + mDisplayId;
result = 31 * result + (mVisible ? 1 : 0);
result = 31 * result + (mHasDirectActivity ? 1 : 0);
+ result = 31 * result + Objects.hashCode(mDecorSurface);
return result;
}
@@ -146,6 +162,7 @@ public class TaskFragmentParentInfo implements Parcelable {
dest.writeInt(mDisplayId);
dest.writeBoolean(mVisible);
dest.writeBoolean(mHasDirectActivity);
+ dest.writeTypedObject(mDecorSurface, flags);
}
private TaskFragmentParentInfo(Parcel in) {
@@ -153,6 +170,7 @@ public class TaskFragmentParentInfo implements Parcelable {
mDisplayId = in.readInt();
mVisible = in.readBoolean();
mHasDirectActivity = in.readBoolean();
+ mDecorSurface = in.readTypedObject(SurfaceControl.CREATOR);
}
public static final Creator<TaskFragmentParentInfo> CREATOR =
diff --git a/core/java/com/android/internal/display/RefreshRateSettingsUtils.java b/core/java/com/android/internal/display/RefreshRateSettingsUtils.java
index f5fe12eb66c0..e55c64199f45 100644
--- a/core/java/com/android/internal/display/RefreshRateSettingsUtils.java
+++ b/core/java/com/android/internal/display/RefreshRateSettingsUtils.java
@@ -37,22 +37,11 @@ public class RefreshRateSettingsUtils {
* @return The highest refresh rate
*/
public static float findHighestRefreshRateForDefaultDisplay(Context context) {
- return findHighestRefreshRate(context, Display.DEFAULT_DISPLAY);
- }
-
- /**
- * Find the highest refresh rate among all the modes of the specified display.
- *
- * @param context The context
- * @param displayId The display ID
- * @return The highest refresh rate
- */
- public static float findHighestRefreshRate(Context context, int displayId) {
final DisplayManager dm = context.getSystemService(DisplayManager.class);
- final Display display = dm.getDisplay(displayId);
+ final Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
if (display == null) {
- Log.w(TAG, "No valid display device with ID = " + displayId);
+ Log.w(TAG, "No valid default display device");
return DEFAULT_REFRESH_RATE;
}
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 8bbc80907ad6..1d4e01a95591 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4993,6 +4993,11 @@
<!-- Component name for the default module metadata provider on this device -->
<string name="config_defaultModuleMetadataProvider" translatable="false">com.android.modulemetadata</string>
+ <!-- Packages that contain a security state.
+ {@link SecurityStateManager#getGlobalSecurityState} will read and report the state/version
+ of these packages. -->
+ <string-array name="config_securityStatePackages" translatable="false" />
+
<!-- Package name for the default Health Connect app.
OEMs can set this with their own health app package name to define a default app with high
priority for the app to store the health data. If set the app always has priority of 1
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3d43004db98f..4b0fa4ba5173 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1274,6 +1274,7 @@
<java-symbol type="array" name="policy_exempt_apps" />
<java-symbol type="array" name="vendor_policy_exempt_apps" />
<java-symbol type="array" name="cloneable_apps" />
+ <java-symbol type="array" name="config_securityStatePackages" />
<java-symbol type="drawable" name="default_wallpaper" />
<java-symbol type="drawable" name="default_lock_wallpaper" />
diff --git a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java
index aaaa3c7740c5..ac1f7d0e345f 100644
--- a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java
+++ b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java
@@ -48,6 +48,11 @@ public class BatteryUsageStatsPulledTest {
private static final int UID_1 = 2000;
private static final int UID_2 = 3000;
private static final int UID_3 = 4000;
+ private static final int[] UID_USAGE_TIME_PROCESS_STATES = {
+ BatteryConsumer.PROCESS_STATE_FOREGROUND,
+ BatteryConsumer.PROCESS_STATE_BACKGROUND,
+ BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE
+ };
@Test
public void testGetStatsProto() {
@@ -195,6 +200,20 @@ public class BatteryUsageStatsPulledTest {
assertEquals("For uid " + uid,
uidConsumer.getTimeInStateMs(android.os.UidBatteryConsumer.STATE_BACKGROUND),
uidConsumerProto.timeInBackgroundMillis);
+ for (int processState : UID_USAGE_TIME_PROCESS_STATES) {
+ final long timeInStateMillis = uidConsumer.getTimeInProcessStateMs(processState);
+ if (timeInStateMillis <= 0) {
+ continue;
+ }
+ assertEquals("For uid " + uid + ", process state " + processState,
+ timeInStateMillis,
+ Arrays.stream(uidConsumerProto.timeInState)
+ .filter(timeInState -> timeInState.processState == processState)
+ .findFirst()
+ .orElseThrow()
+ .timeInStateMillis);
+ }
+
if (expectNullBatteryConsumerData) {
assertNull("For uid " + uid, uidConsumerProto.batteryConsumerData);
} else {
@@ -250,8 +269,8 @@ public class BatteryUsageStatsPulledTest {
final UidBatteryConsumer.Builder uidBuilder = builder
.getOrCreateUidBatteryConsumerBuilder(UID_0)
.setPackageWithHighestDrain("myPackage0")
- .setTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND, 1000)
- .setTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND, 2000)
+ .setTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_FOREGROUND, 1000)
+ .setTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_BACKGROUND, 2000)
.setConsumedPower(
BatteryConsumer.POWER_COMPONENT_SCREEN, 300)
.setConsumedPower(
@@ -285,7 +304,7 @@ public class BatteryUsageStatsPulledTest {
builder.getOrCreateUidBatteryConsumerBuilder(UID_1)
.setPackageWithHighestDrain("myPackage1")
- .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_FOREGROUND, 1234);
+ .setTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_FOREGROUND, 1234);
builder.getOrCreateUidBatteryConsumerBuilder(UID_2)
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN,
@@ -331,8 +350,10 @@ public class BatteryUsageStatsPulledTest {
// significantly larger than 50 Kb
for (int i = 0; i < 3000; i++) {
builder.getOrCreateUidBatteryConsumerBuilder(i)
- .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_FOREGROUND, 1 * 60 * 1000)
- .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_BACKGROUND, 2 * 60 * 1000)
+ .setTimeInProcessStateMs(
+ BatteryConsumer.PROCESS_STATE_FOREGROUND, 1 * 60 * 1000)
+ .setTimeInProcessStateMs(
+ BatteryConsumer.PROCESS_STATE_BACKGROUND, 2 * 60 * 1000)
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, 30)
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU, 40);
}
@@ -340,16 +361,16 @@ public class BatteryUsageStatsPulledTest {
// Add a UID with much larger battery footprint
final int largeConsumerUid = 3001;
builder.getOrCreateUidBatteryConsumerBuilder(largeConsumerUid)
- .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_FOREGROUND, 10 * 60 * 1000)
- .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_BACKGROUND, 20 * 60 * 1000)
+ .setTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_FOREGROUND, 10 * 60 * 1000)
+ .setTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_BACKGROUND, 20 * 60 * 1000)
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, 300)
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU, 400);
// Add a UID with much larger usage duration
final int highUsageUid = 3002;
builder.getOrCreateUidBatteryConsumerBuilder(highUsageUid)
- .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_FOREGROUND, 60 * 60 * 1000)
- .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_BACKGROUND, 120 * 60 * 1000)
+ .setTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_FOREGROUND, 60 * 60 * 1000)
+ .setTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_BACKGROUND, 120 * 60 * 1000)
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, 3)
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU, 4);
diff --git a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
index 87c167c0df07..4a9cb7180a3f 100644
--- a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
+++ b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
@@ -83,6 +83,12 @@ public class ResourcesManagerTest extends TestCase {
}
@Override
+ protected AssetManager createAssetManager(@NonNull final ResourcesKey key,
+ ResourcesManager.ApkAssetsSupplier apkSupplier) {
+ return createAssetManager(key);
+ }
+
+ @Override
protected DisplayMetrics getDisplayMetrics(int displayId, DisplayAdjustments daj) {
return mDisplayMetricsMap.get(displayId);
}
@@ -100,7 +106,7 @@ public class ResourcesManagerTest extends TestCase {
null, APP_ONE_RES_DIR, null, null, null, null, null, null,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(newResources);
- assertSame(resources, newResources);
+ assertSame(resources.getImpl(), newResources.getImpl());
}
@SmallTest
diff --git a/keystore/java/android/security/KeyStore2.java b/keystore/java/android/security/KeyStore2.java
index 5e16bcee1a0e..dd703f5eefb9 100644
--- a/keystore/java/android/security/KeyStore2.java
+++ b/keystore/java/android/security/KeyStore2.java
@@ -33,7 +33,6 @@ import android.system.keystore2.ResponseCode;
import android.util.Log;
import java.util.Calendar;
-import java.util.Objects;
/**
* @hide This should not be made public in its present form because it
@@ -139,13 +138,25 @@ public class KeyStore2 {
return new KeyStore2();
}
+ /**
+ * Gets the {@link IKeystoreService} that should be started in early_hal in Android.
+ *
+ * @throws IllegalStateException if the KeystoreService is not available or has not
+ * been initialized when called. This is a state that should not happen and indicates
+ * and error somewhere in the stack or with the calling processes access permissions.
+ */
@NonNull private synchronized IKeystoreService getService(boolean retryLookup) {
if (mBinder == null || retryLookup) {
mBinder = IKeystoreService.Stub.asInterface(ServiceManager
- .getService(KEYSTORE2_SERVICE_NAME));
- Binder.allowBlocking(mBinder.asBinder());
+ .getService(KEYSTORE2_SERVICE_NAME));
+ }
+ if (mBinder == null) {
+ throw new IllegalStateException(
+ "Could not connect to Keystore service. Keystore may have crashed or not been"
+ + " initialized");
}
- return Objects.requireNonNull(mBinder);
+ Binder.allowBlocking(mBinder.asBinder());
+ return mBinder;
}
void delete(KeyDescriptor descriptor) throws KeyStoreException {
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
index 50cfd941adb3..4c2433fab2f8 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
@@ -443,7 +443,8 @@ public class OverlayPresentationTest {
assertThat(taskContainer.getTaskFragmentContainers()).containsExactly(overlayContainer);
taskContainer.updateTaskFragmentParentInfo(new TaskFragmentParentInfo(Configuration.EMPTY,
- DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */));
+ DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */,
+ null /* decorSurface */));
mSplitController.updateOverlayContainer(mTransaction, overlayContainer);
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
index 02031a67e7e3..8c274a26177d 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
@@ -1139,7 +1139,8 @@ public class SplitControllerTest {
public void testOnTransactionReady_taskFragmentParentInfoChanged() {
final TaskFragmentTransaction transaction = new TaskFragmentTransaction();
final TaskFragmentParentInfo parentInfo = new TaskFragmentParentInfo(Configuration.EMPTY,
- DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */);
+ DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */,
+ null /* decorSurface */);
transaction.addChange(new TaskFragmentTransaction.Change(
TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED)
.setTaskId(TASK_ID)
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java
index e56c8ab686e7..7b77235f66f7 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java
@@ -79,14 +79,16 @@ public class TaskContainerTest {
configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
taskContainer.updateTaskFragmentParentInfo(new TaskFragmentParentInfo(configuration,
- DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */));
+ DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */,
+ null /* decorSurface */));
assertEquals(WINDOWING_MODE_MULTI_WINDOW,
taskContainer.getWindowingModeForSplitTaskFragment(splitBounds));
configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
taskContainer.updateTaskFragmentParentInfo(new TaskFragmentParentInfo(configuration,
- DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */));
+ DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */,
+ null /* decorSurface */));
assertEquals(WINDOWING_MODE_FREEFORM,
taskContainer.getWindowingModeForSplitTaskFragment(splitBounds));
@@ -106,13 +108,15 @@ public class TaskContainerTest {
configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
taskContainer.updateTaskFragmentParentInfo(new TaskFragmentParentInfo(configuration,
- DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */));
+ DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */,
+ null /* decorSurface */));
assertFalse(taskContainer.isInPictureInPicture());
configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_PINNED);
taskContainer.updateTaskFragmentParentInfo(new TaskFragmentParentInfo(configuration,
- DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */));
+ DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */,
+ null /* decorSurface */));
assertTrue(taskContainer.isInPictureInPicture());
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index f5b877a70b84..a3eb429b1d7e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -412,6 +412,23 @@ public class BubbleExpandedView extends LinearLayout {
setLayoutDirection(LAYOUT_DIRECTION_LOCALE);
}
+
+ /** Updates the width of the task view if it changed. */
+ void updateTaskViewContentWidth() {
+ if (mTaskView != null) {
+ int width = getContentWidth();
+ if (mTaskView.getWidth() != width) {
+ FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(width, MATCH_PARENT);
+ mTaskView.setLayoutParams(lp);
+ }
+ }
+ }
+
+ private int getContentWidth() {
+ boolean isStackOnLeft = mPositioner.isStackOnLeft(mStackView.getStackPosition());
+ return mPositioner.getTaskViewContentWidth(isStackOnLeft);
+ }
+
/**
* Initialize {@link BubbleController} and {@link BubbleStackView} here, this method must need
* to be called after view inflate.
@@ -438,7 +455,12 @@ public class BubbleExpandedView extends LinearLayout {
mController.getTaskViewTransitions(), mController.getSyncTransactionQueue());
mTaskView = new TaskView(mContext, mTaskViewTaskController);
mTaskView.setListener(mController.getMainExecutor(), mTaskViewListener);
- mExpandedViewContainer.addView(mTaskView);
+
+ // set a fixed width so it is not recalculated as part of a rotation. the width will be
+ // updated manually after the rotation.
+ FrameLayout.LayoutParams lp =
+ new FrameLayout.LayoutParams(getContentWidth(), MATCH_PARENT);
+ mExpandedViewContainer.addView(mTaskView, lp);
bringChildToFront(mTaskView);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
index 1efd9df3a1d9..baa52a0b5626 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
@@ -375,6 +375,13 @@ public class BubblePositioner {
}
}
+ /** Returns the width of the task view content. */
+ public int getTaskViewContentWidth(boolean onLeft) {
+ int[] paddings = getExpandedViewContainerPadding(onLeft, /* isOverflow = */ false);
+ int pointerOffset = showBubblesVertically() ? getPointerSize() : 0;
+ return mPositionRect.width() - paddings[0] - paddings[2] - pointerOffset;
+ }
+
/** Gets the y position of the expanded view if it was top-aligned. */
public float getExpandedViewYTopAligned() {
final int top = getAvailableRect().top;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 8f904c42d247..91a8ce726c42 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -537,8 +537,8 @@ public class BubbleStackView extends FrameLayout
return;
}
- final boolean clickedBubbleIsCurrentlyExpandedBubble =
- clickedBubble.getKey().equals(mExpandedBubble.getKey());
+ final boolean clickedBubbleIsCurrentlyExpandedBubble = mExpandedBubble != null
+ && clickedBubble.getKey().equals(mExpandedBubble.getKey());
if (isExpanded()) {
mExpandedAnimationController.onGestureFinished();
@@ -3288,6 +3288,7 @@ public class BubbleStackView extends FrameLayout
mExpandedViewContainer.setTranslationY(mPositioner.getExpandedViewY(mExpandedBubble,
mPositioner.showBubblesVertically() ? p.y : p.x));
mExpandedViewContainer.setTranslationX(0f);
+ mExpandedBubble.getExpandedView().updateTaskViewContentWidth();
mExpandedBubble.getExpandedView().updateView(
mExpandedViewContainer.getLocationOnScreen());
updatePointerPosition(false /* forIme */);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index 271a3b26305d..63afd3e7a2ca 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -627,7 +627,8 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
&& mRecentsTask.equals(change.getContainer());
hasTaskChange = hasTaskChange || isRootTask;
final boolean isLeafTask = leafTaskFilter.test(change);
- if (TransitionUtil.isOpeningType(change.getMode())) {
+ if (TransitionUtil.isOpeningType(change.getMode())
+ || TransitionUtil.isOrderOnly(change)) {
if (isRecentsTask) {
recentsOpening = change;
} else if (isRootTask || isLeafTask) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
index 8cbcde320795..53ec20192f2b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
@@ -49,7 +49,6 @@ import android.view.View;
import android.view.ViewConfiguration;
import android.view.WindowManagerGlobal;
-import com.android.internal.view.BaseIWindow;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayLayout;
@@ -70,7 +69,9 @@ class DragResizeInputListener implements AutoCloseable {
private final Supplier<SurfaceControl.Transaction> mSurfaceControlTransactionSupplier;
private final int mDisplayId;
- private final BaseIWindow mFakeWindow;
+
+ private final IBinder mClientToken;
+
private final IBinder mFocusGrantToken;
private final SurfaceControl mDecorationSurface;
private final InputChannel mInputChannel;
@@ -78,7 +79,7 @@ class DragResizeInputListener implements AutoCloseable {
private final DragPositioningCallback mCallback;
private final SurfaceControl mInputSinkSurface;
- private final BaseIWindow mFakeSinkWindow;
+ private final IBinder mSinkClientToken;
private final InputChannel mSinkInputChannel;
private final DisplayController mDisplayController;
@@ -116,17 +117,14 @@ class DragResizeInputListener implements AutoCloseable {
mTaskCornerRadius = taskCornerRadius;
mDecorationSurface = decorationSurface;
mDisplayController = displayController;
- // Use a fake window as the backing surface is a container layer, and we don't want to
- // create a buffer layer for it, so we can't use ViewRootImpl.
- mFakeWindow = new BaseIWindow();
- mFakeWindow.setSession(mWindowSession);
+ mClientToken = new Binder();
mFocusGrantToken = new Binder();
mInputChannel = new InputChannel();
try {
mWindowSession.grantInputChannel(
mDisplayId,
mDecorationSurface,
- mFakeWindow.asBinder(),
+ mClientToken,
null /* hostInputToken */,
FLAG_NOT_FOCUSABLE,
PRIVATE_FLAG_TRUSTED_OVERLAY,
@@ -155,13 +153,13 @@ class DragResizeInputListener implements AutoCloseable {
.setLayer(mInputSinkSurface, WindowDecoration.INPUT_SINK_Z_ORDER)
.show(mInputSinkSurface)
.apply();
- mFakeSinkWindow = new BaseIWindow();
+ mSinkClientToken = new Binder();
mSinkInputChannel = new InputChannel();
try {
mWindowSession.grantInputChannel(
mDisplayId,
mInputSinkSurface,
- mFakeSinkWindow.asBinder(),
+ mSinkClientToken,
null /* hostInputToken */,
FLAG_NOT_FOCUSABLE,
0 /* privateFlags */,
@@ -324,14 +322,14 @@ class DragResizeInputListener implements AutoCloseable {
mInputEventReceiver.dispose();
mInputChannel.dispose();
try {
- mWindowSession.remove(mFakeWindow.asBinder());
+ mWindowSession.remove(mClientToken);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
mSinkInputChannel.dispose();
try {
- mWindowSession.remove(mFakeSinkWindow.asBinder());
+ mWindowSession.remove(mSinkClientToken);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/csuiteDefaultTemplate.xml b/libs/WindowManager/Shell/tests/flicker/pip/csuiteDefaultTemplate.xml
index 6429b00a2a58..fafd37bba14b 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/csuiteDefaultTemplate.xml
+++ b/libs/WindowManager/Shell/tests/flicker/pip/csuiteDefaultTemplate.xml
@@ -45,12 +45,15 @@
<option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
<option name="run-command" value="settings put system show_touches 1"/>
<option name="run-command" value="settings put system pointer_location 1"/>
+ <option name="run-command" value="settings put global package_verifier_user_consent -1"/>
<option name="teardown-command"
value="settings delete secure show_ime_with_hard_keyboard"/>
<option name="teardown-command" value="settings delete system show_touches"/>
<option name="teardown-command" value="settings delete system pointer_location"/>
<option name="teardown-command"
value="cmd overlay enable com.android.internal.systemui.navbar.gestural"/>
+ <option name="teardown-command"
+ value="settings put global package_verifier_user_consent 1"/>
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true"/>
@@ -76,6 +79,8 @@
value="appops set com.android.shell android:mock_location deny"/>
</target_preparer>
+ <target_preparer class="com.android.csuite.core.AppCrawlTesterHostPreparer"/>
+
<!-- Use app crawler to log into Netflix -->
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="run-command"
diff --git a/location/api/system-current.txt b/location/api/system-current.txt
index a1d6ab5798e1..b1cf96d41497 100644
--- a/location/api/system-current.txt
+++ b/location/api/system-current.txt
@@ -113,13 +113,13 @@ package android.location {
}
public final class GnssMeasurementRequest implements android.os.Parcelable {
- method @NonNull public android.os.WorkSource getWorkSource();
+ method @FlaggedApi(Flags.FLAG_GNSS_API_MEASUREMENT_REQUEST_WORK_SOURCE) @NonNull public android.os.WorkSource getWorkSource();
method public boolean isCorrelationVectorOutputsEnabled();
}
public static final class GnssMeasurementRequest.Builder {
method @NonNull public android.location.GnssMeasurementRequest.Builder setCorrelationVectorOutputsEnabled(boolean);
- method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public android.location.GnssMeasurementRequest.Builder setWorkSource(@Nullable android.os.WorkSource);
+ method @FlaggedApi(Flags.FLAG_GNSS_API_MEASUREMENT_REQUEST_WORK_SOURCE) @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public android.location.GnssMeasurementRequest.Builder setWorkSource(@Nullable android.os.WorkSource);
}
public final class GnssReflectingPlane implements android.os.Parcelable {
diff --git a/location/java/android/location/GnssMeasurementRequest.java b/location/java/android/location/GnssMeasurementRequest.java
index 65af3928bd02..2f0835ab8af5 100644
--- a/location/java/android/location/GnssMeasurementRequest.java
+++ b/location/java/android/location/GnssMeasurementRequest.java
@@ -17,11 +17,13 @@
package android.location;
import android.Manifest;
+import android.annotation.FlaggedApi;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
+import android.location.flags.Flags;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.WorkSource;
@@ -121,6 +123,7 @@ public final class GnssMeasurementRequest implements Parcelable {
*
* @hide
*/
+ @FlaggedApi(Flags.FLAG_GNSS_API_MEASUREMENT_REQUEST_WORK_SOURCE)
@SystemApi
public @NonNull WorkSource getWorkSource() {
return mWorkSource;
@@ -298,6 +301,7 @@ public final class GnssMeasurementRequest implements Parcelable {
*
* @hide
*/
+ @FlaggedApi(Flags.FLAG_GNSS_API_MEASUREMENT_REQUEST_WORK_SOURCE)
@SystemApi
@RequiresPermission(Manifest.permission.UPDATE_DEVICE_STATS)
public @NonNull Builder setWorkSource(@Nullable WorkSource workSource) {
diff --git a/location/java/android/location/flags/gnss.aconfig b/location/java/android/location/flags/gnss.aconfig
index c471a2749617..b6055e818f8c 100644
--- a/location/java/android/location/flags/gnss.aconfig
+++ b/location/java/android/location/flags/gnss.aconfig
@@ -5,4 +5,18 @@ flag {
namespace: "location"
description: "Flag for GNSS API for NavIC L1"
bug: "302199306"
-} \ No newline at end of file
+}
+
+flag {
+ name: "gnss_call_stop_before_set_position_mode"
+ namespace: "location"
+ description: "Flag for calling stop() before setPositionMode()"
+ bug: "306874828"
+}
+
+flag {
+ name: "gnss_api_measurement_request_work_source"
+ namespace: "location"
+ description: "Flag for GnssMeasurementRequest WorkSource API"
+ bug: "295235160"
+}
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index d14775fa9ad9..5c8758a6aa73 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -739,7 +739,7 @@ interface IAudioService {
oneway void stopLoudnessCodecUpdates(int piid);
- oneway void addLoudnessCodecInfo(int piid, in LoudnessCodecInfo codecInfo);
+ oneway void addLoudnessCodecInfo(int piid, int mediaCodecHash, in LoudnessCodecInfo codecInfo);
oneway void removeLoudnessCodecInfo(int piid, in LoudnessCodecInfo codecInfo);
diff --git a/media/java/android/media/LoudnessCodecConfigurator.java b/media/java/android/media/LoudnessCodecConfigurator.java
index 92f337244daf..de9d87c0b28c 100644
--- a/media/java/android/media/LoudnessCodecConfigurator.java
+++ b/media/java/android/media/LoudnessCodecConfigurator.java
@@ -30,10 +30,10 @@ import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Executor;
@@ -47,9 +47,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
* parameter updates are defined by the CTA-2075 standard.
* <p>A new object should be instantiated for each {@link AudioTrack} with the help
* of {@link #create()} or {@link #create(Executor, OnLoudnessCodecUpdateListener)}.
- *
- * TODO: remove hide once API is final
- * @hide
*/
@FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
public class LoudnessCodecConfigurator {
@@ -57,9 +54,6 @@ public class LoudnessCodecConfigurator {
/**
* Listener used for receiving asynchronous loudness metadata updates.
- *
- * TODO: remove hide once API is final
- * @hide
*/
@FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
public interface OnLoudnessCodecUpdateListener {
@@ -76,9 +70,6 @@ public class LoudnessCodecConfigurator {
* @return a Bundle which contains the original computed codecValues
* aggregated with user edits. The platform will configure the associated
* MediaCodecs with the returned Bundle params.
- *
- * TODO: remove hide once API is final
- * @hide
*/
@FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
@NonNull
@@ -112,9 +103,6 @@ public class LoudnessCodecConfigurator {
* Otherwise, use {@link #create(Executor, OnLoudnessCodecUpdateListener)}.
*
* @return the {@link LoudnessCodecConfigurator} instance
- *
- * TODO: remove hide once API is final
- * @hide
*/
@FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
public static @NonNull LoudnessCodecConfigurator create() {
@@ -133,9 +121,6 @@ public class LoudnessCodecConfigurator {
* @param listener used for receiving updates
*
* @return the {@link LoudnessCodecConfigurator} instance
- *
- * TODO: remove hide once API is final
- * @hide
*/
@FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
public static @NonNull LoudnessCodecConfigurator create(
@@ -200,12 +185,9 @@ public class LoudnessCodecConfigurator {
* method will have the effect of clearing the existing set
* {@link AudioTrack} and will stop receiving asynchronous
* loudness updates
- *
- * TODO: remove hide once API is final
- * @hide
*/
@FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
- public void setAudioTrack(AudioTrack audioTrack) {
+ public void setAudioTrack(@Nullable AudioTrack audioTrack) {
List<LoudnessCodecInfo> codecInfos;
int piid = PLAYER_PIID_INVALID;
int oldPiid = PLAYER_PIID_INVALID;
@@ -250,10 +232,11 @@ public class LoudnessCodecConfigurator {
* previously added.
*
* @param mediaCodec the codec to start receiving asynchronous loudness
- * updates
- *
- * TODO: remove hide once API is final
- * @hide
+ * updates. The codec has to be in a configured or started
+ * state in order to add it for loudness updates.
+ * @throws IllegalArgumentException if the {@code mediaCodec} was not configured,
+ * does not contain loudness metadata or if it
+ * was already added before
*/
@FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
public void addMediaCodec(@NonNull MediaCodec mediaCodec) {
@@ -262,31 +245,32 @@ public class LoudnessCodecConfigurator {
int piid = PLAYER_PIID_INVALID;
final LoudnessCodecInfo mcInfo = getCodecInfo(mc);
- if (mcInfo != null) {
- synchronized (mConfiguratorLock) {
- final AtomicBoolean containsCodec = new AtomicBoolean(false);
- Set<MediaCodec> newSet = mMediaCodecs.computeIfPresent(mcInfo, (info, codecSet) -> {
- containsCodec.set(!codecSet.add(mc));
- return codecSet;
- });
- if (newSet == null) {
- newSet = new HashSet<>();
- newSet.add(mc);
- mMediaCodecs.put(mcInfo, newSet);
- }
- if (containsCodec.get()) {
- Log.v(TAG, "Loudness configurator already added media codec " + mediaCodec);
- return;
- }
- if (mAudioTrack != null) {
- piid = mAudioTrack.getPlayerIId();
- }
+ if (mcInfo == null) {
+ throw new IllegalArgumentException("Could not extract codec loudness information");
+ }
+ synchronized (mConfiguratorLock) {
+ final AtomicBoolean containsCodec = new AtomicBoolean(false);
+ Set<MediaCodec> newSet = mMediaCodecs.computeIfPresent(mcInfo, (info, codecSet) -> {
+ containsCodec.set(!codecSet.add(mc));
+ return codecSet;
+ });
+ if (newSet == null) {
+ newSet = new HashSet<>();
+ newSet.add(mc);
+ mMediaCodecs.put(mcInfo, newSet);
}
-
- if (piid != PLAYER_PIID_INVALID) {
- mLcDispatcher.addLoudnessCodecInfo(piid, mcInfo);
+ if (containsCodec.get()) {
+ throw new IllegalArgumentException(
+ "Loudness configurator already added " + mediaCodec);
+ }
+ if (mAudioTrack != null) {
+ piid = mAudioTrack.getPlayerIId();
}
}
+
+ if (piid != PLAYER_PIID_INVALID) {
+ mLcDispatcher.addLoudnessCodecInfo(piid, mediaCodec.hashCode(), mcInfo);
+ }
}
/**
@@ -297,37 +281,44 @@ public class LoudnessCodecConfigurator {
* <p>No elements will be removed if the passed mediaCodec was not added before.
*
* @param mediaCodec the element to remove for receiving asynchronous updates
- *
- * TODO: remove hide once API is final
- * @hide
+ * @throws IllegalArgumentException if the {@code mediaCodec} was not configured,
+ * does not contain loudness metadata or if it
+ * was not added before
*/
@FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
public void removeMediaCodec(@NonNull MediaCodec mediaCodec) {
int piid = PLAYER_PIID_INVALID;
LoudnessCodecInfo mcInfo;
- AtomicBoolean removed = new AtomicBoolean(false);
+ AtomicBoolean removedMc = new AtomicBoolean(false);
+ AtomicBoolean removeInfo = new AtomicBoolean(false);
mcInfo = getCodecInfo(Objects.requireNonNull(mediaCodec,
"MediaCodec for removeMediaCodec cannot be null"));
- if (mcInfo != null) {
- synchronized (mConfiguratorLock) {
- if (mAudioTrack != null) {
- piid = mAudioTrack.getPlayerIId();
+ if (mcInfo == null) {
+ throw new IllegalArgumentException("Could not extract codec loudness information");
+ }
+ synchronized (mConfiguratorLock) {
+ if (mAudioTrack != null) {
+ piid = mAudioTrack.getPlayerIId();
+ }
+ mMediaCodecs.computeIfPresent(mcInfo, (format, mcs) -> {
+ removedMc.set(mcs.remove(mediaCodec));
+ if (mcs.isEmpty()) {
+ // remove the entry
+ removeInfo.set(true);
+ return null;
}
- mMediaCodecs.computeIfPresent(mcInfo, (format, mcs) -> {
- removed.set(mcs.remove(mediaCodec));
- if (mcs.isEmpty()) {
- // remove the entry
- return null;
- }
- return mcs;
- });
+ return mcs;
+ });
+ if (!removedMc.get()) {
+ throw new IllegalArgumentException(
+ "Loudness configurator does not contain " + mediaCodec);
}
+ }
- if (piid != PLAYER_PIID_INVALID && removed.get()) {
- mLcDispatcher.removeLoudnessCodecInfo(piid, mcInfo);
- }
+ if (piid != PLAYER_PIID_INVALID && removeInfo.get()) {
+ mLcDispatcher.removeLoudnessCodecInfo(piid, mcInfo);
}
}
@@ -342,9 +333,6 @@ public class LoudnessCodecConfigurator {
*
* @return the {@link Bundle} containing the current loudness parameters. Caller is
* responsible to update the {@link MediaCodec}
- *
- * TODO: remove hide once API is final
- * @hide
*/
@FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
@NonNull
@@ -375,9 +363,9 @@ public class LoudnessCodecConfigurator {
}
/** @hide */
- /*package*/ List<MediaCodec> getRegisteredMediaCodecList() {
+ /*package*/ Map<LoudnessCodecInfo, Set<MediaCodec>> getRegisteredMediaCodecs() {
synchronized (mConfiguratorLock) {
- return mMediaCodecs.values().stream().flatMap(Collection::stream).toList();
+ return mMediaCodecs;
}
}
@@ -397,40 +385,43 @@ public class LoudnessCodecConfigurator {
return null;
}
- final MediaFormat inputFormat = mediaCodec.getInputFormat();
- final String mimeType = inputFormat.getString(MediaFormat.KEY_MIME);
- if (MediaFormat.MIMETYPE_AUDIO_AAC.equalsIgnoreCase(mimeType)) {
- // check both KEY_AAC_PROFILE and KEY_PROFILE as some codecs may only recognize one of
- // these two keys
- int aacProfile = -1;
- int profile = -1;
- try {
- aacProfile = inputFormat.getInteger(MediaFormat.KEY_AAC_PROFILE);
- } catch (NullPointerException e) {
- // does not contain KEY_AAC_PROFILE. do nothing
- }
- try {
- profile = inputFormat.getInteger(MediaFormat.KEY_PROFILE);
- } catch (NullPointerException e) {
- // does not contain KEY_PROFILE. do nothing
- }
- if (aacProfile == MediaCodecInfo.CodecProfileLevel.AACObjectXHE
- || profile == MediaCodecInfo.CodecProfileLevel.AACObjectXHE) {
- lci.metadataType = CODEC_METADATA_TYPE_MPEG_D;
+ try {
+ final MediaFormat inputFormat = mediaCodec.getInputFormat();
+ final String mimeType = inputFormat.getString(MediaFormat.KEY_MIME);
+ if (MediaFormat.MIMETYPE_AUDIO_AAC.equalsIgnoreCase(mimeType)) {
+ // check both KEY_AAC_PROFILE and KEY_PROFILE as some codecs may only recognize
+ // one of these two keys
+ int aacProfile = -1;
+ int profile = -1;
+ try {
+ aacProfile = inputFormat.getInteger(MediaFormat.KEY_AAC_PROFILE);
+ } catch (NullPointerException e) {
+ // does not contain KEY_AAC_PROFILE. do nothing
+ }
+ try {
+ profile = inputFormat.getInteger(MediaFormat.KEY_PROFILE);
+ } catch (NullPointerException e) {
+ // does not contain KEY_PROFILE. do nothing
+ }
+ if (aacProfile == MediaCodecInfo.CodecProfileLevel.AACObjectXHE
+ || profile == MediaCodecInfo.CodecProfileLevel.AACObjectXHE) {
+ lci.metadataType = CODEC_METADATA_TYPE_MPEG_D;
+ } else {
+ lci.metadataType = CODEC_METADATA_TYPE_MPEG_4;
+ }
} else {
- lci.metadataType = CODEC_METADATA_TYPE_MPEG_4;
+ Log.w(TAG, "MediaCodec mime type not supported for loudness annotation");
+ return null;
}
- } else {
- Log.w(TAG, "MediaCodec mime type not supported for loudness annotation");
+
+ final MediaFormat outputFormat = mediaCodec.getOutputFormat();
+ lci.isDownmixing = outputFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT)
+ < inputFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
+ } catch (IllegalStateException e) {
+ Log.e(TAG, "MediaCodec is not configured", e);
return null;
}
- final MediaFormat outputFormat = mediaCodec.getOutputFormat();
- lci.isDownmixing = outputFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT)
- < inputFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
-
- lci.mediaCodecHashCode = mediaCodec.hashCode();
-
return lci;
}
}
diff --git a/media/java/android/media/LoudnessCodecDispatcher.java b/media/java/android/media/LoudnessCodecDispatcher.java
index be881b11e545..b546a81b0498 100644
--- a/media/java/android/media/LoudnessCodecDispatcher.java
+++ b/media/java/android/media/LoudnessCodecDispatcher.java
@@ -27,12 +27,16 @@ import android.os.PersistableBundle;
import android.os.RemoteException;
import android.util.Log;
+import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
+import java.util.Set;
import java.util.concurrent.Executor;
/**
@@ -52,6 +56,9 @@ public class LoudnessCodecDispatcher implements CallbackUtil.DispatcherStub {
private final CallbackUtil.LazyListenerManager<OnLoudnessCodecUpdateListener>
mLoudnessListenerMgr = new CallbackUtil.LazyListenerManager<>();
+ private final Object mLock = new Object();
+
+ @GuardedBy("mLock")
private final HashMap<OnLoudnessCodecUpdateListener, LoudnessCodecConfigurator>
mConfiguratorListener = new HashMap<>();
@@ -66,38 +73,56 @@ public class LoudnessCodecDispatcher implements CallbackUtil.DispatcherStub {
@Override
public void dispatchLoudnessCodecParameterChange(int piid, PersistableBundle params) {
- mLoudnessListenerMgr.callListeners(listener ->
+ if (DEBUG) {
+ Log.d(TAG, "dispatchLoudnessCodecParameterChange for piid " + piid
+ + " persistable bundle: " + params);
+ }
+ mLoudnessListenerMgr.callListeners(listener -> {
+ synchronized (mLock) {
mConfiguratorListener.computeIfPresent(listener, (l, lcConfig) -> {
// send the appropriate bundle for the user to update
if (lcConfig.getAssignedTrackPiid() == piid) {
- final List<MediaCodec> mediaCodecs =
- lcConfig.getRegisteredMediaCodecList();
- for (MediaCodec mediaCodec : mediaCodecs) {
- final String infoKey = Integer.toString(mediaCodec.hashCode());
+ final Map<LoudnessCodecInfo, Set<MediaCodec>> mediaCodecsMap =
+ lcConfig.getRegisteredMediaCodecs();
+ for (LoudnessCodecInfo codecInfo : mediaCodecsMap.keySet()) {
+ final String infoKey = Integer.toString(codecInfo.hashCode());
+ Bundle bundle = null;
if (params.containsKey(infoKey)) {
- Bundle bundle = new Bundle(
- params.getPersistableBundle(infoKey));
- if (DEBUG) {
- Log.d(TAG,
- "Received for piid " + piid + " bundle: " + bundle);
+ bundle = new Bundle(params.getPersistableBundle(infoKey));
+ }
+
+ final Set<MediaCodec> mediaCodecs = mediaCodecsMap.get(codecInfo);
+ for (MediaCodec mediaCodec : mediaCodecs) {
+ final String mediaCodecKey = Integer.toString(
+ mediaCodec.hashCode());
+ if (bundle == null && !params.containsKey(mediaCodecKey)) {
+ continue;
+ }
+ boolean canBreak = false;
+ if (bundle == null) {
+ // key was set by media codec hash to update single codec
+ bundle = new Bundle(
+ params.getPersistableBundle(mediaCodecKey));
+ canBreak = true;
}
bundle =
LoudnessCodecUpdatesDispatcherStub.filterLoudnessParams(
- l.onLoudnessCodecUpdate(mediaCodec, bundle));
- if (DEBUG) {
- Log.d(TAG, "User changed for piid " + piid
- + " to filtered bundle: " + bundle);
- }
+ l.onLoudnessCodecUpdate(mediaCodec,
+ bundle));
if (!bundle.isDefinitelyEmpty()) {
mediaCodec.setParameters(bundle);
}
+ if (canBreak) {
+ break;
+ }
}
}
}
-
return lcConfig;
- }));
+ });
+ }
+ });
}
private static Bundle filterLoudnessParams(Bundle bundle) {
@@ -130,21 +155,33 @@ public class LoudnessCodecDispatcher implements CallbackUtil.DispatcherStub {
mLoudnessListenerMgr.addListener(
executor, listener, "addLoudnessCodecListener",
() -> dispatcher);
- mConfiguratorListener.put(listener, configurator);
+ synchronized (mLock) {
+ mConfiguratorListener.put(listener, configurator);
+ }
}
void removeLoudnessCodecListener(@NonNull LoudnessCodecConfigurator configurator) {
Objects.requireNonNull(configurator);
- for (Entry<OnLoudnessCodecUpdateListener, LoudnessCodecConfigurator> e :
- mConfiguratorListener.entrySet()) {
- if (e.getValue() == configurator) {
- final OnLoudnessCodecUpdateListener listener = e.getKey();
- mConfiguratorListener.remove(listener);
- mLoudnessListenerMgr.removeListener(listener, "removeLoudnessCodecListener");
- break;
+ OnLoudnessCodecUpdateListener listenerToRemove = null;
+ synchronized (mLock) {
+ Iterator<Entry<OnLoudnessCodecUpdateListener, LoudnessCodecConfigurator>> iterator =
+ mConfiguratorListener.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Entry<OnLoudnessCodecUpdateListener, LoudnessCodecConfigurator> e =
+ iterator.next();
+ if (e.getValue() == configurator) {
+ final OnLoudnessCodecUpdateListener listener = e.getKey();
+ iterator.remove();
+ listenerToRemove = listener;
+ break;
+ }
}
}
+ if (listenerToRemove != null) {
+ mLoudnessListenerMgr.removeListener(listenerToRemove,
+ "removeLoudnessCodecListener");
+ }
}
}
@@ -202,9 +239,10 @@ public class LoudnessCodecDispatcher implements CallbackUtil.DispatcherStub {
}
/** @hide */
- public void addLoudnessCodecInfo(int piid, @NonNull LoudnessCodecInfo mcInfo) {
+ public void addLoudnessCodecInfo(int piid, int mediaCodecHash,
+ @NonNull LoudnessCodecInfo mcInfo) {
try {
- mAudioService.addLoudnessCodecInfo(piid, mcInfo);
+ mAudioService.addLoudnessCodecInfo(piid, mediaCodecHash, mcInfo);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
diff --git a/media/java/android/media/LoudnessCodecInfo.aidl b/media/java/android/media/LoudnessCodecInfo.aidl
index fd695179057d..0ac5646a3047 100644
--- a/media/java/android/media/LoudnessCodecInfo.aidl
+++ b/media/java/android/media/LoudnessCodecInfo.aidl
@@ -23,7 +23,7 @@ package android.media;
*
* {@hide}
*/
-@JavaDerive(equals = true)
+@JavaDerive(equals = true, toString = true)
parcelable LoudnessCodecInfo {
/** Supported codec metadata types for loudness updates. */
@Backing(type="int")
@@ -37,7 +37,6 @@ parcelable LoudnessCodecInfo {
CODEC_METADATA_TYPE_DTS_UHD = 6
}
- int mediaCodecHashCode;
CodecMetadataType metadataType;
boolean isDownmixing;
} \ No newline at end of file
diff --git a/media/java/android/media/tv/ad/TvAdManager.java b/media/java/android/media/tv/ad/TvAdManager.java
index aa5a290346b0..2b52c4b107b6 100644
--- a/media/java/android/media/tv/ad/TvAdManager.java
+++ b/media/java/android/media/tv/ad/TvAdManager.java
@@ -16,6 +16,10 @@
package android.media.tv.ad;
+import android.annotation.FlaggedApi;
+import android.annotation.SystemService;
+import android.content.Context;
+import android.media.tv.flags.Flags;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
@@ -23,14 +27,17 @@ import android.util.Log;
/**
* Central system API to the overall client-side TV AD architecture, which arbitrates interaction
* between applications and AD services.
- * @hide
*/
+@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW)
+@SystemService(Context.TV_AD_SERVICE)
public class TvAdManager {
+ // TODO: implement more methods and unhide APIs.
private static final String TAG = "TvAdManager";
private final ITvAdManager mService;
private final int mUserId;
+ /** @hide */
public TvAdManager(ITvAdManager service, int userId) {
mService = service;
mUserId = userId;
@@ -38,6 +45,7 @@ public class TvAdManager {
/**
* The Session provides the per-session functionality of AD service.
+ * @hide
*/
public static final class Session {
private final IBinder mToken;
diff --git a/media/java/android/media/tv/flags/media_tv.aconfig b/media/java/android/media/tv/flags/media_tv.aconfig
index a73d1ff72a17..018eaf6dc32f 100644
--- a/media/java/android/media/tv/flags/media_tv.aconfig
+++ b/media/java/android/media/tv/flags/media_tv.aconfig
@@ -5,4 +5,11 @@ flag {
namespace: "media_tv"
description: "Constants for standardizing broadcast visibility types."
bug: "222402395"
+}
+
+flag {
+ name: "enable_ad_service_fw"
+ namespace: "media_tv"
+ description: "Enable the TV client-side AD framework."
+ bug: "303506816"
} \ No newline at end of file
diff --git a/media/tests/LoudnessCodecApiTest/src/com/android/loudnesscodecapitest/LoudnessCodecConfiguratorTest.java b/media/tests/LoudnessCodecApiTest/src/com/android/loudnesscodecapitest/LoudnessCodecConfiguratorTest.java
index 65a9799431e7..c9e36b7f10bd 100644
--- a/media/tests/LoudnessCodecApiTest/src/com/android/loudnesscodecapitest/LoudnessCodecConfiguratorTest.java
+++ b/media/tests/LoudnessCodecApiTest/src/com/android/loudnesscodecapitest/LoudnessCodecConfiguratorTest.java
@@ -208,7 +208,7 @@ public class LoudnessCodecConfiguratorTest {
verify(mAudioService).startLoudnessCodecUpdates(eq(track.getPlayerIId()), anyList());
mLcc.addMediaCodec(createAndConfigureMediaCodec());
- verify(mAudioService).addLoudnessCodecInfo(eq(track.getPlayerIId()), any());
+ verify(mAudioService).addLoudnessCodecInfo(eq(track.getPlayerIId()), anyInt(), any());
}
@Test
diff --git a/packages/CredentialManager/Android.bp b/packages/CredentialManager/Android.bp
index fe26dc3d7feb..991fe41bb7f3 100644
--- a/packages/CredentialManager/Android.bp
+++ b/packages/CredentialManager/Android.bp
@@ -16,10 +16,12 @@ android_app {
dex_preopt: {
profile_guided: true,
+ //TODO: b/312357299 - Update baseline profile
profile: "profile.txt.prof",
},
static_libs: [
+ "CredentialManagerShared",
"PlatformComposeCore",
"androidx.activity_activity-compose",
"androidx.appcompat_appcompat",
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/IntentParser.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/IntentParser.kt
index 42f1207c69cb..325d3f819f14 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/IntentParser.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/IntentParser.kt
@@ -16,6 +16,7 @@
package com.android.credentialmanager
+import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.credentials.ui.RequestInfo
@@ -27,10 +28,10 @@ import com.android.credentialmanager.mapper.toGet
import com.android.credentialmanager.model.Request
fun Intent.parse(
- packageManager: PackageManager,
+ context: Context,
): Request {
- return parseCancelUiRequest(packageManager)
- ?: parseRequestInfo()
+ return parseCancelUiRequest(context.packageManager)
+ ?: parseRequestInfo(context)
}
fun Intent.parseCancelUiRequest(packageManager: PackageManager): Request? =
@@ -51,11 +52,11 @@ fun Intent.parseCancelUiRequest(packageManager: PackageManager): Request? =
}
}
-fun Intent.parseRequestInfo(): Request =
+fun Intent.parseRequestInfo(context: Context): Request =
requestInfo.let{ info ->
when (info?.type) {
RequestInfo.TYPE_CREATE -> Request.Create(info.token)
- RequestInfo.TYPE_GET -> toGet()
+ RequestInfo.TYPE_GET -> toGet(context)
else -> {
throw IllegalStateException("Unrecognized request type: ${info?.type}")
}
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/client/impl/CredentialManagerClientImpl.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/client/impl/CredentialManagerClientImpl.kt
index 83183b5f58eb..3ef65b052560 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/client/impl/CredentialManagerClientImpl.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/client/impl/CredentialManagerClientImpl.kt
@@ -16,8 +16,8 @@
package com.android.credentialmanager.client.impl
+import android.content.Context
import android.content.Intent
-import android.content.pm.PackageManager
import android.credentials.ui.BaseDialogResult
import android.credentials.ui.UserSelectionDialogResult
import android.os.Bundle
@@ -26,12 +26,13 @@ import com.android.credentialmanager.TAG
import com.android.credentialmanager.model.Request
import com.android.credentialmanager.parse
import com.android.credentialmanager.client.CredentialManagerClient
+import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import javax.inject.Inject
class CredentialManagerClientImpl @Inject constructor(
- private val packageManager: PackageManager,
+ @ApplicationContext private val context: Context,
) : CredentialManagerClient {
private val _requests = MutableStateFlow<Request?>(null)
@@ -40,7 +41,7 @@ class CredentialManagerClientImpl @Inject constructor(
override fun updateRequest(intent: Intent) {
val request = intent.parse(
- packageManager = packageManager,
+ context = context,
)
Log.d(TAG, "Request parsed: $request, client instance: $this")
if (request is Request.Cancel || request is Request.Close) {
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/CredentialKtx.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/CredentialKtx.kt
new file mode 100644
index 000000000000..f063074b39b4
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/CredentialKtx.kt
@@ -0,0 +1,369 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.ktx
+
+import android.app.slice.Slice
+import android.content.ComponentName
+import android.content.Context
+import android.content.pm.PackageInfo
+import android.content.pm.PackageManager
+import android.credentials.Credential
+import android.credentials.flags.Flags
+import android.credentials.ui.AuthenticationEntry
+import android.credentials.ui.Entry
+import android.credentials.ui.GetCredentialProviderData
+import android.graphics.drawable.Drawable
+import android.text.TextUtils
+import android.util.Log
+import androidx.activity.result.IntentSenderRequest
+import androidx.credentials.PublicKeyCredential
+import androidx.credentials.provider.Action
+import androidx.credentials.provider.AuthenticationAction
+import androidx.credentials.provider.CredentialEntry
+import androidx.credentials.provider.CustomCredentialEntry
+import androidx.credentials.provider.PasswordCredentialEntry
+import androidx.credentials.provider.PublicKeyCredentialEntry
+import androidx.credentials.provider.RemoteEntry
+import com.android.credentialmanager.IS_AUTO_SELECTED_KEY
+import com.android.credentialmanager.model.get.ActionEntryInfo
+import com.android.credentialmanager.model.get.AuthenticationEntryInfo
+import com.android.credentialmanager.model.get.CredentialEntryInfo
+import com.android.credentialmanager.model.CredentialType
+import com.android.credentialmanager.model.get.ProviderInfo
+import com.android.credentialmanager.model.get.RemoteEntryInfo
+import com.android.credentialmanager.TAG
+
+fun CredentialEntryInfo.getIntentSenderRequest(
+ isAutoSelected: Boolean = false
+): IntentSenderRequest? {
+ val entryIntent = fillInIntent?.putExtra(IS_AUTO_SELECTED_KEY, isAutoSelected)
+
+ return pendingIntent?.let{
+ IntentSenderRequest
+ .Builder(pendingIntent = it)
+ .setFillInIntent(entryIntent)
+ .build()
+ }
+}
+
+// Returns the list (potentially empty) of enabled provider.
+fun List<GetCredentialProviderData>.toProviderList(
+ context: Context,
+): List<ProviderInfo> {
+ val providerList: MutableList<ProviderInfo> = mutableListOf()
+ this.forEach {
+ val providerLabelAndIcon = getServiceLabelAndIcon(
+ context.packageManager,
+ it.providerFlattenedComponentName
+ ) ?: return@forEach
+ val (providerLabel, providerIcon) = providerLabelAndIcon
+ providerList.add(
+ ProviderInfo(
+ id = it.providerFlattenedComponentName,
+ icon = providerIcon,
+ displayName = providerLabel,
+ credentialEntryList = getCredentialOptionInfoList(
+ providerId = it.providerFlattenedComponentName,
+ providerLabel = providerLabel,
+ credentialEntries = it.credentialEntries,
+ context = context
+ ),
+ authenticationEntryList = getAuthenticationEntryList(
+ it.providerFlattenedComponentName,
+ providerLabel,
+ providerIcon,
+ it.authenticationEntries),
+ remoteEntry = getRemoteEntry(
+ it.providerFlattenedComponentName,
+ it.remoteEntry
+ ),
+ actionEntryList = getActionEntryList(
+ it.providerFlattenedComponentName, it.actionChips, providerIcon
+ ),
+ )
+ )
+ }
+ return providerList
+}
+
+/**
+ * Note: caller required handle empty list due to parsing error.
+ */
+private fun getCredentialOptionInfoList(
+ providerId: String,
+ providerLabel: String,
+ credentialEntries: List<Entry>,
+ context: Context,
+): List<CredentialEntryInfo> {
+ val result: MutableList<CredentialEntryInfo> = mutableListOf()
+ credentialEntries.forEach {
+ val credentialEntry = it.slice.credentialEntry
+ when (credentialEntry) {
+ is PasswordCredentialEntry -> {
+ result.add(
+ CredentialEntryInfo(
+ providerId = providerId,
+ providerDisplayName = providerLabel,
+ entryKey = it.key,
+ entrySubkey = it.subkey,
+ pendingIntent = credentialEntry.pendingIntent,
+ fillInIntent = it.frameworkExtrasIntent,
+ credentialType = CredentialType.PASSWORD,
+ credentialTypeDisplayName = credentialEntry.typeDisplayName.toString(),
+ userName = credentialEntry.username.toString(),
+ displayName = credentialEntry.displayName?.toString(),
+ icon = credentialEntry.icon.loadDrawable(context),
+ shouldTintIcon = credentialEntry.isDefaultIcon,
+ lastUsedTimeMillis = credentialEntry.lastUsedTime,
+ isAutoSelectable = credentialEntry.isAutoSelectAllowed &&
+ credentialEntry.autoSelectAllowedFromOption,
+ )
+ )
+ }
+ is PublicKeyCredentialEntry -> {
+ result.add(
+ CredentialEntryInfo(
+ providerId = providerId,
+ providerDisplayName = providerLabel,
+ entryKey = it.key,
+ entrySubkey = it.subkey,
+ pendingIntent = credentialEntry.pendingIntent,
+ fillInIntent = it.frameworkExtrasIntent,
+ credentialType = CredentialType.PASSKEY,
+ credentialTypeDisplayName = credentialEntry.typeDisplayName.toString(),
+ userName = credentialEntry.username.toString(),
+ displayName = credentialEntry.displayName?.toString(),
+ icon = credentialEntry.icon.loadDrawable(context),
+ shouldTintIcon = credentialEntry.isDefaultIcon,
+ lastUsedTimeMillis = credentialEntry.lastUsedTime,
+ isAutoSelectable = credentialEntry.isAutoSelectAllowed &&
+ credentialEntry.autoSelectAllowedFromOption,
+ )
+ )
+ }
+ is CustomCredentialEntry -> {
+ result.add(
+ CredentialEntryInfo(
+ providerId = providerId,
+ providerDisplayName = providerLabel,
+ entryKey = it.key,
+ entrySubkey = it.subkey,
+ pendingIntent = credentialEntry.pendingIntent,
+ fillInIntent = it.frameworkExtrasIntent,
+ credentialType = CredentialType.UNKNOWN,
+ credentialTypeDisplayName =
+ credentialEntry.typeDisplayName?.toString().orEmpty(),
+ userName = credentialEntry.title.toString(),
+ displayName = credentialEntry.subtitle?.toString(),
+ icon = credentialEntry.icon.loadDrawable(context),
+ shouldTintIcon = credentialEntry.isDefaultIcon,
+ lastUsedTimeMillis = credentialEntry.lastUsedTime,
+ isAutoSelectable = credentialEntry.isAutoSelectAllowed &&
+ credentialEntry.autoSelectAllowedFromOption,
+ )
+ )
+ }
+ else -> Log.d(
+ TAG,
+ "Encountered unrecognized credential entry ${it.slice.spec?.type}"
+ )
+ }
+ }
+ return result
+}
+val Slice.credentialEntry: CredentialEntry?
+ get() =
+ try {
+ when (spec?.type) {
+ Credential.TYPE_PASSWORD_CREDENTIAL -> PasswordCredentialEntry.fromSlice(this)!!
+ PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL ->
+ PublicKeyCredentialEntry.fromSlice(this)!!
+
+ else -> CustomCredentialEntry.fromSlice(this)!!
+ }
+ } catch (e: Exception) {
+ // Try CustomCredentialEntry.fromSlice one last time in case the cause was a failed
+ // password / passkey parsing attempt.
+ CustomCredentialEntry.fromSlice(this)
+ }
+
+
+/**
+ * Note: caller required handle empty list due to parsing error.
+ */
+private fun getAuthenticationEntryList(
+ providerId: String,
+ providerDisplayName: String,
+ providerIcon: Drawable,
+ authEntryList: List<AuthenticationEntry>,
+): List<AuthenticationEntryInfo> {
+ val result: MutableList<AuthenticationEntryInfo> = mutableListOf()
+ authEntryList.forEach { entry ->
+ val structuredAuthEntry =
+ AuthenticationAction.fromSlice(entry.slice) ?: return@forEach
+
+ val title: String =
+ structuredAuthEntry.title.toString().ifEmpty { providerDisplayName }
+
+ result.add(
+ AuthenticationEntryInfo(
+ providerId = providerId,
+ entryKey = entry.key,
+ entrySubkey = entry.subkey,
+ pendingIntent = structuredAuthEntry.pendingIntent,
+ fillInIntent = entry.frameworkExtrasIntent,
+ title = title,
+ providerDisplayName = providerDisplayName,
+ icon = providerIcon,
+ isUnlockedAndEmpty = entry.status != AuthenticationEntry.STATUS_LOCKED,
+ isLastUnlocked =
+ entry.status == AuthenticationEntry.STATUS_UNLOCKED_BUT_EMPTY_MOST_RECENT
+ )
+ )
+ }
+ return result
+}
+
+private fun getRemoteEntry(providerId: String, remoteEntry: Entry?): RemoteEntryInfo? {
+ if (remoteEntry == null) {
+ return null
+ }
+ val structuredRemoteEntry = RemoteEntry.fromSlice(remoteEntry.slice)
+ ?: return null
+ return RemoteEntryInfo(
+ providerId = providerId,
+ entryKey = remoteEntry.key,
+ entrySubkey = remoteEntry.subkey,
+ pendingIntent = structuredRemoteEntry.pendingIntent,
+ fillInIntent = remoteEntry.frameworkExtrasIntent,
+ )
+}
+
+/**
+ * Note: caller required handle empty list due to parsing error.
+ */
+private fun getActionEntryList(
+ providerId: String,
+ actionEntries: List<Entry>,
+ providerIcon: Drawable,
+): List<ActionEntryInfo> {
+ val result: MutableList<ActionEntryInfo> = mutableListOf()
+ actionEntries.forEach {
+ val actionEntryUi = Action.fromSlice(it.slice) ?: return@forEach
+ result.add(
+ ActionEntryInfo(
+ providerId = providerId,
+ entryKey = it.key,
+ entrySubkey = it.subkey,
+ pendingIntent = actionEntryUi.pendingIntent,
+ fillInIntent = it.frameworkExtrasIntent,
+ title = actionEntryUi.title.toString(),
+ icon = providerIcon,
+ subTitle = actionEntryUi.subtitle?.toString(),
+ )
+ )
+ }
+ return result
+}
+
+
+
+private fun getServiceLabelAndIcon(
+ pm: PackageManager,
+ providerFlattenedComponentName: String
+): Pair<String, Drawable>? {
+ var providerLabel: String? = null
+ var providerIcon: Drawable? = null
+ val component = ComponentName.unflattenFromString(providerFlattenedComponentName)
+ if (component == null) {
+ // Test data has only package name not component name.
+ // For test data usage only.
+ try {
+ val pkgInfo = if (Flags.instantAppsEnabled()) {
+ getPackageInfo(pm, providerFlattenedComponentName)
+ } else {
+ pm.getPackageInfo(
+ providerFlattenedComponentName,
+ PackageManager.PackageInfoFlags.of(0)
+ )
+ }
+ val applicationInfo = checkNotNull(pkgInfo.applicationInfo)
+ providerLabel =
+ applicationInfo.loadSafeLabel(
+ pm, 0f,
+ TextUtils.SAFE_STRING_FLAG_FIRST_LINE or TextUtils.SAFE_STRING_FLAG_TRIM
+ ).toString()
+ providerIcon = applicationInfo.loadIcon(pm)
+ } catch (e: Exception) {
+ Log.e(TAG, "Provider package info not found", e)
+ }
+ } else {
+ try {
+ val si = pm.getServiceInfo(component, PackageManager.ComponentInfoFlags.of(0))
+ providerLabel = si.loadSafeLabel(
+ pm, 0f,
+ TextUtils.SAFE_STRING_FLAG_FIRST_LINE or TextUtils.SAFE_STRING_FLAG_TRIM
+ ).toString()
+ providerIcon = si.loadIcon(pm)
+ } catch (e: PackageManager.NameNotFoundException) {
+ Log.e(TAG, "Provider service info not found", e)
+ // Added for mdoc use case where the provider may not need to register a service and
+ // instead only relies on the registration api.
+ try {
+ val pkgInfo = if (Flags.instantAppsEnabled()) {
+ getPackageInfo(pm, providerFlattenedComponentName)
+ } else {
+ pm.getPackageInfo(
+ component.packageName,
+ PackageManager.PackageInfoFlags.of(0)
+ )
+ }
+ val applicationInfo = checkNotNull(pkgInfo.applicationInfo)
+ providerLabel =
+ applicationInfo.loadSafeLabel(
+ pm, 0f,
+ TextUtils.SAFE_STRING_FLAG_FIRST_LINE or TextUtils.SAFE_STRING_FLAG_TRIM
+ ).toString()
+ providerIcon = applicationInfo.loadIcon(pm)
+ } catch (e: Exception) {
+ Log.e(TAG, "Provider package info not found", e)
+ }
+ }
+ }
+ return if (providerLabel == null || providerIcon == null) {
+ Log.d(
+ TAG,
+ "Failed to load provider label/icon for provider $providerFlattenedComponentName"
+ )
+ null
+ } else {
+ Pair(providerLabel, providerIcon)
+ }
+}
+
+private fun getPackageInfo(
+ pm: PackageManager,
+ packageName: String
+): PackageInfo {
+ val packageManagerFlags = PackageManager.MATCH_INSTANT
+
+ return pm.getPackageInfo(
+ packageName,
+ PackageManager.PackageInfoFlags.of(
+ (packageManagerFlags).toLong())
+ )
+} \ No newline at end of file
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/PasswordKtx.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/PasswordKtx.kt
deleted file mode 100644
index 34710704facb..000000000000
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/PasswordKtx.kt
+++ /dev/null
@@ -1,32 +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.0N
- *
- * 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.credentialmanager.ktx
-
-import androidx.activity.result.IntentSenderRequest
-import com.android.credentialmanager.IS_AUTO_SELECTED_KEY
-import com.android.credentialmanager.model.Password
-
-fun Password.getIntentSenderRequest(
- isAutoSelected: Boolean = false
-): IntentSenderRequest {
- val entryIntent = entry.frameworkExtrasIntent
- entryIntent?.putExtra(IS_AUTO_SELECTED_KEY, isAutoSelected)
-
- return IntentSenderRequest.Builder(
- pendingIntent = passwordCredentialEntry.pendingIntent
- ).setFillInIntent(entryIntent).build()
-}
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestGetMapper.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestGetMapper.kt
index d4bca2add6cb..f1f1f7ca842e 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestGetMapper.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestGetMapper.kt
@@ -16,48 +16,18 @@
package com.android.credentialmanager.mapper
+import android.content.Context
import android.content.Intent
-import android.credentials.ui.Entry
-import androidx.credentials.provider.PasswordCredentialEntry
-import com.android.credentialmanager.factory.fromSlice
import com.android.credentialmanager.ktx.getCredentialProviderDataList
import com.android.credentialmanager.ktx.requestInfo
import com.android.credentialmanager.ktx.resultReceiver
-import com.android.credentialmanager.model.Password
+import com.android.credentialmanager.ktx.toProviderList
import com.android.credentialmanager.model.Request
-import com.google.common.collect.ImmutableList
-import com.google.common.collect.ImmutableMap
-
-fun Intent.toGet(): Request.Get {
- val credentialEntries = mutableListOf<Pair<String, Entry>>()
- for (providerData in getCredentialProviderDataList) {
- for (credentialEntry in providerData.credentialEntries) {
- credentialEntries.add(
- Pair(providerData.providerFlattenedComponentName, credentialEntry)
- )
- }
- }
-
- val passwordEntries = mutableListOf<Password>()
- for ((providerId, entry) in credentialEntries) {
- val slice = fromSlice(entry.slice)
- if (slice is PasswordCredentialEntry) {
- passwordEntries.add(
- Password(
- providerId = providerId,
- entry = entry,
- passwordCredentialEntry = slice
- )
- )
- }
- }
+fun Intent.toGet(context: Context): Request.Get {
return Request.Get(
token = requestInfo?.token,
- resultReceiver = this.resultReceiver,
- providers = ImmutableMap.copyOf(
- getCredentialProviderDataList.associateBy { it.providerFlattenedComponentName }
- ),
- passwordEntries = ImmutableList.copyOf(passwordEntries)
+ resultReceiver = resultReceiver,
+ providerInfos = getCredentialProviderDataList.toProviderList(context)
)
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/CredentialType.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/CredentialType.kt
index cc92f60de048..3f85192d937f 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/CredentialType.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/CredentialType.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.credentialmanager.common
+package com.android.credentialmanager.model
enum class CredentialType {
UNKNOWN, PASSKEY, PASSWORD,
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/BaseEntry.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/EntryInfo.kt
index ee36989b3da0..6d59f11d5643 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/BaseEntry.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/EntryInfo.kt
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-package com.android.credentialmanager.common
+package com.android.credentialmanager.model
import android.app.PendingIntent
import android.content.Intent
-open class BaseEntry (
+open class EntryInfo (
val providerId: String,
val entryKey: String,
val entrySubkey: String,
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Request.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Request.kt
index 2289ed7320ca..763646233324 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Request.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Request.kt
@@ -16,11 +16,9 @@
package com.android.credentialmanager.model
-import android.credentials.ui.ProviderData
import android.os.IBinder
import android.os.ResultReceiver
-import com.google.common.collect.ImmutableList
-import com.google.common.collect.ImmutableMap
+import com.android.credentialmanager.model.get.ProviderInfo
/**
* Represents the request made by the CredentialManager API.
@@ -51,8 +49,7 @@ sealed class Request private constructor(
data class Get(
override val token: IBinder?,
val resultReceiver: ResultReceiver?,
- val providers: ImmutableMap<String, ProviderData>,
- val passwordEntries: ImmutableList<Password>,
+ val providerInfos: List<ProviderInfo>,
) : Request(token)
/**
* Request to start the create credentials flow.
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/creation/CreateOptionInfo.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/creation/CreateOptionInfo.kt
new file mode 100644
index 000000000000..d6189eb15ff3
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/creation/CreateOptionInfo.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.model.creation
+
+import android.app.PendingIntent
+import android.content.Intent
+import android.graphics.drawable.Drawable
+import com.android.credentialmanager.model.EntryInfo
+import java.time.Instant
+
+class CreateOptionInfo(
+ providerId: String,
+ entryKey: String,
+ entrySubkey: String,
+ pendingIntent: PendingIntent?,
+ fillInIntent: Intent?,
+ val userProviderDisplayName: String,
+ val profileIcon: Drawable?,
+ val passwordCount: Int?,
+ val passkeyCount: Int?,
+ val totalCredentialCount: Int?,
+ val lastUsedTime: Instant,
+ val footerDescription: String?,
+ val allowAutoSelect: Boolean,
+) : EntryInfo(
+ providerId,
+ entryKey,
+ entrySubkey,
+ pendingIntent,
+ fillInIntent,
+ shouldTerminateUiUponSuccessfulProviderResult = true,
+) \ No newline at end of file
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/creation/RemoteInfo.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/creation/RemoteInfo.kt
new file mode 100644
index 000000000000..7ee50d7c4e73
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/creation/RemoteInfo.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.model.creation
+
+import android.app.PendingIntent
+import android.content.Intent
+import com.android.credentialmanager.model.EntryInfo
+
+class RemoteInfo(
+ providerId: String,
+ entryKey: String,
+ entrySubkey: String,
+ pendingIntent: PendingIntent?,
+ fillInIntent: Intent?,
+) : EntryInfo(
+ providerId,
+ entryKey,
+ entrySubkey,
+ pendingIntent,
+ fillInIntent,
+ shouldTerminateUiUponSuccessfulProviderResult = true,
+) \ No newline at end of file
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/ActionEntryInfo.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/ActionEntryInfo.kt
new file mode 100644
index 000000000000..d9eee868c17f
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/ActionEntryInfo.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.model.get
+
+import android.app.PendingIntent
+import android.content.Intent
+import android.graphics.drawable.Drawable
+import com.android.credentialmanager.model.EntryInfo
+
+class ActionEntryInfo(
+ providerId: String,
+ entryKey: String,
+ entrySubkey: String,
+ pendingIntent: PendingIntent?,
+ fillInIntent: Intent?,
+ val title: String,
+ val icon: Drawable,
+ val subTitle: String?,
+) : EntryInfo(
+ providerId,
+ entryKey,
+ entrySubkey,
+ pendingIntent,
+ fillInIntent,
+ shouldTerminateUiUponSuccessfulProviderResult = true,
+) \ No newline at end of file
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/AuthenticationEntryInfo.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/AuthenticationEntryInfo.kt
new file mode 100644
index 000000000000..01c394fc0d74
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/AuthenticationEntryInfo.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.model.get
+
+import android.app.PendingIntent
+import android.content.Intent
+import android.graphics.drawable.Drawable
+import com.android.credentialmanager.model.EntryInfo
+
+class AuthenticationEntryInfo(
+ providerId: String,
+ entryKey: String,
+ entrySubkey: String,
+ pendingIntent: PendingIntent?,
+ fillInIntent: Intent?,
+ val title: String,
+ val providerDisplayName: String,
+ val icon: Drawable,
+ // The entry had been unlocked and turned out to be empty. Used to determine whether to
+ // show "Tap to unlock" or "No sign-in info" for this entry.
+ val isUnlockedAndEmpty: Boolean,
+ // True if the entry was the last one unlocked. Used to show the no sign-in info snackbar.
+ val isLastUnlocked: Boolean,
+) : EntryInfo(
+ providerId,
+ entryKey, entrySubkey,
+ pendingIntent,
+ fillInIntent,
+ shouldTerminateUiUponSuccessfulProviderResult = false,
+) \ No newline at end of file
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/CredentialEntryInfo.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/CredentialEntryInfo.kt
new file mode 100644
index 000000000000..9725881e1c97
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/CredentialEntryInfo.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.model.get
+
+import android.app.PendingIntent
+import android.content.Intent
+import android.graphics.drawable.Drawable
+import com.android.credentialmanager.model.CredentialType
+import com.android.credentialmanager.model.EntryInfo
+import java.time.Instant
+
+class CredentialEntryInfo(
+ providerId: String,
+ entryKey: String,
+ entrySubkey: String,
+ pendingIntent: PendingIntent?,
+ fillInIntent: Intent?,
+ /** Type of this credential used for sorting. Not localized so must not be directly displayed. */
+ val credentialType: CredentialType,
+ /** Localized type value of this credential used for display purpose. */
+ val credentialTypeDisplayName: String,
+ val providerDisplayName: String,
+ val userName: String,
+ val displayName: String?,
+ val icon: Drawable?,
+ val shouldTintIcon: Boolean,
+ val lastUsedTimeMillis: Instant?,
+ val isAutoSelectable: Boolean,
+) : EntryInfo(
+ providerId,
+ entryKey,
+ entrySubkey,
+ pendingIntent,
+ fillInIntent,
+ shouldTerminateUiUponSuccessfulProviderResult = true,
+) \ No newline at end of file
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/ProviderInfo.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/ProviderInfo.kt
new file mode 100644
index 000000000000..6da414617752
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/ProviderInfo.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.model.get
+
+import android.graphics.drawable.Drawable
+
+data class ProviderInfo(
+ /**
+ * Unique id (component name) of this provider.
+ * Not for display purpose - [displayName] should be used for ui rendering.
+ */
+ val id: String,
+ val icon: Drawable,
+ val displayName: String,
+ val credentialEntryList: List<CredentialEntryInfo>,
+ val authenticationEntryList: List<AuthenticationEntryInfo>,
+ val remoteEntry: RemoteEntryInfo?,
+ val actionEntryList: List<ActionEntryInfo>,
+) \ No newline at end of file
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/RemoteEntryInfo.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/RemoteEntryInfo.kt
new file mode 100644
index 000000000000..a68bf7413b25
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/RemoteEntryInfo.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.model.get
+
+import android.app.PendingIntent
+import android.content.Intent
+import com.android.credentialmanager.model.EntryInfo
+
+class RemoteEntryInfo(
+ providerId: String,
+ entryKey: String,
+ entrySubkey: String,
+ pendingIntent: PendingIntent?,
+ fillInIntent: Intent?,
+) : EntryInfo(
+ providerId,
+ entryKey,
+ entrySubkey,
+ pendingIntent,
+ fillInIntent,
+ shouldTerminateUiUponSuccessfulProviderResult = true,
+) \ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
index bce86c477e77..6c5a984f20f7 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
@@ -28,7 +28,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
-import com.android.credentialmanager.common.BaseEntry
+import com.android.credentialmanager.model.EntryInfo
import com.android.credentialmanager.common.Constants
import com.android.credentialmanager.common.DialogState
import com.android.credentialmanager.common.ProviderActivityResult
@@ -47,7 +47,7 @@ import com.android.internal.logging.UiEventLogger.UiEventEnum
data class UiState(
val createCredentialUiState: CreateCredentialUiState?,
val getCredentialUiState: GetCredentialUiState?,
- val selectedEntry: BaseEntry? = null,
+ val selectedEntry: EntryInfo? = null,
val providerActivityState: ProviderActivityState = ProviderActivityState.NOT_APPLICABLE,
val dialogState: DialogState = DialogState.ACTIVE,
// True if the UI has one and only one auto selectable entry. Its provider activity will be
@@ -115,12 +115,13 @@ class CredentialSelectorViewModel(
launcher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>
) {
val entry = uiState.selectedEntry
- if (entry != null && entry.pendingIntent != null) {
+ val pendingIntent = entry?.pendingIntent
+ if (pendingIntent != null) {
Log.d(Constants.LOG_TAG, "Launching provider activity")
uiState = uiState.copy(providerActivityState = ProviderActivityState.PENDING)
val entryIntent = entry.fillInIntent
entryIntent?.putExtra(Constants.IS_AUTO_SELECTED_KEY, uiState.isAutoSelectFlow)
- val intentSenderRequest = IntentSenderRequest.Builder(entry.pendingIntent)
+ val intentSenderRequest = IntentSenderRequest.Builder(pendingIntent)
.setFillInIntent(entryIntent).build()
try {
launcher.launch(intentSenderRequest)
@@ -201,7 +202,7 @@ class CredentialSelectorViewModel(
/**************************************************************************/
/***** Get Flow Callbacks *****/
/**************************************************************************/
- fun getFlowOnEntrySelected(entry: BaseEntry) {
+ fun getFlowOnEntrySelected(entry: EntryInfo) {
Log.d(Constants.LOG_TAG, "credential selected: {provider=${entry.providerId}" +
", key=${entry.entryKey}, subkey=${entry.entrySubkey}}")
uiState = if (entry.pendingIntent != null) {
@@ -363,7 +364,7 @@ class CredentialSelectorViewModel(
)
}
- fun createFlowOnEntrySelected(selectedEntry: BaseEntry) {
+ fun createFlowOnEntrySelected(selectedEntry: EntryInfo) {
val providerId = selectedEntry.providerId
val entryKey = selectedEntry.entryKey
val entrySubkey = selectedEntry.entrySubkey
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
index f0fa6c5c4dd2..fc3970de2cee 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
@@ -16,13 +16,10 @@
package com.android.credentialmanager
-import android.app.slice.Slice
import android.content.ComponentName
import android.content.Context
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
-import android.credentials.Credential.TYPE_PASSWORD_CREDENTIAL
-import android.credentials.ui.AuthenticationEntry
import android.credentials.ui.CreateCredentialProviderData
import android.credentials.ui.DisabledProviderData
import android.credentials.ui.Entry
@@ -32,36 +29,26 @@ import android.graphics.drawable.Drawable
import android.text.TextUtils
import android.util.Log
import com.android.credentialmanager.common.Constants
-import com.android.credentialmanager.common.CredentialType
+import com.android.credentialmanager.model.CredentialType
import com.android.credentialmanager.createflow.ActiveEntry
import com.android.credentialmanager.createflow.CreateCredentialUiState
-import com.android.credentialmanager.createflow.CreateOptionInfo
+import com.android.credentialmanager.model.creation.CreateOptionInfo
import com.android.credentialmanager.createflow.CreateScreenState
import com.android.credentialmanager.createflow.DisabledProviderInfo
import com.android.credentialmanager.createflow.EnabledProviderInfo
-import com.android.credentialmanager.createflow.RemoteInfo
+import com.android.credentialmanager.model.creation.RemoteInfo
import com.android.credentialmanager.createflow.RequestDisplayInfo
-import com.android.credentialmanager.getflow.ActionEntryInfo
-import com.android.credentialmanager.getflow.AuthenticationEntryInfo
-import com.android.credentialmanager.getflow.CredentialEntryInfo
-import com.android.credentialmanager.getflow.ProviderInfo
-import com.android.credentialmanager.getflow.RemoteEntryInfo
-import com.android.credentialmanager.getflow.TopBrandingContent
+import com.android.credentialmanager.model.get.ProviderInfo
+import com.android.credentialmanager.ktx.toProviderList
import androidx.credentials.CreateCredentialRequest
import androidx.credentials.CreateCustomCredentialRequest
import androidx.credentials.CreatePasswordRequest
import androidx.credentials.CreatePublicKeyCredentialRequest
-import androidx.credentials.PublicKeyCredential.Companion.TYPE_PUBLIC_KEY_CREDENTIAL
-import androidx.credentials.provider.Action
-import androidx.credentials.provider.AuthenticationAction
import androidx.credentials.provider.CreateEntry
-import androidx.credentials.provider.CredentialEntry
-import androidx.credentials.provider.CustomCredentialEntry
-import androidx.credentials.provider.PasswordCredentialEntry
-import androidx.credentials.provider.PublicKeyCredentialEntry
import androidx.credentials.provider.RemoteEntry
import org.json.JSONObject
import android.credentials.flags.Flags
+import com.android.credentialmanager.getflow.TopBrandingContent
import java.time.Instant
@@ -179,43 +166,7 @@ class GetFlowUtils {
fun toProviderList(
providerDataList: List<GetCredentialProviderData>,
context: Context,
- ): List<ProviderInfo> {
- val providerList: MutableList<ProviderInfo> = mutableListOf()
- providerDataList.forEach {
- val providerLabelAndIcon = getServiceLabelAndIcon(
- context.packageManager,
- it.providerFlattenedComponentName
- ) ?: return@forEach
- val (providerLabel, providerIcon) = providerLabelAndIcon
- providerList.add(
- ProviderInfo(
- id = it.providerFlattenedComponentName,
- icon = providerIcon,
- displayName = providerLabel,
- credentialEntryList = getCredentialOptionInfoList(
- providerId = it.providerFlattenedComponentName,
- providerLabel = providerLabel,
- credentialEntries = it.credentialEntries,
- context = context
- ),
- authenticationEntryList = getAuthenticationEntryList(
- it.providerFlattenedComponentName,
- providerLabel,
- providerIcon,
- it.authenticationEntries),
- remoteEntry = getRemoteEntry(
- it.providerFlattenedComponentName,
- it.remoteEntry
- ),
- actionEntryList = getActionEntryList(
- it.providerFlattenedComponentName, it.actionChips, providerIcon
- ),
- )
- )
- }
- return providerList
- }
-
+ ): List<ProviderInfo> = providerDataList.toProviderList(context)
fun toRequestDisplayInfo(
requestInfo: RequestInfo?,
context: Context,
@@ -254,178 +205,6 @@ class GetFlowUtils {
preferTopBrandingContent = preferTopBrandingContent,
)
}
-
-
- /**
- * Note: caller required handle empty list due to parsing error.
- */
- private fun getCredentialOptionInfoList(
- providerId: String,
- providerLabel: String,
- credentialEntries: List<Entry>,
- context: Context,
- ): List<CredentialEntryInfo> {
- val result: MutableList<CredentialEntryInfo> = mutableListOf()
- credentialEntries.forEach {
- val credentialEntry = parseCredentialEntryFromSlice(it.slice)
- when (credentialEntry) {
- is PasswordCredentialEntry -> {
- result.add(CredentialEntryInfo(
- providerId = providerId,
- providerDisplayName = providerLabel,
- entryKey = it.key,
- entrySubkey = it.subkey,
- pendingIntent = credentialEntry.pendingIntent,
- fillInIntent = it.frameworkExtrasIntent,
- credentialType = CredentialType.PASSWORD,
- credentialTypeDisplayName = credentialEntry.typeDisplayName.toString(),
- userName = credentialEntry.username.toString(),
- displayName = credentialEntry.displayName?.toString(),
- icon = credentialEntry.icon.loadDrawable(context),
- shouldTintIcon = credentialEntry.isDefaultIcon,
- lastUsedTimeMillis = credentialEntry.lastUsedTime,
- isAutoSelectable = credentialEntry.isAutoSelectAllowed &&
- credentialEntry.autoSelectAllowedFromOption,
- ))
- }
- is PublicKeyCredentialEntry -> {
- result.add(CredentialEntryInfo(
- providerId = providerId,
- providerDisplayName = providerLabel,
- entryKey = it.key,
- entrySubkey = it.subkey,
- pendingIntent = credentialEntry.pendingIntent,
- fillInIntent = it.frameworkExtrasIntent,
- credentialType = CredentialType.PASSKEY,
- credentialTypeDisplayName = credentialEntry.typeDisplayName.toString(),
- userName = credentialEntry.username.toString(),
- displayName = credentialEntry.displayName?.toString(),
- icon = credentialEntry.icon.loadDrawable(context),
- shouldTintIcon = credentialEntry.isDefaultIcon,
- lastUsedTimeMillis = credentialEntry.lastUsedTime,
- isAutoSelectable = credentialEntry.isAutoSelectAllowed &&
- credentialEntry.autoSelectAllowedFromOption,
- ))
- }
- is CustomCredentialEntry -> {
- result.add(CredentialEntryInfo(
- providerId = providerId,
- providerDisplayName = providerLabel,
- entryKey = it.key,
- entrySubkey = it.subkey,
- pendingIntent = credentialEntry.pendingIntent,
- fillInIntent = it.frameworkExtrasIntent,
- credentialType = CredentialType.UNKNOWN,
- credentialTypeDisplayName =
- credentialEntry.typeDisplayName?.toString().orEmpty(),
- userName = credentialEntry.title.toString(),
- displayName = credentialEntry.subtitle?.toString(),
- icon = credentialEntry.icon.loadDrawable(context),
- shouldTintIcon = credentialEntry.isDefaultIcon,
- lastUsedTimeMillis = credentialEntry.lastUsedTime,
- isAutoSelectable = credentialEntry.isAutoSelectAllowed &&
- credentialEntry.autoSelectAllowedFromOption,
- ))
- }
- else -> Log.d(
- Constants.LOG_TAG,
- "Encountered unrecognized credential entry ${it.slice.spec?.type}"
- )
- }
- }
- return result
- }
-
- /**
- * @hide
- */
- fun parseCredentialEntryFromSlice(slice: Slice): CredentialEntry? {
- try {
- when (slice.spec?.type) {
- TYPE_PASSWORD_CREDENTIAL -> return PasswordCredentialEntry.fromSlice(slice)!!
- TYPE_PUBLIC_KEY_CREDENTIAL -> return PublicKeyCredentialEntry.fromSlice(slice)!!
- else -> return CustomCredentialEntry.fromSlice(slice)!!
- }
- } catch (e: Exception) {
- // Try CustomCredentialEntry.fromSlice one last time in case the cause was a failed
- // password / passkey parsing attempt.
- return CustomCredentialEntry.fromSlice(slice)
- }
- }
-
- /**
- * Note: caller required handle empty list due to parsing error.
- */
- private fun getAuthenticationEntryList(
- providerId: String,
- providerDisplayName: String,
- providerIcon: Drawable,
- authEntryList: List<AuthenticationEntry>,
- ): List<AuthenticationEntryInfo> {
- val result: MutableList<AuthenticationEntryInfo> = mutableListOf()
- authEntryList.forEach { entry ->
- val structuredAuthEntry =
- AuthenticationAction.fromSlice(entry.slice) ?: return@forEach
-
- val title: String =
- structuredAuthEntry.title.toString().ifEmpty { providerDisplayName }
-
- result.add(AuthenticationEntryInfo(
- providerId = providerId,
- entryKey = entry.key,
- entrySubkey = entry.subkey,
- pendingIntent = structuredAuthEntry.pendingIntent,
- fillInIntent = entry.frameworkExtrasIntent,
- title = title,
- providerDisplayName = providerDisplayName,
- icon = providerIcon,
- isUnlockedAndEmpty = entry.status != AuthenticationEntry.STATUS_LOCKED,
- isLastUnlocked =
- entry.status == AuthenticationEntry.STATUS_UNLOCKED_BUT_EMPTY_MOST_RECENT
- ))
- }
- return result
- }
-
- private fun getRemoteEntry(providerId: String, remoteEntry: Entry?): RemoteEntryInfo? {
- if (remoteEntry == null) {
- return null
- }
- val structuredRemoteEntry = RemoteEntry.fromSlice(remoteEntry.slice)
- ?: return null
- return RemoteEntryInfo(
- providerId = providerId,
- entryKey = remoteEntry.key,
- entrySubkey = remoteEntry.subkey,
- pendingIntent = structuredRemoteEntry.pendingIntent,
- fillInIntent = remoteEntry.frameworkExtrasIntent,
- )
- }
-
- /**
- * Note: caller required handle empty list due to parsing error.
- */
- private fun getActionEntryList(
- providerId: String,
- actionEntries: List<Entry>,
- providerIcon: Drawable,
- ): List<ActionEntryInfo> {
- val result: MutableList<ActionEntryInfo> = mutableListOf()
- actionEntries.forEach {
- val actionEntryUi = Action.fromSlice(it.slice) ?: return@forEach
- result.add(ActionEntryInfo(
- providerId = providerId,
- entryKey = it.key,
- entrySubkey = it.subkey,
- pendingIntent = actionEntryUi.pendingIntent,
- fillInIntent = it.frameworkExtrasIntent,
- title = actionEntryUi.title.toString(),
- icon = providerIcon,
- subTitle = actionEntryUi.subtitle?.toString(),
- ))
- }
- return result
- }
}
}
@@ -686,7 +465,8 @@ class CreateFlowUtils {
val result: MutableList<CreateOptionInfo> = mutableListOf()
creationEntries.forEach {
val createEntry = CreateEntry.fromSlice(it.slice) ?: return@forEach
- result.add(CreateOptionInfo(
+ result.add(
+ CreateOptionInfo(
providerId = providerId,
entryKey = it.key,
entrySubkey = it.subkey,
@@ -705,7 +485,8 @@ class CreateFlowUtils {
it.hasHint("androidx.credentials.provider.createEntry.SLICE_HINT_AUTO_" +
"SELECT_ALLOWED")
}?.text == "true",
- ))
+ )
+ )
}
return result.sortedWith(
compareByDescending { it.lastUsedTime }
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
index 281696dec717..20d2f09ced8f 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
@@ -48,10 +48,11 @@ import androidx.credentials.provider.CustomCredentialEntry
import androidx.credentials.provider.PasswordCredentialEntry
import androidx.credentials.provider.PublicKeyCredentialEntry
import com.android.credentialmanager.GetFlowUtils
-import com.android.credentialmanager.getflow.CredentialEntryInfo
+import com.android.credentialmanager.model.get.CredentialEntryInfo
import com.android.credentialmanager.getflow.ProviderDisplayInfo
-import com.android.credentialmanager.getflow.ProviderInfo
+import com.android.credentialmanager.model.get.ProviderInfo
import com.android.credentialmanager.getflow.toProviderDisplayInfo
+import com.android.credentialmanager.ktx.credentialEntry
import org.json.JSONObject
import java.util.concurrent.Executors
@@ -122,8 +123,7 @@ class CredentialAutofillService : AutofillService() {
val entryIconMap: MutableMap<String, Icon> = mutableMapOf()
candidateProviderDataList.forEach { provider ->
provider.credentialEntries.forEach { entry ->
- val credentialEntry = GetFlowUtils.parseCredentialEntryFromSlice(entry.slice)
- when (credentialEntry) {
+ when (val credentialEntry = entry.slice.credentialEntry) {
is PasswordCredentialEntry -> {
entryIconMap[entry.key + entry.subkey] = credentialEntry.icon
}
@@ -172,11 +172,11 @@ class CredentialAutofillService : AutofillService() {
}
private fun processProvidersForAutofillId(
- filLRequest: FillRequest,
- autofillId: AutofillId,
- providerList: List<ProviderInfo>,
- entryIconMap: Map<String, Icon>,
- fillResponseBuilder: FillResponse.Builder
+ filLRequest: FillRequest,
+ autofillId: AutofillId,
+ providerList: List<ProviderInfo>,
+ entryIconMap: Map<String, Icon>,
+ fillResponseBuilder: FillResponse.Builder
): Boolean {
if (providerList.isEmpty()) {
return false
@@ -200,7 +200,8 @@ class CredentialAutofillService : AutofillService() {
providerDisplayInfo.sortedUserNameToCredentialEntryList.forEach usernameLoop@ {
val primaryEntry = it.sortedCredentialEntryList.first()
val pendingIntent = primaryEntry.pendingIntent
- if (pendingIntent == null || primaryEntry.fillInIntent == null) {
+ val fillInIntent = primaryEntry.fillInIntent
+ if (pendingIntent == null || fillInIntent == null) {
// FillInIntent will not be null because autofillId was retrieved from it.
Log.e(TAG, "PendingIntent was missing from the entry.")
return@usernameLoop
@@ -245,7 +246,7 @@ class CredentialAutofillService : AutofillService() {
presentationBuilder.build())
.build())
.setAuthentication(pendingIntent.intentSender)
- .setAuthenticationExtras(primaryEntry.fillInIntent.extras)
+ .setAuthenticationExtras(fillInIntent.extras)
.build())
datasetAdded = true
}
@@ -322,8 +323,8 @@ class CredentialAutofillService : AutofillService() {
}
private fun copyProviderInfo(
- providerInfo: ProviderInfo,
- credentialList: List<CredentialEntryInfo>
+ providerInfo: ProviderInfo,
+ credentialList: List<CredentialEntryInfo>
): ProviderInfo {
return ProviderInfo(
providerInfo.id,
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
index d45b6f687193..14a91651753b 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
@@ -48,8 +48,8 @@ import androidx.compose.ui.unit.dp
import androidx.core.graphics.drawable.toBitmap
import com.android.credentialmanager.CredentialSelectorViewModel
import com.android.credentialmanager.R
-import com.android.credentialmanager.common.BaseEntry
-import com.android.credentialmanager.common.CredentialType
+import com.android.credentialmanager.model.EntryInfo
+import com.android.credentialmanager.model.CredentialType
import com.android.credentialmanager.common.ProviderActivityState
import com.android.credentialmanager.common.material.ModalBottomSheetDefaults
import com.android.credentialmanager.common.ui.ActionButton
@@ -68,6 +68,8 @@ import com.android.credentialmanager.common.ui.SheetContainerCard
import com.android.credentialmanager.common.ui.PasskeyBenefitRow
import com.android.credentialmanager.common.ui.HeadlineText
import com.android.credentialmanager.logging.CreateCredentialEvent
+import com.android.credentialmanager.model.creation.CreateOptionInfo
+import com.android.credentialmanager.model.creation.RemoteInfo
import com.android.credentialmanager.ui.theme.LocalAndroidColorScheme
import com.android.internal.logging.UiEventLogger.UiEventEnum
@@ -259,15 +261,15 @@ fun PasskeyIntroCard(
@Composable
fun MoreOptionsSelectionCard(
- requestDisplayInfo: RequestDisplayInfo,
- enabledProviderList: List<EnabledProviderInfo>,
- disabledProviderList: List<DisabledProviderInfo>?,
- sortedCreateOptionsPairs: List<Pair<CreateOptionInfo, EnabledProviderInfo>>,
- onBackCreationSelectionButtonSelected: () -> Unit,
- onOptionSelected: (ActiveEntry) -> Unit,
- onDisabledProvidersSelected: () -> Unit,
- onRemoteEntrySelected: (BaseEntry) -> Unit,
- onLog: @Composable (UiEventEnum) -> Unit,
+ requestDisplayInfo: RequestDisplayInfo,
+ enabledProviderList: List<EnabledProviderInfo>,
+ disabledProviderList: List<DisabledProviderInfo>?,
+ sortedCreateOptionsPairs: List<Pair<CreateOptionInfo, EnabledProviderInfo>>,
+ onBackCreationSelectionButtonSelected: () -> Unit,
+ onOptionSelected: (ActiveEntry) -> Unit,
+ onDisabledProvidersSelected: () -> Unit,
+ onRemoteEntrySelected: (EntryInfo) -> Unit,
+ onLog: @Composable (UiEventEnum) -> Unit,
) {
SheetContainerCard(topAppBar = {
MoreOptionTopAppBar(
@@ -378,14 +380,14 @@ fun NonDefaultUsageConfirmationCard(
@Composable
fun CreationSelectionCard(
- requestDisplayInfo: RequestDisplayInfo,
- enabledProviderList: List<EnabledProviderInfo>,
- providerInfo: EnabledProviderInfo,
- createOptionInfo: CreateOptionInfo,
- onOptionSelected: (BaseEntry) -> Unit,
- onConfirm: () -> Unit,
- onMoreOptionsSelected: () -> Unit,
- onLog: @Composable (UiEventEnum) -> Unit,
+ requestDisplayInfo: RequestDisplayInfo,
+ enabledProviderList: List<EnabledProviderInfo>,
+ providerInfo: EnabledProviderInfo,
+ createOptionInfo: CreateOptionInfo,
+ onOptionSelected: (EntryInfo) -> Unit,
+ onConfirm: () -> Unit,
+ onMoreOptionsSelected: () -> Unit,
+ onLog: @Composable (UiEventEnum) -> Unit,
) {
SheetContainerCard {
item {
@@ -474,11 +476,11 @@ fun CreationSelectionCard(
@Composable
fun ExternalOnlySelectionCard(
- requestDisplayInfo: RequestDisplayInfo,
- activeRemoteEntry: BaseEntry,
- onOptionSelected: (BaseEntry) -> Unit,
- onConfirm: () -> Unit,
- onLog: @Composable (UiEventEnum) -> Unit,
+ requestDisplayInfo: RequestDisplayInfo,
+ activeRemoteEntry: EntryInfo,
+ onOptionSelected: (EntryInfo) -> Unit,
+ onConfirm: () -> Unit,
+ onLog: @Composable (UiEventEnum) -> Unit,
) {
SheetContainerCard {
item { HeadlineIcon(imageVector = Icons.Outlined.QrCodeScanner) }
@@ -575,17 +577,14 @@ fun MoreAboutPasskeysIntroCard(
@Composable
fun PrimaryCreateOptionRow(
requestDisplayInfo: RequestDisplayInfo,
- entryInfo: BaseEntry,
- onOptionSelected: (BaseEntry) -> Unit
+ entryInfo: EntryInfo,
+ onOptionSelected: (EntryInfo) -> Unit
) {
Entry(
onClick = { onOptionSelected(entryInfo) },
- iconImageBitmap =
- if (entryInfo is CreateOptionInfo && entryInfo.profileIcon != null) {
- entryInfo.profileIcon.toBitmap().asImageBitmap()
- } else {
- requestDisplayInfo.typeIcon.toBitmap().asImageBitmap()
- },
+ iconImageBitmap = ((entryInfo as? CreateOptionInfo)?.profileIcon
+ ?: requestDisplayInfo.typeIcon)
+ .toBitmap().asImageBitmap(),
shouldApplyIconImageBitmapTint = !(entryInfo is CreateOptionInfo &&
entryInfo.profileIcon != null),
entryHeadlineText = requestDisplayInfo.title,
@@ -627,32 +626,33 @@ fun MoreOptionsInfoRow(
entryThirdLineText =
if (requestDisplayInfo.type == CredentialType.PASSKEY ||
requestDisplayInfo.type == CredentialType.PASSWORD) {
- if (createOptionInfo.passwordCount != null &&
- createOptionInfo.passkeyCount != null
- ) {
+ val passwordCount = createOptionInfo.passwordCount
+ val passkeyCount = createOptionInfo.passkeyCount
+ if (passwordCount != null && passkeyCount != null) {
stringResource(
R.string.more_options_usage_passwords_passkeys,
- createOptionInfo.passwordCount,
- createOptionInfo.passkeyCount
+ passwordCount,
+ passkeyCount
)
- } else if (createOptionInfo.passwordCount != null) {
+ } else if (passwordCount != null) {
stringResource(
R.string.more_options_usage_passwords,
- createOptionInfo.passwordCount
+ passwordCount
)
- } else if (createOptionInfo.passkeyCount != null) {
+ } else if (passkeyCount != null) {
stringResource(
R.string.more_options_usage_passkeys,
- createOptionInfo.passkeyCount
+ passkeyCount
)
} else {
null
}
} else {
- if (createOptionInfo.totalCredentialCount != null) {
+ val totalCredentialCount = createOptionInfo.totalCredentialCount
+ if (totalCredentialCount != null) {
stringResource(
R.string.more_options_usage_credentials,
- createOptionInfo.totalCredentialCount
+ totalCredentialCount
)
} else {
null
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
index e9e8c2e0ccbf..8b0ba87fa9be 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
@@ -16,22 +16,21 @@
package com.android.credentialmanager.createflow
-import android.app.PendingIntent
-import android.content.Intent
import android.graphics.drawable.Drawable
-import com.android.credentialmanager.common.BaseEntry
-import com.android.credentialmanager.common.CredentialType
-import java.time.Instant
+import com.android.credentialmanager.model.EntryInfo
+import com.android.credentialmanager.model.CredentialType
+import com.android.credentialmanager.model.creation.CreateOptionInfo
+import com.android.credentialmanager.model.creation.RemoteInfo
data class CreateCredentialUiState(
- val enabledProviders: List<EnabledProviderInfo>,
- val disabledProviders: List<DisabledProviderInfo>? = null,
- val currentScreenState: CreateScreenState,
- val requestDisplayInfo: RequestDisplayInfo,
- val sortedCreateOptionsPairs: List<Pair<CreateOptionInfo, EnabledProviderInfo>>,
- val activeEntry: ActiveEntry? = null,
- val remoteEntry: RemoteInfo? = null,
- val foundCandidateFromUserDefaultProvider: Boolean,
+ val enabledProviders: List<EnabledProviderInfo>,
+ val disabledProviders: List<DisabledProviderInfo>? = null,
+ val currentScreenState: CreateScreenState,
+ val requestDisplayInfo: RequestDisplayInfo,
+ val sortedCreateOptionsPairs: List<Pair<CreateOptionInfo, EnabledProviderInfo>>,
+ val activeEntry: ActiveEntry? = null,
+ val remoteEntry: RemoteInfo? = null,
+ val foundCandidateFromUserDefaultProvider: Boolean,
)
internal fun isFlowAutoSelectable(
@@ -75,44 +74,6 @@ class DisabledProviderInfo(
displayName: String,
) : ProviderInfo(icon, id, displayName)
-class CreateOptionInfo(
- providerId: String,
- entryKey: String,
- entrySubkey: String,
- pendingIntent: PendingIntent?,
- fillInIntent: Intent?,
- val userProviderDisplayName: String,
- val profileIcon: Drawable?,
- val passwordCount: Int?,
- val passkeyCount: Int?,
- val totalCredentialCount: Int?,
- val lastUsedTime: Instant,
- val footerDescription: String?,
- val allowAutoSelect: Boolean,
-) : BaseEntry(
- providerId,
- entryKey,
- entrySubkey,
- pendingIntent,
- fillInIntent,
- shouldTerminateUiUponSuccessfulProviderResult = true,
-)
-
-class RemoteInfo(
- providerId: String,
- entryKey: String,
- entrySubkey: String,
- pendingIntent: PendingIntent?,
- fillInIntent: Intent?,
-) : BaseEntry(
- providerId,
- entryKey,
- entrySubkey,
- pendingIntent,
- fillInIntent,
- shouldTerminateUiUponSuccessfulProviderResult = true,
-)
-
data class RequestDisplayInfo(
val title: String,
val subtitle: String?,
@@ -131,8 +92,8 @@ data class RequestDisplayInfo(
* user selects a different entry on the more option page.
*/
data class ActiveEntry (
- val activeProvider: EnabledProviderInfo,
- val activeEntryInfo: BaseEntry,
+ val activeProvider: EnabledProviderInfo,
+ val activeEntryInfo: EntryInfo,
)
/** The name of the current screen. */
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
index 72d030b3e657..4ed84b908865 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
@@ -48,8 +48,9 @@ import androidx.compose.ui.unit.dp
import androidx.core.graphics.drawable.toBitmap
import com.android.credentialmanager.CredentialSelectorViewModel
import com.android.credentialmanager.R
-import com.android.credentialmanager.common.BaseEntry
-import com.android.credentialmanager.common.CredentialType
+import com.android.credentialmanager.model.EntryInfo
+import com.android.credentialmanager.model.CredentialType
+import com.android.credentialmanager.model.get.ProviderInfo
import com.android.credentialmanager.common.ProviderActivityState
import com.android.credentialmanager.common.material.ModalBottomSheetDefaults
import com.android.credentialmanager.common.ui.ActionButton
@@ -68,6 +69,10 @@ import com.android.credentialmanager.common.ui.HeadlineIcon
import com.android.credentialmanager.common.ui.LargeLabelTextOnSurfaceVariant
import com.android.credentialmanager.common.ui.Snackbar
import com.android.credentialmanager.logging.GetCredentialEvent
+import com.android.credentialmanager.model.get.ActionEntryInfo
+import com.android.credentialmanager.model.get.AuthenticationEntryInfo
+import com.android.credentialmanager.model.get.CredentialEntryInfo
+import com.android.credentialmanager.model.get.RemoteEntryInfo
import com.android.credentialmanager.userAndDisplayNameForPasskey
import com.android.internal.logging.UiEventLogger.UiEventEnum
@@ -175,8 +180,8 @@ fun PrimarySelectionCard(
requestDisplayInfo: RequestDisplayInfo,
providerDisplayInfo: ProviderDisplayInfo,
providerInfoList: List<ProviderInfo>,
- activeEntry: BaseEntry?,
- onEntrySelected: (BaseEntry) -> Unit,
+ activeEntry: EntryInfo?,
+ onEntrySelected: (EntryInfo) -> Unit,
onConfirm: () -> Unit,
onMoreOptionSelected: () -> Unit,
onLog: @Composable (UiEventEnum) -> Unit,
@@ -358,7 +363,7 @@ fun PrimarySelectionCard(
fun AllSignInOptionCard(
providerInfoList: List<ProviderInfo>,
providerDisplayInfo: ProviderDisplayInfo,
- onEntrySelected: (BaseEntry) -> Unit,
+ onEntrySelected: (EntryInfo) -> Unit,
onBackButtonClicked: () -> Unit,
onCancel: () -> Unit,
onLog: @Composable (UiEventEnum) -> Unit,
@@ -436,7 +441,7 @@ fun HeadlineProviderIconAndName(
@Composable
fun ActionChips(
providerInfoList: List<ProviderInfo>,
- onEntrySelected: (BaseEntry) -> Unit,
+ onEntrySelected: (EntryInfo) -> Unit,
isFirstSection: Boolean,
) {
val actionChips = providerInfoList.flatMap { it.actionEntryList }
@@ -460,7 +465,7 @@ fun ActionChips(
@Composable
fun RemoteEntryCard(
remoteEntry: RemoteEntryInfo,
- onEntrySelected: (BaseEntry) -> Unit,
+ onEntrySelected: (EntryInfo) -> Unit,
isFirstSection: Boolean,
) {
CredentialListSectionHeader(
@@ -486,7 +491,7 @@ fun RemoteEntryCard(
@Composable
fun LockedCredentials(
authenticationEntryList: List<AuthenticationEntryInfo>,
- onEntrySelected: (BaseEntry) -> Unit,
+ onEntrySelected: (EntryInfo) -> Unit,
isFirstSection: Boolean,
) {
CredentialListSectionHeader(
@@ -508,7 +513,7 @@ fun LockedCredentials(
@Composable
fun PerUserNameCredentials(
perUserNameCredentialEntryList: PerUserNameCredentialEntryList,
- onEntrySelected: (BaseEntry) -> Unit,
+ onEntrySelected: (EntryInfo) -> Unit,
isFirstSection: Boolean,
) {
CredentialListSectionHeader(
@@ -532,7 +537,7 @@ fun PerUserNameCredentials(
@Composable
fun CredentialEntryRow(
credentialEntryInfo: CredentialEntryInfo,
- onEntrySelected: (BaseEntry) -> Unit,
+ onEntrySelected: (EntryInfo) -> Unit,
enforceOneLine: Boolean = false,
onTextLayout: (TextLayoutResult) -> Unit = {},
) {
@@ -571,7 +576,7 @@ fun CredentialEntryRow(
@Composable
fun AuthenticationEntryRow(
authenticationEntryInfo: AuthenticationEntryInfo,
- onEntrySelected: (BaseEntry) -> Unit,
+ onEntrySelected: (EntryInfo) -> Unit,
enforceOneLine: Boolean = false,
) {
Entry(
@@ -596,7 +601,7 @@ fun AuthenticationEntryRow(
@Composable
fun ActionEntryRow(
actionEntryInfo: ActionEntryInfo,
- onEntrySelected: (BaseEntry) -> Unit,
+ onEntrySelected: (EntryInfo) -> Unit,
) {
ActionEntry(
iconImageBitmap = actionEntryInfo.icon.toBitmap().asImageBitmap(),
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
index 447a9d2aaa8d..46bebc4073ab 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
@@ -16,21 +16,21 @@
package com.android.credentialmanager.getflow
-import android.app.PendingIntent
-import android.content.Intent
import android.graphics.drawable.Drawable
-import com.android.credentialmanager.common.BaseEntry
-import com.android.credentialmanager.common.CredentialType
+import com.android.credentialmanager.model.get.ProviderInfo
+import com.android.credentialmanager.model.EntryInfo
+import com.android.credentialmanager.model.CredentialType
+import com.android.credentialmanager.model.get.AuthenticationEntryInfo
+import com.android.credentialmanager.model.get.CredentialEntryInfo
+import com.android.credentialmanager.model.get.RemoteEntryInfo
import com.android.internal.util.Preconditions
-import java.time.Instant
-
data class GetCredentialUiState(
val providerInfoList: List<ProviderInfo>,
val requestDisplayInfo: RequestDisplayInfo,
val providerDisplayInfo: ProviderDisplayInfo = toProviderDisplayInfo(providerInfoList),
val currentScreenState: GetScreenState = toGetScreenState(providerDisplayInfo),
- val activeEntry: BaseEntry? = toActiveEntry(providerDisplayInfo),
+ val activeEntry: EntryInfo? = toActiveEntry(providerDisplayInfo),
val isNoAccount: Boolean = false,
)
@@ -58,20 +58,6 @@ internal fun findAutoSelectEntry(providerDisplayInfo: ProviderDisplayInfo): Cred
return null
}
-data class ProviderInfo(
- /**
- * Unique id (component name) of this provider.
- * Not for display purpose - [displayName] should be used for ui rendering.
- */
- val id: String,
- val icon: Drawable,
- val displayName: String,
- val credentialEntryList: List<CredentialEntryInfo>,
- val authenticationEntryList: List<AuthenticationEntryInfo>,
- val remoteEntry: RemoteEntryInfo?,
- val actionEntryList: List<ActionEntryInfo>,
-)
-
/** Display-centric data structure derived from the [ProviderInfo]. This abstraction is not grouping
* by the provider id but instead focuses on structures convenient for display purposes. */
data class ProviderDisplayInfo(
@@ -84,87 +70,6 @@ data class ProviderDisplayInfo(
val remoteEntry: RemoteEntryInfo?
)
-class CredentialEntryInfo(
- providerId: String,
- entryKey: String,
- entrySubkey: String,
- pendingIntent: PendingIntent?,
- fillInIntent: Intent?,
- /** Type of this credential used for sorting. Not localized so must not be directly displayed. */
- val credentialType: CredentialType,
- /** Localized type value of this credential used for display purpose. */
- val credentialTypeDisplayName: String,
- val providerDisplayName: String,
- val userName: String,
- val displayName: String?,
- val icon: Drawable?,
- val shouldTintIcon: Boolean,
- val lastUsedTimeMillis: Instant?,
- val isAutoSelectable: Boolean,
-) : BaseEntry(
- providerId,
- entryKey,
- entrySubkey,
- pendingIntent,
- fillInIntent,
- shouldTerminateUiUponSuccessfulProviderResult = true,
-)
-
-class AuthenticationEntryInfo(
- providerId: String,
- entryKey: String,
- entrySubkey: String,
- pendingIntent: PendingIntent?,
- fillInIntent: Intent?,
- val title: String,
- val providerDisplayName: String,
- val icon: Drawable,
- // The entry had been unlocked and turned out to be empty. Used to determine whether to
- // show "Tap to unlock" or "No sign-in info" for this entry.
- val isUnlockedAndEmpty: Boolean,
- // True if the entry was the last one unlocked. Used to show the no sign-in info snackbar.
- val isLastUnlocked: Boolean,
-) : BaseEntry(
- providerId,
- entryKey, entrySubkey,
- pendingIntent,
- fillInIntent,
- shouldTerminateUiUponSuccessfulProviderResult = false,
-)
-
-class RemoteEntryInfo(
- providerId: String,
- entryKey: String,
- entrySubkey: String,
- pendingIntent: PendingIntent?,
- fillInIntent: Intent?,
-) : BaseEntry(
- providerId,
- entryKey,
- entrySubkey,
- pendingIntent,
- fillInIntent,
- shouldTerminateUiUponSuccessfulProviderResult = true,
-)
-
-class ActionEntryInfo(
- providerId: String,
- entryKey: String,
- entrySubkey: String,
- pendingIntent: PendingIntent?,
- fillInIntent: Intent?,
- val title: String,
- val icon: Drawable,
- val subTitle: String?,
-) : BaseEntry(
- providerId,
- entryKey,
- entrySubkey,
- pendingIntent,
- fillInIntent,
- shouldTerminateUiUponSuccessfulProviderResult = true,
-)
-
data class RequestDisplayInfo(
val appName: String,
val preferImmediatelyAvailableCredentials: Boolean,
@@ -218,8 +123,8 @@ fun toProviderDisplayInfo(
val remoteEntryList = mutableListOf<RemoteEntryInfo>()
providerInfoList.forEach { providerInfo ->
authenticationEntryList.addAll(providerInfo.authenticationEntryList)
- if (providerInfo.remoteEntry != null) {
- remoteEntryList.add(providerInfo.remoteEntry)
+ providerInfo.remoteEntry?.let {
+ remoteEntryList.add(it)
}
// There can only be at most one remote entry
Preconditions.checkState(remoteEntryList.size <= 1)
@@ -260,11 +165,11 @@ fun toProviderDisplayInfo(
private fun toActiveEntry(
providerDisplayInfo: ProviderDisplayInfo,
-): BaseEntry? {
+): EntryInfo? {
val sortedUserNameToCredentialEntryList =
providerDisplayInfo.sortedUserNameToCredentialEntryList
val authenticationEntryList = providerDisplayInfo.authenticationEntryList
- var activeEntry: BaseEntry? = null
+ var activeEntry: EntryInfo? = null
if (sortedUserNameToCredentialEntryList
.size == 1 && authenticationEntryList.isEmpty()
) {
@@ -302,17 +207,18 @@ internal class CredentialEntryInfoComparatorByTypeThenTimestamp : Comparator<Cre
return 1
}
}
-
+ val p0LastUsedTimeMillis = p0.lastUsedTimeMillis
+ val p1LastUsedTimeMillis = p1.lastUsedTimeMillis
// Then order by last used timestamp
- if (p0.lastUsedTimeMillis != null && p1.lastUsedTimeMillis != null) {
- if (p0.lastUsedTimeMillis < p1.lastUsedTimeMillis) {
+ if (p0LastUsedTimeMillis != null && p1LastUsedTimeMillis != null) {
+ if (p0LastUsedTimeMillis < p1LastUsedTimeMillis) {
return 1
- } else if (p0.lastUsedTimeMillis > p1.lastUsedTimeMillis) {
+ } else if (p0LastUsedTimeMillis > p1LastUsedTimeMillis) {
return -1
}
- } else if (p0.lastUsedTimeMillis != null) {
+ } else if (p0LastUsedTimeMillis != null) {
return -1
- } else if (p1.lastUsedTimeMillis != null) {
+ } else if (p1LastUsedTimeMillis != null) {
return 1
}
return 0
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/di/AppModule.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/di/AppModule.kt
index 6ededf3411bf..d8a6019b68a2 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/di/AppModule.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/di/AppModule.kt
@@ -1,29 +1,20 @@
package com.android.credentialmanager.di
-import android.content.Context
-import android.content.pm.PackageManager
import com.android.credentialmanager.client.CredentialManagerClient
import com.android.credentialmanager.client.impl.CredentialManagerClientImpl
+import dagger.Binds
import dagger.Module
-import dagger.Provides
import dagger.hilt.InstallIn
-import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
-internal object AppModule {
- @Provides
+abstract class AppModule {
+ @Binds
@Singleton
- @JvmStatic
- fun providePackageManager(@ApplicationContext context: Context): PackageManager =
- context.packageManager
-
- @Provides
- @Singleton
- @JvmStatic
- fun provideCredentialManagerClient(packageManager: PackageManager): CredentialManagerClient =
- CredentialManagerClientImpl(packageManager)
+ abstract fun provideCredentialManagerClient(
+ client: CredentialManagerClientImpl
+ ): CredentialManagerClient
}
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt
index f2f878e8ac2f..14b992a0d0e9 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt
@@ -23,8 +23,8 @@ fun Request.Get.toGet(): CredentialSelectorUiState.Get {
// TODO: b/301206470 returning a hard coded state for MVP
if (true) return CredentialSelectorUiState.Get.SingleProviderSinglePassword
- return if (providers.size == 1) {
- if (passwordEntries.size == 1) {
+ return if (providerInfos.size == 1) {
+ if (providerInfos.first().credentialEntryList.size == 1) {
CredentialSelectorUiState.Get.SingleProviderSinglePassword
} else {
TODO() // b/301206470 - Implement other get flows
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt
index c28df3e8895a..b64f58192d23 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt
@@ -76,7 +76,9 @@ fun SinglePasswordScreen(
}
SideEffect {
- launcher.launch(state.intentSenderRequest)
+ state.intentSenderRequest?.let {
+ launcher.launch(it)
+ }
}
}
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreenViewModel.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreenViewModel.kt
index fb72c544c978..26bee1f8d191 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreenViewModel.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreenViewModel.kt
@@ -26,9 +26,9 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.android.credentialmanager.TAG
import com.android.credentialmanager.ktx.getIntentSenderRequest
-import com.android.credentialmanager.model.Password
import com.android.credentialmanager.model.Request
import com.android.credentialmanager.client.CredentialManagerClient
+import com.android.credentialmanager.model.get.CredentialEntryInfo
import com.android.credentialmanager.ui.model.PasswordUiModel
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
@@ -44,7 +44,7 @@ class SinglePasswordScreenViewModel @Inject constructor(
private var initializeCalled = false
private lateinit var requestGet: Request.Get
- private lateinit var password: Password
+ private lateinit var entryInfo: CredentialEntryInfo
private val _uiState =
MutableStateFlow<SinglePasswordScreenUiState>(SinglePasswordScreenUiState.Idle)
@@ -63,14 +63,15 @@ class SinglePasswordScreenViewModel @Inject constructor(
_uiState.value = SinglePasswordScreenUiState.Error
} else {
requestGet = request
- if (requestGet.passwordEntries.isEmpty()) {
+
+ if (requestGet.providerInfos.all { it.credentialEntryList.isEmpty() }) {
Log.d(TAG, "Empty passwordEntries")
_uiState.value = SinglePasswordScreenUiState.Error
} else {
- password = requestGet.passwordEntries.first()
+ entryInfo = requestGet.providerInfos.first().credentialEntryList.first()
_uiState.value = SinglePasswordScreenUiState.Loaded(
PasswordUiModel(
- email = password.passwordCredentialEntry.username.toString(),
+ email = entryInfo.userName,
)
)
}
@@ -84,7 +85,7 @@ class SinglePasswordScreenViewModel @Inject constructor(
fun onOKClick() {
_uiState.value = SinglePasswordScreenUiState.PasswordSelected(
- intentSenderRequest = password.getIntentSenderRequest()
+ intentSenderRequest = entryInfo.getIntentSenderRequest()
)
}
@@ -94,9 +95,9 @@ class SinglePasswordScreenViewModel @Inject constructor(
) {
val userSelectionDialogResult = UserSelectionDialogResult(
requestGet.token,
- password.providerId,
- password.entry.key,
- password.entry.subkey,
+ entryInfo.providerId,
+ entryInfo.entryKey,
+ entryInfo.entrySubkey,
if (resultCode != null) ProviderPendingIntentResponse(resultCode, resultData) else null
)
credentialManagerClient.sendResult(userSelectionDialogResult)
@@ -108,7 +109,7 @@ sealed class SinglePasswordScreenUiState {
data object Idle : SinglePasswordScreenUiState()
data class Loaded(val passwordUiModel: PasswordUiModel) : SinglePasswordScreenUiState()
data class PasswordSelected(
- val intentSenderRequest: IntentSenderRequest
+ val intentSenderRequest: IntentSenderRequest?
) : SinglePasswordScreenUiState()
data object Cancel : SinglePasswordScreenUiState()
diff --git a/packages/PackageInstaller/Android.bp b/packages/PackageInstaller/Android.bp
index 38bd7d5f3944..6213b34034af 100644
--- a/packages/PackageInstaller/Android.bp
+++ b/packages/PackageInstaller/Android.bp
@@ -49,6 +49,7 @@ android_app {
"androidx.fragment_fragment",
"androidx.lifecycle_lifecycle-livedata",
"androidx.lifecycle_lifecycle-extensions",
+ "android.content.pm.flags-aconfig-java",
],
lint: {
@@ -75,6 +76,7 @@ android_app {
"androidx.fragment_fragment",
"androidx.lifecycle_lifecycle-livedata",
"androidx.lifecycle_lifecycle-extensions",
+ "android.content.pm.flags-aconfig-java",
],
aaptflags: ["--product tablet"],
@@ -103,6 +105,7 @@ android_app {
"androidx.fragment_fragment",
"androidx.lifecycle_lifecycle-livedata",
"androidx.lifecycle_lifecycle-extensions",
+ "android.content.pm.flags-aconfig-java",
],
aaptflags: ["--product tv"],
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
index e2107ebe2525..418705845065 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
@@ -16,12 +16,14 @@
package com.android.packageinstaller;
+import static android.content.pm.Flags.usePiaV2;
import static com.android.packageinstaller.PackageUtil.getMaxTargetSdkVersionForUid;
import android.Manifest;
import android.app.Activity;
import android.app.DialogFragment;
import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -57,14 +59,21 @@ public class InstallStart extends Activity {
private final boolean mLocalLOGV = false;
- // TODO (sumedhsen): Replace with an Android Feature Flag once implemented
- private static final boolean USE_PIA_V2 = false;
-
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- if (USE_PIA_V2) {
+ mPackageManager = getPackageManager();
+ if (usePiaV2()) {
+ Log.i(TAG, "Using Pia V2");
+
+ mPackageManager.setComponentEnabledSetting(new ComponentName(this,
+ com.android.packageinstaller.InstallEventReceiver.class),
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0);
+ mPackageManager.setComponentEnabledSetting(new ComponentName(this,
+ com.android.packageinstaller.v2.model.InstallEventReceiver.class),
+ PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
+
Intent piaV2 = new Intent(getIntent());
piaV2.putExtra(InstallLaunch.EXTRA_CALLING_PKG_NAME, getCallingPackage());
piaV2.putExtra(InstallLaunch.EXTRA_CALLING_PKG_UID, getLaunchedFromUid());
@@ -74,7 +83,6 @@ public class InstallStart extends Activity {
finish();
return;
}
- mPackageManager = getPackageManager();
mUserManager = getSystemService(UserManager.class);
Intent intent = getIntent();
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java
index 34062a4cbde6..ba627e9e9202 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java
@@ -17,8 +17,8 @@
package com.android.packageinstaller;
import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.content.pm.Flags.usePiaV2;
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
-
import static com.android.packageinstaller.PackageUtil.getMaxTargetSdkVersionForUid;
import android.Manifest;
@@ -81,9 +81,6 @@ public class UninstallerActivity extends Activity {
private String mPackageName;
private DialogInfo mDialogInfo;
- // TODO (sumedhsen): Replace with an Android Feature Flag once implemented
- private static final boolean USE_PIA_V2 = false;
-
@Override
public void onCreate(Bundle icicle) {
getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
@@ -92,7 +89,18 @@ public class UninstallerActivity extends Activity {
// be stale, if e.g. the app was uninstalled while the activity was destroyed.
super.onCreate(null);
- if (USE_PIA_V2 && !isTv()) {
+ if (usePiaV2() && !isTv()) {
+ Log.i(TAG, "Using Pia V2");
+
+ PackageManager pm = getPackageManager();
+ pm.setComponentEnabledSetting(
+ new ComponentName(this, com.android.packageinstaller.UninstallEventReceiver.class),
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0);
+ pm.setComponentEnabledSetting(
+ new ComponentName(this,
+ com.android.packageinstaller.v2.model.UninstallEventReceiver.class),
+ PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
+
boolean returnResult = getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false);
Intent piaV2 = new Intent(getIntent());
piaV2.putExtra(UninstallLaunch.EXTRA_CALLING_PKG_UID, getLaunchedFromUid());
diff --git a/packages/SettingsLib/Spa/build.gradle.kts b/packages/SettingsLib/Spa/build.gradle.kts
index 80b944f5749f..60bf48c8b75e 100644
--- a/packages/SettingsLib/Spa/build.gradle.kts
+++ b/packages/SettingsLib/Spa/build.gradle.kts
@@ -25,11 +25,11 @@ plugins {
alias(libs.plugins.kotlin.android) apply false
}
-val androidTop : String = File(rootDir, "../../../../..").canonicalPath
+val androidTop: String = File(rootDir, "../../../../..").canonicalPath
allprojects {
extra["androidTop"] = androidTop
- extra["jetpackComposeVersion"] = "1.6.0-alpha08"
+ extra["jetpackComposeVersion"] = "1.6.0-beta01"
}
subprojects {
diff --git a/packages/SettingsLib/Spa/spa/build.gradle.kts b/packages/SettingsLib/Spa/spa/build.gradle.kts
index 4335173dd706..acd90f3c4f4d 100644
--- a/packages/SettingsLib/Spa/spa/build.gradle.kts
+++ b/packages/SettingsLib/Spa/spa/build.gradle.kts
@@ -57,13 +57,13 @@ dependencies {
api("androidx.slice:slice-builders:1.1.0-alpha02")
api("androidx.slice:slice-core:1.1.0-alpha02")
api("androidx.slice:slice-view:1.1.0-alpha02")
- api("androidx.compose.material3:material3:1.2.0-alpha10")
+ api("androidx.compose.material3:material3:1.2.0-alpha11")
api("androidx.compose.material:material-icons-extended:$jetpackComposeVersion")
api("androidx.compose.runtime:runtime-livedata:$jetpackComposeVersion")
api("androidx.compose.ui:ui-tooling-preview:$jetpackComposeVersion")
api("androidx.lifecycle:lifecycle-livedata-ktx")
api("androidx.lifecycle:lifecycle-runtime-compose")
- api("androidx.navigation:navigation-compose:2.7.5")
+ api("androidx.navigation:navigation-compose:2.7.4")
api("com.github.PhilJay:MPAndroidChart:v3.1.0-alpha")
api("com.google.android.material:material:1.7.0-alpha03")
debugApi("androidx.compose.ui:ui-tooling:$jetpackComposeVersion")
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTheme.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTheme.kt
index 26372b6bfd32..c395558b769c 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTheme.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTheme.kt
@@ -17,9 +17,7 @@
package com.android.settingslib.spa.framework.theme
import androidx.compose.foundation.isSystemInDarkTheme
-import androidx.compose.material.ripple.LocalRippleTheme
-import androidx.compose.material.ripple.RippleAlpha
-import androidx.compose.material.ripple.RippleTheme
+import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
@@ -39,7 +37,7 @@ fun SettingsTheme(content: @Composable () -> Unit) {
MaterialTheme(colorScheme = colorScheme, typography = rememberSettingsTypography()) {
CompositionLocalProvider(
LocalColorScheme provides settingsColorScheme(isDarkTheme),
- LocalRippleTheme provides SettingsRippleTheme,
+ LocalContentColor provides MaterialTheme.colorScheme.onSurface,
) {
content()
}
@@ -52,19 +50,3 @@ object SettingsTheme {
@ReadOnlyComposable
get() = LocalColorScheme.current
}
-
-private object SettingsRippleTheme : RippleTheme {
- @Composable
- override fun defaultColor() = MaterialTheme.colorScheme.onSurface
-
- @Composable
- override fun rippleAlpha() = RippleAlpha
-}
-
-/** Alpha levels for all content. */
-private val RippleAlpha = RippleAlpha(
- pressedAlpha = 0.48f,
- focusedAlpha = 0.48f,
- draggedAlpha = 0.32f,
- hoveredAlpha = 0.16f,
-)
diff --git a/packages/SettingsLib/src/com/android/settingslib/PrimarySwitchPreference.java b/packages/SettingsLib/src/com/android/settingslib/PrimarySwitchPreference.java
index 0a2d9fc3372e..e41126f03c60 100644
--- a/packages/SettingsLib/src/com/android/settingslib/PrimarySwitchPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/PrimarySwitchPreference.java
@@ -140,12 +140,6 @@ public class PrimarySwitchPreference extends RestrictedPreference {
}
}
- @Override
- public void setEnabled(boolean enabled) {
- super.setEnabled(enabled);
- setSwitchEnabled(enabled);
- }
-
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
public boolean isSwitchEnabled() {
return mEnableSwitch;
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
index 8b0f19d455d2..29ea25e13835 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
@@ -22,7 +22,6 @@ import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.UserHandle;
import android.text.TextUtils;
@@ -237,15 +236,13 @@ public class RestrictedPreferenceHelper {
}
private void updateDisabledState() {
- boolean isEnabled = !(mDisabledByAdmin || mDisabledByAppOps);
if (!(mPreference instanceof RestrictedTopLevelPreference)) {
- mPreference.setEnabled(isEnabled);
+ mPreference.setEnabled(!(mDisabledByAdmin || mDisabledByAppOps));
}
- Drawable icon = mPreference.getIcon();
- if (!isEnabled && icon != null) {
- Utils.convertToGrayscale(icon);
- mPreference.setIcon(icon);
+ if (mPreference instanceof PrimarySwitchPreference) {
+ ((PrimarySwitchPreference) mPreference)
+ .setSwitchEnabled(!(mDisabledByAdmin || mDisabledByAppOps));
}
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index f03263b71138..107d5f8a8ae9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -728,14 +728,4 @@ public class Utils {
return false;
}
- /**
- * Convert a drawable to grayscale drawable
- */
- public static void convertToGrayscale(@NonNull Drawable drawable) {
- ColorMatrix matrix = new ColorMatrix();
- matrix.setSaturation(0.0f);
-
- ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
- drawable.setColorFilter(filter);
- }
}
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index efed8c3c1ef4..85e87691ac85 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -235,6 +235,7 @@ public class SettingsBackupTest {
Settings.Global.DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR,
Settings.Global.DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH,
Settings.Global.DEVICE_DEMO_MODE,
+ Settings.Global.DEVICE_IDLE_CONSTANTS,
Settings.Global.DISABLE_WINDOW_BLURS,
Settings.Global.BATTERY_SAVER_CONSTANTS,
Settings.Global.BATTERY_TIP_CONSTANTS,
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index d78038ecee61..7cf562f48ff3 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -242,184 +242,10 @@ filegroup {
}
filegroup {
- name: "SystemUI-test-fakes",
- srcs: [
- /* Status bar fakes */
- "tests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/FakeAirplaneModeRepository.kt",
- "tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/FakeConnectivityRepository.kt",
- "tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt",
- "tests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt",
-
- /* QS fakes */
- "tests/src/com/android/systemui/qs/pipeline/domain/interactor/FakeQSTile.kt",
- ],
- path: "tests/src",
-}
-
-filegroup {
- name: "SystemUI-tests-robolectric-pilots",
- srcs: [
- /* Keyguard converted tests */
- // data
- "tests/src/com/android/systemui/bouncer/data/repository/SimBouncerRepositoryTest.kt",
- "tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt",
- "tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt",
- "tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt",
- "tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt",
- "tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt",
- "tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt",
- "tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt",
- "tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt",
- "tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt",
- "tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt",
- "tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt",
- "tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt",
- "tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt",
- "tests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt",
- "tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt",
- "tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt",
- "tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt",
- "tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt",
- // domain
- "tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt",
- "tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt",
- "tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt",
- "tests/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractorTest.kt",
- "tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt",
- "tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt",
- "tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt",
- "tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt",
- "tests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt",
- // ui
- "tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt",
- "tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt",
- "tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt",
- "tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt",
- "tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt",
- "tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt",
- "tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt",
- // Keyguard helper
- "tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt",
- "tests/src/com/android/systemui/dock/DockManagerFake.java",
- "tests/src/com/android/systemui/dump/LogBufferHelper.kt",
- "tests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java",
-
- /* Biometric converted tests */
- "tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt",
- "tests/src/com/android/systemui/biometrics/AuthControllerTest.java",
- "tests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java",
- "tests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt",
- "tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt",
- "tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt",
- "tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java",
- "tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java",
- "tests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java",
- "tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java",
- "tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerTest.java",
- "tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt",
- "tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt",
- "tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt",
-
- /* Status bar wifi converted tests */
- "tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt",
- "tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt",
- "tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt",
- "tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt",
- "tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt",
- "tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt",
- "tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt",
-
- /* Bouncer UI tests */
- "tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt",
- "tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt",
- "tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java",
- "tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt",
- "tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java",
- "tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt",
- "tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java",
- "tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt",
- "tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt",
-
- /* Communal tests */
- "tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt",
- "tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt",
- "tests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt",
-
- /* Dream tests */
- "tests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java",
- "tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java",
- "tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java",
- "tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java",
- "tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java",
- "tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java",
- "tests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java",
- "tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt",
- "tests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt",
- "tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java",
- "tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java",
- "tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java",
- "tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java",
- "tests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java",
- "tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java",
-
- /* Smartspace tests */
- "tests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt",
- "tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt",
- "tests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt",
- "tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt",
-
- /* Quick Settings new pipeline converted tests */
- "tests/src/com/android/systemui/qs/pipeline/data/**/*Test.kt",
- "tests/src/com/android/systemui/qs/pipeline/domain/**/*Test.kt",
- "tests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt",
- "tests/src/com/android/systemui/qs/tiles/base/**/*.kt",
- "tests/src/com/android/systemui/qs/tiles/viewmodel/**/*.kt",
- "tests/src/com/android/systemui/qs/tiles/impl/**/*.kt",
-
- /* Authentication */
- "tests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt",
- "tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt",
-
- /* Device entry */
- "tests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt",
- "tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt",
-
- /* Bouncer scene */
- "tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt",
- "tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt",
- "tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt",
- "tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt",
- "tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt",
- "tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt",
- "tests/src/com/android/systemui/bouncer/ui/viewmodel/PinInputViewModelTest.kt",
-
- /* Lockscreen scene */
- "tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt",
-
- /* Shade scene */
- "tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt",
- "tests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt",
-
- /* Quick Settings scene */
- "tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt",
-
- /* Flexiglass / Scene framework tests */
- "tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt",
- "tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt",
- "tests/src/com/android/systemui/scene/data/repository/WindowRootViewVisibilityRepositoryTest.kt",
- "tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt",
- "tests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt",
- "tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt",
- "tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt",
-
- ],
- path: "tests/src",
-}
-
-filegroup {
name: "SystemUI-tests-multivalent",
srcs: [
"multivalentTests/src/**/*.kt",
+ "multivalentTests/src/**/*.java",
],
path: "multivalentTests/src",
}
@@ -597,8 +423,6 @@ android_robolectric_test {
"tests/robolectric/src/**/*.kt",
"tests/robolectric/src/**/*.java",
":SystemUI-tests-utils",
- ":SystemUI-test-fakes",
- ":SystemUI-tests-robolectric-pilots",
":SystemUI-tests-multivalent",
],
static_libs: [
diff --git a/packages/SystemUI/aconfig/OWNERS b/packages/SystemUI/aconfig/OWNERS
index e1a7a0f84ad0..902ba907a100 100644
--- a/packages/SystemUI/aconfig/OWNERS
+++ b/packages/SystemUI/aconfig/OWNERS
@@ -1 +1,2 @@
per-file accessibility.aconfig = file:/core/java/android/view/accessibility/OWNERS
+per-file biometrics_framework.aconfig = file:/services/core/java/com/android/server/biometrics/OWNERS
diff --git a/packages/SystemUI/aconfig/biometrics_framework.aconfig b/packages/SystemUI/aconfig/biometrics_framework.aconfig
new file mode 100644
index 000000000000..5fd3b485e9ed
--- /dev/null
+++ b/packages/SystemUI/aconfig/biometrics_framework.aconfig
@@ -0,0 +1,10 @@
+package: "com.android.systemui"
+
+# NOTE: Keep alphabetized to help limit merge conflicts from multiple simultaneous editors.
+
+flag {
+ name: "bp_talkback"
+ namespace: "biometrics_framework"
+ description: "Adds talkback directional guidance when using UDFPS with biometric prompt"
+ bug: "310044658"
+} \ No newline at end of file
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 17620651128f..3e84597a375d 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -164,3 +164,9 @@ flag {
bug: "296122467"
}
+flag {
+ name: "record_issue_qs_tile"
+ namespace: "systemui"
+ description: "Replace Record Trace QS Tile with expanded Record Issue QS Tile"
+ bug: "305049544"
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt
index 0b1338305076..eb0688914b9d 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt
@@ -16,12 +16,10 @@
package com.android.systemui.bouncer.ui.composable
+import android.view.ViewTreeObserver
import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.imeAnimationTarget
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.LocalTextStyle
@@ -30,46 +28,56 @@ import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.State
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
-import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
+import androidx.core.view.WindowInsetsCompat
import com.android.systemui.bouncer.ui.viewmodel.PasswordBouncerViewModel
/** UI for the input part of a password-requiring version of the bouncer. */
-@OptIn(ExperimentalLayoutApi::class)
@Composable
internal fun PasswordBouncer(
viewModel: PasswordBouncerViewModel,
modifier: Modifier = Modifier,
) {
val focusRequester = remember { FocusRequester() }
+ val isTextFieldFocusRequested by viewModel.isTextFieldFocusRequested.collectAsState()
+ LaunchedEffect(isTextFieldFocusRequested) {
+ if (isTextFieldFocusRequested) {
+ focusRequester.requestFocus()
+ }
+ }
+ val (isTextFieldFocused, onTextFieldFocusChanged) = remember { mutableStateOf(false) }
+ LaunchedEffect(isTextFieldFocused) {
+ viewModel.onTextFieldFocusChanged(isFocused = isTextFieldFocused)
+ }
+
val password: String by viewModel.password.collectAsState()
val isInputEnabled: Boolean by viewModel.isInputEnabled.collectAsState()
val animateFailure: Boolean by viewModel.animateFailure.collectAsState()
- val density = LocalDensity.current
- val isImeVisible by rememberUpdatedState(WindowInsets.imeAnimationTarget.getBottom(density) > 0)
+ val isImeVisible by isSoftwareKeyboardVisible()
LaunchedEffect(isImeVisible) { viewModel.onImeVisibilityChanged(isImeVisible) }
DisposableEffect(Unit) {
viewModel.onShown()
-
- // When the UI comes up, request focus on the TextField to bring up the software keyboard.
- focusRequester.requestFocus()
-
onDispose { viewModel.onHidden() }
}
@@ -104,16 +112,39 @@ internal fun PasswordBouncer(
onDone = { viewModel.onAuthenticateKeyPressed() },
),
modifier =
- Modifier.focusRequester(focusRequester).drawBehind {
- drawLine(
- color = color,
- start = Offset(x = 0f, y = size.height - lineWidthPx),
- end = Offset(size.width, y = size.height - lineWidthPx),
- strokeWidth = lineWidthPx,
- )
- },
+ Modifier.focusRequester(focusRequester)
+ .onFocusChanged { onTextFieldFocusChanged(it.isFocused) }
+ .drawBehind {
+ drawLine(
+ color = color,
+ start = Offset(x = 0f, y = size.height - lineWidthPx),
+ end = Offset(size.width, y = size.height - lineWidthPx),
+ strokeWidth = lineWidthPx,
+ )
+ },
)
Spacer(Modifier.height(100.dp))
}
}
+
+/** Returns a [State] with `true` when the IME/keyboard is visible and `false` when it's not. */
+@Composable
+fun isSoftwareKeyboardVisible(): State<Boolean> {
+ val view = LocalView.current
+ val viewTreeObserver = view.viewTreeObserver
+
+ return produceState(
+ initialValue = false,
+ key1 = viewTreeObserver,
+ ) {
+ val listener =
+ ViewTreeObserver.OnGlobalLayoutListener {
+ value = view.rootWindowInsets?.isVisible(WindowInsetsCompat.Type.ime()) ?: false
+ }
+
+ viewTreeObserver.addOnGlobalLayoutListener(listener)
+
+ awaitDispose { viewTreeObserver.removeOnGlobalLayoutListener(listener) }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
index 3fbcf6d77f82..3fbcf6d77f82 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
index 74c922561343..74c922561343 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
index d41c2497b230..d41c2497b230 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt
index 80d45bcc23dd..80d45bcc23dd 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
index 543b2910bbda..543b2910bbda 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
index 156e06843d15..156e06843d15 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java
index 7bb6ef1c8895..7bb6ef1c8895 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt
index 94c3bde29597..94c3bde29597 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt
index 7b1f302da6e8..7b1f302da6e8 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt
index 64ddbc7828ac..64ddbc7828ac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
index 56d3d260d196..56d3d260d196 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java
index 602f3dc29491..602f3dc29491 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java
index 714461b715d6..714461b715d6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
index 15633d1baed1..15633d1baed1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt
index 39f0d570cb26..39f0d570cb26 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
index a1b801cd3d3f..a1b801cd3d3f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
index f5b6f14a627c..f5b6f14a627c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index e2cab29c473c..e2cab29c473c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java
index cd9189bef7f1..cd9189bef7f1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java
index 5239966f1923..5239966f1923 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java
index 2ea803c6aa8f..2ea803c6aa8f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerTest.java
index 98d8b054716c..98d8b054716c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt
index 79f062536404..79f062536404 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsShellTest.kt
index 8b374ae54127..8b374ae54127 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsShellTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
index 9fbe09619ff1..9fbe09619ff1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/data/repository/SimBouncerRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/data/repository/SimBouncerRepositoryTest.kt
index b391b5a45799..b391b5a45799 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/data/repository/SimBouncerRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/data/repository/SimBouncerRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt
index f0d26b6bbb78..f0d26b6bbb78 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
index 1e8073246f98..83fb17fa50e4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
@@ -319,10 +319,10 @@ class BouncerInteractorTest : SysuiTestCase() {
@Test
fun imeHiddenEvent_isTriggered() =
testScope.runTest {
- val imeHiddenEvent by collectLastValue(underTest.onImeHidden)
+ val imeHiddenEvent by collectLastValue(underTest.onImeHiddenByUser)
runCurrent()
- underTest.onImeHidden()
+ underTest.onImeHiddenByUser()
runCurrent()
assertThat(imeHiddenEvent).isNotNull()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt
index 4aea4f329858..4aea4f329858 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt
index bdf5041f8a38..bdf5041f8a38 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractorTest.kt
index 8c53c0e3f267..8c53c0e3f267 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
index 63c992bd7854..45c186dc3a77 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
@@ -23,8 +23,6 @@ import com.android.systemui.authentication.data.repository.FakeAuthenticationRep
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.scene.SceneTestUtils
-import com.android.systemui.scene.shared.model.SceneKey
-import com.android.systemui.scene.shared.model.SceneModel
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runTest
@@ -76,18 +74,4 @@ class AuthMethodBouncerViewModelTest : SysuiTestCase() {
underTest.onAuthenticateButtonClicked()
assertThat(animateFailure).isFalse()
}
-
- @Test
- fun onImeVisibilityChanged() =
- testScope.runTest {
- sceneInteractor.changeScene(SceneModel(SceneKey.Bouncer), "")
- sceneInteractor.onSceneChanged(SceneModel(SceneKey.Bouncer), "")
- val onImeHidden by collectLastValue(bouncerInteractor.onImeHidden)
-
- underTest.onImeVisibilityChanged(true)
- assertThat(onImeHidden).isNull()
-
- underTest.onImeVisibilityChanged(false)
- assertThat(onImeHidden).isNotNull()
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
index 75d6a007b4aa..75d6a007b4aa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt
index 90e0c19b7c65..90e0c19b7c65 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
index 9b1e9585979a..937c703d6775 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
@@ -20,7 +20,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.coroutines.collectValues
import com.android.systemui.res.R
import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.shared.model.SceneKey
@@ -43,7 +45,11 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
private val utils = SceneTestUtils(this)
private val testScope = utils.testScope
- private val authenticationInteractor = utils.authenticationInteractor()
+ private val authenticationRepository = utils.authenticationRepository
+ private val authenticationInteractor =
+ utils.authenticationInteractor(
+ repository = authenticationRepository,
+ )
private val sceneInteractor = utils.sceneInteractor()
private val bouncerInteractor =
utils.bouncerInteractor(
@@ -207,6 +213,101 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
}
+ @Test
+ fun onImeVisibilityChanged_false_doesNothing() =
+ testScope.runTest {
+ val events by collectValues(bouncerInteractor.onImeHiddenByUser)
+ assertThat(events).isEmpty()
+
+ underTest.onImeVisibilityChanged(isVisible = false)
+ assertThat(events).isEmpty()
+ }
+
+ @Test
+ fun onImeVisibilityChanged_falseAfterTrue_emitsOnImeHiddenByUserEvent() =
+ testScope.runTest {
+ val events by collectValues(bouncerInteractor.onImeHiddenByUser)
+ assertThat(events).isEmpty()
+
+ underTest.onImeVisibilityChanged(isVisible = true)
+ assertThat(events).isEmpty()
+
+ underTest.onImeVisibilityChanged(isVisible = false)
+ assertThat(events).hasSize(1)
+
+ underTest.onImeVisibilityChanged(isVisible = true)
+ assertThat(events).hasSize(1)
+
+ underTest.onImeVisibilityChanged(isVisible = false)
+ assertThat(events).hasSize(2)
+ }
+
+ @Test
+ fun onImeVisibilityChanged_falseAfterTrue_whileThrottling_doesNothing() =
+ testScope.runTest {
+ val events by collectValues(bouncerInteractor.onImeHiddenByUser)
+ assertThat(events).isEmpty()
+ underTest.onImeVisibilityChanged(isVisible = true)
+ setThrottling(true)
+
+ underTest.onImeVisibilityChanged(isVisible = false)
+
+ assertThat(events).isEmpty()
+ }
+
+ @Test
+ fun isTextFieldFocusRequested_initiallyTrue() =
+ testScope.runTest {
+ val isTextFieldFocusRequested by collectLastValue(underTest.isTextFieldFocusRequested)
+ assertThat(isTextFieldFocusRequested).isTrue()
+ }
+
+ @Test
+ fun isTextFieldFocusRequested_focusGained_becomesFalse() =
+ testScope.runTest {
+ val isTextFieldFocusRequested by collectLastValue(underTest.isTextFieldFocusRequested)
+
+ underTest.onTextFieldFocusChanged(isFocused = true)
+
+ assertThat(isTextFieldFocusRequested).isFalse()
+ }
+
+ @Test
+ fun isTextFieldFocusRequested_focusLost_becomesTrue() =
+ testScope.runTest {
+ val isTextFieldFocusRequested by collectLastValue(underTest.isTextFieldFocusRequested)
+ underTest.onTextFieldFocusChanged(isFocused = true)
+
+ underTest.onTextFieldFocusChanged(isFocused = false)
+
+ assertThat(isTextFieldFocusRequested).isTrue()
+ }
+
+ @Test
+ fun isTextFieldFocusRequested_focusLostWhileThrottling_staysFalse() =
+ testScope.runTest {
+ val isTextFieldFocusRequested by collectLastValue(underTest.isTextFieldFocusRequested)
+ underTest.onTextFieldFocusChanged(isFocused = true)
+ setThrottling(true)
+
+ underTest.onTextFieldFocusChanged(isFocused = false)
+
+ assertThat(isTextFieldFocusRequested).isFalse()
+ }
+
+ @Test
+ fun isTextFieldFocusRequested_throttlingCountdownEnds_becomesTrue() =
+ testScope.runTest {
+ val isTextFieldFocusRequested by collectLastValue(underTest.isTextFieldFocusRequested)
+ underTest.onTextFieldFocusChanged(isFocused = true)
+ setThrottling(true)
+ underTest.onTextFieldFocusChanged(isFocused = false)
+
+ setThrottling(false)
+
+ assertThat(isTextFieldFocusRequested).isTrue()
+ }
+
private fun TestScope.switchToScene(toScene: SceneKey) {
val currentScene by collectLastValue(sceneInteractor.desiredScene)
val bouncerShown = currentScene?.key != SceneKey.Bouncer && toScene == SceneKey.Bouncer
@@ -226,6 +327,35 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
switchToScene(SceneKey.Bouncer)
}
+ private suspend fun TestScope.setThrottling(
+ isThrottling: Boolean,
+ failedAttemptCount: Int = 5,
+ ) {
+ if (isThrottling) {
+ repeat(failedAttemptCount) {
+ authenticationRepository.reportAuthenticationAttempt(false)
+ }
+ val remainingTimeMs = 30_000
+ authenticationRepository.setThrottleDuration(remainingTimeMs)
+ authenticationRepository.setThrottling(
+ AuthenticationThrottlingModel(
+ failedAttemptCount = failedAttemptCount,
+ remainingMs = remainingTimeMs,
+ )
+ )
+ } else {
+ authenticationRepository.reportAuthenticationAttempt(true)
+ authenticationRepository.setThrottling(
+ AuthenticationThrottlingModel(
+ failedAttemptCount = failedAttemptCount,
+ remainingMs = 0,
+ )
+ )
+ }
+
+ runCurrent()
+ }
+
companion object {
private const val ENTER_YOUR_PASSWORD = "Enter your password"
private const val WRONG_PASSWORD = "Wrong password"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
index 862c39c9d4cc..862c39c9d4cc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
index c30e405ab911..c30e405ab911 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinInputViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinInputViewModelTest.kt
index 55016bb1fc07..55016bb1fc07 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinInputViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinInputViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt
index 182712a13174..182712a13174 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
index 16cfa2398fd5..16cfa2398fd5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt
index a49629252520..a49629252520 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt
index 97ac8c62d69d..97ac8c62d69d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
index 910097eece52..910097eece52 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dock/DockManagerFake.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dock/DockManagerFake.java
index 37540621557f..37540621557f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dock/DockManagerFake.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dock/DockManagerFake.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt
index 8a35ef11a364..8a35ef11a364 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt
index 2c6c793c97f5..2c6c793c97f5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
index 2af6566e993a..2af6566e993a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java
index d379dc6f3dc1..d379dc6f3dc1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
index e5f997257cfa..e5f997257cfa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
index 6d5cd49b8af6..6d5cd49b8af6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java
index 7ff345cdcf7e..7ff345cdcf7e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
index 39db2beb4c44..39db2beb4c44 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java
index 315a24bfd945..315a24bfd945 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java
index e0c6ab20c6e1..e0c6ab20c6e1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java
index 480754c17616..480754c17616 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
index 3d1efa59a11b..3d1efa59a11b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java
index 6aa821f15ab1..6aa821f15ab1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java
index 017fdbe8ac01..017fdbe8ac01 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java
index 4ee4a60fbeaf..4ee4a60fbeaf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferHelper.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dump/LogBufferHelper.kt
index 0538227abd3f..0538227abd3f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferHelper.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dump/LogBufferHelper.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
index 977f1db44258..977f1db44258 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt
index 548b5646f5d4..548b5646f5d4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt
index 4ae144c03314..4ae144c03314 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
index 7d68cc0a3560..7d68cc0a3560 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
index 26fcb234843d..26fcb234843d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
index 99a01858471c..99a01858471c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt
index a1c9f87ee7bc..a1c9f87ee7bc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt
index b15352bfe6ab..b15352bfe6ab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
index 521dea34513e..521dea34513e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
index 02db0d7a9a50..02db0d7a9a50 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt
index a9b9c9011636..a9b9c9011636 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
index 4587ea6dbdc8..4587ea6dbdc8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
index 45aca175657e..45aca175657e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt
index 2b7221ec192c..2b7221ec192c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt
index ae6c5b7b36b0..ae6c5b7b36b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
index 567e0a9717fc..567e0a9717fc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
index 6c4bb372bc3a..6c4bb372bc3a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt
index 7242cb20dc77..7242cb20dc77 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt
index ee47c58f4002..ee47c58f4002 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
index 706f94e412ac..706f94e412ac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
index 98f0211587ea..98f0211587ea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
index bc4bae0ed959..bc4bae0ed959 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
index 4f7d9444020c..4f7d9444020c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt
index b483085cf1e5..b483085cf1e5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt
index fd125e099f1b..fd125e099f1b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt
index cf2012989624..cf2012989624 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
index d07836d3abce..d07836d3abce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt
index ba72b4c95a44..ba72b4c95a44 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
index 3536d5c77c93..3536d5c77c93 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt
index d0772270ed5e..d0772270ed5e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
index 6cab023d59b0..6cab023d59b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/AutoAddSettingsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/AutoAddSettingsRepositoryTest.kt
index d277fcab3690..d277fcab3690 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/AutoAddSettingsRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/AutoAddSettingsRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/CustomTileAddedSharedPreferencesRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/CustomTileAddedSharedPreferencesRepositoryTest.kt
index 3db676d68f42..3db676d68f42 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/CustomTileAddedSharedPreferencesRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/CustomTileAddedSharedPreferencesRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt
index 070e07a75d23..070e07a75d23 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredBroadcastRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredBroadcastRepositoryTest.kt
index ff8a9bd019fb..ff8a9bd019fb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredBroadcastRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredBroadcastRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt
index f7c3b213730c..f7c3b213730c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TilesSettingConverterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/TilesSettingConverterTest.kt
index 9516c2181ac0..9516c2181ac0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TilesSettingConverterTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/TilesSettingConverterTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserAutoAddRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/UserAutoAddRepositoryTest.kt
index 36e860e37ffa..36e860e37ffa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserAutoAddRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/UserAutoAddRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserTileSpecRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/UserTileSpecRepositoryTest.kt
index d4a9fabd6806..d4a9fabd6806 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserTileSpecRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/UserTileSpecRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt
index 4454a3cb15fc..4454a3cb15fc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingTest.kt
index d153e9d1d361..d153e9d1d361 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CallbackControllerAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CallbackControllerAutoAddableTest.kt
index ec139e4c515e..ec139e4c515e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CallbackControllerAutoAddableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CallbackControllerAutoAddableTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddableTest.kt
index 4fae532d4174..4fae532d4174 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddableTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DataSaverAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DataSaverAutoAddableTest.kt
index 9e2d1f885e2d..9e2d1f885e2d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DataSaverAutoAddableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DataSaverAutoAddableTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DeviceControlsAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DeviceControlsAutoAddableTest.kt
index 0116bd9575d8..0116bd9575d8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DeviceControlsAutoAddableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DeviceControlsAutoAddableTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/HotspotAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/HotspotAutoAddableTest.kt
index e7ea9a66450c..e7ea9a66450c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/HotspotAutoAddableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/HotspotAutoAddableTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddableTest.kt
index 20fd3601f9ef..20fd3601f9ef 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddableTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddableTest.kt
index 19ac63c36cab..19ac63c36cab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddableTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt
index d645ee34619b..d645ee34619b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WalletAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WalletAutoAddableTest.kt
index 83ff35d8022d..83ff35d8022d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WalletAutoAddableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WalletAutoAddableTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt
index adccc84e494b..adccc84e494b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/AutoAddInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/AutoAddInteractorTest.kt
index 41a7ec03408d..41a7ec03408d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/AutoAddInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/AutoAddInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
index 8c896a6a1709..8c896a6a1709 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/FakeQSTile.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/FakeQSTile.kt
index 7e0e7d1f46e8..7e0e7d1f46e8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/FakeQSTile.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/FakeQSTile.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorImplTest.kt
index 0d9711588a1f..0d9711588a1f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/RestoreReconciliationInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/RestoreReconciliationInteractorTest.kt
index f73cab8a10a3..f73cab8a10a3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/RestoreReconciliationInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/RestoreReconciliationInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt
index 558e7694b54c..558e7694b54c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerTest.kt
index bd1c310ab8de..bd1c310ab8de 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt
index 9861606fd1b1..9861606fd1b1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt
index 2bdc154dd885..2bdc154dd885 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt
index 92c2d743c262..92c2d743c262 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileDataInteractorTest.kt
index 937744db500e..937744db500e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileDataInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt
index 81bde8188f5e..81bde8188f5e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/custom/CustomTileDefaultsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTileDefaultsRepositoryTest.kt
index 89ba69fce9ad..89ba69fce9ad 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/custom/CustomTileDefaultsRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTileDefaultsRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/custom/CustomTilePackageUpdatesRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTilePackageUpdatesRepositoryTest.kt
index 4a221134ce67..4a221134ce67 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/custom/CustomTilePackageUpdatesRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTilePackageUpdatesRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt
index cf076c557765..cf076c557765 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt
index eebb145ef384..eebb145ef384 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapperTest.kt
index fab290da2953..7b2ac90b9766 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapperTest.kt
@@ -16,7 +16,6 @@
package com.android.systemui.qs.tiles.impl.flashlight.domain
-import android.graphics.drawable.Drawable
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -26,7 +25,6 @@ import com.android.systemui.qs.tiles.impl.flashlight.domain.model.FlashlightTile
import com.android.systemui.qs.tiles.impl.flashlight.qsFlashlightTileConfig
import com.android.systemui.qs.tiles.viewmodel.QSTileState
import com.android.systemui.res.R
-import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
import junit.framework.Assert.assertEquals
import org.junit.Test
@@ -37,7 +35,7 @@ import org.junit.runner.RunWith
class FlashlightMapperTest : SysuiTestCase() {
private val kosmos = Kosmos()
private val qsTileConfig = kosmos.qsFlashlightTileConfig
- private val mapper by lazy { FlashlightMapper(context) }
+ private val mapper by lazy { FlashlightMapper(context.orCreateTestableResources.resources) }
@Test
fun mapsDisabledDataToInactiveState() {
@@ -58,12 +56,7 @@ class FlashlightMapperTest : SysuiTestCase() {
@Test
fun mapsEnabledDataToOnIconState() {
- val fakeDrawable = mock<Drawable>()
- context.orCreateTestableResources.addOverride(
- R.drawable.qs_flashlight_icon_on,
- fakeDrawable
- )
- val expectedIcon = Icon.Loaded(fakeDrawable, null)
+ val expectedIcon = Icon.Resource(R.drawable.qs_flashlight_icon_on, null)
val tileState: QSTileState = mapper.map(qsTileConfig, FlashlightTileModel(true))
@@ -73,12 +66,7 @@ class FlashlightMapperTest : SysuiTestCase() {
@Test
fun mapsDisabledDataToOffIconState() {
- val fakeDrawable = mock<Drawable>()
- context.orCreateTestableResources.addOverride(
- R.drawable.qs_flashlight_icon_off,
- fakeDrawable
- )
- val expectedIcon = Icon.Loaded(fakeDrawable, null)
+ val expectedIcon = Icon.Resource(R.drawable.qs_flashlight_icon_off, null)
val tileState: QSTileState = mapper.map(qsTileConfig, FlashlightTileModel(false))
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapperTest.kt
index 820c0564c1a7..8791877f8863 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapperTest.kt
@@ -16,7 +16,6 @@
package com.android.systemui.qs.tiles.impl.location.domain
-import android.graphics.drawable.Drawable
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -26,7 +25,6 @@ import com.android.systemui.qs.tiles.impl.location.domain.model.LocationTileMode
import com.android.systemui.qs.tiles.impl.location.qsLocationTileConfig
import com.android.systemui.qs.tiles.viewmodel.QSTileState
import com.android.systemui.res.R
-import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth
import junit.framework.Assert
import org.junit.Test
@@ -37,7 +35,8 @@ import org.junit.runner.RunWith
class LocationTileMapperTest : SysuiTestCase() {
private val kosmos = Kosmos()
private val qsTileConfig = kosmos.qsLocationTileConfig
- private val mapper by lazy { LocationTileMapper(context) }
+
+ private val mapper by lazy { LocationTileMapper(context.orCreateTestableResources.resources) }
@Test
fun mapsDisabledDataToInactiveState() {
@@ -57,9 +56,7 @@ class LocationTileMapperTest : SysuiTestCase() {
@Test
fun mapsEnabledDataToOnIconState() {
- val fakeDrawable = mock<Drawable>()
- context.orCreateTestableResources.addOverride(R.drawable.qs_location_icon_on, fakeDrawable)
- val expectedIcon = Icon.Loaded(fakeDrawable, null)
+ val expectedIcon = Icon.Resource(R.drawable.qs_location_icon_on, null)
val tileState: QSTileState = mapper.map(qsTileConfig, LocationTileModel(true))
@@ -69,9 +66,7 @@ class LocationTileMapperTest : SysuiTestCase() {
@Test
fun mapsDisabledDataToOffIconState() {
- val fakeDrawable = mock<Drawable>()
- context.orCreateTestableResources.addOverride(R.drawable.qs_location_icon_off, fakeDrawable)
- val expectedIcon = Icon.Loaded(fakeDrawable, null)
+ val expectedIcon = Icon.Resource(R.drawable.qs_location_icon_off, null)
val tileState: QSTileState = mapper.map(qsTileConfig, LocationTileModel(false))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderTest.kt
index 5eca8caa7d15..5eca8caa7d15 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt
index 3a0ebdbd6a17..3a0ebdbd6a17 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt
index 22fb152aee44..22fb152aee44 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
index 42e27ba12f42..42e27ba12f42 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
index c953743fd272..18b7168098ab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
@@ -30,6 +30,7 @@ import com.android.systemui.authentication.data.repository.FakeAuthenticationRep
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.bouncer.domain.interactor.BouncerActionButtonInteractor
import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel
+import com.android.systemui.bouncer.ui.viewmodel.PasswordBouncerViewModel
import com.android.systemui.bouncer.ui.viewmodel.PinBouncerViewModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.Flags
@@ -777,11 +778,11 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
private suspend fun TestScope.dismissIme(
showImeBeforeDismissing: Boolean = true,
) {
- bouncerViewModel.authMethodViewModel.value?.apply {
+ (bouncerViewModel.authMethodViewModel.value as? PasswordBouncerViewModel)?.let {
if (showImeBeforeDismissing) {
- onImeVisibilityChanged(true)
+ it.onImeVisibilityChanged(true)
}
- onImeVisibilityChanged(false)
+ it.onImeVisibilityChanged(false)
runCurrent()
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
index ddeb05b39e53..ddeb05b39e53 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/WindowRootViewVisibilityRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/data/repository/WindowRootViewVisibilityRepositoryTest.kt
index 7ae501d05fcd..7ae501d05fcd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/WindowRootViewVisibilityRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/data/repository/WindowRootViewVisibilityRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
index 7f4bbbe36768..7f4bbbe36768 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt
index 8be4eeb7be7a..8be4eeb7be7a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
index adc1c61da50a..3cb97e369a67 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
@@ -479,7 +479,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
underTest.start()
runCurrent()
- bouncerInteractor.onImeHidden()
+ bouncerInteractor.onImeHiddenByUser()
runCurrent()
assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
index c89cd9e0c1f1..c89cd9e0c1f1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt
index 77ddf15c41ad..77ddf15c41ad 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
index e2640af136a7..e2640af136a7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt
index cb83e7c7adbc..cb83e7c7adbc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
index e09385934991..e09385934991 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt
index 886c61ae29dd..886c61ae29dd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt
index 0b5aea7d8683..0b5aea7d8683 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java
index c669c6f6fb1c..c669c6f6fb1c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/FakeAirplaneModeRepository.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/FakeAirplaneModeRepository.kt
index 638925d0a705..638925d0a705 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/FakeAirplaneModeRepository.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/FakeAirplaneModeRepository.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
index 5f4d7bf6f371..5f4d7bf6f371 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
index 75d1869adc7c..75d1869adc7c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt
index a80238167b85..a80238167b85 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/FakeConnectivityRepository.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/FakeConnectivityRepository.kt
index 28d632d9fcea..28d632d9fcea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/FakeConnectivityRepository.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/FakeConnectivityRepository.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt
index 106b54891948..106b54891948 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt
index d06a6e26b4ce..d06a6e26b4ce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt
index ce00250467f6..ce00250467f6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
index cf20ba87e8c2..cf20ba87e8c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
diff --git a/packages/SystemUI/tests/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 7fbbfc77300e..7fbbfc77300e 100644
--- a/packages/SystemUI/tests/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
diff --git a/packages/SystemUI/tests/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 791a028eef4e..791a028eef4e 100644
--- a/packages/SystemUI/tests/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
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java b/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java
index b704f3c89330..1edb551eb944 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java
@@ -71,7 +71,7 @@ public class Magnification implements CoreStartable, CommandQueue.Callbacks {
private final DisplayTracker mDisplayTracker;
private final AccessibilityLogger mA11yLogger;
- private WindowMagnificationConnectionImpl mWindowMagnificationConnectionImpl;
+ private MagnificationConnectionImpl mMagnificationConnectionImpl;
private SysUiState mSysUiState;
@VisibleForTesting
@@ -220,7 +220,7 @@ public class Magnification implements CoreStartable, CommandQueue.Callbacks {
}
@MainThread
- void setScale(int displayId, float scale) {
+ void setScaleForWindowMagnification(int displayId, float scale) {
final WindowMagnificationController windowMagnificationController =
mMagnificationControllerSupplier.get(displayId);
if (windowMagnificationController != null) {
@@ -321,37 +321,37 @@ public class Magnification implements CoreStartable, CommandQueue.Callbacks {
final WindowMagnifierCallback mWindowMagnifierCallback = new WindowMagnifierCallback() {
@Override
public void onWindowMagnifierBoundsChanged(int displayId, Rect frame) {
- if (mWindowMagnificationConnectionImpl != null) {
- mWindowMagnificationConnectionImpl.onWindowMagnifierBoundsChanged(displayId, frame);
+ if (mMagnificationConnectionImpl != null) {
+ mMagnificationConnectionImpl.onWindowMagnifierBoundsChanged(displayId, frame);
}
}
@Override
public void onSourceBoundsChanged(int displayId, Rect sourceBounds) {
- if (mWindowMagnificationConnectionImpl != null) {
- mWindowMagnificationConnectionImpl.onSourceBoundsChanged(displayId, sourceBounds);
+ if (mMagnificationConnectionImpl != null) {
+ mMagnificationConnectionImpl.onSourceBoundsChanged(displayId, sourceBounds);
}
}
@Override
public void onPerformScaleAction(int displayId, float scale, boolean updatePersistence) {
- if (mWindowMagnificationConnectionImpl != null) {
- mWindowMagnificationConnectionImpl.onPerformScaleAction(
+ if (mMagnificationConnectionImpl != null) {
+ mMagnificationConnectionImpl.onPerformScaleAction(
displayId, scale, updatePersistence);
}
}
@Override
public void onAccessibilityActionPerformed(int displayId) {
- if (mWindowMagnificationConnectionImpl != null) {
- mWindowMagnificationConnectionImpl.onAccessibilityActionPerformed(displayId);
+ if (mMagnificationConnectionImpl != null) {
+ mMagnificationConnectionImpl.onAccessibilityActionPerformed(displayId);
}
}
@Override
public void onMove(int displayId) {
- if (mWindowMagnificationConnectionImpl != null) {
- mWindowMagnificationConnectionImpl.onMove(displayId);
+ if (mMagnificationConnectionImpl != null) {
+ mMagnificationConnectionImpl.onMove(displayId);
}
}
@@ -394,8 +394,8 @@ public class Magnification implements CoreStartable, CommandQueue.Callbacks {
@Override
public void onMagnifierScale(int displayId, float scale,
boolean updatePersistence) {
- if (mWindowMagnificationConnectionImpl != null) {
- mWindowMagnificationConnectionImpl.onPerformScaleAction(
+ if (mMagnificationConnectionImpl != null) {
+ mMagnificationConnectionImpl.onPerformScaleAction(
displayId, scale, updatePersistence);
}
mA11yLogger.logThrottled(
@@ -454,8 +454,8 @@ public class Magnification implements CoreStartable, CommandQueue.Callbacks {
if (magnificationSettingsController != null) {
magnificationSettingsController.closeMagnificationSettings();
}
- if (mWindowMagnificationConnectionImpl != null) {
- mWindowMagnificationConnectionImpl.onChangeMagnificationMode(displayId, newMode);
+ if (mMagnificationConnectionImpl != null) {
+ mMagnificationConnectionImpl.onChangeMagnificationMode(displayId, newMode);
}
}
}
@@ -500,12 +500,12 @@ public class Magnification implements CoreStartable, CommandQueue.Callbacks {
}
private void setWindowMagnificationConnection() {
- if (mWindowMagnificationConnectionImpl == null) {
- mWindowMagnificationConnectionImpl = new WindowMagnificationConnectionImpl(this,
+ if (mMagnificationConnectionImpl == null) {
+ mMagnificationConnectionImpl = new MagnificationConnectionImpl(this,
mHandler);
}
mAccessibilityManager.setWindowMagnificationConnection(
- mWindowMagnificationConnectionImpl);
+ mMagnificationConnectionImpl);
}
private void clearWindowMagnificationConnection() {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationConnectionImpl.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java
index 5666851f560f..5f0d496dd5d1 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationConnectionImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java
@@ -32,7 +32,7 @@ import com.android.systemui.dagger.qualifiers.Main;
*
* @see IWindowMagnificationConnection
*/
-class WindowMagnificationConnectionImpl extends IWindowMagnificationConnection.Stub {
+class MagnificationConnectionImpl extends IWindowMagnificationConnection.Stub {
private static final String TAG = "WindowMagnificationConnectionImpl";
@@ -40,7 +40,7 @@ class WindowMagnificationConnectionImpl extends IWindowMagnificationConnection.S
private final Magnification mMagnification;
private final Handler mHandler;
- WindowMagnificationConnectionImpl(@NonNull Magnification magnification,
+ MagnificationConnectionImpl(@NonNull Magnification magnification,
@Main Handler mainHandler) {
mMagnification = magnification;
mHandler = mainHandler;
@@ -57,8 +57,8 @@ class WindowMagnificationConnectionImpl extends IWindowMagnificationConnection.S
}
@Override
- public void setScale(int displayId, float scale) {
- mHandler.post(() -> mMagnification.setScale(displayId, scale));
+ public void setScaleForWindowMagnification(int displayId, float scale) {
+ mHandler.post(() -> mMagnification.setScaleForWindowMagnification(displayId, scale));
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
index b598631c3b57..7c46339ec103 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
@@ -105,9 +105,9 @@ constructor(
val isUserSwitcherVisible: Boolean
get() = repository.isUserSwitcherVisible
- private val _onImeHidden = MutableSharedFlow<Unit>()
- /** Provide the onImeHidden events from the bouncer */
- val onImeHidden: SharedFlow<Unit> = _onImeHidden
+ private val _onImeHiddenByUser = MutableSharedFlow<Unit>()
+ /** Emits a [Unit] each time the IME (keyboard) is hidden by the user. */
+ val onImeHiddenByUser: SharedFlow<Unit> = _onImeHiddenByUser
init {
if (flags.isEnabled()) {
@@ -230,9 +230,9 @@ constructor(
repository.setMessage(errorMessage(authenticationInteractor.getAuthenticationMethod()))
}
- /** Notifies the interactor that the input method editor has been hidden. */
- suspend fun onImeHidden() {
- _onImeHidden.emit(Unit)
+ /** Notifies that the input method editor (software keyboard) has been hidden by the user. */
+ suspend fun onImeHiddenByUser() {
+ _onImeHiddenByUser.emit(Unit)
}
private fun promptMessage(authMethod: AuthenticationMethodModel): String {
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt
index 80248744c25a..e379dab918ef 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt
@@ -46,9 +46,6 @@ sealed class AuthMethodBouncerViewModel(
*/
val animateFailure: StateFlow<Boolean> = _animateFailure.asStateFlow()
- /** Whether the input method editor (for example, the software keyboard) is visible. */
- private var isImeVisible: Boolean = false
-
/** The authentication method that corresponds to this view model. */
abstract val authenticationMethod: AuthenticationMethodModel
@@ -68,7 +65,7 @@ sealed class AuthMethodBouncerViewModel(
/**
* Notifies that the UI has been hidden from the user (after any transitions have completed).
*/
- fun onHidden() {
+ open fun onHidden() {
clearInput()
interactor.resetMessage()
}
@@ -79,18 +76,6 @@ sealed class AuthMethodBouncerViewModel(
}
/**
- * Notifies that the input method editor (for example, the software keyboard) has been shown or
- * hidden.
- */
- suspend fun onImeVisibilityChanged(isVisible: Boolean) {
- if (isImeVisible && !isVisible) {
- interactor.onImeHidden()
- }
-
- isImeVisible = isVisible
- }
-
- /**
* Notifies that the failure animation has been shown. This should be called to consume a `true`
* value in [animateFailure].
*/
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt
index a15698e1f90c..45d181285df7 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt
@@ -21,8 +21,11 @@ import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
import com.android.systemui.res.R
import kotlinx.coroutines.CoroutineScope
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.stateIn
/** Holds UI state and handles user input for the password bouncer UI. */
class PasswordBouncerViewModel(
@@ -45,6 +48,32 @@ class PasswordBouncerViewModel(
override val throttlingMessageId = R.string.kg_too_many_failed_password_attempts_dialog_message
+ /** Whether the input method editor (for example, the software keyboard) is visible. */
+ private var isImeVisible: Boolean = false
+
+ /** Whether the text field element currently has focus. */
+ private val isTextFieldFocused = MutableStateFlow(false)
+
+ /** Whether the UI should request focus on the text field element. */
+ val isTextFieldFocusRequested =
+ combine(
+ interactor.isThrottled,
+ isTextFieldFocused,
+ ) { isThrottled, hasFocus ->
+ !isThrottled && !hasFocus
+ }
+ .stateIn(
+ scope = viewModelScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = !interactor.isThrottled.value && !isTextFieldFocused.value,
+ )
+
+ override fun onHidden() {
+ super.onHidden()
+ isImeVisible = false
+ isTextFieldFocused.value = false
+ }
+
override fun clearInput() {
_password.value = ""
}
@@ -72,4 +101,21 @@ class PasswordBouncerViewModel(
tryAuthenticate()
}
}
+
+ /**
+ * Notifies that the input method editor (for example, the software keyboard) has been shown or
+ * hidden.
+ */
+ suspend fun onImeVisibilityChanged(isVisible: Boolean) {
+ if (isImeVisible && !isVisible && !interactor.isThrottled.value) {
+ interactor.onImeHiddenByUser()
+ }
+
+ isImeVisible = isVisible
+ }
+
+ /** Notifies that the password text field has gained or lost focus. */
+ fun onTextFieldFocusChanged(isFocused: Boolean) {
+ isTextFieldFocused.value = isFocused
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
index bd73d60cda29..62a0b0ebc08c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
@@ -131,13 +131,16 @@ constructor(
when (toState) {
KeyguardState.DREAMING -> TO_DREAMING_DURATION
KeyguardState.AOD -> TO_AOD_DURATION
+ KeyguardState.LOCKSCREEN -> TO_LOCKSCREEN_DURATION
else -> DEFAULT_DURATION
}.inWholeMilliseconds
}
}
+
companion object {
private val DEFAULT_DURATION = 500.milliseconds
val TO_DREAMING_DURATION = 933.milliseconds
val TO_AOD_DURATION = 1300.milliseconds
+ val TO_LOCKSCREEN_DURATION = DEFAULT_DURATION
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
index 152d2172ee4c..cbfd17ff7ae4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
@@ -380,6 +380,8 @@ constructor(
KeyguardState.DREAMING -> TO_DREAMING_DURATION
KeyguardState.OCCLUDED -> TO_OCCLUDED_DURATION
KeyguardState.AOD -> TO_AOD_DURATION
+ KeyguardState.DOZING -> TO_DOZING_DURATION
+ KeyguardState.DREAMING_LOCKSCREEN_HOSTED -> TO_DREAMING_HOSTED_DURATION
else -> DEFAULT_DURATION
}.inWholeMilliseconds
}
@@ -388,7 +390,9 @@ constructor(
companion object {
const val TAG = "FromLockscreenTransitionInteractor"
private val DEFAULT_DURATION = 400.milliseconds
+ val TO_DOZING_DURATION = 500.milliseconds
val TO_DREAMING_DURATION = 933.milliseconds
+ val TO_DREAMING_HOSTED_DURATION = 933.milliseconds
val TO_OCCLUDED_DURATION = 450.milliseconds
val TO_AOD_DURATION = 500.milliseconds
val TO_PRIMARY_BOUNCER_DURATION = DEFAULT_DURATION
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
index 706aba3c0505..f7d1543e4650 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
@@ -72,6 +72,10 @@ constructor(
val fromDreamingTransition: Flow<TransitionStep> =
repository.transitions.filter { step -> step.from == DREAMING }
+ /** LOCKSCREEN->(any) transition information. */
+ val fromLockscreenTransition: Flow<TransitionStep> =
+ repository.transitions.filter { step -> step.from == LOCKSCREEN }
+
/** (any)->Lockscreen transition information */
val anyStateToLockscreenTransition: Flow<TransitionStep> =
repository.transitions.filter { step -> step.to == LOCKSCREEN }
@@ -113,9 +117,16 @@ constructor(
val goneToDreamingLockscreenHostedTransition: Flow<TransitionStep> =
repository.transition(GONE, DREAMING_LOCKSCREEN_HOSTED)
+ /** GONE->LOCKSCREEN transition information. */
+ val goneToLockscreenTransition: Flow<TransitionStep> = repository.transition(GONE, LOCKSCREEN)
+
/** LOCKSCREEN->AOD transition information. */
val lockscreenToAodTransition: Flow<TransitionStep> = repository.transition(LOCKSCREEN, AOD)
+ /** LOCKSCREEN->DOZING transition information. */
+ val lockscreenToDozingTransition: Flow<TransitionStep> =
+ repository.transition(LOCKSCREEN, DOZING)
+
/** LOCKSCREEN->DREAMING transition information. */
val lockscreenToDreamingTransition: Flow<TransitionStep> =
repository.transition(LOCKSCREEN, DREAMING)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
index 99025acef70d..abd79ab793d5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
@@ -30,9 +30,7 @@ import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
-import com.android.app.animation.Interpolators
import com.android.settingslib.Utils
-import com.android.systemui.res.R
import com.android.systemui.animation.Expandable
import com.android.systemui.animation.view.LaunchableImageView
import com.android.systemui.common.shared.model.Icon
@@ -40,6 +38,7 @@ import com.android.systemui.common.ui.binder.IconViewBinder
import com.android.systemui.keyguard.ui.viewmodel.KeyguardQuickAffordanceViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.res.R
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.util.doOnEnd
import kotlinx.coroutines.flow.Flow
@@ -48,9 +47,7 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
-/**
- * This is only for a SINGLE Quick affordance
- */
+/** This is only for a SINGLE Quick affordance */
object KeyguardQuickAffordanceViewBinder {
private const val EXIT_DOZE_BUTTON_REVEAL_ANIMATION_DURATION_MS = 250L
@@ -135,28 +132,12 @@ object KeyguardQuickAffordanceViewBinder {
vibratorHelper: VibratorHelper?,
) {
if (!viewModel.isVisible) {
- view.alpha = 1f
- view
- .animate()
- .alpha(0f)
- .setInterpolator(Interpolators.FAST_OUT_LINEAR_IN)
- .setDuration(EXIT_DOZE_BUTTON_REVEAL_ANIMATION_DURATION_MS)
- .withEndAction { view.isInvisible = true }
- .start()
+ view.isInvisible = true
return
}
if (!view.isVisible) {
view.isVisible = true
- if (viewModel.animateReveal) {
- view.alpha = 0f
- view
- .animate()
- .alpha(1f)
- .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
- .setDuration(EXIT_DOZE_BUTTON_REVEAL_ANIMATION_DURATION_MS)
- .start()
- }
}
IconViewBinder.bind(viewModel.icon, view)
@@ -216,13 +197,14 @@ object KeyguardQuickAffordanceViewBinder {
view.isClickable = viewModel.isClickable
if (viewModel.isClickable) {
if (viewModel.useLongPress) {
- val onTouchListener = KeyguardQuickAffordanceOnTouchListener(
- view,
- viewModel,
- messageDisplayer,
- vibratorHelper,
- falsingManager,
- )
+ val onTouchListener =
+ KeyguardQuickAffordanceOnTouchListener(
+ view,
+ viewModel,
+ messageDisplayer,
+ vibratorHelper,
+ falsingManager,
+ )
view.setOnTouchListener(onTouchListener)
view.setOnClickListener {
messageDisplayer.invoke(R.string.keyguard_affordance_press_too_short)
@@ -241,9 +223,7 @@ object KeyguardQuickAffordanceViewBinder {
KeyguardBottomAreaVibrations.ShakeAnimationDuration.inWholeMilliseconds
shakeAnimator.interpolator =
CycleInterpolator(KeyguardBottomAreaVibrations.ShakeAnimationCycles)
- shakeAnimator.doOnEnd {
- view.translationX = 0f
- }
+ shakeAnimator.doOnEnd { view.translationX = 0f }
shakeAnimator.start()
vibratorHelper?.vibrate(KeyguardBottomAreaVibrations.Shake)
@@ -268,18 +248,18 @@ object KeyguardQuickAffordanceViewBinder {
alphaFlow: Flow<Float>,
) {
combine(viewModel.map { it.isDimmed }, alphaFlow) { isDimmed, alpha ->
- if (isDimmed) DIM_ALPHA else alpha
- }
+ if (isDimmed) DIM_ALPHA else alpha
+ }
.collect { view.alpha = it }
}
private fun loadFromResources(view: View): ConfigurationBasedDimensions {
return ConfigurationBasedDimensions(
buttonSizePx =
- Size(
- view.resources.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_width),
- view.resources.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_height),
- ),
+ Size(
+ view.resources.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_width),
+ view.resources.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_height),
+ ),
)
}
@@ -337,11 +317,9 @@ object KeyguardQuickAffordanceViewBinder {
}
override fun onLongClickUseDefaultHapticFeedback(view: View) = false
-
}
private data class ConfigurationBasedDimensions(
val buttonSizePx: Size,
)
-
-} \ No newline at end of file
+}
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 a2e930c49511..59c798bfca1e 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
@@ -84,6 +84,7 @@ import dagger.assisted.AssistedInject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.runBlocking
/** Renders the preview of the lock screen. */
@@ -158,7 +159,6 @@ constructor(
init {
if (keyguardBottomAreaRefactor()) {
- keyguardRootViewModel.enablePreviewMode()
quickAffordancesCombinedViewModel.enablePreviewMode(
initiallySelectedSlotId =
bundle.getString(
@@ -287,6 +287,10 @@ constructor(
return
}
+ if (smartSpaceView != null) {
+ parentView.removeView(smartSpaceView)
+ }
+
smartSpaceView = lockscreenSmartspaceController.buildAndConnectDateView(parentView)
val topPadding: Int =
@@ -334,26 +338,27 @@ constructor(
),
)
}
-
@OptIn(ExperimentalCoroutinesApi::class)
private fun setupKeyguardRootView(previewContext: Context, rootView: FrameLayout) {
val keyguardRootView = KeyguardRootView(previewContext, null)
- disposables.add(
- KeyguardRootViewBinder.bind(
- keyguardRootView,
- keyguardRootViewModel,
- configuration,
- featureFlags,
- occludingAppDeviceEntryMessageViewModel,
- chipbarCoordinator,
- screenOffAnimationController,
- shadeInteractor,
- null, // clock provider only needed for burn in
- null, // jank monitor not required for preview mode
- null, // device entry haptics not required for preview mode
- null, // device entry haptics not required for preview mode
+ if (!keyguardBottomAreaRefactor()) {
+ disposables.add(
+ KeyguardRootViewBinder.bind(
+ keyguardRootView,
+ keyguardRootViewModel,
+ configuration,
+ featureFlags,
+ occludingAppDeviceEntryMessageViewModel,
+ chipbarCoordinator,
+ screenOffAnimationController,
+ shadeInteractor,
+ null, // clock provider only needed for burn in
+ null, // jank monitor not required for preview mode
+ null, // device entry haptics not required preview mode
+ null, // device entry haptics not required for preview mode
+ )
)
- )
+ }
rootView.addView(
keyguardRootView,
FrameLayout.LayoutParams(
@@ -362,12 +367,13 @@ constructor(
),
)
+ setUpUdfps(previewContext, rootView)
+
disposables.add(
PreviewKeyguardBlueprintViewBinder.bind(keyguardRootView, keyguardBlueprintViewModel) {
if (keyguardBottomAreaRefactor()) {
setupShortcuts(keyguardRootView)
}
- setUpUdfps(previewContext, rootView)
if (!shouldHideClock) {
setUpClock(previewContext, rootView)
@@ -387,30 +393,30 @@ constructor(
}
private fun setupShortcuts(keyguardRootView: ConstraintLayout) {
- keyguardRootView.findViewById<LaunchableImageView?>(R.id.start_button)?.let {
+ keyguardRootView.findViewById<LaunchableImageView?>(R.id.start_button)?.let { imageView ->
shortcutsBindings.add(
KeyguardQuickAffordanceViewBinder.bind(
- it,
- quickAffordancesCombinedViewModel.startButton,
- keyguardRootViewModel.alpha,
- falsingManager,
- vibratorHelper,
- ) {
- indicationController.showTransientIndication(it)
+ view = imageView,
+ viewModel = quickAffordancesCombinedViewModel.startButton,
+ alpha = flowOf(1f),
+ falsingManager = falsingManager,
+ vibratorHelper = vibratorHelper,
+ ) { message ->
+ indicationController.showTransientIndication(message)
}
)
}
- keyguardRootView.findViewById<LaunchableImageView?>(R.id.end_button)?.let {
+ keyguardRootView.findViewById<LaunchableImageView?>(R.id.end_button)?.let { imageView ->
shortcutsBindings.add(
KeyguardQuickAffordanceViewBinder.bind(
- it,
- quickAffordancesCombinedViewModel.endButton,
- keyguardRootViewModel.alpha,
- falsingManager,
- vibratorHelper,
- ) {
- indicationController.showTransientIndication(it)
+ view = imageView,
+ viewModel = quickAffordancesCombinedViewModel.endButton,
+ alpha = flowOf(1f),
+ falsingManager = falsingManager,
+ vibratorHelper = vibratorHelper,
+ ) { message ->
+ indicationController.showTransientIndication(message)
}
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt
index 55df46679f6d..cd46d6cf2188 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt
@@ -61,7 +61,7 @@ constructor(
KeyguardQuickAffordanceViewBinder.bind(
constraintLayout.requireViewById(R.id.start_button),
keyguardQuickAffordancesCombinedViewModel.startButton,
- keyguardRootViewModel.alpha,
+ keyguardQuickAffordancesCombinedViewModel.transitionAlpha,
falsingManager,
vibratorHelper,
) {
@@ -71,7 +71,7 @@ constructor(
KeyguardQuickAffordanceViewBinder.bind(
constraintLayout.requireViewById(R.id.end_button),
keyguardQuickAffordancesCombinedViewModel.endButton,
- keyguardRootViewModel.alpha,
+ keyguardQuickAffordancesCombinedViewModel.transitionAlpha,
falsingManager,
vibratorHelper,
) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt
index 0f6a966aad2e..2a68f26d3ae7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt
@@ -25,14 +25,12 @@ import androidx.constraintlayout.widget.ConstraintSet.LEFT
import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
import androidx.constraintlayout.widget.ConstraintSet.RIGHT
import com.android.systemui.Flags.keyguardBottomAreaRefactor
-import com.android.systemui.res.R
import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.ui.binder.KeyguardQuickAffordanceViewBinder
import com.android.systemui.keyguard.ui.viewmodel.KeyguardQuickAffordancesCombinedViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.res.R
import com.android.systemui.statusbar.KeyguardIndicationController
import com.android.systemui.statusbar.VibratorHelper
import javax.inject.Inject
@@ -61,7 +59,7 @@ constructor(
KeyguardQuickAffordanceViewBinder.bind(
constraintLayout.requireViewById(R.id.start_button),
keyguardQuickAffordancesCombinedViewModel.startButton,
- keyguardRootViewModel.alpha,
+ keyguardQuickAffordancesCombinedViewModel.transitionAlpha,
falsingManager,
vibratorHelper,
) {
@@ -71,7 +69,7 @@ constructor(
KeyguardQuickAffordanceViewBinder.bind(
constraintLayout.requireViewById(R.id.end_button),
keyguardQuickAffordancesCombinedViewModel.endButton,
- keyguardRootViewModel.alpha,
+ keyguardQuickAffordancesCombinedViewModel.transitionAlpha,
falsingManager,
vibratorHelper,
) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt
index 14de01b41867..1864437a7d11 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt
@@ -55,6 +55,14 @@ constructor(
onStep = { 1f },
)
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 167.milliseconds,
+ startTime = 67.milliseconds,
+ onStep = { it },
+ onCancel = { 0f },
+ )
+
val deviceEntryBackgroundViewAlpha: Flow<Float> =
deviceEntryUdfpsInteractor.isUdfpsSupported.flatMapLatest { isUdfps ->
if (isUdfps) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt
index 27fb8a3d2473..a728a2810916 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt
@@ -22,6 +22,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInterac
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
@@ -41,6 +42,13 @@ constructor(
transitionFlow = interactor.dozingToLockscreenTransition,
)
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 150.milliseconds,
+ onStep = { it },
+ onCancel = { 0f },
+ )
+
override val deviceEntryParentViewAlpha: Flow<Float> =
transitionAnimation.immediatelyTransitionTo(1f)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingHostedToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingHostedToLockscreenTransitionViewModel.kt
new file mode 100644
index 000000000000..58235ae02abe
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingHostedToLockscreenTransitionViewModel.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromDreamingLockscreenHostedTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class DreamingHostedToLockscreenTransitionViewModel
+@Inject
+constructor(
+ interactor: KeyguardTransitionInteractor,
+) {
+
+ private val transitionAnimation =
+ KeyguardTransitionAnimationFlow(
+ transitionDuration = TO_LOCKSCREEN_DURATION,
+ transitionFlow = interactor.dreamingLockscreenHostedToLockscreenTransition
+ )
+
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 250.milliseconds,
+ onStep = { it },
+ onCancel = { 0f },
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt
index a3b8b85fc53d..f943bdfa7550 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt
@@ -96,6 +96,14 @@ constructor(
onStep = { it },
)
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ startTime = 233.milliseconds,
+ duration = 250.milliseconds,
+ onStep = { it },
+ onCancel = { 0f },
+ )
+
val deviceEntryBackgroundViewAlpha =
deviceEntryUdfpsInteractor.isUdfpsSupported.flatMapLatest { isUdfps ->
if (isUdfps) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToLockscreenTransitionViewModel.kt
new file mode 100644
index 000000000000..5804a205445c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToLockscreenTransitionViewModel.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromGoneTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class GoneToLockscreenTransitionViewModel
+@Inject
+constructor(
+ interactor: KeyguardTransitionInteractor,
+) {
+
+ private val transitionAnimation =
+ KeyguardTransitionAnimationFlow(
+ transitionDuration = TO_LOCKSCREEN_DURATION,
+ transitionFlow = interactor.goneToLockscreenTransition
+ )
+
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 250.milliseconds,
+ onStep = { it },
+ onCancel = { 0f },
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt
index 02ea5508f34f..188be244be4a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt
@@ -23,6 +23,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceIn
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel
import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
import javax.inject.Inject
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -32,6 +33,7 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
@OptIn(ExperimentalCoroutinesApi::class)
class KeyguardQuickAffordancesCombinedViewModel
@@ -39,6 +41,22 @@ class KeyguardQuickAffordancesCombinedViewModel
constructor(
private val quickAffordanceInteractor: KeyguardQuickAffordanceInteractor,
private val keyguardInteractor: KeyguardInteractor,
+ shadeInteractor: ShadeInteractor,
+ aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel,
+ dozingToLockscreenTransitionViewModel: DozingToLockscreenTransitionViewModel,
+ dreamingHostedToLockscreenTransitionViewModel: DreamingHostedToLockscreenTransitionViewModel,
+ dreamingToLockscreenTransitionViewModel: DreamingToLockscreenTransitionViewModel,
+ goneToLockscreenTransitionViewModel: GoneToLockscreenTransitionViewModel,
+ occludedToLockscreenTransitionViewModel: OccludedToLockscreenTransitionViewModel,
+ offToLockscreenTransitionViewModel: OffToLockscreenTransitionViewModel,
+ primaryBouncerToLockscreenTransitionViewModel: PrimaryBouncerToLockscreenTransitionViewModel,
+ lockscreenToAodTransitionViewModel: LockscreenToAodTransitionViewModel,
+ lockscreenToDozingTransitionViewModel: LockscreenToDozingTransitionViewModel,
+ lockscreenToDreamingHostedTransitionViewModel: LockscreenToDreamingHostedTransitionViewModel,
+ lockscreenToDreamingTransitionViewModel: LockscreenToDreamingTransitionViewModel,
+ lockscreenToGoneTransitionViewModel: LockscreenToGoneTransitionViewModel,
+ lockscreenToOccludedTransitionViewModel: LockscreenToOccludedTransitionViewModel,
+ lockscreenToPrimaryBouncerTransitionViewModel: LockscreenToPrimaryBouncerTransitionViewModel,
) {
data class PreviewMode(
@@ -60,6 +78,39 @@ constructor(
private val selectedPreviewSlotId =
MutableStateFlow(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START)
+ /** alpha while fading the quick affordances out */
+ private val fadeInAlpha: Flow<Float> =
+ merge(
+ aodToLockscreenTransitionViewModel.shortcutsAlpha,
+ dozingToLockscreenTransitionViewModel.shortcutsAlpha,
+ dreamingHostedToLockscreenTransitionViewModel.shortcutsAlpha,
+ dreamingToLockscreenTransitionViewModel.shortcutsAlpha,
+ goneToLockscreenTransitionViewModel.shortcutsAlpha,
+ occludedToLockscreenTransitionViewModel.shortcutsAlpha,
+ offToLockscreenTransitionViewModel.shortcutsAlpha,
+ primaryBouncerToLockscreenTransitionViewModel.shortcutsAlpha,
+ )
+
+ /** alpha while fading the quick affordances in */
+ private val fadeOutAlpha: Flow<Float> =
+ merge(
+ lockscreenToAodTransitionViewModel.shortcutsAlpha,
+ lockscreenToDozingTransitionViewModel.shortcutsAlpha,
+ lockscreenToDreamingHostedTransitionViewModel.shortcutsAlpha,
+ lockscreenToDreamingTransitionViewModel.shortcutsAlpha,
+ lockscreenToGoneTransitionViewModel.shortcutsAlpha,
+ lockscreenToOccludedTransitionViewModel.shortcutsAlpha,
+ lockscreenToPrimaryBouncerTransitionViewModel.shortcutsAlpha,
+ shadeInteractor.qsExpansion.map { 1 - it },
+ )
+
+ /** The source of truth of alpha for all of the quick affordances on lockscreen */
+ val transitionAlpha: Flow<Float> =
+ merge(
+ fadeInAlpha,
+ fadeOutAlpha,
+ )
+
/**
* Whether quick affordances are "opaque enough" to be considered visible to and interactive by
* the user. If they are not interactive, user input should not be allowed on them.
@@ -73,7 +124,7 @@ constructor(
* interactive/clickable unless "fully opaque" to avoid issues like in b/241830987.
*/
private val areQuickAffordancesFullyOpaque: Flow<Boolean> =
- keyguardInteractor.keyguardAlpha
+ transitionAlpha
.map { alpha -> alpha >= AFFORDANCE_FULLY_OPAQUE_ALPHA_THRESHOLD }
.distinctUntilChanged()
@@ -89,7 +140,7 @@ constructor(
* Notifies that a slot with the given ID has been selected in the preview experience that is
* rendering in the wallpaper picker. This is ignored for the real lock screen experience.
*
- * @see [KeyguardRootViewModel.enablePreviewMode]
+ * @see [enablePreviewMode]
*/
fun onPreviewSlotSelected(slotId: String) {
selectedPreviewSlotId.value = slotId
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
index 524fa1ede90a..f63afebb60ab 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
@@ -47,13 +47,11 @@ import javax.inject.Inject
import javax.inject.Provider
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onStart
@@ -74,16 +72,6 @@ constructor(
private val aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel,
screenOffAnimationController: ScreenOffAnimationController,
) {
-
- data class PreviewMode(val isInPreviewMode: Boolean = false)
-
- /**
- * Whether this view-model instance is powering the preview experience that renders exclusively
- * in the wallpaper picker application. This should _always_ be `false` for the real lock screen
- * experience.
- */
- private val previewMode = MutableStateFlow(PreviewMode())
-
var clockControllerProvider: Provider<ClockController>? = null
/** System insets that keyguard needs to stay out of */
@@ -103,14 +91,7 @@ constructor(
keyguardInteractor.notificationContainerBounds
/** An observable for the alpha level for the entire keyguard root view. */
- val alpha: Flow<Float> =
- previewMode.flatMapLatest {
- if (it.isInPreviewMode) {
- flowOf(1f)
- } else {
- keyguardInteractor.keyguardAlpha.distinctUntilChanged()
- }
- }
+ val alpha: Flow<Float> = keyguardInteractor.keyguardAlpha.distinctUntilChanged()
private fun burnIn(): Flow<BurnInModel> {
val dozingAmount: Flow<Float> =
@@ -147,55 +128,29 @@ constructor(
val lockscreenStateAlpha: Flow<Float> = aodToLockscreenTransitionViewModel.lockscreenAlpha
/** For elements that appear and move during the animation -> AOD */
- val burnInLayerAlpha: Flow<Float> =
- previewMode.flatMapLatest {
- if (it.isInPreviewMode) {
- flowOf(1f)
- } else {
- goneToAodTransitionViewModel.enterFromTopAnimationAlpha
- }
- }
+ val burnInLayerAlpha: Flow<Float> = goneToAodTransitionViewModel.enterFromTopAnimationAlpha
val translationY: Flow<Float> =
- previewMode.flatMapLatest {
- if (it.isInPreviewMode) {
- flowOf(0f)
- } else {
- keyguardInteractor.configurationChange.flatMapLatest { _ ->
- val enterFromTopAmount =
- context.resources.getDimensionPixelSize(
- R.dimen.keyguard_enter_from_top_translation_y
- )
- combine(
- keyguardInteractor.keyguardTranslationY.onStart { emit(0f) },
- burnIn().map { it.translationY.toFloat() }.onStart { emit(0f) },
- goneToAodTransitionViewModel
- .enterFromTopTranslationY(enterFromTopAmount)
- .onStart { emit(0f) },
- ) { keyguardTransitionY, burnInTranslationY, goneToAodTransitionTranslationY ->
- // All 3 values need to be combined for a smooth translation
- keyguardTransitionY + burnInTranslationY + goneToAodTransitionTranslationY
- }
- }
+ keyguardInteractor.configurationChange.flatMapLatest { _ ->
+ val enterFromTopAmount =
+ context.resources.getDimensionPixelSize(
+ R.dimen.keyguard_enter_from_top_translation_y
+ )
+ combine(
+ keyguardInteractor.keyguardTranslationY.onStart { emit(0f) },
+ burnIn().map { it.translationY.toFloat() }.onStart { emit(0f) },
+ goneToAodTransitionViewModel.enterFromTopTranslationY(enterFromTopAmount).onStart {
+ emit(0f)
+ },
+ ) { keyguardTransitionY, burnInTranslationY, goneToAodTransitionTranslationY ->
+ // All 3 values need to be combined for a smooth translation
+ keyguardTransitionY + burnInTranslationY + goneToAodTransitionTranslationY
}
}
- val translationX: Flow<Float> =
- previewMode.flatMapLatest {
- if (it.isInPreviewMode) {
- flowOf(0f)
- } else {
- burnIn().map { it.translationX.toFloat() }
- }
- }
+ val translationX: Flow<Float> = burnIn().map { it.translationX.toFloat() }
- val scale: Flow<Pair<Float, Boolean>> =
- previewMode.flatMapLatest { previewMode ->
- burnIn().map {
- val scale = if (previewMode.isInPreviewMode) 1f else it.scale
- Pair(scale, it.scaleClockOnly)
- }
- }
+ val scale: Flow<Pair<Float, Boolean>> = burnIn().map { Pair(it.scale, it.scaleClockOnly) }
/** Is the notification icon container visible? */
val isNotifIconContainerVisible: Flow<AnimatedValue<Boolean>> =
@@ -238,20 +193,7 @@ constructor(
}
.distinctUntilChanged()
- /**
- * Puts this view-model in "preview mode", which means it's being used for UI that is rendering
- * the lock screen preview in wallpaper picker / settings and not the real experience on the
- * lock screen.
- */
- fun enablePreviewMode() {
- previewMode.value = PreviewMode(true)
- }
-
fun onNotificationContainerBoundsChanged(top: Float, bottom: Float) {
- // Notifications should not be visible in preview mode
- if (previewMode.value.isInPreviewMode) {
- return
- }
keyguardInteractor.setNotificationContainerBounds(NotificationContainerBounds(top, bottom))
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt
index 2bf12e8e33b2..8e8fd75cc1c0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt
@@ -57,6 +57,15 @@ constructor(
onFinish = { 0f },
),
)
+
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 250.milliseconds,
+ onStep = { 1 - it },
+ onFinish = { 0f },
+ onCancel = { 1f },
+ )
+
override val deviceEntryParentViewAlpha: Flow<Float> =
deviceEntryUdfpsInteractor.isUdfpsEnrolledAndEnabled.flatMapLatest {
isUdfpsEnrolledAndEnabled ->
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt
new file mode 100644
index 000000000000..263ed11503ba
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor.Companion.TO_DOZING_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class LockscreenToDozingTransitionViewModel
+@Inject
+constructor(
+ interactor: KeyguardTransitionInteractor,
+) {
+
+ private val transitionAnimation =
+ KeyguardTransitionAnimationFlow(
+ transitionDuration = TO_DOZING_DURATION,
+ transitionFlow = interactor.lockscreenToDozingTransition
+ )
+
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 250.milliseconds,
+ onStep = { 1 - it },
+ onFinish = { 0f },
+ onCancel = { 1f },
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingHostedTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingHostedTransitionViewModel.kt
new file mode 100644
index 000000000000..17015056bda0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingHostedTransitionViewModel.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor.Companion.TO_DREAMING_HOSTED_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class LockscreenToDreamingHostedTransitionViewModel
+@Inject
+constructor(
+ interactor: KeyguardTransitionInteractor,
+) {
+
+ private val transitionAnimation =
+ KeyguardTransitionAnimationFlow(
+ transitionDuration = TO_DREAMING_HOSTED_DURATION,
+ transitionFlow = interactor.lockscreenToDreamingLockscreenHostedTransition
+ )
+
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 250.milliseconds,
+ onStep = { 1 - it },
+ onFinish = { 0f },
+ onCancel = { 1f },
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt
index 52296137a3d6..401c0ff76c29 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt
@@ -62,6 +62,14 @@ constructor(
onStep = { 1f - it },
)
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 250.milliseconds,
+ onStep = { 1 - it },
+ onFinish = { 0f },
+ onCancel = { 1f },
+ )
+
override val deviceEntryParentViewAlpha: Flow<Float> =
shadeDependentFlows.transitionFlow(
flowWhenShadeIsNotExpanded = lockscreenAlpha,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt
index 59e5aa845051..cfb4bf59c8a8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt
@@ -23,6 +23,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
@@ -43,6 +44,14 @@ constructor(
transitionFlow = interactor.transition(KeyguardState.LOCKSCREEN, KeyguardState.GONE),
)
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 250.milliseconds,
+ onStep = { 1 - it },
+ onFinish = { 0f },
+ onCancel = { 1f },
+ )
+
override val deviceEntryParentViewAlpha: Flow<Float> =
transitionAnimation.immediatelyTransitionTo(0f)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt
index d49bc4994b0f..a6136f95d0f6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt
@@ -50,6 +50,14 @@ constructor(
onStep = { 1f - it },
)
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 250.milliseconds,
+ onStep = { 1 - it },
+ onFinish = { 0f },
+ onCancel = { 1f },
+ )
+
/** Lockscreen views y-translation */
fun lockscreenTranslationY(translatePx: Int): Flow<Float> {
return transitionAnimation.createFlow(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt
index f04b67a1d4d4..07dd4ef49c5d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt
@@ -26,6 +26,7 @@ import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.map
/**
* Breaks down LOCKSCREEN->PRIMARY BOUNCER transition into discrete steps for corresponding views to
@@ -46,6 +47,11 @@ constructor(
interactor.transition(KeyguardState.LOCKSCREEN, KeyguardState.PRIMARY_BOUNCER),
)
+ val shortcutsAlpha: Flow<Float> =
+ interactor.transition(KeyguardState.LOCKSCREEN, KeyguardState.PRIMARY_BOUNCER).map {
+ 1 - it.value
+ }
+
override val deviceEntryParentViewAlpha: Flow<Float> =
shadeDependentFlows.transitionFlow(
flowWhenShadeIsNotExpanded =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
index 0bdc85d05106..58be0934beca 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
@@ -58,6 +58,13 @@ constructor(
)
}
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 250.milliseconds,
+ onStep = { it },
+ onCancel = { 0f },
+ )
+
/** Lockscreen views alpha */
val lockscreenAlpha: Flow<Float> =
transitionAnimation.createFlow(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModel.kt
new file mode 100644
index 000000000000..c3bc799435a8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModel.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class OffToLockscreenTransitionViewModel
+@Inject
+constructor(
+ interactor: KeyguardTransitionInteractor,
+) {
+
+ private val transitionAnimation =
+ KeyguardTransitionAnimationFlow(
+ transitionDuration = 250.milliseconds,
+ transitionFlow = interactor.offToLockscreenTransition
+ )
+
+ val shortcutsAlpha: Flow<Float> =
+ transitionAnimation.createFlow(
+ duration = 250.milliseconds,
+ onStep = { it },
+ onCancel = { 0f },
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
index 3cf793ab9dc8..7ef8374023fb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
@@ -28,6 +28,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.map
/**
* Breaks down PRIMARY BOUNCER->LOCKSCREEN transition into discrete steps for corresponding views to
@@ -57,6 +58,11 @@ constructor(
}
}
+ val shortcutsAlpha: Flow<Float> =
+ interactor.transition(KeyguardState.PRIMARY_BOUNCER, KeyguardState.LOCKSCREEN).map {
+ it.value
+ }
+
override val deviceEntryParentViewAlpha: Flow<Float> =
transitionAnimation.immediatelyTransitionTo(1f)
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
index 11db69b69f13..6c930b1f3d17 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
@@ -255,6 +255,10 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr
for (QSTile tile : tiles) {
addTile(tile, collapsedView);
}
+ } else {
+ for (QSPanelControllerBase.TileRecord record : mRecords) {
+ record.tile.addCallback(record.callback);
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 69fe46aa9009..529d68407ce9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -109,7 +109,7 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
// Only read and modified in main thread (where click events come through).
private int mClickEventId = 0;
- private final ArrayList<Callback> mCallbacks = new ArrayList<>();
+ private final ArraySet<Callback> mCallbacks = new ArraySet<>();
private final Object mStaleListener = new Object();
protected TState mState;
private TState mTmpState;
@@ -444,9 +444,9 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
}
private void handleStateChanged() {
- if (mCallbacks.size() != 0) {
+ if (!mCallbacks.isEmpty()) {
for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).onStateChanged(mState);
+ mCallbacks.valueAt(i).onStateChanged(mState);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/AirplaneModeMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/AirplaneModeMapper.kt
index c390695b1911..cfb544226c83 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/AirplaneModeMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/AirplaneModeMapper.kt
@@ -16,8 +16,9 @@
package com.android.systemui.qs.tiles.impl.airplane.domain
-import android.content.Context
+import android.content.res.Resources
import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
import com.android.systemui.qs.tiles.impl.airplane.domain.model.AirplaneModeTileModel
import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
@@ -26,29 +27,27 @@ import com.android.systemui.res.R
import javax.inject.Inject
/** Maps [AirplaneModeTileModel] to [QSTileState]. */
-class AirplaneModeMapper @Inject constructor(private val context: Context) :
+class AirplaneModeMapper @Inject constructor(@Main private val resources: Resources) :
QSTileDataToStateMapper<AirplaneModeTileModel> {
override fun map(config: QSTileConfig, data: AirplaneModeTileModel): QSTileState =
- QSTileState.build(context, config.uiConfig) {
+ QSTileState.build(resources, config.uiConfig) {
val icon =
- Icon.Loaded(
- context.getDrawable(
- if (data.isEnabled) {
- R.drawable.qs_airplane_icon_on
- } else {
- R.drawable.qs_airplane_icon_off
- }
- )!!,
+ Icon.Resource(
+ if (data.isEnabled) {
+ R.drawable.qs_airplane_icon_on
+ } else {
+ R.drawable.qs_airplane_icon_off
+ },
contentDescription = null
)
this.icon = { icon }
if (data.isEnabled) {
activationState = QSTileState.ActivationState.ACTIVE
- secondaryLabel = context.resources.getStringArray(R.array.tile_states_airplane)[2]
+ secondaryLabel = resources.getStringArray(R.array.tile_states_airplane)[2]
} else {
activationState = QSTileState.ActivationState.INACTIVE
- secondaryLabel = context.resources.getStringArray(R.array.tile_states_airplane)[1]
+ secondaryLabel = resources.getStringArray(R.array.tile_states_airplane)[1]
}
contentDescription = label
supportedActions =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapper.kt
index b2b226464ee5..881a6bd156d2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapper.kt
@@ -16,8 +16,9 @@
package com.android.systemui.qs.tiles.impl.flashlight.domain
-import android.content.Context
+import android.content.res.Resources
import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
import com.android.systemui.qs.tiles.impl.flashlight.domain.model.FlashlightTileModel
import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
@@ -26,30 +27,28 @@ import com.android.systemui.res.R
import javax.inject.Inject
/** Maps [FlashlightTileModel] to [QSTileState]. */
-class FlashlightMapper @Inject constructor(private val context: Context) :
+class FlashlightMapper @Inject constructor(@Main private val resources: Resources) :
QSTileDataToStateMapper<FlashlightTileModel> {
override fun map(config: QSTileConfig, data: FlashlightTileModel): QSTileState =
- QSTileState.build(context, config.uiConfig) {
+ QSTileState.build(resources, config.uiConfig) {
val icon =
- Icon.Loaded(
- context.resources.getDrawable(
- if (data.isEnabled) {
- R.drawable.qs_flashlight_icon_on
- } else {
- R.drawable.qs_flashlight_icon_off
- }
- ),
+ Icon.Resource(
+ if (data.isEnabled) {
+ R.drawable.qs_flashlight_icon_on
+ } else {
+ R.drawable.qs_flashlight_icon_off
+ },
contentDescription = null
)
this.icon = { icon }
if (data.isEnabled) {
activationState = QSTileState.ActivationState.ACTIVE
- secondaryLabel = context.resources.getStringArray(R.array.tile_states_flashlight)[2]
+ secondaryLabel = resources.getStringArray(R.array.tile_states_flashlight)[2]
} else {
activationState = QSTileState.ActivationState.INACTIVE
- secondaryLabel = context.resources.getStringArray(R.array.tile_states_flashlight)[1]
+ secondaryLabel = resources.getStringArray(R.array.tile_states_flashlight)[1]
}
contentDescription = label
supportedActions =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapper.kt
index 8e53723a5a6b..7e7034d65efd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapper.kt
@@ -16,8 +16,9 @@
package com.android.systemui.qs.tiles.impl.location.domain
-import android.content.Context
+import android.content.res.Resources
import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
import com.android.systemui.qs.tiles.impl.location.domain.model.LocationTileModel
import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
@@ -26,32 +27,30 @@ import com.android.systemui.res.R
import javax.inject.Inject
/** Maps [LocationTileModel] to [QSTileState]. */
-class LocationTileMapper @Inject constructor(private val context: Context) :
+class LocationTileMapper @Inject constructor(@Main private val resources: Resources) :
QSTileDataToStateMapper<LocationTileModel> {
override fun map(config: QSTileConfig, data: LocationTileModel): QSTileState =
- QSTileState.build(context, config.uiConfig) {
+ QSTileState.build(resources, config.uiConfig) {
val icon =
- Icon.Loaded(
- context.resources.getDrawable(
- if (data.isEnabled) {
- R.drawable.qs_location_icon_on
- } else {
- R.drawable.qs_location_icon_off
- }
- ),
+ Icon.Resource(
+ if (data.isEnabled) {
+ R.drawable.qs_location_icon_on
+ } else {
+ R.drawable.qs_location_icon_off
+ },
contentDescription = null
)
this.icon = { icon }
- this.label = context.resources.getString(R.string.quick_settings_location_label)
+ this.label = resources.getString(R.string.quick_settings_location_label)
if (data.isEnabled) {
activationState = QSTileState.ActivationState.ACTIVE
- secondaryLabel = context.resources.getStringArray(R.array.tile_states_location)[2]
+ secondaryLabel = resources.getStringArray(R.array.tile_states_location)[2]
} else {
activationState = QSTileState.ActivationState.INACTIVE
- secondaryLabel = context.resources.getStringArray(R.array.tile_states_location)[1]
+ secondaryLabel = resources.getStringArray(R.array.tile_states_location)[1]
}
contentDescription = label
supportedActions =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
index f9e0b160acd6..23e0cb66bb6a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
@@ -16,7 +16,7 @@
package com.android.systemui.qs.tiles.viewmodel
-import android.content.Context
+import android.content.res.Resources
import android.service.quicksettings.Tile
import android.view.View
import android.widget.Switch
@@ -46,13 +46,13 @@ data class QSTileState(
companion object {
fun build(
- context: Context,
+ resources: Resources,
config: QSTileUIConfig,
build: Builder.() -> Unit
): QSTileState =
build(
{ Icon.Resource(config.iconRes, null) },
- context.getString(config.labelRes),
+ resources.getString(config.labelRes),
build,
)
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
index 1c5330ecd24f..d42fde617394 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
@@ -128,7 +128,7 @@ constructor(
private fun automaticallySwitchScenes() {
applicationScope.launch {
// TODO (b/308001302): Move this to a bouncer specific interactor.
- bouncerInteractor.onImeHidden.collectLatest {
+ bouncerInteractor.onImeHiddenByUser.collectLatest {
if (sceneInteractor.desiredScene.value.key == SceneKey.Bouncer) {
sceneInteractor.changeScene(
scene = SceneModel(SceneKey.Lockscreen),
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
index e7481ccd0efd..b98093e50920 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
@@ -32,13 +32,16 @@ import android.os.Handler;
import android.os.Looper;
import android.os.ResultReceiver;
import android.view.Gravity;
+import android.view.View;
import android.view.Window;
import android.view.WindowManager;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Switch;
import android.widget.TextView;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.systemui.mediaprojection.MediaProjectionCaptureTarget;
@@ -115,6 +118,17 @@ public class ScreenRecordDialog extends SystemUIDialog {
mOptions.setOnItemClickListenerInt((parent, view, position, id) -> {
mAudioSwitch.setChecked(true);
});
+
+ // disable redundant Touch & Hold accessibility action for Switch Access
+ mOptions.setAccessibilityDelegate(new View.AccessibilityDelegate() {
+ @Override
+ public void onInitializeAccessibilityNodeInfo(@NonNull View host,
+ @NonNull AccessibilityNodeInfo info) {
+ info.removeAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK);
+ super.onInitializeAccessibilityNodeInfo(host, info);
+ }
+ });
+ mOptions.setLongClickable(false);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
index 9f4ea27b9ee6..d13edf01cc4a 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
@@ -39,6 +39,7 @@ import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.res.R;
+import com.android.systemui.shade.domain.interactor.ShadeInteractor;
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import com.android.systemui.util.concurrency.DelayableExecutor;
@@ -58,18 +59,21 @@ public class BrightnessDialog extends Activity {
private final DelayableExecutor mMainExecutor;
private final AccessibilityManagerWrapper mAccessibilityMgr;
private Runnable mCancelTimeoutRunnable;
+ private final ShadeInteractor mShadeInteractor;
@Inject
public BrightnessDialog(
BrightnessSliderController.Factory brightnessSliderfactory,
BrightnessController.Factory brightnessControllerFactory,
@Main DelayableExecutor mainExecutor,
- AccessibilityManagerWrapper accessibilityMgr
+ AccessibilityManagerWrapper accessibilityMgr,
+ ShadeInteractor shadeInteractor
) {
mToggleSliderFactory = brightnessSliderfactory;
mBrightnessControllerFactory = brightnessControllerFactory;
mMainExecutor = mainExecutor;
mAccessibilityMgr = accessibilityMgr;
+ mShadeInteractor = shadeInteractor;
}
@@ -79,6 +83,10 @@ public class BrightnessDialog extends Activity {
setWindowAttributes();
setContentView(R.layout.brightness_mirror_container);
setBrightnessDialogViewAttributes();
+
+ if (mShadeInteractor.isQsExpanded().getValue()) {
+ finish();
+ }
}
private void setWindowAttributes() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
index 1b096b592a4a..c1a630f48232 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
@@ -612,7 +612,7 @@ public final class KeyboardShortcutListSearch {
private static KeyboardShortcutMultiMappingGroup getMultiMappingInputShortcuts(
Context context) {
List<ShortcutMultiMappingInfo> shortcutMultiMappingInfoList = Arrays.asList(
- /* Switch input language (next language): Ctrl + Space or Meta + Space */
+ /* Switch input language (next language): Ctrl + Space */
new ShortcutMultiMappingInfo(
context.getString(R.string.input_switch_input_language_next),
null,
@@ -621,14 +621,9 @@ public final class KeyboardShortcutListSearch {
context.getString(
R.string.input_switch_input_language_next),
KeyEvent.KEYCODE_SPACE, KeyEvent.META_CTRL_ON),
- null),
- new ShortcutKeyGroup(new KeyboardShortcutInfo(
- context.getString(
- R.string.input_switch_input_language_next),
- KeyEvent.KEYCODE_SPACE, KeyEvent.META_META_ON),
null))),
/* Switch input language (previous language): */
- /* Ctrl + Shift + Space or Meta + Shift + Space */
+ /* Ctrl + Shift + Space */
new ShortcutMultiMappingInfo(
context.getString(R.string.input_switch_input_language_previous),
null,
@@ -638,12 +633,6 @@ public final class KeyboardShortcutListSearch {
R.string.input_switch_input_language_previous),
KeyEvent.KEYCODE_SPACE,
KeyEvent.META_CTRL_ON | KeyEvent.META_SHIFT_ON),
- null),
- new ShortcutKeyGroup(new KeyboardShortcutInfo(
- context.getString(
- R.string.input_switch_input_language_previous),
- KeyEvent.KEYCODE_SPACE,
- KeyEvent.META_META_ON | KeyEvent.META_SHIFT_ON),
null)))
);
return new KeyboardShortcutMultiMappingGroup(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
index 6d8ec44ad55e..c615887d5c25 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
@@ -67,6 +67,7 @@ public final class StatusBarTouchableRegionManager implements Dumpable {
private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
private boolean mIsStatusBarExpanded = false;
+ private boolean mIsSceneContainerVisible = false;
private boolean mShouldAdjustInsets = false;
private View mNotificationShadeWindowView;
private View mNotificationPanelView;
@@ -128,11 +129,14 @@ public final class StatusBarTouchableRegionManager implements Dumpable {
});
mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
- javaAdapter.alwaysCollectFlow(shadeInteractor.isAnyExpanded(), this::onShadeOrQsExpanded);
if (sceneContainerFlags.isEnabled()) {
javaAdapter.alwaysCollectFlow(
sceneInteractor.get().isVisible(),
+ this::onSceneContainerVisibilityChanged);
+ } else {
+ javaAdapter.alwaysCollectFlow(
+ shadeInteractor.isAnyExpanded(),
this::onShadeOrQsExpanded);
}
@@ -164,6 +168,17 @@ public final class StatusBarTouchableRegionManager implements Dumpable {
}
}
+ private void onSceneContainerVisibilityChanged(Boolean isVisible) {
+ if (isVisible != mIsSceneContainerVisible) {
+ mIsSceneContainerVisible = isVisible;
+ if (isVisible) {
+ // make sure our state is sensible
+ mForceCollapsedUntilLayout = false;
+ }
+ updateTouchableRegion();
+ }
+ }
+
/**
* Calculates the touch region needed for heads up notifications, taking into consideration
* any existing display cutouts (notch)
@@ -267,6 +282,7 @@ public final class StatusBarTouchableRegionManager implements Dumpable {
// since we don't want stray touches to go through the light reveal scrim to whatever is
// underneath.
return mIsStatusBarExpanded
+ || mIsSceneContainerVisible
|| mPrimaryBouncerInteractor.isShowing().getValue()
|| mAlternateBouncerInteractor.isVisibleState()
|| mUnlockedScreenOffAnimationController.isAnimationPlaying();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureController.java
index bbba19d61b5a..87df180353b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureController.java
@@ -73,7 +73,11 @@ public interface DevicePostureController extends CallbackController<Callback> {
/** Callback to be notified about device posture changes. */
interface Callback {
- /** Called when the posture changes. */
+ /**
+ * Called when the posture changes. If there are multiple active displays ("concurrent"),
+ * this will report the physical posture of the device (also known as the base device
+ * state).
+ */
void onPostureChanged(@DevicePostureInt int posture);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureControllerImpl.java
index 8f1ac812da71..422aa4d4aa60 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureControllerImpl.java
@@ -39,8 +39,11 @@ import javax.inject.Inject;
/** Implementation of {@link DevicePostureController} using the DeviceStateManager. */
@SysUISingleton
public class DevicePostureControllerImpl implements DevicePostureController {
+ /** From androidx.window.common.COMMON_STATE_USE_BASE_STATE */
+ private static final int COMMON_STATE_USE_BASE_STATE = 1000;
private final List<Callback> mListeners = new ArrayList<>();
private int mCurrentDevicePosture = DEVICE_POSTURE_UNKNOWN;
+ private int mCurrentBasePosture = DEVICE_POSTURE_UNKNOWN;
private final SparseIntArray mDeviceStateToPostureMap = new SparseIntArray();
@@ -73,16 +76,32 @@ public class DevicePostureControllerImpl implements DevicePostureController {
mDeviceStateToPostureMap.put(deviceState, posture);
}
- deviceStateManager.registerCallback(executor, state -> {
- Assert.isMainThread();
- mCurrentDevicePosture =
- mDeviceStateToPostureMap.get(state, DEVICE_POSTURE_UNKNOWN);
+ deviceStateManager.registerCallback(executor, new DeviceStateManager.DeviceStateCallback() {
+ @Override
+ public void onStateChanged(int state) {
+ Assert.isMainThread();
+ mCurrentDevicePosture =
+ mDeviceStateToPostureMap.get(state, DEVICE_POSTURE_UNKNOWN);
+ sendUpdatePosture();
+ }
+
+ @Override
+ public void onBaseStateChanged(int state) {
+ Assert.isMainThread();
+ mCurrentBasePosture = mDeviceStateToPostureMap.get(state, DEVICE_POSTURE_UNKNOWN);
+
+ if (useBaseState()) {
+ sendUpdatePosture();
+ }
+ }
- ListenersTracing.INSTANCE.forEachTraced(mListeners, "DevicePostureControllerImpl",
+ private void sendUpdatePosture() {
+ ListenersTracing.INSTANCE.forEachTraced(mListeners, "DevicePostureControllerImpl",
l -> {
- l.onPostureChanged(mCurrentDevicePosture);
+ l.onPostureChanged(getDevicePosture());
return Unit.INSTANCE;
});
+ }
});
}
@@ -100,6 +119,14 @@ public class DevicePostureControllerImpl implements DevicePostureController {
@Override
public int getDevicePosture() {
- return mCurrentDevicePosture;
+ if (useBaseState()) {
+ return mCurrentBasePosture;
+ } else {
+ return mCurrentDevicePosture;
+ }
+ }
+
+ private boolean useBaseState() {
+ return mCurrentDevicePosture == COMMON_STATE_USE_BASE_STATE;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
index e576f36d573a..279e5ef1f38c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
@@ -16,6 +16,7 @@ package com.android.systemui.statusbar.policy;
import com.android.systemui.Dumpable;
import com.android.systemui.statusbar.policy.FlashlightController.FlashlightListener;
+import com.android.systemui.util.annotations.WeaklyReferencedCallback;
public interface FlashlightController extends CallbackController<FlashlightListener>, Dumpable {
@@ -24,6 +25,7 @@ public interface FlashlightController extends CallbackController<FlashlightListe
boolean isAvailable();
boolean isEnabled();
+ @WeaklyReferencedCallback
public interface FlashlightListener {
/**
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
index 053148709e69..968981197b83 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
@@ -20,10 +20,12 @@ import android.content.Context
import android.hardware.devicestate.DeviceStateManager
import android.os.SystemProperties
import com.android.systemui.CoreStartable
+import com.android.systemui.Flags
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.LifecycleScreenStatusProvider
import com.android.systemui.unfold.config.UnfoldTransitionConfig
+import com.android.systemui.unfold.dagger.UnfoldBgProgressFlag
import com.android.systemui.unfold.dagger.UnfoldMain
import com.android.systemui.unfold.data.repository.UnfoldTransitionRepository
import com.android.systemui.unfold.data.repository.UnfoldTransitionRepositoryImpl
@@ -64,6 +66,10 @@ class UnfoldTransitionModule {
@Provides @UnfoldTransitionATracePrefix fun tracingTagPrefix() = "systemui"
+ @Provides
+ @UnfoldBgProgressFlag
+ fun unfoldBgProgressFlag() = Flags.unfoldAnimationBackgroundProgress()
+
/** A globally available FoldStateListener that allows one to query the fold state. */
@Provides
@Singleton
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
index d8799e16ebdb..43952824f9a7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
@@ -133,8 +133,8 @@ public class IWindowMagnificationConnectionTest extends SysuiTestCase {
}
@Test
- public void setScale() throws RemoteException {
- mIWindowMagnificationConnection.setScale(TEST_DISPLAY, 3.0f);
+ public void setScaleForWindowMagnification() throws RemoteException {
+ mIWindowMagnificationConnection.setScaleForWindowMagnification(TEST_DISPLAY, 3.0f);
waitForIdleSync();
verify(mWindowMagnificationController).setScale(3.0f);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
index 67c4e2688cd0..0c30d10ea563 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
@@ -51,6 +51,7 @@ import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.res.R
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.FakeSharedPreferences
@@ -58,8 +59,10 @@ import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.settings.FakeSettings
import com.google.common.truth.Truth
-import kotlin.math.max
import kotlin.math.min
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
@@ -73,6 +76,7 @@ import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
+@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(JUnit4::class)
class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() {
@@ -85,6 +89,47 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() {
@Mock private lateinit var keyguardStateController: KeyguardStateController
@Mock private lateinit var launchAnimator: DialogLaunchAnimator
@Mock private lateinit var logger: KeyguardQuickAffordancesMetricsLogger
+ @Mock private lateinit var shadeInteractor: ShadeInteractor
+ @Mock
+ private lateinit var aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel
+ @Mock
+ private lateinit var dozingToLockscreenTransitionViewModel:
+ DozingToLockscreenTransitionViewModel
+ @Mock
+ private lateinit var dreamingHostedToLockscreenTransitionViewModel:
+ DreamingHostedToLockscreenTransitionViewModel
+ @Mock
+ private lateinit var dreamingToLockscreenTransitionViewModel:
+ DreamingToLockscreenTransitionViewModel
+ @Mock
+ private lateinit var goneToLockscreenTransitionViewModel: GoneToLockscreenTransitionViewModel
+ @Mock
+ private lateinit var occludedToLockscreenTransitionViewModel:
+ OccludedToLockscreenTransitionViewModel
+ @Mock
+ private lateinit var offToLockscreenTransitionViewModel: OffToLockscreenTransitionViewModel
+ @Mock
+ private lateinit var primaryBouncerToLockscreenTransitionViewModel:
+ PrimaryBouncerToLockscreenTransitionViewModel
+ @Mock
+ private lateinit var lockscreenToAodTransitionViewModel: LockscreenToAodTransitionViewModel
+ @Mock
+ private lateinit var lockscreenToDozingTransitionViewModel:
+ LockscreenToDozingTransitionViewModel
+ @Mock
+ private lateinit var lockscreenToDreamingHostedTransitionViewModel:
+ LockscreenToDreamingHostedTransitionViewModel
+ @Mock
+ private lateinit var lockscreenToDreamingTransitionViewModel:
+ LockscreenToDreamingTransitionViewModel
+ @Mock
+ private lateinit var lockscreenToGoneTransitionViewModel: LockscreenToGoneTransitionViewModel
+ @Mock
+ private lateinit var lockscreenToOccludedTransitionViewModel:
+ LockscreenToOccludedTransitionViewModel
+ @Mock
+ private lateinit var lockscreenToPrimaryBouncerTransitionViewModel:
+ LockscreenToPrimaryBouncerTransitionViewModel
private lateinit var underTest: KeyguardQuickAffordancesCombinedViewModel
@@ -97,6 +142,10 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() {
private lateinit var biometricSettingsRepository: FakeBiometricSettingsRepository
private lateinit var keyguardInteractor: KeyguardInteractor
+ private val intendedAlphaMutableStateFlow: MutableStateFlow<Float> = MutableStateFlow(1f)
+ // the viewModel does a `map { 1 - it }` on this value, which is why it's different
+ private val intendedShadeAlphaMutableStateFlow: MutableStateFlow<Float> = MutableStateFlow(0f)
+
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
@@ -191,6 +240,31 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() {
userHandle = UserHandle.SYSTEM,
)
+ intendedAlphaMutableStateFlow.value = 1f
+ intendedShadeAlphaMutableStateFlow.value = 0f
+ whenever(aodToLockscreenTransitionViewModel.shortcutsAlpha)
+ .thenReturn(intendedAlphaMutableStateFlow)
+ whenever(dozingToLockscreenTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+ whenever(dreamingHostedToLockscreenTransitionViewModel.shortcutsAlpha)
+ .thenReturn(emptyFlow())
+ whenever(dreamingToLockscreenTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+ whenever(goneToLockscreenTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+ whenever(occludedToLockscreenTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+ whenever(offToLockscreenTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+ whenever(primaryBouncerToLockscreenTransitionViewModel.shortcutsAlpha)
+ .thenReturn(emptyFlow())
+ whenever(lockscreenToAodTransitionViewModel.shortcutsAlpha)
+ .thenReturn(intendedAlphaMutableStateFlow)
+ whenever(lockscreenToDozingTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+ whenever(lockscreenToDreamingHostedTransitionViewModel.shortcutsAlpha)
+ .thenReturn(emptyFlow())
+ whenever(lockscreenToDreamingTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+ whenever(lockscreenToGoneTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+ whenever(lockscreenToOccludedTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+ whenever(lockscreenToPrimaryBouncerTransitionViewModel.shortcutsAlpha)
+ .thenReturn(emptyFlow())
+ whenever(shadeInteractor.qsExpansion).thenReturn(intendedShadeAlphaMutableStateFlow)
+
underTest =
KeyguardQuickAffordancesCombinedViewModel(
quickAffordanceInteractor =
@@ -210,7 +284,27 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() {
backgroundDispatcher = testDispatcher,
appContext = mContext,
),
- keyguardInteractor = keyguardInteractor
+ keyguardInteractor = keyguardInteractor,
+ shadeInteractor = shadeInteractor,
+ aodToLockscreenTransitionViewModel = aodToLockscreenTransitionViewModel,
+ dozingToLockscreenTransitionViewModel = dozingToLockscreenTransitionViewModel,
+ dreamingHostedToLockscreenTransitionViewModel =
+ dreamingHostedToLockscreenTransitionViewModel,
+ dreamingToLockscreenTransitionViewModel = dreamingToLockscreenTransitionViewModel,
+ goneToLockscreenTransitionViewModel = goneToLockscreenTransitionViewModel,
+ occludedToLockscreenTransitionViewModel = occludedToLockscreenTransitionViewModel,
+ offToLockscreenTransitionViewModel = offToLockscreenTransitionViewModel,
+ primaryBouncerToLockscreenTransitionViewModel =
+ primaryBouncerToLockscreenTransitionViewModel,
+ lockscreenToAodTransitionViewModel = lockscreenToAodTransitionViewModel,
+ lockscreenToDozingTransitionViewModel = lockscreenToDozingTransitionViewModel,
+ lockscreenToDreamingHostedTransitionViewModel =
+ lockscreenToDreamingHostedTransitionViewModel,
+ lockscreenToDreamingTransitionViewModel = lockscreenToDreamingTransitionViewModel,
+ lockscreenToGoneTransitionViewModel = lockscreenToGoneTransitionViewModel,
+ lockscreenToOccludedTransitionViewModel = lockscreenToOccludedTransitionViewModel,
+ lockscreenToPrimaryBouncerTransitionViewModel =
+ lockscreenToPrimaryBouncerTransitionViewModel
)
}
@@ -526,15 +620,15 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() {
@Test
fun isClickable_falseWhenAlphaBelowThreshold() =
testScope.runTest {
+ intendedAlphaMutableStateFlow.value =
+ KeyguardQuickAffordancesCombinedViewModel.AFFORDANCE_FULLY_OPAQUE_ALPHA_THRESHOLD -
+ .1f
+ // the viewModel does a `map { 1 - it }` on this value, which is why it's different
+ intendedShadeAlphaMutableStateFlow.value =
+ KeyguardQuickAffordancesCombinedViewModel.AFFORDANCE_FULLY_OPAQUE_ALPHA_THRESHOLD +
+ .1f
repository.setKeyguardShowing(true)
val latest = collectLastValue(underTest.startButton)
- repository.setKeyguardAlpha(
- max(
- 0f,
- KeyguardQuickAffordancesCombinedViewModel
- .AFFORDANCE_FULLY_OPAQUE_ALPHA_THRESHOLD - 0.1f
- ),
- )
val testConfig =
TestConfig(
@@ -561,9 +655,10 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() {
@Test
fun isClickable_falseWhenAlphaAtZero() =
testScope.runTest {
+ intendedAlphaMutableStateFlow.value = 0f
+ intendedShadeAlphaMutableStateFlow.value = 1f
repository.setKeyguardShowing(true)
val latest = collectLastValue(underTest.startButton)
- repository.setKeyguardAlpha(0f)
val testConfig =
TestConfig(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
index e6d6cf263d69..a57feda64723 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
@@ -163,23 +163,6 @@ class KeyguardRootViewModelTest : SysuiTestCase() {
}
@Test
- fun alpha_inPreviewMode_doesNotChange() =
- testScope.runTest {
- val value = collectLastValue(underTest.alpha)
- underTest.enablePreviewMode()
-
- assertThat(value()).isEqualTo(1f)
- repository.setKeyguardAlpha(0.1f)
- assertThat(value()).isEqualTo(1f)
- repository.setKeyguardAlpha(0.5f)
- assertThat(value()).isEqualTo(1f)
- repository.setKeyguardAlpha(0.2f)
- assertThat(value()).isEqualTo(1f)
- repository.setKeyguardAlpha(0f)
- assertThat(value()).isEqualTo(1f)
- }
-
- @Test
fun translationAndScaleFromBurnInNotDozing() =
testScope.runTest {
val translationX by collectLastValue(underTest.translationX)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt
index 6e487cdd65b5..88c728fd1b66 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt
@@ -28,12 +28,16 @@ import androidx.test.rule.ActivityTestRule
import com.android.systemui.SysuiTestCase
import com.android.systemui.activity.SingleActivityFactory
import com.android.systemui.res.R
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
import com.android.systemui.util.concurrency.DelayableExecutor
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
+import dagger.Lazy
+import kotlinx.coroutines.flow.MutableStateFlow
import org.junit.After
import org.junit.Before
import org.junit.Rule
@@ -55,6 +59,8 @@ class BrightnessDialogTest : SysuiTestCase() {
@Mock private lateinit var brightnessControllerFactory: BrightnessController.Factory
@Mock private lateinit var brightnessController: BrightnessController
@Mock private lateinit var accessibilityMgr: AccessibilityManagerWrapper
+ @Mock private lateinit var shadeInteractorLazy: Lazy<ShadeInteractor>
+ @Mock private lateinit var shadeInteractor: ShadeInteractor
private val clock = FakeSystemClock()
private val mainExecutor = FakeExecutor(clock)
@@ -68,7 +74,8 @@ class BrightnessDialogTest : SysuiTestCase() {
brightnessSliderControllerFactory,
brightnessControllerFactory,
mainExecutor,
- accessibilityMgr
+ accessibilityMgr,
+ shadeInteractor
)
},
/* initialTouchMode= */ false,
@@ -82,6 +89,8 @@ class BrightnessDialogTest : SysuiTestCase() {
.thenReturn(brightnessSliderController)
`when`(brightnessSliderController.rootView).thenReturn(View(context))
`when`(brightnessControllerFactory.create(any())).thenReturn(brightnessController)
+ whenever(shadeInteractorLazy.get()).thenReturn(shadeInteractor)
+ whenever(shadeInteractor.isQsExpanded).thenReturn(MutableStateFlow(false))
}
@After
@@ -175,13 +184,15 @@ class BrightnessDialogTest : SysuiTestCase() {
brightnessSliderControllerFactory: BrightnessSliderController.Factory,
brightnessControllerFactory: BrightnessController.Factory,
mainExecutor: DelayableExecutor,
- accessibilityMgr: AccessibilityManagerWrapper
+ accessibilityMgr: AccessibilityManagerWrapper,
+ shadeInteractor: ShadeInteractor
) :
BrightnessDialog(
brightnessSliderControllerFactory,
brightnessControllerFactory,
mainExecutor,
- accessibilityMgr
+ accessibilityMgr,
+ shadeInteractor
) {
private var finishing = false
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DevicePostureControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DevicePostureControllerImplTest.kt
new file mode 100644
index 000000000000..ce471705ed85
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DevicePostureControllerImplTest.kt
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy
+
+import android.hardware.devicestate.DeviceStateManager
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.testing.TestableResources
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_CLOSED
+import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_FLIPPED
+import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_HALF_OPENED
+import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_OPENED
+import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_UNKNOWN
+import com.android.systemui.statusbar.policy.DevicePostureController.SUPPORTED_POSTURES_SIZE
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+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.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class DevicePostureControllerImplTest : SysuiTestCase() {
+ private val useBaseStateDeviceState = SUPPORTED_POSTURES_SIZE
+ private val deviceStateToPostureMapping =
+ arrayOf(
+ "$DEVICE_POSTURE_UNKNOWN:$DEVICE_POSTURE_UNKNOWN",
+ "$DEVICE_POSTURE_CLOSED:$DEVICE_POSTURE_CLOSED",
+ "$DEVICE_POSTURE_HALF_OPENED:$DEVICE_POSTURE_HALF_OPENED",
+ "$DEVICE_POSTURE_OPENED:$DEVICE_POSTURE_OPENED",
+ "$DEVICE_POSTURE_FLIPPED:$DEVICE_POSTURE_FLIPPED",
+ "$useBaseStateDeviceState:1000"
+ )
+ @Mock private lateinit var deviceStateManager: DeviceStateManager
+ @Captor
+ private lateinit var deviceStateCallback: ArgumentCaptor<DeviceStateManager.DeviceStateCallback>
+
+ private lateinit var mainExecutor: FakeExecutor
+ private lateinit var testableResources: TestableResources
+ private lateinit var underTest: DevicePostureControllerImpl
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ mainExecutor = FakeExecutor(FakeSystemClock())
+ testableResources = context.getOrCreateTestableResources()
+ testableResources.addOverride(
+ com.android.internal.R.array.config_device_state_postures,
+ deviceStateToPostureMapping
+ )
+ underTest =
+ DevicePostureControllerImpl(
+ context,
+ deviceStateManager,
+ mainExecutor,
+ )
+ verifyRegistersForDeviceStateCallback()
+ }
+
+ @Test
+ fun testPostureChanged_updates() {
+ var posture = -1
+ underTest.addCallback { posture = it }
+
+ deviceStateCallback.value.onStateChanged(DEVICE_POSTURE_UNKNOWN)
+ assertThat(posture).isEqualTo(DEVICE_POSTURE_UNKNOWN)
+
+ deviceStateCallback.value.onStateChanged(DEVICE_POSTURE_CLOSED)
+ assertThat(posture).isEqualTo(DEVICE_POSTURE_CLOSED)
+
+ deviceStateCallback.value.onStateChanged(DEVICE_POSTURE_HALF_OPENED)
+ assertThat(posture).isEqualTo(DEVICE_POSTURE_HALF_OPENED)
+
+ deviceStateCallback.value.onStateChanged(DEVICE_POSTURE_OPENED)
+ assertThat(posture).isEqualTo(DEVICE_POSTURE_OPENED)
+
+ deviceStateCallback.value.onStateChanged(DEVICE_POSTURE_FLIPPED)
+ assertThat(posture).isEqualTo(DEVICE_POSTURE_FLIPPED)
+ }
+
+ @Test
+ fun testPostureChanged_useBaseUpdate() {
+ var posture = -1
+ underTest.addCallback { posture = it }
+
+ deviceStateCallback.value.onStateChanged(DEVICE_POSTURE_HALF_OPENED)
+ assertThat(posture).isEqualTo(DEVICE_POSTURE_HALF_OPENED)
+
+ // base state change doesn't change the posture
+ deviceStateCallback.value.onBaseStateChanged(DEVICE_POSTURE_CLOSED)
+ assertThat(posture).isEqualTo(DEVICE_POSTURE_HALF_OPENED)
+
+ // WHEN the display state maps to using the base state, then posture updates
+ deviceStateCallback.value.onStateChanged(useBaseStateDeviceState)
+ assertThat(posture).isEqualTo(DEVICE_POSTURE_CLOSED)
+ }
+
+ @Test
+ fun baseStateChanges_doesNotUpdatePosture() {
+ var numPostureChanges = 0
+ underTest.addCallback { numPostureChanges++ }
+
+ deviceStateCallback.value.onStateChanged(DEVICE_POSTURE_HALF_OPENED)
+ assertThat(numPostureChanges).isEqualTo(1)
+
+ // base state changes doesn't send another posture update since the device state isn't
+ // useBaseStateDeviceState
+ deviceStateCallback.value.onBaseStateChanged(DEVICE_POSTURE_CLOSED)
+ deviceStateCallback.value.onBaseStateChanged(DEVICE_POSTURE_HALF_OPENED)
+ deviceStateCallback.value.onBaseStateChanged(DEVICE_POSTURE_FLIPPED)
+ deviceStateCallback.value.onBaseStateChanged(DEVICE_POSTURE_OPENED)
+ deviceStateCallback.value.onBaseStateChanged(DEVICE_POSTURE_UNKNOWN)
+ assertThat(numPostureChanges).isEqualTo(1)
+ }
+
+ private fun verifyRegistersForDeviceStateCallback() {
+ verify(deviceStateManager).registerCallback(eq(mainExecutor), deviceStateCallback.capture())
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/MainThreadUnfoldTransitionProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/MainThreadUnfoldTransitionProgressProviderTest.kt
new file mode 100644
index 000000000000..4e61b89b9c3e
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/MainThreadUnfoldTransitionProgressProviderTest.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.unfold.progress
+
+import android.os.Looper
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.unfold.TestUnfoldTransitionProvider
+import com.android.systemui.utils.os.FakeHandler
+import kotlin.test.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+@RunWithLooper(setAsMainLooper = true)
+class MainThreadUnfoldTransitionProgressProviderTest : SysuiTestCase() {
+
+ private val wrappedProgressProvider = TestUnfoldTransitionProvider()
+ private val fakeHandler = FakeHandler(Looper.getMainLooper())
+ private val listener = TestUnfoldProgressListener()
+
+ private val progressProvider =
+ MainThreadUnfoldTransitionProgressProvider(fakeHandler, wrappedProgressProvider)
+
+ @Test
+ fun onTransitionStarted_propagated() {
+ progressProvider.addCallback(listener)
+
+ wrappedProgressProvider.onTransitionStarted()
+ fakeHandler.dispatchQueuedMessages()
+
+ listener.assertStarted()
+ }
+
+ @Test
+ fun onTransitionProgress_propagated() {
+ progressProvider.addCallback(listener)
+
+ wrappedProgressProvider.onTransitionStarted()
+ wrappedProgressProvider.onTransitionProgress(0.5f)
+ fakeHandler.dispatchQueuedMessages()
+
+ listener.assertLastProgress(0.5f)
+ }
+
+ @Test
+ fun onTransitionFinished_propagated() {
+ progressProvider.addCallback(listener)
+
+ wrappedProgressProvider.onTransitionStarted()
+ wrappedProgressProvider.onTransitionProgress(0.5f)
+ wrappedProgressProvider.onTransitionFinished()
+ fakeHandler.dispatchQueuedMessages()
+
+ listener.ensureTransitionFinished()
+ }
+
+ @Test
+ fun onTransitionFinishing_propagated() {
+ progressProvider.addCallback(listener)
+
+ wrappedProgressProvider.onTransitionStarted()
+ wrappedProgressProvider.onTransitionProgress(0.5f)
+ wrappedProgressProvider.onTransitionFinished()
+ fakeHandler.dispatchQueuedMessages()
+
+ listener.ensureTransitionFinished()
+ }
+
+ @Test
+ fun onTransitionStarted_afterCallbackRemoved_notPropagated() {
+ progressProvider.addCallback(listener)
+ progressProvider.removeCallback(listener)
+
+ wrappedProgressProvider.onTransitionStarted()
+ fakeHandler.dispatchQueuedMessages()
+
+ listener.assertNotStarted()
+ }
+}
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
index 42d31b38ff76..f7fb01465a40 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
@@ -19,8 +19,10 @@ package com.android.systemui.unfold
import android.os.Handler
import com.android.systemui.unfold.config.UnfoldTransitionConfig
import com.android.systemui.unfold.dagger.UnfoldBg
+import com.android.systemui.unfold.dagger.UnfoldBgProgressFlag
import com.android.systemui.unfold.dagger.UnfoldMain
import com.android.systemui.unfold.progress.FixedTimingTransitionProgressProvider
+import com.android.systemui.unfold.progress.MainThreadUnfoldTransitionProgressProvider
import com.android.systemui.unfold.progress.PhysicsBasedUnfoldTransitionProgressProvider
import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder
import com.android.systemui.unfold.updates.DeviceFoldStateProvider
@@ -36,15 +38,18 @@ import com.android.systemui.unfold.util.ScaleAwareTransitionProgressProvider
import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityManager
import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityManagerImpl
import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityProvider
+import dagger.BindsOptionalOf
import dagger.Module
import dagger.Provides
import java.util.Optional
import javax.inject.Provider
import javax.inject.Singleton
+import kotlin.jvm.optionals.getOrDefault
@Module(
includes =
[
+ UnfoldFlagsModule::class,
UnfoldSharedInternalModule::class,
UnfoldRotationProviderInternalModule::class,
HingeAngleProviderInternalModule::class,
@@ -69,6 +74,16 @@ class UnfoldSharedModule {
fun foldStateRepository(impl: FoldStateRepositoryImpl): FoldStateRepository = impl
}
+@Module
+abstract class UnfoldFlagsModule {
+ /**
+ * Users of the library can bind this boolean to notify whether the progress should be
+ * calculated only in the background (and the main thread provider is generated by posting the
+ * background events in the main handler).
+ */
+ @BindsOptionalOf @UnfoldBgProgressFlag abstract fun unfoldBgProgressFlag(): Boolean
+}
+
/**
* Needed as methods inside must be public, but their parameters can be internal (and, a public
* method can't have internal parameters). Making the module internal and included in a public one
@@ -87,17 +102,34 @@ internal class UnfoldSharedInternalModule {
fixedTimingTransitionProgressProvider: Provider<FixedTimingTransitionProgressProvider>,
foldStateProvider: FoldStateProvider,
@UnfoldMain mainHandler: Handler,
+ mainThreadUnfoldTransitionProgressProviderFactory:
+ MainThreadUnfoldTransitionProgressProvider.Factory,
+ @UnfoldBg bgProvider: Provider<Optional<UnfoldTransitionProgressProvider>>,
+ @UnfoldBgProgressFlag unfoldBgProgressFlag: Optional<Boolean>,
): Optional<UnfoldTransitionProgressProvider> {
- return createOptionalUnfoldTransitionProgressProvider(
- config = config,
- scaleAwareProviderFactory = scaleAwareProviderFactory,
- tracingListener = tracingListener.create("MainThread"),
- physicsBasedUnfoldTransitionProgressProvider =
- physicsBasedUnfoldTransitionProgressProvider,
- fixedTimingTransitionProgressProvider = fixedTimingTransitionProgressProvider,
- foldStateProvider = foldStateProvider,
- progressHandler = mainHandler,
- )
+ if (unfoldBgProgressFlag.getOrDefault(false)) {
+ // In this case, we wrap the background progress provider
+ val mainThreadProvider: Optional<UnfoldTransitionProgressProvider> =
+ bgProvider.get().map {
+ mainThreadUnfoldTransitionProgressProviderFactory.create(it)
+ }
+ mainThreadProvider.ifPresent {
+ it.addCallback(tracingListener.create("MainThreadFromBgProgress"))
+ }
+ return mainThreadProvider
+ } else {
+ // TODO(b/277879146): Remove this once unfold_animation_background_progress is launched.
+ return createOptionalUnfoldTransitionProgressProvider(
+ config = config,
+ scaleAwareProviderFactory = scaleAwareProviderFactory,
+ tracingListener = tracingListener.create("MainThread"),
+ physicsBasedUnfoldTransitionProgressProvider =
+ physicsBasedUnfoldTransitionProgressProvider,
+ fixedTimingTransitionProgressProvider = fixedTimingTransitionProgressProvider,
+ foldStateProvider = foldStateProvider,
+ progressHandler = mainHandler,
+ )
+ }
}
@Provides
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Password.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldBgProgressFlag.kt
index 2fe4fd5a12e4..0e371fa6bfb7 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Password.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldBgProgressFlag.kt
@@ -5,7 +5,7 @@
* 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.0N
+ * 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,
@@ -14,13 +14,13 @@
* limitations under the License.
*/
-package com.android.credentialmanager.model
+package com.android.systemui.unfold.dagger
-import android.credentials.ui.Entry
-import androidx.credentials.provider.PasswordCredentialEntry
+import javax.inject.Qualifier
-data class Password(
- val providerId: String,
- val entry: Entry,
- val passwordCredentialEntry: PasswordCredentialEntry,
-)
+/**
+ * Annotates the boolean representing whether we are calculating progresses in the background.
+ *
+ * Used to allow clients to provide this value, without depending on the flags directly.
+ */
+@Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class UnfoldBgProgressFlag
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/MainThreadUnfoldTransitionProgressProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/MainThreadUnfoldTransitionProgressProvider.kt
new file mode 100644
index 000000000000..9bdf3d5d5307
--- /dev/null
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/MainThreadUnfoldTransitionProgressProvider.kt
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.unfold.progress
+
+import android.os.Handler
+import androidx.annotation.FloatRange
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
+import com.android.systemui.unfold.dagger.UnfoldMain
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+
+/**
+ * [UnfoldTransitionProgressProvider] that forwards all progress to the main thread handler.
+ *
+ * This is needed when progress are calculated in the background, but some listeners need the
+ * callbacks in the main thread.
+ */
+class MainThreadUnfoldTransitionProgressProvider
+@AssistedInject
+constructor(
+ @UnfoldMain private val mainHandler: Handler,
+ @Assisted private val rootProvider: UnfoldTransitionProgressProvider
+) : UnfoldTransitionProgressProvider {
+
+ private val listenerMap = mutableMapOf<TransitionProgressListener, TransitionProgressListener>()
+
+ override fun addCallback(listener: TransitionProgressListener) {
+ assertMainThread()
+ val proxy = TransitionProgressListerProxy(listener)
+ rootProvider.addCallback(proxy)
+ listenerMap[listener] = proxy
+ }
+
+ override fun removeCallback(listener: TransitionProgressListener) {
+ assertMainThread()
+ val proxy = listenerMap.remove(listener) ?: return
+ rootProvider.removeCallback(proxy)
+ }
+
+ private fun assertMainThread() {
+ check(mainHandler.looper.isCurrentThread) {
+ "Should be called from the main thread, but this is ${Thread.currentThread()}"
+ }
+ }
+
+ override fun destroy() {
+ rootProvider.destroy()
+ }
+
+ inner class TransitionProgressListerProxy(private val listener: TransitionProgressListener) :
+ TransitionProgressListener {
+ override fun onTransitionStarted() {
+ mainHandler.post { listener.onTransitionStarted() }
+ }
+
+ override fun onTransitionProgress(@FloatRange(from = 0.0, to = 1.0) progress: Float) {
+ mainHandler.post { listener.onTransitionProgress(progress) }
+ }
+
+ override fun onTransitionFinishing() {
+ mainHandler.post { listener.onTransitionFinishing() }
+ }
+
+ override fun onTransitionFinished() {
+ mainHandler.post { listener.onTransitionFinished() }
+ }
+ }
+
+ @AssistedFactory
+ interface Factory {
+ /** Creates a [MainThreadUnfoldTransitionProgressProvider] that wraps the [rootProvider]. */
+ fun create(
+ rootProvider: UnfoldTransitionProgressProvider
+ ): MainThreadUnfoldTransitionProgressProvider
+ }
+}
diff --git a/ravenwood/framework-minus-apex-ravenwood-policies.txt b/ravenwood/framework-minus-apex-ravenwood-policies.txt
index c70c171048e7..79bfa443b330 100644
--- a/ravenwood/framework-minus-apex-ravenwood-policies.txt
+++ b/ravenwood/framework-minus-apex-ravenwood-policies.txt
@@ -1,5 +1,8 @@
# Ravenwood "policy" file for framework-minus-apex.
+# Keep all AIDL interfaces
+class :aidl stubclass
+
# Collections
class android.util.ArrayMap stubclass
class android.util.ArraySet stubclass
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 74538ac02289..6cac6a47c77b 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -668,7 +668,7 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
final Context uiContext = displayContext.createWindowContext(
TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, null /* options */);
magnificationGestureHandler = new WindowMagnificationGestureHandler(uiContext,
- mAms.getWindowMagnificationMgr(), mAms.getTraceManager(),
+ mAms.getMagnificationConnectionManager(), mAms.getTraceManager(),
mAms.getMagnificationController(),
detectControlGestures,
detectTwoFingerTripleTap,
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index b5e8c849517b..2eecb4d3a86c 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -158,10 +158,10 @@ import com.android.internal.util.Preconditions;
import com.android.server.AccessibilityManagerInternal;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.accessibility.magnification.MagnificationConnectionManager;
import com.android.server.accessibility.magnification.MagnificationController;
import com.android.server.accessibility.magnification.MagnificationProcessor;
import com.android.server.accessibility.magnification.MagnificationScaleProvider;
-import com.android.server.accessibility.magnification.WindowMagnificationManager;
import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.server.pm.UserManagerInternal;
import com.android.server.policy.WindowManagerPolicy;
@@ -3442,7 +3442,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
&& (userState.getMagnificationCapabilitiesLocked()
!= Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN)
|| userHasMagnificationServicesLocked(userState);
- getWindowMagnificationMgr().requestConnection(connect);
+ getMagnificationConnectionManager().requestConnection(connect);
}
/**
@@ -4122,17 +4122,17 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
mSecurityPolicy.enforceCallingOrSelfPermission(
android.Manifest.permission.STATUS_BAR_SERVICE);
- getWindowMagnificationMgr().setConnection(connection);
+ getMagnificationConnectionManager().setConnection(connection);
}
/**
- * Getter of {@link WindowMagnificationManager}.
+ * Getter of {@link MagnificationConnectionManager}.
*
- * @return WindowMagnificationManager
+ * @return MagnificationManager
*/
- public WindowMagnificationManager getWindowMagnificationMgr() {
+ public MagnificationConnectionManager getMagnificationConnectionManager() {
synchronized (mLock) {
- return mMagnificationController.getWindowMagnificationMgr();
+ return mMagnificationController.getMagnificationConnectionManager();
}
}
@@ -4423,7 +4423,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
pw.println();
}
pw.append("hasWindowMagnificationConnection=").append(
- String.valueOf(getWindowMagnificationMgr().isConnected()));
+ String.valueOf(getMagnificationConnectionManager().isConnected()));
pw.println();
mMagnificationProcessor.dump(pw, getValidDisplayList());
final int userCount = mUserStates.size();
@@ -5144,7 +5144,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
for (int i = 0; i < displays.size(); i++) {
final int displayId = displays.get(i).getDisplayId();
- getWindowMagnificationMgr().removeMagnificationButton(displayId);
+ getMagnificationConnectionManager().removeMagnificationButton(displayId);
}
}
}
@@ -5580,6 +5580,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
@Override
public void injectInputEventToInputFilter(InputEvent event) {
+ mSecurityPolicy.enforceCallingPermission(Manifest.permission.INJECT_EVENTS,
+ "injectInputEventToInputFilter");
synchronized (mLock) {
final long endMillis =
SystemClock.uptimeMillis() + WAIT_INPUT_FILTER_INSTALL_TIMEOUT_MS;
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java
index 3ea805bbb4a6..5a3c070819bd 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java
@@ -60,19 +60,19 @@ import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
/**
- * A class to manipulate window magnification through {@link MagnificationConnectionWrapper}
+ * A class to manipulate magnification through {@link MagnificationConnectionWrapper}
* create by {@link #setConnection(IWindowMagnificationConnection)}. To set the connection with
* SysUI, call {@code StatusBarManagerInternal#requestWindowMagnificationConnection(boolean)}.
* The applied magnification scale is constrained by
* {@link MagnificationScaleProvider#constrainScale(float)}
*/
-public class WindowMagnificationManager implements
+public class MagnificationConnectionManager implements
PanningScalingHandler.MagnificationDelegate,
WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks {
private static final boolean DBG = false;
- private static final String TAG = "WindowMagnificationMgr";
+ private static final String TAG = "MagnificationConnectionManager";
/**
* Indicate that the magnification window is at the magnification center.
@@ -208,7 +208,7 @@ public class WindowMagnificationManager implements
private final AccessibilityTraceManager mTrace;
private final MagnificationScaleProvider mScaleProvider;
- public WindowMagnificationManager(Context context, Object lock, @NonNull Callback callback,
+ public MagnificationConnectionManager(Context context, Object lock, @NonNull Callback callback,
AccessibilityTraceManager trace, MagnificationScaleProvider scaleProvider) {
mContext = context;
mLock = lock;
@@ -1040,7 +1040,7 @@ public class WindowMagnificationManager implements
private float mScale = MagnificationScaleProvider.MIN_SCALE;
private boolean mEnabled;
- private final WindowMagnificationManager mWindowMagnificationManager;
+ private final MagnificationConnectionManager mMagnificationConnectionManager;
// Records the bounds of window magnification.
private final Rect mBounds = new Rect();
// The magnified bounds on the screen.
@@ -1058,11 +1058,15 @@ public class WindowMagnificationManager implements
"mTrackingTypingFocusSumTime");
private volatile long mTrackingTypingFocusSumTime = 0;
- WindowMagnifier(int displayId, WindowMagnificationManager windowMagnificationManager) {
+ WindowMagnifier(int displayId,
+ MagnificationConnectionManager magnificationConnectionManager) {
mDisplayId = displayId;
- mWindowMagnificationManager = windowMagnificationManager;
+ mMagnificationConnectionManager = magnificationConnectionManager;
}
+ // TODO(b/312324808): Investigating whether
+ // mMagnificationConnectionManager#enableWindowMagnificationInternal requires a sync lock
+ @SuppressWarnings("GuardedBy")
boolean enableWindowMagnificationInternal(float scale, float centerX, float centerY,
@Nullable MagnificationAnimationCallback animationCallback,
@WindowPosition int windowPosition, int id) {
@@ -1072,8 +1076,8 @@ public class WindowMagnificationManager implements
}
final float normScale = MagnificationScaleProvider.constrainScale(scale);
setMagnificationFrameOffsetRatioByWindowPosition(windowPosition);
- if (mWindowMagnificationManager.enableWindowMagnificationInternal(mDisplayId, normScale,
- centerX, centerY, mMagnificationFrameOffsetRatio.x,
+ if (mMagnificationConnectionManager.enableWindowMagnificationInternal(mDisplayId,
+ normScale, centerX, centerY, mMagnificationFrameOffsetRatio.x,
mMagnificationFrameOffsetRatio.y, animationCallback)) {
mScale = normScale;
mEnabled = true;
@@ -1096,12 +1100,15 @@ public class WindowMagnificationManager implements
}
}
+ // TODO(b/312324808): Investigating whether
+ // mMagnificationConnectionManager#disableWindowMagnificationInternal requires a sync lock
+ @SuppressWarnings("GuardedBy")
boolean disableWindowMagnificationInternal(
@Nullable MagnificationAnimationCallback animationResultCallback) {
if (!mEnabled) {
return false;
}
- if (mWindowMagnificationManager.disableWindowMagnificationInternal(
+ if (mMagnificationConnectionManager.disableWindowMagnificationInternal(
mDisplayId, animationResultCallback)) {
mEnabled = false;
mIdOfLastServiceToControl = INVALID_SERVICE_ID;
@@ -1112,6 +1119,10 @@ public class WindowMagnificationManager implements
return false;
}
+ // ErrorProne says the access of mMagnificationConnectionManager#setScaleInternal should
+ // be guarded by 'this.mMagnificationConnectionManager.mLock' which is the same one as
+ // 'mLock'. Therefore, we'll put @SuppressWarnings here.
+ @SuppressWarnings("GuardedBy")
@GuardedBy("mLock")
void setScale(float scale) {
if (!mEnabled) {
@@ -1119,7 +1130,8 @@ public class WindowMagnificationManager implements
}
final float normScale = MagnificationScaleProvider.constrainScale(scale);
if (Float.compare(mScale, normScale) != 0
- && mWindowMagnificationManager.setScaleInternal(mDisplayId, scale)) {
+ && mMagnificationConnectionManager
+ .setScaleForWindowMagnificationInternal(mDisplayId, scale)) {
mScale = normScale;
}
}
@@ -1159,8 +1171,8 @@ public class WindowMagnificationManager implements
}
void setTrackingTypingFocusEnabled(boolean trackingTypingFocusEnabled) {
- if (mWindowMagnificationManager.isWindowMagnifierEnabled(mDisplayId)
- && mWindowMagnificationManager.isImeVisible(mDisplayId)
+ if (mMagnificationConnectionManager.isWindowMagnifierEnabled(mDisplayId)
+ && mMagnificationConnectionManager.isImeVisible(mDisplayId)
&& trackingTypingFocusEnabled) {
startTrackingTypingFocusRecord();
}
@@ -1206,7 +1218,7 @@ public class WindowMagnificationManager implements
Slog.d(TAG, "stop and log: session duration = " + duration
+ ", elapsed = " + elapsed);
}
- mWindowMagnificationManager.logTrackingTypingFocus(duration);
+ mMagnificationConnectionManager.logTrackingTypingFocus(duration);
mTrackingTypingFocusStartTime = 0;
mTrackingTypingFocusSumTime = 0;
}
@@ -1216,9 +1228,14 @@ public class WindowMagnificationManager implements
return mEnabled;
}
+ // ErrorProne says the access of mMagnificationConnectionManager#moveWindowMagnifierInternal
+ // should be guarded by 'this.mMagnificationConnectionManager.mLock' which is the same one
+ // as 'mLock'. Therefore, we'll put @SuppressWarnings here.
+ @SuppressWarnings("GuardedBy")
@GuardedBy("mLock")
void move(float offsetX, float offsetY) {
- mWindowMagnificationManager.moveWindowMagnifierInternal(mDisplayId, offsetX, offsetY);
+ mMagnificationConnectionManager.moveWindowMagnifierInternal(
+ mDisplayId, offsetX, offsetY);
}
@GuardedBy("mLock")
@@ -1270,8 +1287,10 @@ public class WindowMagnificationManager implements
animationCallback);
}
- private boolean setScaleInternal(int displayId, float scale) {
- return mConnectionWrapper != null && mConnectionWrapper.setScale(displayId, scale);
+ @GuardedBy("mLock")
+ private boolean setScaleForWindowMagnificationInternal(int displayId, float scale) {
+ return mConnectionWrapper != null
+ && mConnectionWrapper.setScaleForWindowMagnification(displayId, scale);
}
@GuardedBy("mLock")
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionWrapper.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionWrapper.java
index f0c44d64f5ec..20538f167656 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionWrapper.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionWrapper.java
@@ -82,16 +82,16 @@ class MagnificationConnectionWrapper {
return true;
}
- boolean setScale(int displayId, float scale) {
+ boolean setScaleForWindowMagnification(int displayId, float scale) {
if (mTrace.isA11yTracingEnabledForTypes(FLAGS_WINDOW_MAGNIFICATION_CONNECTION)) {
mTrace.logTrace(TAG + ".setScale", FLAGS_WINDOW_MAGNIFICATION_CONNECTION,
"displayId=" + displayId + ";scale=" + scale);
}
try {
- mConnection.setScale(displayId, scale);
+ mConnection.setScaleForWindowMagnification(displayId, scale);
} catch (RemoteException e) {
if (DBG) {
- Slog.e(TAG, "Error calling setScale()", e);
+ Slog.e(TAG, "Error calling setScaleForWindowMagnification()", e);
}
return false;
}
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
index effd8732d086..52e123a5e70c 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
@@ -77,7 +77,7 @@ import java.util.concurrent.Executor;
* <b>Note</b> Updates magnification switch UI when magnification mode transition
* is done and before invoking {@link TransitionCallBack#onResult}.
*/
-public class MagnificationController implements WindowMagnificationManager.Callback,
+public class MagnificationController implements MagnificationConnectionManager.Callback,
MagnificationGestureHandler.Callback,
FullScreenMagnificationController.MagnificationInfoChangedCallback,
WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks {
@@ -96,7 +96,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
private final AlwaysOnMagnificationFeatureFlag mAlwaysOnMagnificationFeatureFlag;
private final MagnificationScaleProvider mScaleProvider;
private FullScreenMagnificationController mFullScreenMagnificationController;
- private WindowMagnificationManager mWindowMagnificationMgr;
+ private MagnificationConnectionManager mMagnificationConnectionManager;
private int mMagnificationCapabilities = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
/** Whether the platform supports window magnification feature. */
private final boolean mSupportWindowMagnification;
@@ -164,11 +164,11 @@ public class MagnificationController implements WindowMagnificationManager.Callb
@VisibleForTesting
public MagnificationController(AccessibilityManagerService ams, Object lock,
Context context, FullScreenMagnificationController fullScreenMagnificationController,
- WindowMagnificationManager windowMagnificationManager,
+ MagnificationConnectionManager magnificationConnectionManager,
MagnificationScaleProvider scaleProvider, Executor backgroundExecutor) {
this(ams, lock, context, scaleProvider, backgroundExecutor);
mFullScreenMagnificationController = fullScreenMagnificationController;
- mWindowMagnificationMgr = windowMagnificationManager;
+ mMagnificationConnectionManager = magnificationConnectionManager;
}
@Override
@@ -179,10 +179,10 @@ public class MagnificationController implements WindowMagnificationManager.Callb
if (updatePersistence) {
getFullScreenMagnificationController().persistScale(displayId);
}
- } else if (getWindowMagnificationMgr().isWindowMagnifierEnabled(displayId)) {
- getWindowMagnificationMgr().setScale(displayId, scale);
+ } else if (getMagnificationConnectionManager().isWindowMagnifierEnabled(displayId)) {
+ getMagnificationConnectionManager().setScale(displayId, scale);
if (updatePersistence) {
- getWindowMagnificationMgr().persistScale(displayId);
+ getMagnificationConnectionManager().persistScale(displayId);
}
}
}
@@ -222,15 +222,15 @@ public class MagnificationController implements WindowMagnificationManager.Callb
}
if (showModeSwitchButton) {
- getWindowMagnificationMgr().showMagnificationButton(displayId, mode);
+ getMagnificationConnectionManager().showMagnificationButton(displayId, mode);
} else {
- getWindowMagnificationMgr().removeMagnificationButton(displayId);
+ getMagnificationConnectionManager().removeMagnificationButton(displayId);
}
if (!enableSettingsPanel) {
// Whether the settings panel needs to be shown is controlled in system UI.
// Here, we only guarantee that the settings panel is closed when it is not needed.
- getWindowMagnificationMgr().removeMagnificationSettingsPanel(displayId);
+ getMagnificationConnectionManager().removeMagnificationSettingsPanel(displayId);
}
}
@@ -284,7 +284,8 @@ public class MagnificationController implements WindowMagnificationManager.Callb
final FullScreenMagnificationController screenMagnificationController =
getFullScreenMagnificationController();
- final WindowMagnificationManager windowMagnificationMgr = getWindowMagnificationMgr();
+ final MagnificationConnectionManager magnificationConnectionManager =
+ getMagnificationConnectionManager();
final float scale = getTargetModeScaleFromCurrentMagnification(displayId, targetMode);
final DisableMagnificationCallback animationEndCallback =
new DisableMagnificationCallback(transitionCallBack, displayId, targetMode,
@@ -295,7 +296,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
screenMagnificationController.reset(displayId, animationEndCallback);
} else {
- windowMagnificationMgr.disableWindowMagnification(displayId, false,
+ magnificationConnectionManager.disableWindowMagnification(displayId, false,
animationEndCallback);
}
}
@@ -340,7 +341,8 @@ public class MagnificationController implements WindowMagnificationManager.Callb
}
final FullScreenMagnificationController screenMagnificationController =
getFullScreenMagnificationController();
- final WindowMagnificationManager windowMagnificationMgr = getWindowMagnificationMgr();
+ final MagnificationConnectionManager magnificationConnectionManager =
+ getMagnificationConnectionManager();
final float targetScale = Float.isNaN(config.getScale())
? getTargetModeScaleFromCurrentMagnification(displayId, targetMode)
: config.getScale();
@@ -353,14 +355,15 @@ public class MagnificationController implements WindowMagnificationManager.Callb
if (targetMode == MAGNIFICATION_MODE_WINDOW) {
screenMagnificationController.reset(displayId, false);
if (targetActivated) {
- windowMagnificationMgr.enableWindowMagnification(displayId,
+ magnificationConnectionManager.enableWindowMagnification(displayId,
targetScale, magnificationCenter.x, magnificationCenter.y,
magnificationAnimationCallback, id);
} else {
- windowMagnificationMgr.disableWindowMagnification(displayId, false);
+ magnificationConnectionManager.disableWindowMagnification(displayId, false);
}
} else if (targetMode == MAGNIFICATION_MODE_FULLSCREEN) {
- windowMagnificationMgr.disableWindowMagnification(displayId, false, null);
+ magnificationConnectionManager.disableWindowMagnification(
+ displayId, false, null);
if (targetActivated) {
if (!screenMagnificationController.isRegistered(displayId)) {
screenMagnificationController.register(displayId);
@@ -409,7 +412,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
return getFullScreenMagnificationController().getScale(displayId);
} else {
- return getWindowMagnificationMgr().getScale(displayId);
+ return getMagnificationConnectionManager().getScale(displayId);
}
}
@@ -441,7 +444,8 @@ public class MagnificationController implements WindowMagnificationManager.Callb
mAccessibilityCallbacksDelegateArray.put(displayId,
getFullScreenMagnificationController());
} else if (mode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
- mAccessibilityCallbacksDelegateArray.put(displayId, getWindowMagnificationMgr());
+ mAccessibilityCallbacksDelegateArray.put(
+ displayId, getMagnificationConnectionManager());
} else {
mAccessibilityCallbacksDelegateArray.delete(displayId);
}
@@ -462,13 +466,13 @@ public class MagnificationController implements WindowMagnificationManager.Callb
@Override
public void onRequestMagnificationSpec(int displayId, int serviceId) {
- final WindowMagnificationManager windowMagnificationManager;
+ final MagnificationConnectionManager magnificationConnectionManager;
synchronized (mLock) {
updateMagnificationUIControls(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
- windowMagnificationManager = mWindowMagnificationMgr;
+ magnificationConnectionManager = mMagnificationConnectionManager;
}
- if (windowMagnificationManager != null) {
- mWindowMagnificationMgr.disableWindowMagnification(displayId, false);
+ if (magnificationConnectionManager != null) {
+ mMagnificationConnectionManager.disableWindowMagnification(displayId, false);
}
}
@@ -491,7 +495,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
setCurrentMagnificationModeAndSwitchDelegate(displayId,
ACCESSIBILITY_MAGNIFICATION_MODE_NONE);
duration = SystemClock.uptimeMillis() - mWindowModeEnabledTimeArray.get(displayId);
- scale = mWindowMagnificationMgr.getLastActivatedScale(displayId);
+ scale = mMagnificationConnectionManager.getLastActivatedScale(displayId);
}
logMagnificationUsageState(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW, duration, scale);
}
@@ -507,13 +511,14 @@ public class MagnificationController implements WindowMagnificationManager.Callb
public void onSourceBoundsChanged(int displayId, Rect bounds) {
if (shouldNotifyMagnificationChange(displayId, MAGNIFICATION_MODE_WINDOW)) {
// notify sysui the magnification scale changed on window magnifier
- mWindowMagnificationMgr.onUserMagnificationScaleChanged(
- mUserId, displayId, getWindowMagnificationMgr().getScale(displayId));
+ mMagnificationConnectionManager.onUserMagnificationScaleChanged(
+ mUserId, displayId, getMagnificationConnectionManager().getScale(displayId));
final MagnificationConfig config = new MagnificationConfig.Builder()
.setMode(MAGNIFICATION_MODE_WINDOW)
- .setActivated(getWindowMagnificationMgr().isWindowMagnifierEnabled(displayId))
- .setScale(getWindowMagnificationMgr().getScale(displayId))
+ .setActivated(
+ getMagnificationConnectionManager().isWindowMagnifierEnabled(displayId))
+ .setScale(getMagnificationConnectionManager().getScale(displayId))
.setCenterX(bounds.exactCenterX())
.setCenterY(bounds.exactCenterY()).build();
mAms.notifyMagnificationChanged(displayId, new Region(bounds), config);
@@ -525,7 +530,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
@NonNull MagnificationConfig config) {
if (shouldNotifyMagnificationChange(displayId, MAGNIFICATION_MODE_FULLSCREEN)) {
// notify sysui the magnification scale changed on fullscreen magnifier
- mWindowMagnificationMgr.onUserMagnificationScaleChanged(
+ mMagnificationConnectionManager.onUserMagnificationScaleChanged(
mUserId, displayId, config.getScale());
mAms.notifyMagnificationChanged(displayId, region, config);
@@ -548,8 +553,8 @@ public class MagnificationController implements WindowMagnificationManager.Callb
synchronized (mLock) {
final boolean fullScreenActivated = mFullScreenMagnificationController != null
&& mFullScreenMagnificationController.isActivated(displayId);
- final boolean windowEnabled = mWindowMagnificationMgr != null
- && mWindowMagnificationMgr.isWindowMagnifierEnabled(displayId);
+ final boolean windowEnabled = mMagnificationConnectionManager != null
+ && mMagnificationConnectionManager.isWindowMagnifierEnabled(displayId);
final Integer transitionMode = mTransitionModes.get(displayId);
if (((changeMode == MAGNIFICATION_MODE_FULLSCREEN && fullScreenActivated)
|| (changeMode == MAGNIFICATION_MODE_WINDOW && windowEnabled))
@@ -608,10 +613,10 @@ public class MagnificationController implements WindowMagnificationManager.Callb
}
private void disableWindowMagnificationIfNeeded(int displayId) {
- final WindowMagnificationManager windowMagnificationManager =
- getWindowMagnificationMgr();
+ final MagnificationConnectionManager magnificationConnectionManager =
+ getMagnificationConnectionManager();
if (isActivated(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW)) {
- windowMagnificationManager.disableWindowMagnification(displayId, false);
+ magnificationConnectionManager.disableWindowMagnification(displayId, false);
}
}
@@ -620,7 +625,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
synchronized (mLock) {
mIsImeVisibleArray.put(displayId, shown);
}
- getWindowMagnificationMgr().onImeWindowVisibilityChanged(displayId, shown);
+ getMagnificationConnectionManager().onImeWindowVisibilityChanged(displayId, shown);
logMagnificationModeWithImeOnIfNeeded(displayId);
}
@@ -661,7 +666,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
/**
* Updates the active user ID of {@link FullScreenMagnificationController} and {@link
- * WindowMagnificationManager}.
+ * MagnificationConnectionManager}.
*
* @param userId the currently active user ID
*/
@@ -671,10 +676,10 @@ public class MagnificationController implements WindowMagnificationManager.Callb
}
mUserId = userId;
final FullScreenMagnificationController fullMagnificationController;
- final WindowMagnificationManager windowMagnificationManager;
+ final MagnificationConnectionManager magnificationConnectionManager;
synchronized (mLock) {
fullMagnificationController = mFullScreenMagnificationController;
- windowMagnificationManager = mWindowMagnificationMgr;
+ magnificationConnectionManager = mMagnificationConnectionManager;
mAccessibilityCallbacksDelegateArray.clear();
mCurrentMagnificationModeArray.clear();
mLastMagnificationActivatedModeArray.clear();
@@ -685,8 +690,8 @@ public class MagnificationController implements WindowMagnificationManager.Callb
if (fullMagnificationController != null) {
fullMagnificationController.resetAllIfNeeded(false);
}
- if (windowMagnificationManager != null) {
- windowMagnificationManager.disableAllWindowMagnifiers();
+ if (magnificationConnectionManager != null) {
+ magnificationConnectionManager.disableAllWindowMagnifiers();
}
}
@@ -700,8 +705,8 @@ public class MagnificationController implements WindowMagnificationManager.Callb
if (mFullScreenMagnificationController != null) {
mFullScreenMagnificationController.onDisplayRemoved(displayId);
}
- if (mWindowMagnificationMgr != null) {
- mWindowMagnificationMgr.onDisplayRemoved(displayId);
+ if (mMagnificationConnectionManager != null) {
+ mMagnificationConnectionManager.onDisplayRemoved(displayId);
}
mAccessibilityCallbacksDelegateArray.delete(displayId);
mCurrentMagnificationModeArray.delete(displayId);
@@ -728,7 +733,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
* @param enabled Enable the following typing focus feature
*/
public void setMagnificationFollowTypingEnabled(boolean enabled) {
- getWindowMagnificationMgr().setMagnificationFollowTypingEnabled(enabled);
+ getMagnificationConnectionManager().setMagnificationFollowTypingEnabled(enabled);
getFullScreenMagnificationController().setMagnificationFollowTypingEnabled(enabled);
}
@@ -805,29 +810,29 @@ public class MagnificationController implements WindowMagnificationManager.Callb
}
/**
- * Getter of {@link WindowMagnificationManager}.
+ * Getter of {@link MagnificationConnectionManager}.
*
- * @return {@link WindowMagnificationManager}.
+ * @return {@link MagnificationConnectionManager}.
*/
- public WindowMagnificationManager getWindowMagnificationMgr() {
+ public MagnificationConnectionManager getMagnificationConnectionManager() {
synchronized (mLock) {
- if (mWindowMagnificationMgr == null) {
- mWindowMagnificationMgr = new WindowMagnificationManager(mContext,
+ if (mMagnificationConnectionManager == null) {
+ mMagnificationConnectionManager = new MagnificationConnectionManager(mContext,
mLock, this, mAms.getTraceManager(),
mScaleProvider);
}
- return mWindowMagnificationMgr;
+ return mMagnificationConnectionManager;
}
}
private @Nullable PointF getCurrentMagnificationCenterLocked(int displayId, int targetMode) {
if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN) {
- if (mWindowMagnificationMgr == null
- || !mWindowMagnificationMgr.isWindowMagnifierEnabled(displayId)) {
+ if (mMagnificationConnectionManager == null
+ || !mMagnificationConnectionManager.isWindowMagnifierEnabled(displayId)) {
return null;
}
- mTempPoint.set(mWindowMagnificationMgr.getCenterX(displayId),
- mWindowMagnificationMgr.getCenterY(displayId));
+ mTempPoint.set(mMagnificationConnectionManager.getCenterX(displayId),
+ mMagnificationConnectionManager.getCenterY(displayId));
} else {
if (mFullScreenMagnificationController == null
|| !mFullScreenMagnificationController.isActivated(displayId)) {
@@ -858,10 +863,10 @@ public class MagnificationController implements WindowMagnificationManager.Callb
}
} else if (mode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
synchronized (mLock) {
- if (mWindowMagnificationMgr == null) {
+ if (mMagnificationConnectionManager == null) {
return false;
}
- isActivated = mWindowMagnificationMgr.isWindowMagnifierEnabled(displayId);
+ isActivated = mMagnificationConnectionManager.isWindowMagnifierEnabled(displayId);
}
}
return isActivated;
@@ -980,7 +985,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
mCurrentCenter.x, mCurrentCenter.y, mAnimate,
MAGNIFICATION_GESTURE_HANDLER_ID);
} else {
- getWindowMagnificationMgr().enableWindowMagnification(mDisplayId,
+ getMagnificationConnectionManager().enableWindowMagnification(mDisplayId,
mCurrentScale, mCurrentCenter.x,
mCurrentCenter.y, mAnimate ? STUB_ANIMATION_CALLBACK : null,
MAGNIFICATION_GESTURE_HANDLER_ID);
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java
index 5cf2a638fa3e..ed8f1ab3a1b2 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java
@@ -84,13 +84,13 @@ public class MagnificationProcessor {
.setCenterX(fullScreenMagnificationController.getCenterX(displayId))
.setCenterY(fullScreenMagnificationController.getCenterY(displayId));
} else if (mode == MAGNIFICATION_MODE_WINDOW) {
- final WindowMagnificationManager windowMagnificationManager =
- mController.getWindowMagnificationMgr();
+ final MagnificationConnectionManager magnificationConnectionManager =
+ mController.getMagnificationConnectionManager();
builder.setMode(mode)
.setActivated(mController.isActivated(displayId, MAGNIFICATION_MODE_WINDOW))
- .setScale(windowMagnificationManager.getScale(displayId))
- .setCenterX(windowMagnificationManager.getCenterX(displayId))
- .setCenterY(windowMagnificationManager.getCenterY(displayId));
+ .setScale(magnificationConnectionManager.getScale(displayId))
+ .setCenterX(magnificationConnectionManager.getCenterX(displayId))
+ .setCenterY(magnificationConnectionManager.getCenterY(displayId));
} else {
// For undefined mode, set enabled to false
builder.setActivated(false);
@@ -135,12 +135,12 @@ public class MagnificationProcessor {
}
} else if (configMode == MAGNIFICATION_MODE_WINDOW) {
if (configActivated) {
- return mController.getWindowMagnificationMgr().enableWindowMagnification(displayId,
- config.getScale(), config.getCenterX(), config.getCenterY(),
+ return mController.getMagnificationConnectionManager().enableWindowMagnification(
+ displayId, config.getScale(), config.getCenterX(), config.getCenterY(),
animate ? STUB_ANIMATION_CALLBACK : null,
id);
} else {
- return mController.getWindowMagnificationMgr()
+ return mController.getMagnificationConnectionManager()
.disableWindowMagnification(displayId, false);
}
}
@@ -256,7 +256,7 @@ public class MagnificationProcessor {
if (currentMode == MAGNIFICATION_MODE_FULLSCREEN) {
getFullscreenMagnificationRegion(displayId, outRegion, canControlMagnification);
} else if (currentMode == MAGNIFICATION_MODE_WINDOW) {
- mController.getWindowMagnificationMgr().getMagnificationSourceBounds(displayId,
+ mController.getMagnificationConnectionManager().getMagnificationSourceBounds(displayId,
outRegion);
}
}
@@ -297,8 +297,8 @@ public class MagnificationProcessor {
if (mode == MAGNIFICATION_MODE_FULLSCREEN) {
return mController.getFullScreenMagnificationController().reset(displayId, animate);
} else if (mode == MAGNIFICATION_MODE_WINDOW) {
- return mController.getWindowMagnificationMgr().disableWindowMagnification(displayId,
- false, animate ? STUB_ANIMATION_CALLBACK : null);
+ return mController.getMagnificationConnectionManager().disableWindowMagnification(
+ displayId, false, animate ? STUB_ANIMATION_CALLBACK : null);
}
return false;
}
@@ -325,19 +325,20 @@ public class MagnificationProcessor {
*/
public void resetAllIfNeeded(int connectionId) {
mController.getFullScreenMagnificationController().resetAllIfNeeded(connectionId);
- mController.getWindowMagnificationMgr().resetAllIfNeeded(connectionId);
+ mController.getMagnificationConnectionManager().resetAllIfNeeded(connectionId);
}
/**
* {@link FullScreenMagnificationController#isActivated(int)}
- * {@link WindowMagnificationManager#isWindowMagnifierEnabled(int)}
+ * {@link MagnificationConnectionManager#isWindowMagnifierEnabled(int)}
*/
public boolean isMagnifying(int displayId) {
int mode = getControllingMode(displayId);
if (mode == MAGNIFICATION_MODE_FULLSCREEN) {
return mController.getFullScreenMagnificationController().isActivated(displayId);
} else if (mode == MAGNIFICATION_MODE_WINDOW) {
- return mController.getWindowMagnificationMgr().isWindowMagnifierEnabled(displayId);
+ return mController.getMagnificationConnectionManager().isWindowMagnifierEnabled(
+ displayId);
}
return false;
}
@@ -416,22 +417,23 @@ public class MagnificationProcessor {
pw.append(" SupportWindowMagnification="
+ mController.supportWindowMagnification()).println();
pw.append(" WindowMagnificationConnectionState="
- + mController.getWindowMagnificationMgr().getConnectionState()).println();
+ + mController.getMagnificationConnectionManager().getConnectionState()).println();
}
private int getIdOfLastServiceToMagnify(int mode, int displayId) {
return (mode == MAGNIFICATION_MODE_FULLSCREEN)
? mController.getFullScreenMagnificationController()
.getIdOfLastServiceToMagnify(displayId)
- : mController.getWindowMagnificationMgr().getIdOfLastServiceToMagnify(
+ : mController.getMagnificationConnectionManager().getIdOfLastServiceToMagnify(
displayId);
}
private void dumpTrackingTypingFocusEnabledState(final PrintWriter pw, int displayId,
int mode) {
if (mode == MAGNIFICATION_MODE_WINDOW) {
- pw.append(" TrackingTypingFocusEnabled=" + mController
- .getWindowMagnificationMgr().isTrackingTypingFocusEnabled(displayId))
+ pw.append(" TrackingTypingFocusEnabled="
+ + mController.getMagnificationConnectionManager()
+ .isTrackingTypingFocusEnabled(displayId))
.println();
}
}
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/PanningScalingHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/PanningScalingHandler.java
index 94556282d0d3..6b48d2bacf9d 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/PanningScalingHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/PanningScalingHandler.java
@@ -45,6 +45,7 @@ class PanningScalingHandler extends
private static final String TAG = "PanningScalingHandler";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ // TODO(b/312372035): Revisit the scope of usage of the interface
interface MagnificationDelegate {
boolean processScroll(int displayId, float distanceX, float distanceY);
void setScale(int displayId, float scale);
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
index 36e751181cfd..73c267a6e262 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
@@ -79,7 +79,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
private static final float MIN_SCALE = 1.0f;
private static final float MAX_SCALE = MagnificationScaleProvider.MAX_SCALE;
- private final WindowMagnificationManager mWindowMagnificationMgr;
+ private final MagnificationConnectionManager mMagnificationConnectionManager;
@VisibleForTesting
final DelegatingState mDelegatingState;
@VisibleForTesting
@@ -101,7 +101,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
private long mTripleTapAndHoldStartedTime = 0;
public WindowMagnificationGestureHandler(@UiContext Context context,
- WindowMagnificationManager windowMagnificationMgr,
+ MagnificationConnectionManager magnificationConnectionManager,
AccessibilityTraceManager trace,
Callback callback,
boolean detectSingleFingerTripleTap,
@@ -115,7 +115,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
"WindowMagnificationGestureHandler() , displayId = " + displayId + ")");
}
mContext = context;
- mWindowMagnificationMgr = windowMagnificationMgr;
+ mMagnificationConnectionManager = magnificationConnectionManager;
mMotionEventDispatcherDelegate = new MotionEventDispatcherDelegate(context,
(event, rawEvent, policyFlags) -> dispatchTransformedEvent(event, rawEvent,
policyFlags));
@@ -128,18 +128,18 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
@Override
public boolean processScroll(int displayId, float distanceX,
float distanceY) {
- return mWindowMagnificationMgr.processScroll(displayId, distanceX,
- distanceY);
+ return mMagnificationConnectionManager.processScroll(
+ displayId, distanceX, distanceY);
}
@Override
public void setScale(int displayId, float scale) {
- mWindowMagnificationMgr.setScale(displayId, scale);
+ mMagnificationConnectionManager.setScale(displayId, scale);
}
@Override
public float getScale(int displayId) {
- return mWindowMagnificationMgr.getScale(displayId);
+ return mMagnificationConnectionManager.getScale(displayId);
}
}));
@@ -167,7 +167,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
Slog.i(mLogTag, "onDestroy(); delayed = "
+ mDetectingState.toString());
}
- mWindowMagnificationMgr.disableWindowMagnification(mDisplayId, true);
+ mMagnificationConnectionManager.disableWindowMagnification(mDisplayId, true);
resetToDetectState();
}
@@ -176,7 +176,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
final Point screenSize = mTempPoint;
getScreenSize(mTempPoint);
toggleMagnification(screenSize.x / 2.0f, screenSize.y / 2.0f,
- WindowMagnificationManager.WINDOW_POSITION_AT_CENTER);
+ MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER);
}
private void getScreenSize(Point outSize) {
@@ -190,28 +190,29 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
}
private void enableWindowMagnifier(float centerX, float centerY,
- @WindowMagnificationManager.WindowPosition int windowPosition) {
+ @MagnificationConnectionManager.WindowPosition int windowPosition) {
if (DEBUG_ALL) {
Slog.i(mLogTag, "enableWindowMagnifier :"
+ centerX + ", " + centerY + ", " + windowPosition);
}
final float scale = MathUtils.constrain(
- mWindowMagnificationMgr.getPersistedScale(mDisplayId), MIN_SCALE, MAX_SCALE);
- mWindowMagnificationMgr.enableWindowMagnification(mDisplayId, scale, centerX, centerY,
- windowPosition);
+ mMagnificationConnectionManager.getPersistedScale(mDisplayId),
+ MIN_SCALE, MAX_SCALE);
+ mMagnificationConnectionManager.enableWindowMagnification(
+ mDisplayId, scale, centerX, centerY, windowPosition);
}
private void disableWindowMagnifier() {
if (DEBUG_ALL) {
Slog.i(mLogTag, "disableWindowMagnifier()");
}
- mWindowMagnificationMgr.disableWindowMagnification(mDisplayId, false);
+ mMagnificationConnectionManager.disableWindowMagnification(mDisplayId, false);
}
private void toggleMagnification(float centerX, float centerY,
- @WindowMagnificationManager.WindowPosition int windowPosition) {
- if (mWindowMagnificationMgr.isWindowMagnifierEnabled(mDisplayId)) {
+ @MagnificationConnectionManager.WindowPosition int windowPosition) {
+ if (mMagnificationConnectionManager.isWindowMagnifierEnabled(mDisplayId)) {
disableWindowMagnifier();
} else {
enableWindowMagnifier(centerX, centerY, windowPosition);
@@ -223,7 +224,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
Slog.i(mLogTag, "onTripleTap()");
}
toggleMagnification(up.getX(), up.getY(),
- WindowMagnificationManager.WINDOW_POSITION_AT_CENTER);
+ MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER);
}
@VisibleForTesting
@@ -232,9 +233,9 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
Slog.i(mLogTag, "onTripleTapAndHold()");
}
mViewportDraggingState.mEnabledBeforeDrag =
- mWindowMagnificationMgr.isWindowMagnifierEnabled(mDisplayId);
+ mMagnificationConnectionManager.isWindowMagnifierEnabled(mDisplayId);
enableWindowMagnifier(up.getX(), up.getY(),
- WindowMagnificationManager.WINDOW_POSITION_AT_TOP_LEFT);
+ MagnificationConnectionManager.WINDOW_POSITION_AT_TOP_LEFT);
mTripleTapAndHoldStartedTime = SystemClock.uptimeMillis();
transitionTo(mViewportDraggingState);
}
@@ -242,7 +243,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
@VisibleForTesting
void releaseTripleTapAndHold() {
if (!mViewportDraggingState.mEnabledBeforeDrag) {
- mWindowMagnificationMgr.disableWindowMagnification(mDisplayId, true);
+ mMagnificationConnectionManager.disableWindowMagnification(mDisplayId, true);
}
transitionTo(mDetectingState);
if (mTripleTapAndHoldStartedTime != 0) {
@@ -331,7 +332,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
@Override
public void onExit() {
mPanningScalingHandler.setEnabled(false);
- mWindowMagnificationMgr.persistScale(mDisplayId);
+ mMagnificationConnectionManager.persistScale(mDisplayId);
clear();
}
@@ -404,7 +405,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
if (!Float.isNaN(mLastX) && !Float.isNaN(mLastY)) {
float offsetX = event.getX() - mLastX;
float offsetY = event.getY() - mLastY;
- mWindowMagnificationMgr.moveWindowMagnification(mDisplayId, offsetX,
+ mMagnificationConnectionManager.moveWindowMagnification(mDisplayId, offsetX,
offsetY);
}
mLastX = event.getX();
@@ -522,7 +523,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
@Override
public boolean shouldStopDetection(MotionEvent motionEvent) {
- return !mWindowMagnificationMgr.isWindowMagnifierEnabled(mDisplayId)
+ return !mMagnificationConnectionManager.isWindowMagnifierEnabled(mDisplayId)
&& !mDetectSingleFingerTripleTap
&& !(mDetectTwoFingerTripleTap
&& Flags.enableMagnificationMultipleFingerMultipleTapGesture());
@@ -540,7 +541,8 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
"onGestureDetected : delayedEventQueue = " + delayedEventQueue);
}
if (gestureId == MagnificationGestureMatcher.GESTURE_TWO_FINGERS_DOWN_OR_SWIPE
- && mWindowMagnificationMgr.pointersInWindow(mDisplayId, motionEvent) > 0) {
+ && mMagnificationConnectionManager
+ .pointersInWindow(mDisplayId, motionEvent) > 0) {
transitionTo(mObservePanningScalingState);
} else if (gestureId == MagnificationGestureMatcher.GESTURE_TRIPLE_TAP) {
onTripleTap(motionEvent);
@@ -584,7 +586,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
+ ", mMagnifiedInteractionState=" + mObservePanningScalingState
+ ", mCurrentState=" + State.nameOf(mCurrentState)
+ ", mPreviousState=" + State.nameOf(mPreviousState)
- + ", mWindowMagnificationMgr=" + mWindowMagnificationMgr
+ + ", mMagnificationConnectionManager=" + mMagnificationConnectionManager
+ ", mDisplayId=" + mDisplayId
+ '}';
}
diff --git a/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraController.java b/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraController.java
index 5665ad53924e..d089b05238e4 100644
--- a/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraController.java
+++ b/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraController.java
@@ -27,14 +27,14 @@ import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.util.ArraySet;
+import android.util.ArrayMap;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import java.io.PrintWriter;
-import java.util.Set;
+import java.util.Map;
/**
* Manages the registration and removal of virtual camera from the server side.
@@ -47,10 +47,13 @@ public final class VirtualCameraController implements IBinder.DeathRecipient {
private static final String VIRTUAL_CAMERA_SERVICE_NAME = "virtual_camera";
private static final String TAG = "VirtualCameraController";
+ private final Object mServiceLock = new Object();
+
+ @GuardedBy("mServiceLock")
@Nullable private IVirtualCameraService mVirtualCameraService;
@GuardedBy("mCameras")
- private final Set<VirtualCameraConfig> mCameras = new ArraySet<>();
+ private final Map<IBinder, CameraDescriptor> mCameras = new ArrayMap<>();
public VirtualCameraController() {
connectVirtualCameraService();
@@ -71,8 +74,12 @@ public final class VirtualCameraController implements IBinder.DeathRecipient {
try {
if (registerCameraWithService(cameraConfig)) {
+ CameraDescriptor cameraDescriptor =
+ new CameraDescriptor(cameraConfig);
+ IBinder binder = cameraConfig.getCallback().asBinder();
+ binder.linkToDeath(cameraDescriptor, 0 /* flags */);
synchronized (mCameras) {
- mCameras.add(cameraConfig);
+ mCameras.put(binder, cameraDescriptor);
}
} else {
// TODO(b/310857519): Revisit this to find a better way of indicating failure.
@@ -89,17 +96,22 @@ public final class VirtualCameraController implements IBinder.DeathRecipient {
* @param cameraConfig The {@link VirtualCameraConfig} sent by the client.
*/
public void unregisterCamera(@NonNull VirtualCameraConfig cameraConfig) {
- try {
- if (mVirtualCameraService == null) {
- Slog.w(TAG, "Virtual camera service is not connected.");
+ synchronized (mCameras) {
+ IBinder binder = cameraConfig.getCallback().asBinder();
+ if (!mCameras.containsKey(binder)) {
+ Slog.w(TAG, "Virtual camera was not registered.");
} else {
- mVirtualCameraService.unregisterCamera(cameraConfig.getCallback().asBinder());
- }
- synchronized (mCameras) {
- mCameras.remove(cameraConfig);
+ connectVirtualCameraServiceIfNeeded();
+
+ try {
+ synchronized (mServiceLock) {
+ mVirtualCameraService.unregisterCamera(binder);
+ }
+ mCameras.remove(binder);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
}
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
}
}
@@ -108,7 +120,9 @@ public final class VirtualCameraController implements IBinder.DeathRecipient {
connectVirtualCameraServiceIfNeeded();
try {
- return mVirtualCameraService.getCameraId(cameraConfig.getCallback().asBinder());
+ synchronized (mServiceLock) {
+ return mVirtualCameraService.getCameraId(cameraConfig.getCallback().asBinder());
+ }
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -117,7 +131,9 @@ public final class VirtualCameraController implements IBinder.DeathRecipient {
@Override
public void binderDied() {
Slog.d(TAG, "Virtual camera service died.");
- mVirtualCameraService = null;
+ synchronized (mServiceLock) {
+ mVirtualCameraService = null;
+ }
synchronized (mCameras) {
mCameras.clear();
}
@@ -126,44 +142,49 @@ public final class VirtualCameraController implements IBinder.DeathRecipient {
/** Release resources associated with this controller. */
public void close() {
synchronized (mCameras) {
- if (mVirtualCameraService == null) {
- Slog.w(TAG, "Virtual camera service is not connected.");
- } else {
- for (VirtualCameraConfig config : mCameras) {
- try {
- mVirtualCameraService.unregisterCamera(config.getCallback().asBinder());
- } catch (RemoteException e) {
- Slog.w(TAG, "close(): Camera failed to be removed on camera "
- + "service.", e);
+ if (!mCameras.isEmpty()) {
+ connectVirtualCameraServiceIfNeeded();
+
+ synchronized (mServiceLock) {
+ for (IBinder binder : mCameras.keySet()) {
+ try {
+ mVirtualCameraService.unregisterCamera(binder);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "close(): Camera failed to be removed on camera "
+ + "service.", e);
+ }
}
}
+ mCameras.clear();
}
- mCameras.clear();
}
- mVirtualCameraService = null;
+ synchronized (mServiceLock) {
+ mVirtualCameraService = null;
+ }
}
/** Dumps information about this {@link VirtualCameraController} for debugging purposes. */
public void dump(PrintWriter fout, String indent) {
fout.println(indent + "VirtualCameraController:");
indent += indent;
- fout.printf("%sService:%s\n", indent, mVirtualCameraService);
synchronized (mCameras) {
fout.printf("%sRegistered cameras:%d%n\n", indent, mCameras.size());
- for (VirtualCameraConfig config : mCameras) {
- fout.printf("%s token: %s\n", indent, config);
+ for (CameraDescriptor descriptor : mCameras.values()) {
+ fout.printf("%s token: %s\n", indent, descriptor.mConfig);
}
}
}
private void connectVirtualCameraServiceIfNeeded() {
- // Try to connect to service if not connected already.
- if (mVirtualCameraService == null) {
- connectVirtualCameraService();
- }
- // Throw exception if we are unable to connect to service.
- if (mVirtualCameraService == null) {
- throw new IllegalStateException("Virtual camera service is not connected.");
+ synchronized (mServiceLock) {
+ // Try to connect to service if not connected already.
+ if (mVirtualCameraService == null) {
+ connectVirtualCameraService();
+ }
+ // Throw exception if we are unable to connect to service.
+ if (mVirtualCameraService == null) {
+ throw new IllegalStateException("Virtual camera service is not connected.");
+ }
}
}
@@ -188,7 +209,24 @@ public final class VirtualCameraController implements IBinder.DeathRecipient {
private boolean registerCameraWithService(VirtualCameraConfig config) throws RemoteException {
VirtualCameraConfiguration serviceConfiguration = getServiceCameraConfiguration(config);
- return mVirtualCameraService.registerCamera(config.getCallback().asBinder(),
- serviceConfiguration);
+ synchronized (mServiceLock) {
+ return mVirtualCameraService.registerCamera(config.getCallback().asBinder(),
+ serviceConfiguration);
+ }
+ }
+
+ private final class CameraDescriptor implements IBinder.DeathRecipient {
+
+ private final VirtualCameraConfig mConfig;
+
+ CameraDescriptor(VirtualCameraConfig config) {
+ mConfig = config;
+ }
+
+ @Override
+ public void binderDied() {
+ Slog.d(TAG, "Virtual camera binder died");
+ unregisterCamera(mConfig);
+ }
}
}
diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS
index 7fe06827f1b3..c258370dc12b 100644
--- a/services/core/java/com/android/server/OWNERS
+++ b/services/core/java/com/android/server/OWNERS
@@ -1,5 +1,5 @@
-# BootReceiver
-per-file BootReceiver.java = gaillard@google.com
+# BootReceiver / Watchdog
+per-file BootReceiver.java,Watchdog.java = gaillard@google.com
# Connectivity / Networking
per-file ConnectivityService.java,ConnectivityServiceInitializer.java,NetworkManagementService.java,NsdService.java,VpnManagerService.java = file:/services/core/java/com/android/server/net/OWNERS
diff --git a/services/core/java/com/android/server/SecurityStateManagerService.java b/services/core/java/com/android/server/SecurityStateManagerService.java
new file mode 100644
index 000000000000..98039be20897
--- /dev/null
+++ b/services/core/java/com/android/server/SecurityStateManagerService.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import static android.os.SecurityStateManager.KEY_KERNEL_VERSION;
+import static android.os.SecurityStateManager.KEY_SYSTEM_SPL;
+import static android.os.SecurityStateManager.KEY_VENDOR_SPL;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.ISecurityStateManager;
+import android.os.SystemProperties;
+import android.os.VintfRuntimeInfo;
+import android.text.TextUtils;
+import android.util.Slog;
+import android.webkit.WebViewProviderInfo;
+import android.webkit.WebViewUpdateService;
+
+import com.android.internal.R;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class SecurityStateManagerService extends ISecurityStateManager.Stub {
+
+ private static final String TAG = "SecurityStateManagerService";
+
+ static final String VENDOR_SECURITY_PATCH_PROPERTY_KEY = "ro.vendor.build"
+ + ".security_patch";
+ static final Pattern KERNEL_RELEASE_PATTERN = Pattern.compile("(\\d+\\.\\d+\\.\\d+)("
+ + ".*)");
+
+ private final Context mContext;
+ private final PackageManager mPackageManager;
+
+ public SecurityStateManagerService(Context context) {
+ mContext = context;
+ mPackageManager = context.getPackageManager();
+ }
+
+ @Override
+ public Bundle getGlobalSecurityState() {
+ Bundle globalSecurityState = new Bundle();
+ globalSecurityState.putString(KEY_SYSTEM_SPL, Build.VERSION.SECURITY_PATCH);
+ globalSecurityState.putString(KEY_VENDOR_SPL,
+ SystemProperties.get(VENDOR_SECURITY_PATCH_PROPERTY_KEY, ""));
+ String moduleMetadataProviderPackageName =
+ mContext.getString(R.string.config_defaultModuleMetadataProvider);
+ if (!moduleMetadataProviderPackageName.isEmpty()) {
+ globalSecurityState.putString(moduleMetadataProviderPackageName,
+ getSpl(moduleMetadataProviderPackageName));
+ }
+ globalSecurityState.putString(KEY_KERNEL_VERSION, getKernelVersion());
+ addWebViewPackages(globalSecurityState);
+ addSecurityStatePackages(globalSecurityState);
+ return globalSecurityState;
+ }
+
+ private String getSpl(String packageName) {
+ if (!TextUtils.isEmpty(packageName)) {
+ try {
+ return mPackageManager.getPackageInfo(packageName, 0 /* flags */).versionName;
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.e(TAG, TextUtils.formatSimple("Failed to get SPL for package %s.",
+ packageName), e);
+ }
+ }
+ return "";
+ }
+
+ private String getKernelVersion() {
+ Matcher matcher = KERNEL_RELEASE_PATTERN.matcher(VintfRuntimeInfo.getKernelVersion());
+ if (matcher.matches()) {
+ return matcher.group(1);
+ }
+ return "";
+ }
+
+ private void addWebViewPackages(Bundle bundle) {
+ for (WebViewProviderInfo info : WebViewUpdateService.getAllWebViewPackages()) {
+ String packageName = info.packageName;
+ bundle.putString(packageName, getSpl(packageName));
+ }
+ }
+
+ private void addSecurityStatePackages(Bundle bundle) {
+ String[] packageNames;
+ packageNames = mContext.getResources().getStringArray(R.array.config_securityStatePackages);
+ for (String packageName : packageNames) {
+ bundle.putString(packageName, getSpl(packageName));
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 003046ab884f..60f087f53a7e 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -69,6 +69,7 @@ import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.time.Clock;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -98,11 +99,17 @@ public class Watchdog implements Dumpable {
// applications may not work with a debug build. CTS will fail.
private static final long DEFAULT_TIMEOUT = DB ? 10 * 1000 : 60 * 1000;
+ // This ratio is used to compute the pre-watchdog timeout (2 means that the pre-watchdog timeout
+ // will be half the full timeout).
+ //
+ // The pre-watchdog event is similar to a full watchdog except it does not crash system server.
+ private static final int PRE_WATCHDOG_TIMEOUT_RATIO = 2;
+
// These are temporally ordered: larger values as lateness increases
- private static final int COMPLETED = 0;
- private static final int WAITING = 1;
- private static final int WAITED_HALF = 2;
- private static final int OVERDUE = 3;
+ static final int COMPLETED = 0;
+ static final int WAITING = 1;
+ static final int WAITED_UNTIL_PRE_WATCHDOG = 2;
+ static final int OVERDUE = 3;
// Track watchdog timeout history and break the crash loop if there is.
private static final String TIMEOUT_HISTORY_FILE = "/data/system/watchdog-timeout-history.txt";
@@ -237,10 +244,8 @@ public class Watchdog implements Dumpable {
}
}
- /**
- * Used for checking status of handle threads and scheduling monitor callbacks.
- */
- public final class HandlerChecker implements Runnable {
+ /** Used for checking status of handle threads and scheduling monitor callbacks. */
+ public static class HandlerChecker implements Runnable {
private final Handler mHandler;
private final String mName;
private final ArrayList<Monitor> mMonitors = new ArrayList<Monitor>();
@@ -251,11 +256,19 @@ public class Watchdog implements Dumpable {
private long mStartTimeMillis;
private int mPauseCount;
private long mPauseEndTimeMillis;
+ private Clock mClock;
+ private Object mLock;
- HandlerChecker(Handler handler, String name) {
+ HandlerChecker(Handler handler, String name, Object lock, Clock clock) {
mHandler = handler;
mName = name;
+ mLock = lock;
mCompleted = true;
+ mClock = clock;
+ }
+
+ HandlerChecker(Handler handler, String name, Object lock) {
+ this(handler, name, lock, SystemClock.uptimeClock());
}
void addMonitorLocked(Monitor monitor) {
@@ -278,11 +291,9 @@ public class Watchdog implements Dumpable {
mMonitorQueue.clear();
}
- long nowMillis = SystemClock.uptimeMillis();
- boolean isPaused = mPauseCount > 0
- || (mPauseEndTimeMillis > 0 && mPauseEndTimeMillis < nowMillis);
- if ((mMonitors.size() == 0 && mHandler.getLooper().getQueue().isPolling())
- || isPaused) {
+ long nowMillis = mClock.millis();
+ boolean isPaused = mPauseCount > 0 || mPauseEndTimeMillis > nowMillis;
+ if ((mMonitors.size() == 0 && isHandlerPolling()) || isPaused) {
// Don't schedule until after resume OR
// If the target looper has recently been polling, then
// there is no reason to enqueue our checker on it since that
@@ -305,15 +316,19 @@ public class Watchdog implements Dumpable {
mHandler.postAtFrontOfQueue(this);
}
+ boolean isHandlerPolling() {
+ return mHandler.getLooper().getQueue().isPolling();
+ }
+
public int getCompletionStateLocked() {
if (mCompleted) {
return COMPLETED;
} else {
- long latency = SystemClock.uptimeMillis() - mStartTimeMillis;
- if (latency < mWaitMaxMillis / 2) {
+ long latency = mClock.millis() - mStartTimeMillis;
+ if (latency < mWaitMaxMillis / PRE_WATCHDOG_TIMEOUT_RATIO) {
return WAITING;
} else if (latency < mWaitMaxMillis) {
- return WAITED_HALF;
+ return WAITED_UNTIL_PRE_WATCHDOG;
}
}
return OVERDUE;
@@ -334,7 +349,7 @@ public class Watchdog implements Dumpable {
} else {
prefix = "Blocked in monitor " + mCurrentMonitor.getClass().getName();
}
- long latencySeconds = (SystemClock.uptimeMillis() - mStartTimeMillis) / 1000;
+ long latencySeconds = (mClock.millis() - mStartTimeMillis) / 1000;
return prefix + " on " + mName + " (" + getThread().getName() + ")"
+ " for " + latencySeconds + "s";
}
@@ -366,10 +381,11 @@ public class Watchdog implements Dumpable {
* the given time.
*/
public void pauseForLocked(int pauseMillis, String reason) {
- mPauseEndTimeMillis = SystemClock.uptimeMillis() + pauseMillis;
+ mPauseEndTimeMillis = mClock.millis() + pauseMillis;
// Mark as completed, because there's a chance we called this after the watchog
- // thread loop called Object#wait after 'WAITED_HALF'. In that case we want to ensure
- // the next call to #getCompletionStateLocked for this checker returns 'COMPLETED'
+ // thread loop called Object#wait after 'WAITED_UNTIL_PRE_WATCHDOG'. In that case we
+ // want to ensure the next call to #getCompletionStateLocked for this checker returns
+ // 'COMPLETED'
mCompleted = true;
Slog.i(TAG, "Pausing of HandlerChecker: " + mName + " for reason: "
+ reason + ". Pause end time: " + mPauseEndTimeMillis);
@@ -379,8 +395,9 @@ public class Watchdog implements Dumpable {
public void pauseLocked(String reason) {
mPauseCount++;
// Mark as completed, because there's a chance we called this after the watchog
- // thread loop called Object#wait after 'WAITED_HALF'. In that case we want to ensure
- // the next call to #getCompletionStateLocked for this checker returns 'COMPLETED'
+ // thread loop called Object#wait after 'WAITED_UNTIL_PRE_WATCHDOG'. In that case we
+ // want to ensure the next call to #getCompletionStateLocked for this checker returns
+ // 'COMPLETED'
mCompleted = true;
Slog.i(TAG, "Pausing HandlerChecker: " + mName + " for reason: "
+ reason + ". Pause count: " + mPauseCount);
@@ -396,6 +413,11 @@ public class Watchdog implements Dumpable {
Slog.wtf(TAG, "Already resumed HandlerChecker: " + mName);
}
}
+
+ @Override
+ public String toString() {
+ return "CheckerHandler for " + mName;
+ }
}
final class RebootRequestReceiver extends BroadcastReceiver {
@@ -445,31 +467,40 @@ public class Watchdog implements Dumpable {
ServiceThread t = new ServiceThread("watchdog.monitor",
android.os.Process.THREAD_PRIORITY_DEFAULT, true /*allowIo*/);
t.start();
- mMonitorChecker = new HandlerChecker(new Handler(t.getLooper()), "monitor thread");
+ mMonitorChecker = new HandlerChecker(new Handler(t.getLooper()), "monitor thread", mLock);
mHandlerCheckers.add(withDefaultTimeout(mMonitorChecker));
- mHandlerCheckers.add(withDefaultTimeout(
- new HandlerChecker(FgThread.getHandler(), "foreground thread")));
+ mHandlerCheckers.add(
+ withDefaultTimeout(
+ new HandlerChecker(FgThread.getHandler(), "foreground thread", mLock)));
// Add checker for main thread. We only do a quick check since there
// can be UI running on the thread.
- mHandlerCheckers.add(withDefaultTimeout(
- new HandlerChecker(new Handler(Looper.getMainLooper()), "main thread")));
+ mHandlerCheckers.add(
+ withDefaultTimeout(
+ new HandlerChecker(
+ new Handler(Looper.getMainLooper()), "main thread", mLock)));
// Add checker for shared UI thread.
- mHandlerCheckers.add(withDefaultTimeout(
- new HandlerChecker(UiThread.getHandler(), "ui thread")));
+ mHandlerCheckers.add(
+ withDefaultTimeout(new HandlerChecker(UiThread.getHandler(), "ui thread", mLock)));
// And also check IO thread.
- mHandlerCheckers.add(withDefaultTimeout(
- new HandlerChecker(IoThread.getHandler(), "i/o thread")));
+ mHandlerCheckers.add(
+ withDefaultTimeout(new HandlerChecker(IoThread.getHandler(), "i/o thread", mLock)));
// And the display thread.
- mHandlerCheckers.add(withDefaultTimeout(
- new HandlerChecker(DisplayThread.getHandler(), "display thread")));
+ mHandlerCheckers.add(
+ withDefaultTimeout(
+ new HandlerChecker(DisplayThread.getHandler(), "display thread", mLock)));
// And the animation thread.
- mHandlerCheckers.add(withDefaultTimeout(
- new HandlerChecker(AnimationThread.getHandler(), "animation thread")));
+ mHandlerCheckers.add(
+ withDefaultTimeout(
+ new HandlerChecker(
+ AnimationThread.getHandler(), "animation thread", mLock)));
// And the surface animation thread.
- mHandlerCheckers.add(withDefaultTimeout(
- new HandlerChecker(SurfaceAnimationThread.getHandler(),
- "surface animation thread")));
+ mHandlerCheckers.add(
+ withDefaultTimeout(
+ new HandlerChecker(
+ SurfaceAnimationThread.getHandler(),
+ "surface animation thread",
+ mLock)));
// Initialize monitor for Binder threads.
addMonitor(new BinderThreadMonitor());
@@ -609,7 +640,7 @@ public class Watchdog implements Dumpable {
public void addThread(Handler thread) {
synchronized (mLock) {
final String name = thread.getLooper().getThread().getName();
- mHandlerCheckers.add(withDefaultTimeout(new HandlerChecker(thread, name)));
+ mHandlerCheckers.add(withDefaultTimeout(new HandlerChecker(thread, name, mLock)));
}
}
@@ -617,7 +648,7 @@ public class Watchdog implements Dumpable {
synchronized (mLock) {
final String name = thread.getLooper().getThread().getName();
mHandlerCheckers.add(
- withCustomTimeout(new HandlerChecker(thread, name), timeoutMillis));
+ withCustomTimeout(new HandlerChecker(thread, name, mLock), timeoutMillis));
}
}
@@ -797,11 +828,11 @@ public class Watchdog implements Dumpable {
String subject = "";
boolean allowRestart = true;
int debuggerWasConnected = 0;
- boolean doWaitedHalfDump = false;
+ boolean doWaitedPreDump = false;
// The value of mWatchdogTimeoutMillis might change while we are executing the loop.
// We store the current value to use a consistent value for all handlers.
final long watchdogTimeoutMillis = mWatchdogTimeoutMillis;
- final long checkIntervalMillis = watchdogTimeoutMillis / 2;
+ final long checkIntervalMillis = watchdogTimeoutMillis / PRE_WATCHDOG_TIMEOUT_RATIO;
final ArrayList<Integer> pids;
synchronized (mLock) {
long timeout = checkIntervalMillis;
@@ -848,15 +879,16 @@ public class Watchdog implements Dumpable {
} else if (waitState == WAITING) {
// still waiting but within their configured intervals; back off and recheck
continue;
- } else if (waitState == WAITED_HALF) {
+ } else if (waitState == WAITED_UNTIL_PRE_WATCHDOG) {
if (!waitedHalf) {
- Slog.i(TAG, "WAITED_HALF");
+ Slog.i(TAG, "WAITED_UNTIL_PRE_WATCHDOG");
waitedHalf = true;
- // We've waited half, but we'd need to do the stack trace dump w/o the lock.
- blockedCheckers = getCheckersWithStateLocked(WAITED_HALF);
+ // We've waited until the pre-watchdog, but we'd need to do the stack trace
+ // dump w/o the lock.
+ blockedCheckers = getCheckersWithStateLocked(WAITED_UNTIL_PRE_WATCHDOG);
subject = describeCheckersLocked(blockedCheckers);
pids = new ArrayList<>(mInterestingJavaPids);
- doWaitedHalfDump = true;
+ doWaitedPreDump = true;
} else {
continue;
}
@@ -874,12 +906,12 @@ public class Watchdog implements Dumpable {
// First collect stack traces from all threads of the system process.
//
// Then, if we reached the full timeout, kill this process so that the system will
- // restart. If we reached half of the timeout, just log some information and continue.
- logWatchog(doWaitedHalfDump, subject, pids);
+ // restart. If we reached pre-watchdog timeout, just log some information and continue.
+ logWatchog(doWaitedPreDump, subject, pids);
- if (doWaitedHalfDump) {
- // We have waited for only half of the timeout, we continue to wait for the duration
- // of the full timeout before killing the process.
+ if (doWaitedPreDump) {
+ // We have waited for only pre-watchdog timeout, we continue to wait for the
+ // duration of the full timeout before killing the process.
continue;
}
@@ -928,8 +960,8 @@ public class Watchdog implements Dumpable {
}
}
- private void logWatchog(boolean halfWatchdog, String subject, ArrayList<Integer> pids) {
- // Get critical event log before logging the half watchdog so that it doesn't
+ private void logWatchog(boolean preWatchdog, String subject, ArrayList<Integer> pids) {
+ // Get critical event log before logging the pre-watchdog so that it doesn't
// occur in the log.
String criticalEvents =
CriticalEventLog.getInstance().logLinesForSystemServerTraceFile();
@@ -941,7 +973,7 @@ public class Watchdog implements Dumpable {
}
final String dropboxTag;
- if (halfWatchdog) {
+ if (preWatchdog) {
dropboxTag = "pre_watchdog";
CriticalEventLog.getInstance().logHalfWatchdog(subject);
FrameworkStatsLog.write(FrameworkStatsLog.SYSTEM_SERVER_PRE_WATCHDOG_OCCURRED);
@@ -971,7 +1003,7 @@ public class Watchdog implements Dumpable {
report.append(processCpuTracker.printCurrentState(anrTime, 10));
report.append(tracesFileException.getBuffer());
- if (!halfWatchdog) {
+ if (!preWatchdog) {
// Trigger the kernel to dump all blocked threads, and backtraces on all CPUs to the
// kernel log
doSysRq('w');
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 54c8ed38bb1c..b87d02d86c22 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -79,7 +79,6 @@ import static android.os.PowerExemptionManager.REASON_ACTIVITY_VISIBILITY_GRACE_
import static android.os.PowerExemptionManager.REASON_BACKGROUND_ACTIVITY_PERMISSION;
import static android.os.PowerExemptionManager.REASON_BOOT_COMPLETED;
import static android.os.PowerExemptionManager.REASON_COMPANION_DEVICE_MANAGER;
-import static android.os.PowerExemptionManager.REASON_DENIED;
import static android.os.PowerExemptionManager.REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION;
import static android.os.PowerExemptionManager.REASON_LOCKED_BOOT_COMPLETED;
import static android.os.PowerExemptionManager.REASON_PROC_STATE_BTOP;
@@ -5051,7 +5050,7 @@ public class ActivityManagerService extends IActivityManager.Stub
REASON_LOCKED_BOOT_COMPLETED);
}
// Send BOOT_COMPLETED if the user is unlocked
- if (StorageManager.isUserKeyUnlocked(app.userId)) {
+ if (StorageManager.isCeStorageUnlocked(app.userId)) {
sendBootBroadcastToAppLocked(app, new Intent(Intent.ACTION_BOOT_COMPLETED),
REASON_BOOT_COMPLETED);
}
@@ -14150,7 +14149,8 @@ public class ActivityManagerService extends IActivityManager.Stub
|| action.startsWith("android.intent.action.PACKAGE_")
|| action.startsWith("android.intent.action.UID_")
|| action.startsWith("android.intent.action.EXTERNAL_")
- || action.startsWith("android.bluetooth.")) {
+ || action.startsWith("android.bluetooth.")
+ || action.equals(Intent.ACTION_SHUTDOWN)) {
if (DEBUG_BROADCAST) {
Slog.wtf(TAG,
"System internals registering for " + filter.toLongString()
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index e65603021708..1928780fa090 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -3013,7 +3013,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
mBatteryStatsConfig, Clock.SYSTEM_CLOCK, mMonotonicClock,
null, mStats.mHandler, null, null,
mUserManagerUserInfoProvider, mPowerProfile,
- mCpuScalingPolicies, null);
+ mCpuScalingPolicies, new PowerStatsUidResolver());
checkinStats.readSummaryFromParcel(in);
in.recycle();
checkinStats.dumpProtoLocked(mContext, fd, apps, flags,
@@ -3055,7 +3055,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
mBatteryStatsConfig, Clock.SYSTEM_CLOCK, mMonotonicClock,
null, mStats.mHandler, null, null,
mUserManagerUserInfoProvider, mPowerProfile,
- mCpuScalingPolicies, null);
+ mCpuScalingPolicies, new PowerStatsUidResolver());
checkinStats.readSummaryFromParcel(in);
in.recycle();
checkinStats.dumpCheckin(mContext, pw, apps, flags,
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 3f27ca024f15..5d47e35a8729 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -10667,8 +10667,8 @@ public class AudioService extends IAudioService.Stub
/** @see LoudnessCodecConfigurator#addMediaCodec(MediaCodec) */
@Override
- public void addLoudnessCodecInfo(int piid, LoudnessCodecInfo codecInfo) {
- mLoudnessCodecHelper.addLoudnessCodecInfo(piid, codecInfo);
+ public void addLoudnessCodecInfo(int piid, int mediaCodecHash, LoudnessCodecInfo codecInfo) {
+ mLoudnessCodecHelper.addLoudnessCodecInfo(piid, mediaCodecHash, codecInfo);
}
/** @see LoudnessCodecConfigurator#removeMediaCodec(MediaCodec) */
@@ -11372,6 +11372,8 @@ public class AudioService extends IAudioService.Stub
static final int LOG_NB_EVENTS_SPATIAL = 30;
static final int LOG_NB_EVENTS_SOUND_DOSE = 30;
+ static final int LOG_NB_EVENTS_LOUDNESS_CODEC = 30;
+
static final EventLogger
sLifecycleLogger = new EventLogger(LOG_NB_EVENTS_LIFECYCLE,
"audio services lifecycle");
@@ -11571,6 +11573,10 @@ public class AudioService extends IAudioService.Stub
mSpatializerHelper.dump(pw);
sSpatialLogger.dump(pw);
+ pw.println("\n");
+ pw.println("\nLoudness alignment:");
+ mLoudnessCodecHelper.dump(pw);
+
mAudioSystem.dump(pw);
}
diff --git a/services/core/java/com/android/server/audio/AudioServiceEvents.java b/services/core/java/com/android/server/audio/AudioServiceEvents.java
index f69b9f6523cc..de8901179028 100644
--- a/services/core/java/com/android/server/audio/AudioServiceEvents.java
+++ b/services/core/java/com/android/server/audio/AudioServiceEvents.java
@@ -622,6 +622,55 @@ public class AudioServiceEvents {
}
}
+ static final class LoudnessEvent extends EventLogger.Event {
+ static final int START_PIID = 0;
+
+ static final int STOP_PIID = 1;
+
+ static final int CLIENT_DIED = 2;
+
+ final int mEventType;
+ final int mIntValue1;
+ final int mIntValue2;
+
+ private LoudnessEvent(int event, int i1, int i2) {
+ mEventType = event;
+ mIntValue1 = i1;
+ mIntValue2 = i2;
+ }
+
+ static LoudnessEvent getStartPiid(int piid, int pid) {
+ return new LoudnessEvent(START_PIID, piid, pid);
+ }
+
+ static LoudnessEvent getStopPiid(int piid, int pid) {
+ return new LoudnessEvent(STOP_PIID, piid, pid);
+ }
+
+ static LoudnessEvent getClientDied(int pid) {
+ return new LoudnessEvent(CLIENT_DIED, 0 /* ignored */, pid);
+ }
+
+
+ @Override
+ public String eventToString() {
+ switch (mEventType) {
+ case START_PIID:
+ return String.format(
+ "Start loudness updates for piid %d for client pid %d",
+ mIntValue1, mIntValue2);
+ case STOP_PIID:
+ return String.format(
+ "Stop loudness updates for piid %d for client pid %d",
+ mIntValue1, mIntValue2);
+ case CLIENT_DIED:
+ return String.format("Loudness client with pid %d died", mIntValue2);
+
+ }
+ return new StringBuilder("FIXME invalid event type:").append(mEventType).toString();
+ }
+ }
+
/**
* Class to log stream type mute/unmute events
*/
diff --git a/services/core/java/com/android/server/audio/LoudnessCodecHelper.java b/services/core/java/com/android/server/audio/LoudnessCodecHelper.java
index 3c67e9dd116b..bbe819f22e3a 100644
--- a/services/core/java/com/android/server/audio/LoudnessCodecHelper.java
+++ b/services/core/java/com/android/server/audio/LoudnessCodecHelper.java
@@ -21,6 +21,11 @@ import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_HEADPHONES;
import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_HEARING_AID;
import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_WATCH;
import static android.media.AudioPlaybackConfiguration.PLAYER_DEVICEID_INVALID;
+import static android.media.LoudnessCodecInfo.CodecMetadataType.CODEC_METADATA_TYPE_MPEG_4;
+import static android.media.LoudnessCodecInfo.CodecMetadataType.CODEC_METADATA_TYPE_MPEG_D;
+import static android.media.MediaFormat.KEY_AAC_DRC_EFFECT_TYPE;
+import static android.media.MediaFormat.KEY_AAC_DRC_HEAVY_COMPRESSION;
+import static android.media.MediaFormat.KEY_AAC_DRC_TARGET_REFERENCE_LEVEL;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -41,7 +46,11 @@ import android.util.SparseArray;
import android.util.SparseIntArray;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.audio.AudioServiceEvents.LoudnessEvent;
+import com.android.server.utils.EventLogger;
+import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -50,6 +59,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
+import java.util.stream.Collectors;
/**
* Class to handle the updates in loudness parameters and responsible to generate parameters that
@@ -70,10 +80,14 @@ public class LoudnessCodecHelper {
private static final String SYSTEM_PROPERTY_SPEAKER_SPL_RANGE_SIZE =
"audio.loudness.builtin-speaker-spl-range-size";
- private static final int SPL_RANGE_UNKNOWN = 0;
- private static final int SPL_RANGE_SMALL = 1;
- private static final int SPL_RANGE_MEDIUM = 2;
- private static final int SPL_RANGE_LARGE = 3;
+ @VisibleForTesting
+ static final int SPL_RANGE_UNKNOWN = 0;
+ @VisibleForTesting
+ static final int SPL_RANGE_SMALL = 1;
+ @VisibleForTesting
+ static final int SPL_RANGE_MEDIUM = 2;
+ @VisibleForTesting
+ static final int SPL_RANGE_LARGE = 3;
/** The possible transducer SPL ranges as defined in CTA2075 */
@IntDef({
@@ -99,12 +113,19 @@ public class LoudnessCodecHelper {
pid = (Integer) cookie;
}
if (pid != null) {
- mLoudnessCodecHelper.removePid(pid);
+ if (DEBUG) {
+ Log.d(TAG, "Client with pid " + pid + " died, removing from receiving updates");
+ }
+ sLogger.enqueue(LoudnessEvent.getClientDied(pid));
+ mLoudnessCodecHelper.onClientPidDied(pid);
}
super.onCallbackDied(callback, cookie);
}
}
+ private static final EventLogger sLogger = new EventLogger(
+ AudioService.LOG_NB_EVENTS_LOUDNESS_CODEC, "Loudness updates");
+
private final LoudnessRemoteCallbackList mLoudnessUpdateDispatchers =
new LoudnessRemoteCallbackList(this);
@@ -125,7 +146,8 @@ public class LoudnessCodecHelper {
private final AudioService mAudioService;
/** Contains the properties necessary to compute the codec loudness related parameters. */
- private static final class LoudnessCodecInputProperties {
+ @VisibleForTesting
+ static final class LoudnessCodecInputProperties {
private final int mMetadataType;
private final boolean mIsDownmixing;
@@ -200,10 +222,53 @@ public class LoudnessCodecHelper {
}
PersistableBundle createLoudnessParameters() {
- // TODO: create bundle with new parameters
- return new PersistableBundle();
- }
+ PersistableBundle loudnessParams = new PersistableBundle();
+
+ switch (mDeviceSplRange) {
+ case SPL_RANGE_LARGE:
+ // corresponds to -31dB attenuation
+ loudnessParams.putInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, 124);
+ if (mMetadataType == CODEC_METADATA_TYPE_MPEG_4) {
+ loudnessParams.putInt(KEY_AAC_DRC_HEAVY_COMPRESSION, 0);
+ } else if (mMetadataType == CODEC_METADATA_TYPE_MPEG_D) {
+ // general compression
+ loudnessParams.putInt(KEY_AAC_DRC_EFFECT_TYPE, 6);
+ }
+ break;
+ case SPL_RANGE_MEDIUM:
+ // corresponds to -24dB attenuation
+ loudnessParams.putInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, 96);
+ if (mMetadataType == CODEC_METADATA_TYPE_MPEG_4) {
+ loudnessParams.putInt(KEY_AAC_DRC_HEAVY_COMPRESSION, mIsDownmixing ? 1 : 0);
+ } else if (mMetadataType == CODEC_METADATA_TYPE_MPEG_D) {
+ // general compression
+ loudnessParams.putInt(KEY_AAC_DRC_EFFECT_TYPE, 6);
+ }
+ break;
+ case SPL_RANGE_SMALL:
+ // corresponds to -16dB attenuation
+ loudnessParams.putInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, 64);
+ if (mMetadataType == CODEC_METADATA_TYPE_MPEG_4) {
+ loudnessParams.putInt(KEY_AAC_DRC_HEAVY_COMPRESSION, 1);
+ } else if (mMetadataType == CODEC_METADATA_TYPE_MPEG_D) {
+ // limited playback range compression
+ loudnessParams.putInt(KEY_AAC_DRC_EFFECT_TYPE, 3);
+ }
+ break;
+ default:
+ // corresponds to -24dB attenuation
+ loudnessParams.putInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, 96);
+ if (mMetadataType == CODEC_METADATA_TYPE_MPEG_4) {
+ loudnessParams.putInt(KEY_AAC_DRC_HEAVY_COMPRESSION, mIsDownmixing ? 1 : 0);
+ } else if (mMetadataType == CODEC_METADATA_TYPE_MPEG_D) {
+ // general compression
+ loudnessParams.putInt(KEY_AAC_DRC_EFFECT_TYPE, 6);
+ }
+ break;
+ }
+ return loudnessParams;
+ }
}
@GuardedBy("mLock")
@@ -227,22 +292,25 @@ public class LoudnessCodecHelper {
if (DEBUG) {
Log.d(TAG, "startLoudnessCodecUpdates: piid " + piid + " codecInfos " + codecInfoList);
}
- Set<LoudnessCodecInfo> infoSet;
+
synchronized (mLock) {
if (mStartedPiids.contains(piid)) {
Log.w(TAG, "Already started loudness updates for piid " + piid);
return;
}
- infoSet = new HashSet<>(codecInfoList);
+ Set<LoudnessCodecInfo> infoSet = new HashSet<>(codecInfoList);
mStartedPiids.put(piid, infoSet);
- mPiidToPidCache.put(piid, Binder.getCallingPid());
+ int pid = Binder.getCallingPid();
+ mPiidToPidCache.put(piid, pid);
+
+ sLogger.enqueue(LoudnessEvent.getStartPiid(piid, pid));
}
try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
mAudioService.getActivePlaybackConfigurations().stream().filter(
conf -> conf.getPlayerInterfaceId() == piid).findFirst().ifPresent(
- apc -> updateCodecParametersForConfiguration(apc, infoSet));
+ this::updateCodecParametersForConfiguration);
}
}
@@ -250,20 +318,24 @@ public class LoudnessCodecHelper {
if (DEBUG) {
Log.d(TAG, "stopLoudnessCodecUpdates: piid " + piid);
}
+
synchronized (mLock) {
if (!mStartedPiids.contains(piid)) {
Log.w(TAG, "Loudness updates are already stopped for piid " + piid);
return;
}
mStartedPiids.remove(piid);
+
+ sLogger.enqueue(LoudnessEvent.getStopPiid(piid, mPiidToPidCache.get(piid, -1)));
mPiidToDeviceIdCache.delete(piid);
mPiidToPidCache.delete(piid);
}
}
- void addLoudnessCodecInfo(int piid, LoudnessCodecInfo info) {
+ void addLoudnessCodecInfo(int piid, int mediaCodecHash, LoudnessCodecInfo info) {
if (DEBUG) {
- Log.d(TAG, "addLoudnessCodecInfo: piid " + piid + " info " + info);
+ Log.d(TAG, "addLoudnessCodecInfo: piid " + piid + " mcHash " + mediaCodecHash + " info "
+ + info);
}
Set<LoudnessCodecInfo> infoSet;
@@ -280,7 +352,20 @@ public class LoudnessCodecHelper {
try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
mAudioService.getActivePlaybackConfigurations().stream().filter(
conf -> conf.getPlayerInterfaceId() == piid).findFirst().ifPresent(
- apc -> updateCodecParametersForConfiguration(apc, Set.of(info)));
+ apc -> {
+ final AudioDeviceInfo deviceInfo = apc.getAudioDeviceInfo();
+ if (deviceInfo != null) {
+ PersistableBundle updateBundle = new PersistableBundle();
+ synchronized (mLock) {
+ updateBundle.putPersistableBundle(
+ Integer.toString(mediaCodecHash),
+ getCodecBundle_l(deviceInfo, info));
+ }
+ if (!updateBundle.isDefinitelyEmpty()) {
+ dispatchNewLoudnessParameters(piid, updateBundle);
+ }
+ }
+ });
}
}
@@ -298,24 +383,6 @@ public class LoudnessCodecHelper {
}
}
- void removePid(int pid) {
- if (DEBUG) {
- Log.d(TAG, "Removing pid " + pid + " from receiving updates");
- }
- synchronized (mLock) {
- for (int i = 0; i < mPiidToPidCache.size(); ++i) {
- int piid = mPiidToPidCache.keyAt(i);
- if (mPiidToPidCache.get(piid) == pid) {
- if (DEBUG) {
- Log.d(TAG, "Removing piid " + piid);
- }
- mStartedPiids.delete(piid);
- mPiidToDeviceIdCache.delete(piid);
- }
- }
- }
- }
-
PersistableBundle getLoudnessParams(int piid, LoudnessCodecInfo codecInfo) {
if (DEBUG) {
Log.d(TAG, "getLoudnessParams: piid " + piid + " codecInfo " + codecInfo);
@@ -381,48 +448,77 @@ public class LoudnessCodecHelper {
}
}
- updateApcList.forEach(apc -> updateCodecParametersForConfiguration(apc, null));
+ updateApcList.forEach(apc -> updateCodecParametersForConfiguration(apc));
+ }
+
+ /** Updates and dispatches the new loudness parameters for all its registered codecs. */
+ void dump(PrintWriter pw) {
+ // Registered clients
+ pw.println("\nRegistered clients:\n");
+ synchronized (mLock) {
+ for (int i = 0; i < mStartedPiids.size(); ++i) {
+ int piid = mStartedPiids.keyAt(i);
+ int pid = mPiidToPidCache.get(piid, -1);
+ final Set<LoudnessCodecInfo> codecInfos = mStartedPiids.get(piid);
+ pw.println(String.format("Player piid %d pid %d active codec types %s\n", piid,
+ pid, codecInfos.stream().map(Object::toString).collect(
+ Collectors.joining(", "))));
+ }
+ pw.println();
+ }
+
+ sLogger.dump(pw);
+ pw.println();
}
- /** Updates and dispatches the new loudness parameters for the {@code codecInfos} set.
+ private void onClientPidDied(int pid) {
+ synchronized (mLock) {
+ for (int i = 0; i < mPiidToPidCache.size(); ++i) {
+ int piid = mPiidToPidCache.keyAt(i);
+ if (mPiidToPidCache.get(piid) == pid) {
+ if (DEBUG) {
+ Log.d(TAG, "Removing piid " + piid);
+ }
+ mStartedPiids.delete(piid);
+ mPiidToDeviceIdCache.delete(piid);
+ }
+ }
+ }
+ }
+
+ /**
+ * Updates and dispatches the new loudness parameters for the {@code codecInfos} set.
*
* @param apc the player configuration for which the loudness parameters are updated.
- * @param codecInfos the codec info for which the parameters are updated. If {@code null},
- * send updates for all the started codecs assigned to {@code apc}
*/
- private void updateCodecParametersForConfiguration(AudioPlaybackConfiguration apc,
- Set<LoudnessCodecInfo> codecInfos) {
+ private void updateCodecParametersForConfiguration(AudioPlaybackConfiguration apc) {
if (DEBUG) {
- Log.d(TAG, "updateCodecParametersForConfiguration apc:" + apc + " codecInfos: "
- + codecInfos);
+ Log.d(TAG, "updateCodecParametersForConfiguration apc:" + apc);
}
+
final PersistableBundle allBundles = new PersistableBundle();
final int piid = apc.getPlayerInterfaceId();
+
synchronized (mLock) {
- if (codecInfos == null) {
- codecInfos = mStartedPiids.get(piid);
- }
+ final Set<LoudnessCodecInfo> codecInfos = mStartedPiids.get(piid);
final AudioDeviceInfo deviceInfo = apc.getAudioDeviceInfo();
if (codecInfos != null && deviceInfo != null) {
for (LoudnessCodecInfo info : codecInfos) {
- allBundles.putPersistableBundle(Integer.toString(info.mediaCodecHashCode),
+ allBundles.putPersistableBundle(Integer.toString(info.hashCode()),
getCodecBundle_l(deviceInfo, info));
}
}
}
if (!allBundles.isDefinitelyEmpty()) {
- if (DEBUG) {
- Log.d(TAG, "Dispatching for piid: " + piid + " bundle: " + allBundles);
- }
dispatchNewLoudnessParameters(piid, allBundles);
}
}
private void dispatchNewLoudnessParameters(int piid, PersistableBundle bundle) {
if (DEBUG) {
- Log.d(TAG, "dispatchNewLoudnessParameters: piid " + piid);
+ Log.d(TAG, "dispatchNewLoudnessParameters: piid " + piid + " bundle: " + bundle);
}
final int nbDispatchers = mLoudnessUpdateDispatchers.beginBroadcast();
for (int i = 0; i < nbDispatchers; ++i) {
diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
index debf828abf0a..d848f4b6cce5 100644
--- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
+++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
@@ -121,6 +121,7 @@ public abstract class BrightnessMappingStrategy {
// Display independent, mode dependent values
float[] brightnessLevelsNits;
+ float[] brightnessLevels = null;
float[] luxLevels;
if (isForIdleMode) {
brightnessLevelsNits = getFloatArray(resources.obtainTypedArray(
@@ -130,11 +131,21 @@ public abstract class BrightnessMappingStrategy {
} else {
brightnessLevelsNits = displayDeviceConfig.getAutoBrightnessBrighteningLevelsNits();
luxLevels = displayDeviceConfig.getAutoBrightnessBrighteningLevelsLux();
+
+ brightnessLevels = displayDeviceConfig.getAutoBrightnessBrighteningLevels();
+ if (brightnessLevels == null || brightnessLevels.length == 0) {
+ // Load the old configuration in the range [0, 255]. The values need to be
+ // normalized to the range [0, 1].
+ int[] brightnessLevelsInt = resources.getIntArray(
+ com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
+ brightnessLevels = new float[brightnessLevelsInt.length];
+ for (int i = 0; i < brightnessLevels.length; i++) {
+ brightnessLevels[i] = normalizeAbsoluteBrightness(brightnessLevelsInt[i]);
+ }
+ }
}
// Display independent, mode independent values
- int[] brightnessLevelsBacklight = resources.getIntArray(
- com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
float autoBrightnessAdjustmentMaxGamma = resources.getFraction(
com.android.internal.R.fraction.config_autoBrightnessAdjustmentMaxGamma,
1, 1);
@@ -155,8 +166,8 @@ public abstract class BrightnessMappingStrategy {
builder.setShortTermModelUpperLuxMultiplier(SHORT_TERM_MODEL_THRESHOLD_RATIO);
return new PhysicalMappingStrategy(builder.build(), nitsRange, brightnessRange,
autoBrightnessAdjustmentMaxGamma, isForIdleMode, displayWhiteBalanceController);
- } else if (isValidMapping(luxLevels, brightnessLevelsBacklight) && !isForIdleMode) {
- return new SimpleMappingStrategy(luxLevels, brightnessLevelsBacklight,
+ } else if (isValidMapping(luxLevels, brightnessLevels)) {
+ return new SimpleMappingStrategy(luxLevels, brightnessLevels,
autoBrightnessAdjustmentMaxGamma, shortTermModelTimeout);
} else {
return null;
@@ -620,7 +631,7 @@ public abstract class BrightnessMappingStrategy {
private float mUserBrightness;
private long mShortTermModelTimeout;
- private SimpleMappingStrategy(float[] lux, int[] brightness, float maxGamma,
+ private SimpleMappingStrategy(float[] lux, float[] brightness, float maxGamma,
long timeout) {
Preconditions.checkArgument(lux.length != 0 && brightness.length != 0,
"Lux and brightness arrays must not be empty!");
@@ -635,7 +646,7 @@ public abstract class BrightnessMappingStrategy {
mBrightness = new float[N];
for (int i = 0; i < N; i++) {
mLux[i] = lux[i];
- mBrightness[i] = normalizeAbsoluteBrightness(brightness[i]);
+ mBrightness[i] = brightness[i];
}
mMaxGamma = maxGamma;
diff --git a/services/core/java/com/android/server/display/DisplayAdapter.java b/services/core/java/com/android/server/display/DisplayAdapter.java
index 70d4ad2c6e1f..c26118eac7a2 100644
--- a/services/core/java/com/android/server/display/DisplayAdapter.java
+++ b/services/core/java/com/android/server/display/DisplayAdapter.java
@@ -20,6 +20,8 @@ import android.content.Context;
import android.os.Handler;
import android.view.Display;
+import com.android.server.display.feature.DisplayManagerFlags;
+
import java.io.PrintWriter;
import java.util.concurrent.atomic.AtomicInteger;
@@ -39,6 +41,7 @@ abstract class DisplayAdapter {
private final Handler mHandler;
private final Listener mListener;
private final String mName;
+ private final DisplayManagerFlags mFeatureFlags;
public static final int DISPLAY_DEVICE_EVENT_ADDED = 1;
public static final int DISPLAY_DEVICE_EVENT_CHANGED = 2;
@@ -50,13 +53,14 @@ abstract class DisplayAdapter {
private static final AtomicInteger NEXT_DISPLAY_MODE_ID = new AtomicInteger(1); // 0 = no mode.
// Called with SyncRoot lock held.
- public DisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
- Context context, Handler handler, Listener listener, String name) {
+ DisplayAdapter(DisplayManagerService.SyncRoot syncRoot, Context context, Handler handler,
+ Listener listener, String name, DisplayManagerFlags featureFlags) {
mSyncRoot = syncRoot;
mContext = context;
mHandler = handler;
mListener = listener;
mName = name;
+ mFeatureFlags = featureFlags;
}
/**
@@ -88,6 +92,10 @@ abstract class DisplayAdapter {
return mName;
}
+ public final DisplayManagerFlags getFeatureFlags() {
+ return mFeatureFlags;
+ }
+
/**
* Registers the display adapter with the display manager.
*
diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java
index 2fdf90d7d286..3b05b47eb542 100644
--- a/services/core/java/com/android/server/display/DisplayDevice.java
+++ b/services/core/java/com/android/server/display/DisplayDevice.java
@@ -400,6 +400,7 @@ abstract class DisplayDevice {
}
private DisplayDeviceConfig loadDisplayDeviceConfig() {
- return DisplayDeviceConfig.create(mContext, false);
+ return DisplayDeviceConfig.create(mContext, /* useConfigXml= */ false,
+ mDisplayAdapter.getFeatureFlags());
}
}
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index e6aa8258041a..d97127c91fbf 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -57,6 +57,7 @@ import com.android.server.display.config.HdrBrightnessData;
import com.android.server.display.config.HighBrightnessMode;
import com.android.server.display.config.IntegerArray;
import com.android.server.display.config.LuxThrottling;
+import com.android.server.display.config.LuxToBrightnessMapping;
import com.android.server.display.config.NitsMap;
import com.android.server.display.config.NonNegativeFloatToFloatPoint;
import com.android.server.display.config.Point;
@@ -77,6 +78,7 @@ import com.android.server.display.config.ThermalThrottling;
import com.android.server.display.config.ThresholdPoint;
import com.android.server.display.config.UsiVersion;
import com.android.server.display.config.XmlParser;
+import com.android.server.display.feature.DisplayManagerFlags;
import com.android.server.display.utils.DebugUtils;
import org.xmlpull.v1.XmlPullParserException;
@@ -310,16 +312,18 @@ import javax.xml.datatype.DatatypeConfigurationException;
* <darkeningLightDebounceIdleMillis>
* 1000
* </darkeningLightDebounceIdleMillis>
- * <displayBrightnessMapping>
- * <displayBrightnessPoint>
- * <lux>50</lux>
- * <nits>45.32</nits>
- * </displayBrightnessPoint>
- * <displayBrightnessPoint>
- * <lux>80</lux>
- * <nits>75.43</nits>
- * </displayBrightnessPoint>
- * </displayBrightnessMapping>
+ * <luxToBrightnessMapping>
+ * <map>
+ * <point>
+ * <first>0</first>
+ * <second>0.2</second>
+ * </point>
+ * <point>
+ * <first>80</first>
+ * <second>0.3</second>
+ * </point>
+ * </map>
+ * </luxToBrightnessMapping>
* </autoBrightness>
*
* <screenBrightnessRampFastDecrease>0.01</screenBrightnessRampFastDecrease>
@@ -630,7 +634,6 @@ public class DisplayDeviceConfig {
// for the corresponding values above
private float[] mBrightness;
-
/**
* Array of desired screen brightness in nits corresponding to the lux values
* in the mBrightnessLevelsLux array. The display brightness is defined as the
@@ -640,20 +643,25 @@ public class DisplayDeviceConfig {
private float[] mBrightnessLevelsNits;
/**
- * Array of light sensor lux values to define our levels for auto backlight
- * brightness support.
+ * Array of desired screen brightness corresponding to the lux values
+ * in the mBrightnessLevelsLux array. The brightness values must be non-negative and
+ * non-decreasing. They must be between {@link PowerManager.BRIGHTNESS_MIN} and
+ * {@link PowerManager.BRIGHTNESS_MAX}. This must be overridden in platform specific overlays
+ */
+ private float[] mBrightnessLevels;
+
+ /**
+ * Array of light sensor lux values to define our levels for auto-brightness support.
*
- * The N + 1 entries of this array define N control points defined in mBrightnessLevelsNits,
- * with first value always being 0 lux
+ * The first lux value is always 0.
*
- * The control points must be strictly increasing. Each control point
- * corresponds to an entry in the brightness backlight values arrays.
- * For example, if lux == level[1] (second element of the levels array)
- * then the brightness will be determined by value[0] (first element
- * of the brightness values array).
+ * The control points must be strictly increasing. Each control point corresponds to an entry
+ * in the brightness values arrays. For example, if lux == luxLevels[1] (second element
+ * of the levels array) then the brightness will be determined by brightnessLevels[1] (second
+ * element of the brightness values array).
*
- * Spline interpolation is used to determine the auto-brightness
- * backlight values for lux levels between these control points.
+ * Spline interpolation is used to determine the auto-brightness values for lux levels between
+ * these control points.
*/
private float[] mBrightnessLevelsLux;
@@ -849,9 +857,12 @@ public class DisplayDeviceConfig {
*/
private float mBrightnessCapForWearBedtimeMode;
+ private final DisplayManagerFlags mFlags;
+
@VisibleForTesting
- DisplayDeviceConfig(Context context) {
+ DisplayDeviceConfig(Context context, DisplayManagerFlags flags) {
mContext = context;
+ mFlags = flags;
}
/**
@@ -867,9 +878,9 @@ public class DisplayDeviceConfig {
* @return A configuration instance for the specified display.
*/
public static DisplayDeviceConfig create(Context context, long physicalDisplayId,
- boolean isFirstDisplay) {
+ boolean isFirstDisplay, DisplayManagerFlags flags) {
final DisplayDeviceConfig config = createWithoutDefaultValues(context, physicalDisplayId,
- isFirstDisplay);
+ isFirstDisplay, flags);
config.copyUninitializedValuesFromSecondaryConfig(loadDefaultConfigurationXml(context));
return config;
@@ -884,28 +895,29 @@ public class DisplayDeviceConfig {
* or the default values.
* @return A configuration instance.
*/
- public static DisplayDeviceConfig create(Context context, boolean useConfigXml) {
+ public static DisplayDeviceConfig create(Context context, boolean useConfigXml,
+ DisplayManagerFlags flags) {
final DisplayDeviceConfig config;
if (useConfigXml) {
- config = getConfigFromGlobalXml(context);
+ config = getConfigFromGlobalXml(context, flags);
} else {
- config = getConfigFromPmValues(context);
+ config = getConfigFromPmValues(context, flags);
}
return config;
}
private static DisplayDeviceConfig createWithoutDefaultValues(Context context,
- long physicalDisplayId, boolean isFirstDisplay) {
+ long physicalDisplayId, boolean isFirstDisplay, DisplayManagerFlags flags) {
DisplayDeviceConfig config;
config = loadConfigFromDirectory(context, Environment.getProductDirectory(),
- physicalDisplayId);
+ physicalDisplayId, flags);
if (config != null) {
return config;
}
config = loadConfigFromDirectory(context, Environment.getVendorDirectory(),
- physicalDisplayId);
+ physicalDisplayId, flags);
if (config != null) {
return config;
}
@@ -913,7 +925,7 @@ public class DisplayDeviceConfig {
// If no config can be loaded from any ddc xml at all,
// prepare a whole config using the global config.xml.
// Guaranteed not null
- return create(context, isFirstDisplay);
+ return create(context, isFirstDisplay, flags);
}
private static DisplayConfiguration loadDefaultConfigurationXml(Context context) {
@@ -966,18 +978,19 @@ public class DisplayDeviceConfig {
}
private static DisplayDeviceConfig loadConfigFromDirectory(Context context,
- File baseDirectory, long physicalDisplayId) {
+ File baseDirectory, long physicalDisplayId, DisplayManagerFlags flags) {
DisplayDeviceConfig config;
// Create config using filename from physical ID (including "stable" bit).
config = getConfigFromSuffix(context, baseDirectory, STABLE_ID_SUFFIX_FORMAT,
- physicalDisplayId);
+ physicalDisplayId, flags);
if (config != null) {
return config;
}
// Create config using filename from physical ID (excluding "stable" bit).
final long withoutStableFlag = physicalDisplayId & ~STABLE_FLAG;
- config = getConfigFromSuffix(context, baseDirectory, NO_SUFFIX_FORMAT, withoutStableFlag);
+ config = getConfigFromSuffix(context, baseDirectory, NO_SUFFIX_FORMAT, withoutStableFlag,
+ flags);
if (config != null) {
return config;
}
@@ -986,7 +999,7 @@ public class DisplayDeviceConfig {
final DisplayAddress.Physical physicalAddress =
DisplayAddress.fromPhysicalDisplayId(physicalDisplayId);
int port = physicalAddress.getPort();
- config = getConfigFromSuffix(context, baseDirectory, PORT_SUFFIX_FORMAT, port);
+ config = getConfigFromSuffix(context, baseDirectory, PORT_SUFFIX_FORMAT, port, flags);
return config;
}
@@ -1605,6 +1618,13 @@ public class DisplayDeviceConfig {
}
/**
+ * @return Auto brightness brightening levels
+ */
+ public float[] getAutoBrightnessBrighteningLevels() {
+ return mBrightnessLevels;
+ }
+
+ /**
* @return Default peak refresh rate of the associated display
*/
public int getDefaultPeakRefreshRate() {
@@ -1857,6 +1877,7 @@ public class DisplayDeviceConfig {
+ mAutoBrightnessDarkeningLightDebounceIdle
+ ", mBrightnessLevelsLux= " + Arrays.toString(mBrightnessLevelsLux)
+ ", mBrightnessLevelsNits= " + Arrays.toString(mBrightnessLevelsNits)
+ + ", mBrightnessLevels= " + Arrays.toString(mBrightnessLevels)
+ ", mDdcAutoBrightnessAvailable= " + mDdcAutoBrightnessAvailable
+ ", mAutoBrightnessAvailable= " + mAutoBrightnessAvailable
+ "\n"
@@ -1890,27 +1911,29 @@ public class DisplayDeviceConfig {
}
private static DisplayDeviceConfig getConfigFromSuffix(Context context, File baseDirectory,
- String suffixFormat, long idNumber) {
+ String suffixFormat, long idNumber, DisplayManagerFlags flags) {
final String suffix = String.format(Locale.ROOT, suffixFormat, idNumber);
final String filename = String.format(Locale.ROOT, CONFIG_FILE_FORMAT, suffix);
final File filePath = Environment.buildPath(
baseDirectory, ETC_DIR, DISPLAY_CONFIG_DIR, filename);
- final DisplayDeviceConfig config = new DisplayDeviceConfig(context);
+ final DisplayDeviceConfig config = new DisplayDeviceConfig(context, flags);
if (config.initFromFile(filePath)) {
return config;
}
return null;
}
- private static DisplayDeviceConfig getConfigFromGlobalXml(Context context) {
- DisplayDeviceConfig config = new DisplayDeviceConfig(context);
+ private static DisplayDeviceConfig getConfigFromGlobalXml(Context context,
+ DisplayManagerFlags flags) {
+ DisplayDeviceConfig config = new DisplayDeviceConfig(context, flags);
config.initFromGlobalXml();
return config;
}
- private static DisplayDeviceConfig getConfigFromPmValues(Context context) {
- DisplayDeviceConfig config = new DisplayDeviceConfig(context);
+ private static DisplayDeviceConfig getConfigFromPmValues(Context context,
+ DisplayManagerFlags flags) {
+ DisplayDeviceConfig config = new DisplayDeviceConfig(context, flags);
config.initFromDefaultValues();
return config;
}
@@ -2615,8 +2638,23 @@ public class DisplayDeviceConfig {
* loading the value from the display config, and if not present, falls back to config.xml.
*/
private void loadAutoBrightnessDisplayBrightnessMapping(AutoBrightness autoBrightnessConfig) {
- if (autoBrightnessConfig == null
- || autoBrightnessConfig.getDisplayBrightnessMapping() == null) {
+ if (mFlags.areAutoBrightnessModesEnabled() && autoBrightnessConfig != null
+ && autoBrightnessConfig.getLuxToBrightnessMapping() != null) {
+ LuxToBrightnessMapping mapping = autoBrightnessConfig.getLuxToBrightnessMapping();
+ final int size = mapping.getMap().getPoint().size();
+ mBrightnessLevels = new float[size];
+ mBrightnessLevelsLux = new float[size];
+ for (int i = 0; i < size; i++) {
+ float backlight = mapping.getMap().getPoint().get(i).getSecond().floatValue();
+ mBrightnessLevels[i] = mBacklightToBrightnessSpline.interpolate(backlight);
+ mBrightnessLevelsLux[i] = mapping.getMap().getPoint().get(i).getFirst()
+ .floatValue();
+ }
+ if (size > 0 && mBrightnessLevelsLux[0] != 0) {
+ throw new IllegalArgumentException(
+ "The first lux value in the display brightness mapping must be 0");
+ }
+ } else {
mBrightnessLevelsNits = getFloatArray(mContext.getResources()
.obtainTypedArray(com.android.internal.R.array
.config_autoBrightnessDisplayValuesNits), PowerManager
@@ -2624,18 +2662,6 @@ public class DisplayDeviceConfig {
mBrightnessLevelsLux = getLuxLevels(mContext.getResources()
.getIntArray(com.android.internal.R.array
.config_autoBrightnessLevels));
- } else {
- final int size = autoBrightnessConfig.getDisplayBrightnessMapping()
- .getDisplayBrightnessPoint().size();
- mBrightnessLevelsNits = new float[size];
- // The first control point is implicit and always at 0 lux.
- mBrightnessLevelsLux = new float[size + 1];
- for (int i = 0; i < size; i++) {
- mBrightnessLevelsNits[i] = autoBrightnessConfig.getDisplayBrightnessMapping()
- .getDisplayBrightnessPoint().get(i).getNits().floatValue();
- mBrightnessLevelsLux[i + 1] = autoBrightnessConfig.getDisplayBrightnessMapping()
- .getDisplayBrightnessPoint().get(i).getLux().floatValue();
- }
}
}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 6a7c17d54980..2ab15e639d68 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -1853,7 +1853,7 @@ public final class DisplayManagerService extends SystemService {
// early apps like SetupWizard/Launcher. In particular, SUW is displayed using
// the virtual display inside VR before any VR-specific apps even run.
mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext,
- mHandler, mDisplayDeviceRepo);
+ mHandler, mDisplayDeviceRepo, mFlags);
if (mVirtualDisplayAdapter != null) {
registerDisplayAdapterLocked(mVirtualDisplayAdapter);
}
@@ -1871,7 +1871,7 @@ public final class DisplayManagerService extends SystemService {
private void registerOverlayDisplayAdapterLocked() {
registerDisplayAdapterLocked(new OverlayDisplayAdapter(
- mSyncRoot, mContext, mHandler, mDisplayDeviceRepo, mUiHandler));
+ mSyncRoot, mContext, mHandler, mDisplayDeviceRepo, mUiHandler, mFlags));
}
private void registerWifiDisplayAdapterLocked() {
@@ -1880,7 +1880,7 @@ public final class DisplayManagerService extends SystemService {
|| SystemProperties.getInt(FORCE_WIFI_DISPLAY_ENABLE, -1) == 1) {
mWifiDisplayAdapter = new WifiDisplayAdapter(
mSyncRoot, mContext, mHandler, mDisplayDeviceRepo,
- mPersistentDataStore);
+ mPersistentDataStore, mFlags);
registerDisplayAdapterLocked(mWifiDisplayAdapter);
}
}
@@ -3288,8 +3288,10 @@ public final class DisplayManagerService extends SystemService {
@VisibleForTesting
static class Injector {
VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context,
- Handler handler, DisplayAdapter.Listener displayAdapterListener) {
- return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener);
+ Handler handler, DisplayAdapter.Listener displayAdapterListener,
+ DisplayManagerFlags flags) {
+ return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener,
+ flags);
}
LocalDisplayAdapter getLocalDisplayAdapter(SyncRoot syncRoot, Context context,
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index ff9a1ab61b13..22898a65c5de 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -84,8 +84,6 @@ final class LocalDisplayAdapter extends DisplayAdapter {
private final boolean mIsBootDisplayModeSupported;
- private final DisplayManagerFlags mFlags;
-
private final DisplayNotificationManager mDisplayNotificationManager;
private Context mOverlayContext;
@@ -103,12 +101,11 @@ final class LocalDisplayAdapter extends DisplayAdapter {
Listener listener, DisplayManagerFlags flags,
DisplayNotificationManager displayNotificationManager,
Injector injector) {
- super(syncRoot, context, handler, listener, TAG);
+ super(syncRoot, context, handler, listener, TAG, flags);
mDisplayNotificationManager = displayNotificationManager;
mInjector = injector;
mSurfaceControlProxy = mInjector.getSurfaceControlProxy();
mIsBootDisplayModeSupported = mSurfaceControlProxy.getBootDisplayModeSupport();
- mFlags = flags;
}
@Override
@@ -510,7 +507,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
// Load display device config
final Context context = getOverlayContext();
mDisplayDeviceConfig = mInjector.createDisplayDeviceConfig(context, mPhysicalDisplayId,
- mIsFirstDisplay);
+ mIsFirstDisplay, getFeatureFlags());
// Load brightness HWC quirk
mBacklightAdapter.setForceSurfaceControl(mDisplayDeviceConfig.hasQuirk(
@@ -831,7 +828,8 @@ final class LocalDisplayAdapter extends DisplayAdapter {
+ ", state=" + Display.stateToString(state) + ")");
}
- boolean isDisplayOffloadEnabled = mFlags.isDisplayOffloadEnabled();
+ boolean isDisplayOffloadEnabled =
+ getFeatureFlags().isDisplayOffloadEnabled();
// We must tell sidekick/displayoffload to stop controlling the display
// before we can change its power mode, so do that first.
@@ -1377,8 +1375,8 @@ final class LocalDisplayAdapter extends DisplayAdapter {
}
public DisplayDeviceConfig createDisplayDeviceConfig(Context context,
- long physicalDisplayId, boolean isFirstDisplay) {
- return DisplayDeviceConfig.create(context, physicalDisplayId, isFirstDisplay);
+ long physicalDisplayId, boolean isFirstDisplay, DisplayManagerFlags flags) {
+ return DisplayDeviceConfig.create(context, physicalDisplayId, isFirstDisplay, flags);
}
}
diff --git a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
index 2ce7690ecc3f..22ff2d0eeffd 100644
--- a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
@@ -36,6 +36,7 @@ import android.view.SurfaceControl;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.display.feature.DisplayManagerFlags;
import com.android.server.display.mode.DisplayModeDirector;
import java.io.PrintWriter;
@@ -134,8 +135,9 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
// Called with SyncRoot lock held.
public OverlayDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
- Context context, Handler handler, Listener listener, Handler uiHandler) {
- super(syncRoot, context, handler, listener, TAG);
+ Context context, Handler handler, Listener listener, Handler uiHandler,
+ DisplayManagerFlags featureFlags) {
+ super(syncRoot, context, handler, listener, TAG, featureFlags);
mUiHandler = uiHandler;
}
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index edbd42465534..ec5ad7de11b3 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -61,6 +61,7 @@ import android.view.Surface;
import android.view.SurfaceControl;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.display.feature.DisplayManagerFlags;
import java.io.PrintWriter;
import java.util.concurrent.atomic.AtomicInteger;
@@ -88,7 +89,7 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
// Called with SyncRoot lock held.
public VirtualDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
- Context context, Handler handler, Listener listener) {
+ Context context, Handler handler, Listener listener, DisplayManagerFlags featureFlags) {
this(syncRoot, context, handler, listener, new SurfaceControlDisplayFactory() {
@Override
public IBinder createDisplay(String name, boolean secure, float requestedRefreshRate) {
@@ -99,14 +100,15 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
public void destroyDisplay(IBinder displayToken) {
DisplayControl.destroyDisplay(displayToken);
}
- });
+ }, featureFlags);
}
@VisibleForTesting
VirtualDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
Context context, Handler handler, Listener listener,
- SurfaceControlDisplayFactory surfaceControlDisplayFactory) {
- super(syncRoot, context, handler, listener, TAG);
+ SurfaceControlDisplayFactory surfaceControlDisplayFactory,
+ DisplayManagerFlags featureFlags) {
+ super(syncRoot, context, handler, listener, TAG, featureFlags);
mHandler = handler;
mSurfaceControlDisplayFactory = surfaceControlDisplayFactory;
}
diff --git a/services/core/java/com/android/server/display/WifiDisplayAdapter.java b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
index 7660cf8a1c3a..aa98cd85d38e 100644
--- a/services/core/java/com/android/server/display/WifiDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
@@ -41,6 +41,7 @@ import android.view.SurfaceControl;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.display.feature.DisplayManagerFlags;
import com.android.server.display.utils.DebugUtils;
import java.io.PrintWriter;
@@ -99,8 +100,8 @@ final class WifiDisplayAdapter extends DisplayAdapter {
// Called with SyncRoot lock held.
public WifiDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
Context context, Handler handler, Listener listener,
- PersistentDataStore persistentDataStore) {
- super(syncRoot, context, handler, listener, TAG);
+ PersistentDataStore persistentDataStore, DisplayManagerFlags featureFlags) {
+ super(syncRoot, context, handler, listener, TAG, featureFlags);
if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)) {
throw new RuntimeException("WiFi display was requested, "
diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
index eb8798406152..c71f0cf2dd91 100644
--- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
+++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
@@ -94,6 +94,10 @@ public class DisplayManagerFlags {
Flags.FLAG_BRIGHTNESS_WEAR_BEDTIME_MODE_CLAMPER,
Flags::brightnessWearBedtimeModeClamper);
+ private final FlagState mAutoBrightnessModesFlagState = new FlagState(
+ Flags.FLAG_AUTO_BRIGHTNESS_MODES,
+ Flags::autoBrightnessModes);
+
/** Returns whether connected display management is enabled or not. */
public boolean isConnectedDisplayManagementEnabled() {
return mConnectedDisplayManagementFlagState.isEnabled();
@@ -187,6 +191,13 @@ public class DisplayManagerFlags {
}
/**
+ * @return Whether generic auto-brightness modes are enabled
+ */
+ public boolean areAutoBrightnessModesEnabled() {
+ return mAutoBrightnessModesFlagState.isEnabled();
+ }
+
+ /**
* dumps all flagstates
* @param pw printWriter
*/
@@ -206,6 +217,7 @@ public class DisplayManagerFlags {
pw.println(" " + mBrightnessIntRangeUserPerceptionFlagState);
pw.println(" " + mVsyncProximityVote);
pw.println(" " + mBrightnessWearBedtimeModeClamperFlagState);
+ pw.println(" " + mAutoBrightnessModesFlagState);
}
private static class FlagState {
diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig
index 9dab76152dad..9dfa1ee41ad6 100644
--- a/services/core/java/com/android/server/display/feature/display_flags.aconfig
+++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig
@@ -128,3 +128,11 @@ flag {
bug: "293613040"
is_fixed_read_only: true
}
+
+flag {
+ name: "auto_brightness_modes"
+ namespace: "display_manager"
+ description: "Feature flag for generic auto-brightness modes"
+ bug: "293613040"
+ is_fixed_read_only: true
+}
diff --git a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
index 8eb03ec0d3bd..8fa838de3327 100644
--- a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
@@ -21,8 +21,8 @@ import static android.hardware.display.DisplayManagerInternal.REFRESH_RATE_LIMIT
import static android.os.PowerManager.BRIGHTNESS_INVALID_FLOAT;
import static android.view.Display.Mode.INVALID_MODE_ID;
-import static com.android.internal.display.RefreshRateSettingsUtils.findHighestRefreshRate;
import static com.android.server.display.DisplayDeviceConfig.DEFAULT_LOW_REFRESH_RATE;
+import static com.android.internal.display.RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay;
import android.annotation.IntegerRes;
import android.annotation.NonNull;
@@ -925,16 +925,11 @@ public class DisplayModeDirector {
}
@VisibleForTesting
- DisplayObserver getDisplayObserver() {
- return mDisplayObserver;
- }
-
- @VisibleForTesting
DesiredDisplayModeSpecs getDesiredDisplayModeSpecsWithInjectedFpsSettings(
float minRefreshRate, float peakRefreshRate, float defaultRefreshRate) {
synchronized (mLock) {
- mSettingsObserver.updateRefreshRateSettingLocked(minRefreshRate, peakRefreshRate,
- defaultRefreshRate, Display.DEFAULT_DISPLAY);
+ mSettingsObserver.updateRefreshRateSettingLocked(
+ minRefreshRate, peakRefreshRate, defaultRefreshRate);
return getDesiredDisplayModeSpecs(Display.DEFAULT_DISPLAY);
}
}
@@ -1268,23 +1263,9 @@ public class DisplayModeDirector {
mBrightnessObserver.onLowPowerModeEnabledLocked(inLowPowerMode);
}
- /**
- * Update refresh rate settings for all displays
- */
private void updateRefreshRateSettingLocked() {
- Display[] displays = mInjector.getDisplays();
- for (int i = 0; i < displays.length; i++) {
- updateRefreshRateSettingLocked(displays[i].getDisplayId());
- }
- }
-
- /**
- * Update refresh rate settings for a specific display
- * @param displayId The display ID
- */
- private void updateRefreshRateSettingLocked(int displayId) {
final ContentResolver cr = mContext.getContentResolver();
- float highestRefreshRate = findHighestRefreshRate(mContext, displayId);
+ float highestRefreshRate = findHighestRefreshRateForDefaultDisplay(mContext);
float minRefreshRate = Settings.System.getFloatForUser(cr,
Settings.System.MIN_REFRESH_RATE, 0f, cr.getUserId());
@@ -1312,12 +1293,11 @@ public class DisplayModeDirector {
}
}
- updateRefreshRateSettingLocked(minRefreshRate, peakRefreshRate, mDefaultRefreshRate,
- displayId);
+ updateRefreshRateSettingLocked(minRefreshRate, peakRefreshRate, mDefaultRefreshRate);
}
- private void updateRefreshRateSettingLocked(float minRefreshRate, float peakRefreshRate,
- float defaultRefreshRate, int displayId) {
+ private void updateRefreshRateSettingLocked(
+ float minRefreshRate, float peakRefreshRate, float defaultRefreshRate) {
// TODO(b/156304339): The logic in here, aside from updating the refresh rate votes, is
// used to predict if we're going to be doing frequent refresh rate switching, and if
// so, enable the brightness observer. The logic here is more complicated and fragile
@@ -1325,9 +1305,9 @@ public class DisplayModeDirector {
Vote peakVote = peakRefreshRate == 0f
? null
: Vote.forRenderFrameRates(0f, Math.max(minRefreshRate, peakRefreshRate));
- mVotesStorage.updateVote(displayId, Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE,
+ mVotesStorage.updateGlobalVote(Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE,
peakVote);
- mVotesStorage.updateVote(displayId, Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE,
+ mVotesStorage.updateGlobalVote(Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE,
Vote.forRenderFrameRates(minRefreshRate, Float.POSITIVE_INFINITY));
Vote defaultVote =
defaultRefreshRate == 0f
@@ -1484,8 +1464,7 @@ public class DisplayModeDirector {
}
}
- @VisibleForTesting
- public final class DisplayObserver implements DisplayManager.DisplayListener {
+ private final class DisplayObserver implements DisplayManager.DisplayListener {
// Note that we can never call into DisplayManager or any of the non-POD classes it
// returns, while holding mLock since it may call into DMS, which might be simultaneously
// calling into us already holding its own lock.
@@ -1577,7 +1556,6 @@ public class DisplayModeDirector {
updateDisplayModes(displayId, displayInfo);
updateLayoutLimitedFrameRate(displayId, displayInfo);
updateUserSettingDisplayPreferredSize(displayInfo);
- mSettingsObserver.updateRefreshRateSettingLocked(displayId);
}
@Nullable
diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
index 6f9b7d6328c7..27b01a5424b8 100644
--- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
@@ -67,6 +67,7 @@ import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationRequest;
import android.location.LocationResult;
+import android.location.flags.Flags;
import android.location.provider.ProviderProperties;
import android.location.provider.ProviderRequest;
import android.location.util.identity.CallerIdentity;
@@ -1048,10 +1049,22 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
stopBatching();
if (mStarted && mGnssNative.getCapabilities().hasScheduling()) {
- // change period and/or lowPowerMode
- if (!setPositionMode(mPositionMode, GNSS_POSITION_RECURRENCE_PERIODIC,
- mFixInterval, mProviderRequest.isLowPower())) {
- Log.e(TAG, "set_position_mode failed in updateRequirements");
+ if (Flags.gnssCallStopBeforeSetPositionMode()) {
+ GnssPositionMode positionMode = new GnssPositionMode(mPositionMode,
+ GNSS_POSITION_RECURRENCE_PERIODIC, mFixInterval,
+ /* preferredAccuracy= */ 0,
+ /* preferredTime= */ 0,
+ mProviderRequest.isLowPower());
+ if (!positionMode.equals(mLastPositionMode)) {
+ stopNavigating();
+ startNavigating();
+ }
+ } else {
+ // change period and/or lowPowerMode
+ if (!setPositionMode(mPositionMode, GNSS_POSITION_RECURRENCE_PERIODIC,
+ mFixInterval, mProviderRequest.isLowPower())) {
+ Log.e(TAG, "set_position_mode failed in updateRequirements");
+ }
}
} else if (!mStarted) {
// start GPS
@@ -1234,11 +1247,32 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
}
int interval = mGnssNative.getCapabilities().hasScheduling() ? mFixInterval : 1000;
- if (!setPositionMode(mPositionMode, GNSS_POSITION_RECURRENCE_PERIODIC,
- interval, mProviderRequest.isLowPower())) {
- setStarted(false);
- Log.e(TAG, "set_position_mode failed in startNavigating()");
- return;
+
+ if (Flags.gnssCallStopBeforeSetPositionMode()) {
+ boolean success = mGnssNative.setPositionMode(mPositionMode,
+ GNSS_POSITION_RECURRENCE_PERIODIC, interval,
+ /* preferredAccuracy= */ 0,
+ /* preferredTime= */ 0,
+ mProviderRequest.isLowPower());
+ if (success) {
+ mLastPositionMode = new GnssPositionMode(mPositionMode,
+ GNSS_POSITION_RECURRENCE_PERIODIC, interval,
+ /* preferredAccuracy= */ 0,
+ /* preferredTime= */ 0,
+ mProviderRequest.isLowPower());
+ } else {
+ mLastPositionMode = null;
+ setStarted(false);
+ Log.e(TAG, "set_position_mode failed in startNavigating()");
+ return;
+ }
+ } else {
+ if (!setPositionMode(mPositionMode, GNSS_POSITION_RECURRENCE_PERIODIC,
+ interval, mProviderRequest.isLowPower())) {
+ setStarted(false);
+ Log.e(TAG, "set_position_mode failed in startNavigating()");
+ return;
+ }
}
if (!mGnssNative.start()) {
setStarted(false);
diff --git a/services/core/java/com/android/server/media/AudioAttributesUtils.java b/services/core/java/com/android/server/media/AudioAttributesUtils.java
deleted file mode 100644
index 8cb334dc2260..000000000000
--- a/services/core/java/com/android/server/media/AudioAttributesUtils.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.media;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.media.AudioAttributes;
-import android.media.AudioDeviceAttributes;
-import android.media.AudioDeviceInfo;
-import android.media.MediaRoute2Info;
-
-import com.android.media.flags.Flags;
-
-/* package */ final class AudioAttributesUtils {
-
- /* package */ static final AudioAttributes ATTRIBUTES_MEDIA = new AudioAttributes.Builder()
- .setUsage(AudioAttributes.USAGE_MEDIA)
- .build();
-
- private AudioAttributesUtils() {
- // no-op to prevent instantiation.
- }
-
- @MediaRoute2Info.Type
- /* package */ static int mapToMediaRouteType(
- @NonNull AudioDeviceAttributes audioDeviceAttributes) {
- if (Flags.enableAudioPoliciesDeviceAndBluetoothController()) {
- switch (audioDeviceAttributes.getType()) {
- case AudioDeviceInfo.TYPE_HDMI_ARC:
- return MediaRoute2Info.TYPE_HDMI_ARC;
- case AudioDeviceInfo.TYPE_HDMI_EARC:
- return MediaRoute2Info.TYPE_HDMI_EARC;
- }
- }
- switch (audioDeviceAttributes.getType()) {
- case AudioDeviceInfo.TYPE_BUILTIN_EARPIECE:
- case AudioDeviceInfo.TYPE_BUILTIN_SPEAKER:
- return MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
- case AudioDeviceInfo.TYPE_WIRED_HEADSET:
- return MediaRoute2Info.TYPE_WIRED_HEADSET;
- case AudioDeviceInfo.TYPE_WIRED_HEADPHONES:
- return MediaRoute2Info.TYPE_WIRED_HEADPHONES;
- case AudioDeviceInfo.TYPE_DOCK:
- case AudioDeviceInfo.TYPE_DOCK_ANALOG:
- return MediaRoute2Info.TYPE_DOCK;
- case AudioDeviceInfo.TYPE_HDMI:
- case AudioDeviceInfo.TYPE_HDMI_ARC:
- case AudioDeviceInfo.TYPE_HDMI_EARC:
- return MediaRoute2Info.TYPE_HDMI;
- case AudioDeviceInfo.TYPE_USB_DEVICE:
- return MediaRoute2Info.TYPE_USB_DEVICE;
- case AudioDeviceInfo.TYPE_BLUETOOTH_A2DP:
- return MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
- case AudioDeviceInfo.TYPE_BLE_HEADSET:
- return MediaRoute2Info.TYPE_BLE_HEADSET;
- case AudioDeviceInfo.TYPE_HEARING_AID:
- return MediaRoute2Info.TYPE_HEARING_AID;
- default:
- return MediaRoute2Info.TYPE_UNKNOWN;
- }
- }
-
- /* package */ static boolean isDeviceOutputAttributes(
- @Nullable AudioDeviceAttributes audioDeviceAttributes) {
- if (audioDeviceAttributes == null) {
- return false;
- }
-
- if (audioDeviceAttributes.getRole() != AudioDeviceAttributes.ROLE_OUTPUT) {
- return false;
- }
-
- switch (audioDeviceAttributes.getType()) {
- case AudioDeviceInfo.TYPE_BUILTIN_EARPIECE:
- case AudioDeviceInfo.TYPE_BUILTIN_SPEAKER:
- case AudioDeviceInfo.TYPE_WIRED_HEADSET:
- case AudioDeviceInfo.TYPE_WIRED_HEADPHONES:
- case AudioDeviceInfo.TYPE_DOCK:
- case AudioDeviceInfo.TYPE_DOCK_ANALOG:
- case AudioDeviceInfo.TYPE_HDMI:
- case AudioDeviceInfo.TYPE_HDMI_ARC:
- case AudioDeviceInfo.TYPE_HDMI_EARC:
- case AudioDeviceInfo.TYPE_USB_DEVICE:
- return true;
- default:
- return false;
- }
- }
-
- /* package */ static boolean isBluetoothOutputAttributes(
- @Nullable AudioDeviceAttributes audioDeviceAttributes) {
- if (audioDeviceAttributes == null) {
- return false;
- }
-
- if (audioDeviceAttributes.getRole() != AudioDeviceAttributes.ROLE_OUTPUT) {
- return false;
- }
-
- switch (audioDeviceAttributes.getType()) {
- case AudioDeviceInfo.TYPE_BLUETOOTH_A2DP:
- case AudioDeviceInfo.TYPE_BLE_HEADSET:
- case AudioDeviceInfo.TYPE_BLE_SPEAKER:
- case AudioDeviceInfo.TYPE_HEARING_AID:
- return true;
- default:
- return false;
- }
- }
-
-}
diff --git a/services/core/java/com/android/server/media/AudioPoliciesBluetoothRouteController.java b/services/core/java/com/android/server/media/AudioPoliciesBluetoothRouteController.java
index 8bc69c226d1a..a00999d08b5b 100644
--- a/services/core/java/com/android/server/media/AudioPoliciesBluetoothRouteController.java
+++ b/services/core/java/com/android/server/media/AudioPoliciesBluetoothRouteController.java
@@ -17,7 +17,6 @@
package com.android.server.media;
import static android.bluetooth.BluetoothAdapter.ACTIVE_DEVICE_AUDIO;
-import static android.bluetooth.BluetoothAdapter.STATE_CONNECTED;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -31,38 +30,37 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.media.AudioManager;
-import android.media.AudioSystem;
import android.media.MediaRoute2Info;
import android.os.UserHandle;
import android.text.TextUtils;
+import android.util.Log;
import android.util.Slog;
import android.util.SparseBooleanArray;
-import android.util.SparseIntArray;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
/**
- * Controls bluetooth routes and provides selected route override.
+ * Maintains a list of connected {@link BluetoothDevice bluetooth devices} and allows their
+ * activation.
*
- * <p>The controller offers similar functionality to {@link LegacyBluetoothRouteController} but does
- * not support routes selection logic. Instead, relies on external clients to make a decision
- * about currently selected route.
- *
- * <p>Selected route override should be used by {@link AudioManager} which is aware of Audio
- * Policies.
+ * <p>This class also serves as ground truth for assigning {@link MediaRoute2Info#getId() route ids}
+ * for bluetooth routes via {@link #getRouteIdForBluetoothAddress}.
*/
-/* package */ class AudioPoliciesBluetoothRouteController
- implements BluetoothRouteController {
- private static final String TAG = "APBtRouteController";
+// TODO: b/305199571 - Rename this class to remove the RouteController suffix, which causes
+// confusion with the BluetoothRouteController interface.
+/* package */ class AudioPoliciesBluetoothRouteController {
+ private static final String TAG = SystemMediaRoute2Provider.TAG;
private static final String HEARING_AID_ROUTE_ID_PREFIX = "HEARING_AID_";
private static final String LE_AUDIO_ROUTE_ID_PREFIX = "LE_AUDIO_";
@@ -75,11 +73,8 @@ import java.util.Set;
private final DeviceStateChangedReceiver mDeviceStateChangedReceiver =
new DeviceStateChangedReceiver();
- @NonNull
- private final Map<String, BluetoothRouteInfo> mBluetoothRoutes = new HashMap<>();
-
- @NonNull
- private final SparseIntArray mVolumeMap = new SparseIntArray();
+ @NonNull private Map<String, BluetoothDevice> mAddressToBondedDevice = new HashMap<>();
+ @NonNull private final Map<String, BluetoothRouteInfo> mBluetoothRoutes = new HashMap<>();
@NonNull
private final Context mContext;
@@ -89,11 +84,6 @@ import java.util.Set;
private final BluetoothRouteController.BluetoothRoutesUpdatedListener mListener;
@NonNull
private final BluetoothProfileMonitor mBluetoothProfileMonitor;
- @NonNull
- private final AudioManager mAudioManager;
-
- @Nullable
- private BluetoothRouteInfo mSelectedBluetoothRoute;
AudioPoliciesBluetoothRouteController(@NonNull Context context,
@NonNull BluetoothAdapter bluetoothAdapter,
@@ -107,21 +97,12 @@ import java.util.Set;
@NonNull BluetoothAdapter bluetoothAdapter,
@NonNull BluetoothProfileMonitor bluetoothProfileMonitor,
@NonNull BluetoothRouteController.BluetoothRoutesUpdatedListener listener) {
- Objects.requireNonNull(context);
- Objects.requireNonNull(bluetoothAdapter);
- Objects.requireNonNull(bluetoothProfileMonitor);
- Objects.requireNonNull(listener);
-
- mContext = context;
- mBluetoothAdapter = bluetoothAdapter;
- mBluetoothProfileMonitor = bluetoothProfileMonitor;
- mAudioManager = mContext.getSystemService(AudioManager.class);
- mListener = listener;
-
- updateBluetoothRoutes();
+ mContext = Objects.requireNonNull(context);
+ mBluetoothAdapter = Objects.requireNonNull(bluetoothAdapter);
+ mBluetoothProfileMonitor = Objects.requireNonNull(bluetoothProfileMonitor);
+ mListener = Objects.requireNonNull(listener);
}
- @Override
public void start(UserHandle user) {
mBluetoothProfileMonitor.start();
@@ -133,122 +114,63 @@ import java.util.Set;
IntentFilter deviceStateChangedIntentFilter = new IntentFilter();
- deviceStateChangedIntentFilter.addAction(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED);
deviceStateChangedIntentFilter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
deviceStateChangedIntentFilter.addAction(BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED);
deviceStateChangedIntentFilter.addAction(
BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
deviceStateChangedIntentFilter.addAction(
BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED);
- deviceStateChangedIntentFilter.addAction(
- BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED);
mContext.registerReceiverAsUser(mDeviceStateChangedReceiver, user,
deviceStateChangedIntentFilter, null, null);
+ updateBluetoothRoutes();
}
- @Override
public void stop() {
mContext.unregisterReceiver(mAdapterStateChangedReceiver);
mContext.unregisterReceiver(mDeviceStateChangedReceiver);
}
- @Override
- public boolean selectRoute(@Nullable String deviceAddress) {
- synchronized (this) {
- // Fetch all available devices in order to avoid race conditions with Bluetooth stack.
- updateBluetoothRoutes();
-
- if (deviceAddress == null) {
- mSelectedBluetoothRoute = null;
- return true;
- }
-
- BluetoothRouteInfo bluetoothRouteInfo = mBluetoothRoutes.get(deviceAddress);
-
- if (bluetoothRouteInfo == null) {
- Slog.w(TAG, "Cannot find bluetooth route for " + deviceAddress);
- return false;
- }
-
- mSelectedBluetoothRoute = bluetoothRouteInfo;
- setRouteConnectionState(mSelectedBluetoothRoute, STATE_CONNECTED);
-
- updateConnectivityStateForDevicesInTheSameGroup();
-
- return true;
- }
- }
-
- /**
- * Updates connectivity state for devices in the same devices group.
- *
- * <p>{@link BluetoothProfile#LE_AUDIO} and {@link BluetoothProfile#HEARING_AID} support
- * grouping devices. Devices that belong to the same group should have the same routeId but
- * different physical address.
- *
- * <p>In case one of the devices from the group is selected then other devices should also
- * reflect this by changing their connectivity status to
- * {@link MediaRoute2Info#CONNECTION_STATE_CONNECTED}.
- */
- private void updateConnectivityStateForDevicesInTheSameGroup() {
- synchronized (this) {
- for (BluetoothRouteInfo btRoute : mBluetoothRoutes.values()) {
- if (TextUtils.equals(btRoute.mRoute.getId(), mSelectedBluetoothRoute.mRoute.getId())
- && !TextUtils.equals(btRoute.mBtDevice.getAddress(),
- mSelectedBluetoothRoute.mBtDevice.getAddress())) {
- setRouteConnectionState(btRoute, STATE_CONNECTED);
- }
- }
- }
+ @Nullable
+ public synchronized String getRouteIdForBluetoothAddress(@Nullable String address) {
+ BluetoothDevice bluetoothDevice = mAddressToBondedDevice.get(address);
+ // TODO: b/305199571 - Optimize the following statement to avoid creating the full
+ // MediaRoute2Info instance. We just need the id.
+ return bluetoothDevice != null
+ ? createBluetoothRoute(bluetoothDevice).mRoute.getId()
+ : null;
}
- @Override
- public void transferTo(@Nullable String routeId) {
- if (routeId == null) {
- mBluetoothAdapter.removeActiveDevice(ACTIVE_DEVICE_AUDIO);
- return;
- }
-
- BluetoothRouteInfo btRouteInfo = findBluetoothRouteWithRouteId(routeId);
+ public synchronized void activateBluetoothDeviceWithAddress(String address) {
+ BluetoothRouteInfo btRouteInfo = mBluetoothRoutes.get(address);
if (btRouteInfo == null) {
- Slog.w(TAG, "transferTo: Unknown route. ID=" + routeId);
+ Slog.w(TAG, "activateBluetoothDeviceWithAddress: Ignoring unknown address " + address);
return;
}
-
mBluetoothAdapter.setActiveDevice(btRouteInfo.mBtDevice, ACTIVE_DEVICE_AUDIO);
}
- @Nullable
- private BluetoothRouteInfo findBluetoothRouteWithRouteId(@Nullable String routeId) {
- if (routeId == null) {
- return null;
- }
- synchronized (this) {
- for (BluetoothRouteInfo btRouteInfo : mBluetoothRoutes.values()) {
- if (TextUtils.equals(btRouteInfo.mRoute.getId(), routeId)) {
- return btRouteInfo;
- }
- }
- }
- return null;
- }
-
private void updateBluetoothRoutes() {
Set<BluetoothDevice> bondedDevices = mBluetoothAdapter.getBondedDevices();
- if (bondedDevices == null) {
- return;
- }
-
synchronized (this) {
mBluetoothRoutes.clear();
-
- // We need to query all available to BT stack devices in order to avoid inconsistency
- // between external services, like, AndroidManager, and BT stack.
+ if (bondedDevices == null) {
+ // Bonded devices is null upon running into a BluetoothAdapter error.
+ Log.w(TAG, "BluetoothAdapter.getBondedDevices returned null.");
+ return;
+ }
+ // We don't clear bonded devices if we receive a null getBondedDevices result, because
+ // that probably means that the bluetooth stack ran into an issue. Not that all devices
+ // have been unpaired.
+ mAddressToBondedDevice =
+ bondedDevices.stream()
+ .collect(
+ Collectors.toMap(
+ BluetoothDevice::getAddress, Function.identity()));
for (BluetoothDevice device : bondedDevices) {
- if (isDeviceConnected(device)) {
+ if (device.isConnected()) {
BluetoothRouteInfo newBtRoute = createBluetoothRoute(device);
if (newBtRoute.mConnectedProfiles.size() > 0) {
mBluetoothRoutes.put(device.getAddress(), newBtRoute);
@@ -258,106 +180,51 @@ import java.util.Set;
}
}
- @VisibleForTesting
- /* package */ boolean isDeviceConnected(@NonNull BluetoothDevice device) {
- return device.isConnected();
- }
-
- @Nullable
- @Override
- public MediaRoute2Info getSelectedRoute() {
- synchronized (this) {
- if (mSelectedBluetoothRoute == null) {
- return null;
- }
-
- return mSelectedBluetoothRoute.mRoute;
- }
- }
-
@NonNull
- @Override
- public List<MediaRoute2Info> getTransferableRoutes() {
- List<MediaRoute2Info> routes = getAllBluetoothRoutes();
- synchronized (this) {
- if (mSelectedBluetoothRoute != null) {
- routes.remove(mSelectedBluetoothRoute.mRoute);
- }
- }
- return routes;
- }
-
- @NonNull
- @Override
- public List<MediaRoute2Info> getAllBluetoothRoutes() {
+ public List<MediaRoute2Info> getAvailableBluetoothRoutes() {
List<MediaRoute2Info> routes = new ArrayList<>();
- List<String> routeIds = new ArrayList<>();
-
- MediaRoute2Info selectedRoute = getSelectedRoute();
- if (selectedRoute != null) {
- routes.add(selectedRoute);
- routeIds.add(selectedRoute.getId());
- }
+ Set<String> routeIds = new HashSet<>();
synchronized (this) {
for (BluetoothRouteInfo btRoute : mBluetoothRoutes.values()) {
- // A pair of hearing aid devices or having the same hardware address
- if (routeIds.contains(btRoute.mRoute.getId())) {
- continue;
+ // See createBluetoothRoute for info on why we do this.
+ if (routeIds.add(btRoute.mRoute.getId())) {
+ routes.add(btRoute.mRoute);
}
- routes.add(btRoute.mRoute);
- routeIds.add(btRoute.mRoute.getId());
}
}
return routes;
}
- @Override
- public boolean updateVolumeForDevices(int devices, int volume) {
- int routeType;
- if ((devices & (AudioSystem.DEVICE_OUT_HEARING_AID)) != 0) {
- routeType = MediaRoute2Info.TYPE_HEARING_AID;
- } else if ((devices & (AudioManager.DEVICE_OUT_BLUETOOTH_A2DP
- | AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES
- | AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) != 0) {
- routeType = MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
- } else if ((devices & (AudioManager.DEVICE_OUT_BLE_HEADSET)) != 0) {
- routeType = MediaRoute2Info.TYPE_BLE_HEADSET;
- } else {
- return false;
- }
-
- synchronized (this) {
- mVolumeMap.put(routeType, volume);
- if (mSelectedBluetoothRoute == null
- || mSelectedBluetoothRoute.mRoute.getType() != routeType) {
- return false;
- }
-
- mSelectedBluetoothRoute.mRoute =
- new MediaRoute2Info.Builder(mSelectedBluetoothRoute.mRoute)
- .setVolume(volume)
- .build();
- }
-
- notifyBluetoothRoutesUpdated();
- return true;
- }
-
private void notifyBluetoothRoutesUpdated() {
mListener.onBluetoothRoutesUpdated();
}
+ /**
+ * Creates a new {@link BluetoothRouteInfo}, including its member {@link
+ * BluetoothRouteInfo#mRoute}.
+ *
+ * <p>The most important logic in this method is around the {@link MediaRoute2Info#getId() route
+ * id} assignment. In some cases we want to group multiple {@link BluetoothDevice bluetooth
+ * devices} as a single media route. For example, the left and right hearing aids get exposed as
+ * two different BluetoothDevice instances, but we want to show them as a single route. In this
+ * case, we assign the same route id to all "group" bluetooth devices (like left and right
+ * hearing aids), so that a single route is exposed for both of them.
+ *
+ * <p>Deduplication by id happens downstream because we need to be able to refer to all
+ * bluetooth devices individually, since the audio stack refers to a bluetooth device group by
+ * any of its member devices.
+ */
private BluetoothRouteInfo createBluetoothRoute(BluetoothDevice device) {
BluetoothRouteInfo
newBtRoute = new BluetoothRouteInfo();
newBtRoute.mBtDevice = device;
-
- String routeId = device.getAddress();
String deviceName = device.getName();
if (TextUtils.isEmpty(deviceName)) {
deviceName = mContext.getResources().getText(R.string.unknownName).toString();
}
+
+ String routeId = device.getAddress();
int type = MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
newBtRoute.mConnectedProfiles = new SparseBooleanArray();
if (mBluetoothProfileMonitor.isProfileSupported(BluetoothProfile.A2DP, device)) {
@@ -365,7 +232,6 @@ import java.util.Set;
}
if (mBluetoothProfileMonitor.isProfileSupported(BluetoothProfile.HEARING_AID, device)) {
newBtRoute.mConnectedProfiles.put(BluetoothProfile.HEARING_AID, true);
- // Intentionally assign the same ID for a pair of devices to publish only one of them.
routeId = HEARING_AID_ROUTE_ID_PREFIX
+ mBluetoothProfileMonitor.getGroupId(BluetoothProfile.HEARING_AID, device);
type = MediaRoute2Info.TYPE_HEARING_AID;
@@ -377,66 +243,27 @@ import java.util.Set;
type = MediaRoute2Info.TYPE_BLE_HEADSET;
}
- // Current volume will be set when connected.
- newBtRoute.mRoute = new MediaRoute2Info.Builder(routeId, deviceName)
- .addFeature(MediaRoute2Info.FEATURE_LIVE_AUDIO)
- .addFeature(MediaRoute2Info.FEATURE_LOCAL_PLAYBACK)
- .setConnectionState(MediaRoute2Info.CONNECTION_STATE_DISCONNECTED)
- .setDescription(mContext.getResources().getText(
- R.string.bluetooth_a2dp_audio_route_name).toString())
- .setType(type)
- .setVolumeHandling(MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE)
- .setVolumeMax(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC))
- .setAddress(device.getAddress())
- .build();
+ // Note that volume is only relevant for active bluetooth routes, and those are managed via
+ // AudioManager.
+ newBtRoute.mRoute =
+ new MediaRoute2Info.Builder(routeId, deviceName)
+ .addFeature(MediaRoute2Info.FEATURE_LIVE_AUDIO)
+ .addFeature(MediaRoute2Info.FEATURE_LOCAL_PLAYBACK)
+ .setConnectionState(MediaRoute2Info.CONNECTION_STATE_DISCONNECTED)
+ .setDescription(
+ mContext.getResources()
+ .getText(R.string.bluetooth_a2dp_audio_route_name)
+ .toString())
+ .setType(type)
+ .setAddress(device.getAddress())
+ .build();
return newBtRoute;
}
- private void setRouteConnectionState(@NonNull BluetoothRouteInfo btRoute,
- @MediaRoute2Info.ConnectionState int state) {
- if (btRoute == null) {
- Slog.w(TAG, "setRouteConnectionState: route shouldn't be null");
- return;
- }
- if (btRoute.mRoute.getConnectionState() == state) {
- return;
- }
-
- MediaRoute2Info.Builder builder = new MediaRoute2Info.Builder(btRoute.mRoute)
- .setConnectionState(state);
- builder.setType(btRoute.getRouteType());
-
-
-
- if (state == MediaRoute2Info.CONNECTION_STATE_CONNECTED) {
- int currentVolume;
- synchronized (this) {
- currentVolume = mVolumeMap.get(btRoute.getRouteType(), 0);
- }
- builder.setVolume(currentVolume);
- }
-
- btRoute.mRoute = builder.build();
- }
-
private static class BluetoothRouteInfo {
private BluetoothDevice mBtDevice;
private MediaRoute2Info mRoute;
private SparseBooleanArray mConnectedProfiles;
-
- @MediaRoute2Info.Type
- int getRouteType() {
- // Let hearing aid profile have a priority.
- if (mConnectedProfiles.get(BluetoothProfile.HEARING_AID, false)) {
- return MediaRoute2Info.TYPE_HEARING_AID;
- }
-
- if (mConnectedProfiles.get(BluetoothProfile.LE_AUDIO, false)) {
- return MediaRoute2Info.TYPE_BLE_HEADSET;
- }
-
- return MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
- }
}
private class AdapterStateChangedReceiver extends BroadcastReceiver {
@@ -468,9 +295,6 @@ import java.util.Set;
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
- case BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED:
- case BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED:
- case BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED:
case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
case BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED:
case BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED:
diff --git a/services/core/java/com/android/server/media/AudioPoliciesDeviceRouteController.java b/services/core/java/com/android/server/media/AudioPoliciesDeviceRouteController.java
index 6bdfae2dc02f..27df00f30531 100644
--- a/services/core/java/com/android/server/media/AudioPoliciesDeviceRouteController.java
+++ b/services/core/java/com/android/server/media/AudioPoliciesDeviceRouteController.java
@@ -17,228 +17,590 @@
package com.android.server.media;
import static android.media.MediaRoute2Info.FEATURE_LIVE_AUDIO;
-import static android.media.MediaRoute2Info.FEATURE_LIVE_VIDEO;
import static android.media.MediaRoute2Info.FEATURE_LOCAL_PLAYBACK;
-import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
-import static android.media.MediaRoute2Info.TYPE_DOCK;
-import static android.media.MediaRoute2Info.TYPE_HDMI;
-import static android.media.MediaRoute2Info.TYPE_HDMI_ARC;
-import static android.media.MediaRoute2Info.TYPE_HDMI_EARC;
-import static android.media.MediaRoute2Info.TYPE_USB_DEVICE;
-import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES;
-import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET;
+import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
import android.content.Context;
+import android.media.AudioAttributes;
+import android.media.AudioDeviceAttributes;
+import android.media.AudioDeviceCallback;
+import android.media.AudioDeviceInfo;
import android.media.AudioManager;
-import android.media.AudioRoutesInfo;
-import android.media.IAudioRoutesObserver;
-import android.media.IAudioService;
import android.media.MediaRoute2Info;
-import android.os.RemoteException;
+import android.media.audiopolicy.AudioProductStrategy;
+import android.os.Handler;
+import android.os.HandlerExecutor;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.text.TextUtils;
import android.util.Slog;
+import android.util.SparseArray;
import com.android.internal.R;
-import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.media.BluetoothRouteController.NoOpBluetoothRouteController;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import java.util.Objects;
+/**
+ * Maintains a list of all available routes and supports transfers to any of them.
+ *
+ * <p>This implementation is intended for use in conjunction with {@link
+ * NoOpBluetoothRouteController}, as it manages bluetooth devices directly.
+ *
+ * <p>This implementation obtains and manages all routes via {@link AudioManager}, with the
+ * exception of {@link AudioManager#handleBluetoothActiveDeviceChanged inactive bluetooth} routes
+ * which are managed by {@link AudioPoliciesBluetoothRouteController}, which depends on the
+ * bluetooth stack (for example {@link BluetoothAdapter}.
+ */
+// TODO: b/305199571 - Rename this class to avoid the AudioPolicies prefix, which has been flagged
+// by the audio team as a confusing name.
/* package */ final class AudioPoliciesDeviceRouteController implements DeviceRouteController {
+ private static final String TAG = SystemMediaRoute2Provider.TAG;
- private static final String TAG = "APDeviceRoutesController";
-
- @NonNull
- private final Context mContext;
@NonNull
- private final AudioManager mAudioManager;
- @NonNull
- private final IAudioService mAudioService;
+ private static final AudioAttributes MEDIA_USAGE_AUDIO_ATTRIBUTES =
+ new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build();
@NonNull
- private final OnDeviceRouteChangedListener mOnDeviceRouteChangedListener;
- @NonNull
- private final AudioRoutesObserver mAudioRoutesObserver = new AudioRoutesObserver();
+ private static final SparseArray<SystemRouteInfo> AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO =
+ new SparseArray<>();
- private int mDeviceVolume;
+ @NonNull private final Context mContext;
+ @NonNull private final AudioManager mAudioManager;
+ @NonNull private final Handler mHandler;
+ @NonNull private final OnDeviceRouteChangedListener mOnDeviceRouteChangedListener;
+ @NonNull private final AudioPoliciesBluetoothRouteController mBluetoothRouteController;
@NonNull
- private MediaRoute2Info mDeviceRoute;
- @Nullable
- private MediaRoute2Info mSelectedRoute;
+ private final Map<String, MediaRoute2InfoHolder> mRouteIdToAvailableDeviceRoutes =
+ new HashMap<>();
+
+ @NonNull private final AudioProductStrategy mStrategyForMedia;
- @VisibleForTesting
- /* package */ AudioPoliciesDeviceRouteController(@NonNull Context context,
+ @NonNull private final AudioDeviceCallback mAudioDeviceCallback = new AudioDeviceCallbackImpl();
+
+ @NonNull
+ private final AudioManager.OnDevicesForAttributesChangedListener
+ mOnDevicesForAttributesChangedListener = this::onDevicesForAttributesChangedListener;
+
+ @NonNull private MediaRoute2Info mSelectedRoute;
+
+ // TODO: b/305199571 - Support nullable btAdapter and strategyForMedia which, when null, means
+ // no support for transferring to inactive bluetooth routes and transferring to any routes
+ // respectively.
+ @RequiresPermission(
+ anyOf = {
+ Manifest.permission.MODIFY_AUDIO_ROUTING,
+ Manifest.permission.QUERY_AUDIO_STATE
+ })
+ /* package */ AudioPoliciesDeviceRouteController(
+ @NonNull Context context,
@NonNull AudioManager audioManager,
- @NonNull IAudioService audioService,
+ @NonNull Looper looper,
+ @NonNull AudioProductStrategy strategyForMedia,
+ @NonNull BluetoothAdapter btAdapter,
@NonNull OnDeviceRouteChangedListener onDeviceRouteChangedListener) {
- Objects.requireNonNull(context);
- Objects.requireNonNull(audioManager);
- Objects.requireNonNull(audioService);
- Objects.requireNonNull(onDeviceRouteChangedListener);
+ mContext = Objects.requireNonNull(context);
+ mAudioManager = Objects.requireNonNull(audioManager);
+ mHandler = new Handler(Objects.requireNonNull(looper));
+ mStrategyForMedia = Objects.requireNonNull(strategyForMedia);
+ mOnDeviceRouteChangedListener = Objects.requireNonNull(onDeviceRouteChangedListener);
+ mBluetoothRouteController =
+ new AudioPoliciesBluetoothRouteController(
+ mContext, btAdapter, this::rebuildAvailableRoutes);
+ rebuildAvailableRoutes();
+ }
- mContext = context;
- mOnDeviceRouteChangedListener = onDeviceRouteChangedListener;
+ @RequiresPermission(
+ anyOf = {
+ Manifest.permission.MODIFY_AUDIO_ROUTING,
+ Manifest.permission.QUERY_AUDIO_STATE
+ })
+ @Override
+ public void start(UserHandle mUser) {
+ mBluetoothRouteController.start(mUser);
+ mAudioManager.registerAudioDeviceCallback(mAudioDeviceCallback, mHandler);
+ mAudioManager.addOnDevicesForAttributesChangedListener(
+ AudioRoutingUtils.ATTRIBUTES_MEDIA,
+ new HandlerExecutor(mHandler),
+ mOnDevicesForAttributesChangedListener);
+ }
- mAudioManager = audioManager;
- mAudioService = audioService;
+ @RequiresPermission(
+ anyOf = {
+ Manifest.permission.MODIFY_AUDIO_ROUTING,
+ Manifest.permission.QUERY_AUDIO_STATE
+ })
+ @Override
+ public void stop() {
+ mAudioManager.removeOnDevicesForAttributesChangedListener(
+ mOnDevicesForAttributesChangedListener);
+ mAudioManager.unregisterAudioDeviceCallback(mAudioDeviceCallback);
+ mBluetoothRouteController.stop();
+ mHandler.removeCallbacksAndMessages(/* token= */ null);
+ }
- AudioRoutesInfo newAudioRoutes = null;
- try {
- newAudioRoutes = mAudioService.startWatchingRoutes(mAudioRoutesObserver);
- } catch (RemoteException e) {
- Slog.w(TAG, "Cannot connect to audio service to start listen to routes", e);
- }
+ @Override
+ @NonNull
+ public synchronized MediaRoute2Info getSelectedRoute() {
+ return mSelectedRoute;
+ }
- mDeviceRoute = createRouteFromAudioInfo(newAudioRoutes);
+ @Override
+ @NonNull
+ public synchronized List<MediaRoute2Info> getAvailableRoutes() {
+ return mRouteIdToAvailableDeviceRoutes.values().stream()
+ .map(it -> it.mMediaRoute2Info)
+ .toList();
}
+ @RequiresPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)
@Override
- public synchronized boolean selectRoute(@Nullable Integer type) {
- if (type == null) {
- mSelectedRoute = null;
- return true;
+ public synchronized void transferTo(@Nullable String routeId) {
+ if (routeId == null) {
+ // This should never happen: This branch should only execute when the matching bluetooth
+ // route controller is not the no-op one.
+ // TODO: b/305199571 - Make routeId non-null and remove this branch once we remove the
+ // legacy route controller implementations.
+ Slog.e(TAG, "Unexpected call to AudioPoliciesDeviceRouteController#transferTo(null)");
+ return;
}
-
- if (!isDeviceRouteType(type)) {
- return false;
+ MediaRoute2InfoHolder mediaRoute2InfoHolder = mRouteIdToAvailableDeviceRoutes.get(routeId);
+ if (mediaRoute2InfoHolder == null) {
+ Slog.w(TAG, "transferTo: Ignoring transfer request to unknown route id : " + routeId);
+ return;
+ }
+ if (mediaRoute2InfoHolder.mCorrespondsToInactiveBluetoothRoute) {
+ // By default, the last connected device is the active route so we don't need to apply a
+ // routing audio policy.
+ mBluetoothRouteController.activateBluetoothDeviceWithAddress(
+ mediaRoute2InfoHolder.mMediaRoute2Info.getAddress());
+ mAudioManager.removePreferredDeviceForStrategy(mStrategyForMedia);
+ } else {
+ AudioDeviceAttributes attr =
+ new AudioDeviceAttributes(
+ AudioDeviceAttributes.ROLE_OUTPUT,
+ mediaRoute2InfoHolder.mAudioDeviceInfoType,
+ /* address= */ ""); // This is not a BT device, hence no address needed.
+ mAudioManager.setPreferredDeviceForStrategy(mStrategyForMedia, attr);
}
+ }
- mSelectedRoute = createRouteFromAudioInfo(type);
+ @RequiresPermission(
+ anyOf = {
+ Manifest.permission.MODIFY_AUDIO_ROUTING,
+ Manifest.permission.QUERY_AUDIO_STATE
+ })
+ @Override
+ public synchronized boolean updateVolume(int volume) {
+ // TODO: b/305199571 - Optimize so that we only update the volume of the selected route. We
+ // don't need to rebuild all available routes.
+ rebuildAvailableRoutes();
return true;
}
- @Override
- @NonNull
- public synchronized MediaRoute2Info getSelectedRoute() {
- if (mSelectedRoute != null) {
- return mSelectedRoute;
+ @RequiresPermission(
+ anyOf = {
+ Manifest.permission.MODIFY_AUDIO_ROUTING,
+ Manifest.permission.QUERY_AUDIO_STATE
+ })
+ private void onDevicesForAttributesChangedListener(
+ AudioAttributes attributes, List<AudioDeviceAttributes> unusedAudioDeviceAttributes) {
+ if (attributes.getUsage() == AudioAttributes.USAGE_MEDIA) {
+ // We only care about the media usage. Ignore everything else.
+ rebuildAvailableRoutes();
}
- return mDeviceRoute;
}
- @Override
- public synchronized boolean updateVolume(int volume) {
- if (mDeviceVolume == volume) {
- return false;
+ @RequiresPermission(
+ anyOf = {
+ Manifest.permission.MODIFY_AUDIO_ROUTING,
+ Manifest.permission.QUERY_AUDIO_STATE
+ })
+ private synchronized void rebuildAvailableRoutes() {
+ List<AudioDeviceAttributes> attributesOfSelectedOutputDevices =
+ mAudioManager.getDevicesForAttributes(MEDIA_USAGE_AUDIO_ATTRIBUTES);
+ int selectedDeviceAttributesType;
+ if (attributesOfSelectedOutputDevices.isEmpty()) {
+ Slog.e(
+ TAG,
+ "Unexpected empty list of output devices for media. Using built-in speakers.");
+ selectedDeviceAttributesType = AudioDeviceInfo.TYPE_BUILTIN_SPEAKER;
+ } else {
+ if (attributesOfSelectedOutputDevices.size() > 1) {
+ Slog.w(
+ TAG,
+ "AudioManager.getDevicesForAttributes returned more than one element. Using"
+ + " the first one.");
+ }
+ selectedDeviceAttributesType = attributesOfSelectedOutputDevices.get(0).getType();
}
- mDeviceVolume = volume;
-
- if (mSelectedRoute != null) {
- mSelectedRoute = new MediaRoute2Info.Builder(mSelectedRoute)
- .setVolume(volume)
- .build();
+ AudioDeviceInfo[] audioDeviceInfos =
+ mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
+ mRouteIdToAvailableDeviceRoutes.clear();
+ MediaRoute2InfoHolder newSelectedRouteHolder = null;
+ for (AudioDeviceInfo audioDeviceInfo : audioDeviceInfos) {
+ MediaRoute2Info mediaRoute2Info =
+ createMediaRoute2InfoFromAudioDeviceInfo(audioDeviceInfo);
+ // Null means audioDeviceInfo is not a supported media output, like a phone's builtin
+ // earpiece. We ignore those.
+ if (mediaRoute2Info != null) {
+ int audioDeviceInfoType = audioDeviceInfo.getType();
+ MediaRoute2InfoHolder newHolder =
+ MediaRoute2InfoHolder.createForAudioManagerRoute(
+ mediaRoute2Info, audioDeviceInfoType);
+ mRouteIdToAvailableDeviceRoutes.put(mediaRoute2Info.getId(), newHolder);
+ if (selectedDeviceAttributesType == audioDeviceInfoType) {
+ newSelectedRouteHolder = newHolder;
+ }
+ }
}
- mDeviceRoute = new MediaRoute2Info.Builder(mDeviceRoute)
- .setVolume(volume)
- .build();
+ if (mRouteIdToAvailableDeviceRoutes.isEmpty()) {
+ // Due to an unknown reason (possibly an audio server crash), we ended up with an empty
+ // list of routes. Our entire codebase assumes at least one system route always exists,
+ // so we create a placeholder route represented as a built-in speaker for
+ // user-presentation purposes.
+ Slog.e(TAG, "Ended up with an empty list of routes. Creating a placeholder route.");
+ MediaRoute2InfoHolder placeholderRouteHolder = createPlaceholderBuiltinSpeakerRoute();
+ String placeholderRouteId = placeholderRouteHolder.mMediaRoute2Info.getId();
+ mRouteIdToAvailableDeviceRoutes.put(placeholderRouteId, placeholderRouteHolder);
+ }
- return true;
+ if (newSelectedRouteHolder == null) {
+ Slog.e(
+ TAG,
+ "Could not map this selected device attribute type to an available route: "
+ + selectedDeviceAttributesType);
+ // We know mRouteIdToAvailableDeviceRoutes is not empty.
+ newSelectedRouteHolder = mRouteIdToAvailableDeviceRoutes.values().iterator().next();
+ }
+ MediaRoute2InfoHolder selectedRouteHolderWithUpdatedVolumeInfo =
+ newSelectedRouteHolder.copyWithVolumeInfoFromAudioManager(mAudioManager);
+ mRouteIdToAvailableDeviceRoutes.put(
+ newSelectedRouteHolder.mMediaRoute2Info.getId(),
+ selectedRouteHolderWithUpdatedVolumeInfo);
+ mSelectedRoute = selectedRouteHolderWithUpdatedVolumeInfo.mMediaRoute2Info;
+
+ // We only add those BT routes that we have not already obtained from audio manager (which
+ // are active).
+ mBluetoothRouteController.getAvailableBluetoothRoutes().stream()
+ .filter(it -> !mRouteIdToAvailableDeviceRoutes.containsKey(it.getId()))
+ .map(MediaRoute2InfoHolder::createForInactiveBluetoothRoute)
+ .forEach(
+ it -> mRouteIdToAvailableDeviceRoutes.put(it.mMediaRoute2Info.getId(), it));
+ mOnDeviceRouteChangedListener.onDeviceRouteChanged();
}
- @NonNull
- private MediaRoute2Info createRouteFromAudioInfo(@Nullable AudioRoutesInfo newRoutes) {
- int type = TYPE_BUILTIN_SPEAKER;
-
- if (newRoutes != null) {
- if ((newRoutes.mainType & AudioRoutesInfo.MAIN_HEADPHONES) != 0) {
- type = TYPE_WIRED_HEADPHONES;
- } else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_HEADSET) != 0) {
- type = TYPE_WIRED_HEADSET;
- } else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_DOCK_SPEAKERS) != 0) {
- type = TYPE_DOCK;
- } else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_HDMI) != 0) {
- type = TYPE_HDMI;
- } else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_USB) != 0) {
- type = TYPE_USB_DEVICE;
- }
- }
+ private MediaRoute2InfoHolder createPlaceholderBuiltinSpeakerRoute() {
+ int type = AudioDeviceInfo.TYPE_BUILTIN_SPEAKER;
+ return MediaRoute2InfoHolder.createForAudioManagerRoute(
+ createMediaRoute2Info(
+ /* routeId= */ null, type, /* productName= */ null, /* address= */ null),
+ type);
+ }
- return createRouteFromAudioInfo(type);
+ @Nullable
+ private MediaRoute2Info createMediaRoute2InfoFromAudioDeviceInfo(
+ AudioDeviceInfo audioDeviceInfo) {
+ String address = audioDeviceInfo.getAddress();
+ // Passing a null route id means we want to get the default id for the route. Generally, we
+ // only expect to pass null for non-Bluetooth routes.
+ String routeId =
+ TextUtils.isEmpty(address)
+ ? null
+ : mBluetoothRouteController.getRouteIdForBluetoothAddress(address);
+ return createMediaRoute2Info(
+ routeId, audioDeviceInfo.getType(), audioDeviceInfo.getProductName(), address);
}
- @NonNull
- private MediaRoute2Info createRouteFromAudioInfo(@MediaRoute2Info.Type int type) {
- int name = R.string.default_audio_route_name;
- switch (type) {
- case TYPE_WIRED_HEADPHONES:
- case TYPE_WIRED_HEADSET:
- name = R.string.default_audio_route_name_headphones;
- break;
- case TYPE_DOCK:
- name = R.string.default_audio_route_name_dock_speakers;
- break;
- case TYPE_HDMI:
- case TYPE_HDMI_ARC:
- case TYPE_HDMI_EARC:
- name = R.string.default_audio_route_name_external_device;
- break;
- case TYPE_USB_DEVICE:
- name = R.string.default_audio_route_name_usb;
- break;
- }
-
- synchronized (this) {
- return new MediaRoute2Info.Builder(
- MediaRoute2Info.ROUTE_ID_DEVICE,
- mContext.getResources().getText(name).toString())
- .setVolumeHandling(
- mAudioManager.isVolumeFixed()
- ? MediaRoute2Info.PLAYBACK_VOLUME_FIXED
- : MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE)
- .setVolume(mDeviceVolume)
- .setVolumeMax(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC))
- .setType(type)
- .addFeature(FEATURE_LIVE_AUDIO)
- .addFeature(FEATURE_LIVE_VIDEO)
- .addFeature(FEATURE_LOCAL_PLAYBACK)
- .setConnectionState(MediaRoute2Info.CONNECTION_STATE_CONNECTED)
- .build();
+ /**
+ * Creates a new {@link MediaRoute2Info} using the provided information.
+ *
+ * @param routeId A route id, or null to use an id pre-defined for the given {@code type}.
+ * @param audioDeviceInfoType The type as obtained from {@link AudioDeviceInfo#getType}.
+ * @param productName The product name as obtained from {@link
+ * AudioDeviceInfo#getProductName()}, or null to use a predefined name for the given {@code
+ * type}.
+ * @param address The type as obtained from {@link AudioDeviceInfo#getAddress()} or {@link
+ * BluetoothDevice#getAddress()}.
+ * @return The new {@link MediaRoute2Info}.
+ */
+ @Nullable
+ private MediaRoute2Info createMediaRoute2Info(
+ @Nullable String routeId,
+ int audioDeviceInfoType,
+ @Nullable CharSequence productName,
+ @Nullable String address) {
+ SystemRouteInfo systemRouteInfo =
+ AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.get(audioDeviceInfoType);
+ if (systemRouteInfo == null) {
+ // Device type that's intentionally unsupported for media output, like the built-in
+ // earpiece.
+ return null;
+ }
+ CharSequence humanReadableName = productName;
+ if (TextUtils.isEmpty(humanReadableName)) {
+ humanReadableName = mContext.getResources().getText(systemRouteInfo.mNameResource);
+ }
+ if (routeId == null) {
+ // The caller hasn't provided an id, so we use a pre-defined one. This happens when we
+ // are creating a non-BT route, or we are creating a BT route but a race condition
+ // caused AudioManager to expose the BT route before BluetoothAdapter, preventing us
+ // from getting an id using BluetoothRouteController#getRouteIdForBluetoothAddress.
+ routeId = systemRouteInfo.mDefaultRouteId;
}
+ return new MediaRoute2Info.Builder(routeId, humanReadableName)
+ .setType(systemRouteInfo.mMediaRoute2InfoType)
+ .setAddress(address)
+ .setSystemRoute(true)
+ .addFeature(FEATURE_LIVE_AUDIO)
+ .addFeature(FEATURE_LOCAL_PLAYBACK)
+ .setConnectionState(MediaRoute2Info.CONNECTION_STATE_CONNECTED)
+ .build();
}
/**
- * Checks if the given type is a device route.
- *
- * <p>Device route means a route which is either built-in or wired to the current device.
- *
- * @param type specifies the type of the device.
- * @return {@code true} if the device is wired or built-in and {@code false} otherwise.
+ * Holds a {@link MediaRoute2Info} and associated information that we don't want to put in the
+ * {@link MediaRoute2Info} class because it's solely necessary for the implementation of this
+ * class.
*/
- private boolean isDeviceRouteType(@MediaRoute2Info.Type int type) {
- switch (type) {
- case TYPE_BUILTIN_SPEAKER:
- case TYPE_WIRED_HEADPHONES:
- case TYPE_WIRED_HEADSET:
- case TYPE_DOCK:
- case TYPE_HDMI:
- case TYPE_HDMI_ARC:
- case TYPE_HDMI_EARC:
- case TYPE_USB_DEVICE:
- return true;
- default:
- return false;
+ private static class MediaRoute2InfoHolder {
+
+ public final MediaRoute2Info mMediaRoute2Info;
+ public final int mAudioDeviceInfoType;
+ public final boolean mCorrespondsToInactiveBluetoothRoute;
+
+ public static MediaRoute2InfoHolder createForAudioManagerRoute(
+ MediaRoute2Info mediaRoute2Info, int audioDeviceInfoType) {
+ return new MediaRoute2InfoHolder(
+ mediaRoute2Info,
+ audioDeviceInfoType,
+ /* correspondsToInactiveBluetoothRoute= */ false);
+ }
+
+ public static MediaRoute2InfoHolder createForInactiveBluetoothRoute(
+ MediaRoute2Info mediaRoute2Info) {
+ // There's no corresponding audio device info, hence the audio device info type is
+ // unknown.
+ return new MediaRoute2InfoHolder(
+ mediaRoute2Info,
+ /* audioDeviceInfoType= */ AudioDeviceInfo.TYPE_UNKNOWN,
+ /* correspondsToInactiveBluetoothRoute= */ true);
+ }
+
+ private MediaRoute2InfoHolder(
+ MediaRoute2Info mediaRoute2Info,
+ int audioDeviceInfoType,
+ boolean correspondsToInactiveBluetoothRoute) {
+ mMediaRoute2Info = mediaRoute2Info;
+ mAudioDeviceInfoType = audioDeviceInfoType;
+ mCorrespondsToInactiveBluetoothRoute = correspondsToInactiveBluetoothRoute;
+ }
+
+ public MediaRoute2InfoHolder copyWithVolumeInfoFromAudioManager(
+ AudioManager mAudioManager) {
+ MediaRoute2Info routeInfoWithVolumeInfo =
+ new MediaRoute2Info.Builder(mMediaRoute2Info)
+ .setVolumeHandling(
+ mAudioManager.isVolumeFixed()
+ ? MediaRoute2Info.PLAYBACK_VOLUME_FIXED
+ : MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE)
+ .setVolume(mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC))
+ .setVolumeMax(
+ mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC))
+ .build();
+ return new MediaRoute2InfoHolder(
+ routeInfoWithVolumeInfo,
+ mAudioDeviceInfoType,
+ mCorrespondsToInactiveBluetoothRoute);
}
}
- private class AudioRoutesObserver extends IAudioRoutesObserver.Stub {
+ /**
+ * Holds route information about an {@link AudioDeviceInfo#getType() audio device info type}.
+ */
+ private static class SystemRouteInfo {
+ /** The type to use for {@link MediaRoute2Info#getType()}. */
+ public final int mMediaRoute2InfoType;
+
+ /**
+ * Holds the route id to use if no other id is provided.
+ *
+ * <p>We only expect this id to be used for non-bluetooth routes. For bluetooth routes, in a
+ * normal scenario, the id is generated from the device information (like address, or
+ * hiSyncId), and this value is ignored. A non-normal scenario may occur when there's race
+ * condition between {@link BluetoothAdapter} and {@link AudioManager}, who are not
+ * synchronized.
+ */
+ public final String mDefaultRouteId;
+
+ /**
+ * The name to use for {@link MediaRoute2Info#getName()}.
+ *
+ * <p>Usually replaced by the UI layer with a localized string.
+ */
+ public final int mNameResource;
+
+ private SystemRouteInfo(int mediaRoute2InfoType, String defaultRouteId, int nameResource) {
+ mMediaRoute2InfoType = mediaRoute2InfoType;
+ mDefaultRouteId = defaultRouteId;
+ mNameResource = nameResource;
+ }
+ }
+ private class AudioDeviceCallbackImpl extends AudioDeviceCallback {
+ @RequiresPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)
@Override
- public void dispatchAudioRoutesChanged(AudioRoutesInfo newAudioRoutes) {
- boolean isDeviceRouteChanged;
- MediaRoute2Info deviceRoute = createRouteFromAudioInfo(newAudioRoutes);
-
- synchronized (AudioPoliciesDeviceRouteController.this) {
- mDeviceRoute = deviceRoute;
- isDeviceRouteChanged = mSelectedRoute == null;
+ public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
+ for (AudioDeviceInfo deviceInfo : addedDevices) {
+ if (AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.contains(deviceInfo.getType())) {
+ // When a new valid media output is connected, we clear any routing policies so
+ // that the default routing logic from the audio framework kicks in. As a result
+ // of this, when the user connects a bluetooth device or a wired headset, the
+ // new device becomes the active route, which is the traditional behavior.
+ mAudioManager.removePreferredDeviceForStrategy(mStrategyForMedia);
+ rebuildAvailableRoutes();
+ break;
+ }
}
+ }
- if (isDeviceRouteChanged) {
- mOnDeviceRouteChangedListener.onDeviceRouteChanged();
+ @RequiresPermission(
+ anyOf = {
+ Manifest.permission.MODIFY_AUDIO_ROUTING,
+ Manifest.permission.QUERY_AUDIO_STATE
+ })
+ @Override
+ public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
+ for (AudioDeviceInfo deviceInfo : removedDevices) {
+ if (AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.contains(deviceInfo.getType())) {
+ rebuildAvailableRoutes();
+ break;
+ }
}
}
}
+ static {
+ AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+ AudioDeviceInfo.TYPE_BUILTIN_SPEAKER,
+ new SystemRouteInfo(
+ MediaRoute2Info.TYPE_BUILTIN_SPEAKER,
+ /* defaultRouteId= */ "ROUTE_ID_BUILTIN_SPEAKER",
+ /* nameResource= */ R.string.default_audio_route_name));
+ AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+ AudioDeviceInfo.TYPE_WIRED_HEADSET,
+ new SystemRouteInfo(
+ MediaRoute2Info.TYPE_WIRED_HEADSET,
+ /* defaultRouteId= */ "ROUTE_ID_WIRED_HEADSET",
+ /* nameResource= */ R.string.default_audio_route_name_headphones));
+ AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+ AudioDeviceInfo.TYPE_WIRED_HEADPHONES,
+ new SystemRouteInfo(
+ MediaRoute2Info.TYPE_WIRED_HEADPHONES,
+ /* defaultRouteId= */ "ROUTE_ID_WIRED_HEADPHONES",
+ /* nameResource= */ R.string.default_audio_route_name_headphones));
+ AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+ AudioDeviceInfo.TYPE_BLUETOOTH_A2DP,
+ new SystemRouteInfo(
+ MediaRoute2Info.TYPE_BLUETOOTH_A2DP,
+ /* defaultRouteId= */ "ROUTE_ID_BLUETOOTH_A2DP",
+ /* nameResource= */ R.string.bluetooth_a2dp_audio_route_name));
+ AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+ AudioDeviceInfo.TYPE_HDMI,
+ new SystemRouteInfo(
+ MediaRoute2Info.TYPE_HDMI,
+ /* defaultRouteId= */ "ROUTE_ID_HDMI",
+ /* nameResource= */ R.string.default_audio_route_name_external_device));
+ AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+ AudioDeviceInfo.TYPE_DOCK,
+ new SystemRouteInfo(
+ MediaRoute2Info.TYPE_DOCK,
+ /* defaultRouteId= */ "ROUTE_ID_DOCK",
+ /* nameResource= */ R.string.default_audio_route_name_dock_speakers));
+ AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+ AudioDeviceInfo.TYPE_USB_DEVICE,
+ new SystemRouteInfo(
+ MediaRoute2Info.TYPE_USB_DEVICE,
+ /* defaultRouteId= */ "ROUTE_ID_USB_DEVICE",
+ /* nameResource= */ R.string.default_audio_route_name_usb));
+ AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+ AudioDeviceInfo.TYPE_USB_HEADSET,
+ new SystemRouteInfo(
+ MediaRoute2Info.TYPE_USB_HEADSET,
+ /* defaultRouteId= */ "ROUTE_ID_USB_HEADSET",
+ /* nameResource= */ R.string.default_audio_route_name_usb));
+ AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+ AudioDeviceInfo.TYPE_HDMI_ARC,
+ new SystemRouteInfo(
+ MediaRoute2Info.TYPE_HDMI_ARC,
+ /* defaultRouteId= */ "ROUTE_ID_HDMI_ARC",
+ /* nameResource= */ R.string.default_audio_route_name_external_device));
+ AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+ AudioDeviceInfo.TYPE_HDMI_EARC,
+ new SystemRouteInfo(
+ MediaRoute2Info.TYPE_HDMI_EARC,
+ /* defaultRouteId= */ "ROUTE_ID_HDMI_EARC",
+ /* nameResource= */ R.string.default_audio_route_name_external_device));
+ // TODO: b/305199571 - Add a proper type constants and human readable names for AUX_LINE,
+ // LINE_ANALOG, LINE_DIGITAL, BLE_BROADCAST, BLE_SPEAKER, BLE_HEADSET, and HEARING_AID.
+ AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+ AudioDeviceInfo.TYPE_HEARING_AID,
+ new SystemRouteInfo(
+ MediaRoute2Info.TYPE_HEARING_AID,
+ /* defaultRouteId= */ "ROUTE_ID_HEARING_AID",
+ /* nameResource= */ R.string.bluetooth_a2dp_audio_route_name));
+ AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+ AudioDeviceInfo.TYPE_BLE_HEADSET,
+ new SystemRouteInfo(
+ MediaRoute2Info.TYPE_BLE_HEADSET,
+ /* defaultRouteId= */ "ROUTE_ID_BLE_HEADSET",
+ /* nameResource= */ R.string.bluetooth_a2dp_audio_route_name));
+ AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+ AudioDeviceInfo.TYPE_BLE_SPEAKER,
+ new SystemRouteInfo(
+ MediaRoute2Info.TYPE_BLE_HEADSET, // TODO: b/305199571 - Make a new type.
+ /* defaultRouteId= */ "ROUTE_ID_BLE_SPEAKER",
+ /* nameResource= */ R.string.bluetooth_a2dp_audio_route_name));
+ AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+ AudioDeviceInfo.TYPE_BLE_BROADCAST,
+ new SystemRouteInfo(
+ MediaRoute2Info.TYPE_BLE_HEADSET,
+ /* defaultRouteId= */ "ROUTE_ID_BLE_BROADCAST",
+ /* nameResource= */ R.string.bluetooth_a2dp_audio_route_name));
+ AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+ AudioDeviceInfo.TYPE_LINE_DIGITAL,
+ new SystemRouteInfo(
+ MediaRoute2Info.TYPE_UNKNOWN,
+ /* defaultRouteId= */ "ROUTE_ID_LINE_DIGITAL",
+ /* nameResource= */ R.string.default_audio_route_name_external_device));
+ AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+ AudioDeviceInfo.TYPE_LINE_ANALOG,
+ new SystemRouteInfo(
+ MediaRoute2Info.TYPE_UNKNOWN,
+ /* defaultRouteId= */ "ROUTE_ID_LINE_ANALOG",
+ /* nameResource= */ R.string.default_audio_route_name_external_device));
+ AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+ AudioDeviceInfo.TYPE_AUX_LINE,
+ new SystemRouteInfo(
+ MediaRoute2Info.TYPE_UNKNOWN,
+ /* defaultRouteId= */ "ROUTE_ID_AUX_LINE",
+ /* nameResource= */ R.string.default_audio_route_name_external_device));
+ AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+ AudioDeviceInfo.TYPE_DOCK_ANALOG,
+ new SystemRouteInfo(
+ MediaRoute2Info.TYPE_DOCK,
+ /* defaultRouteId= */ "ROUTE_ID_DOCK_ANALOG",
+ /* nameResource= */ R.string.default_audio_route_name_dock_speakers));
+ }
}
diff --git a/services/core/java/com/android/server/media/AudioRoutingUtils.java b/services/core/java/com/android/server/media/AudioRoutingUtils.java
new file mode 100644
index 000000000000..13f11eb80ece
--- /dev/null
+++ b/services/core/java/com/android/server/media/AudioRoutingUtils.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.media;
+
+import android.Manifest;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.media.AudioAttributes;
+import android.media.AudioManager;
+import android.media.audiopolicy.AudioProductStrategy;
+
+/** Holds utils related to routing in the audio framework. */
+/* package */ final class AudioRoutingUtils {
+
+ /* package */ static final AudioAttributes ATTRIBUTES_MEDIA =
+ new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build();
+
+ @RequiresPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)
+ @Nullable
+ /* package */ static AudioProductStrategy getMediaAudioProductStrategy() {
+ for (AudioProductStrategy strategy : AudioManager.getAudioProductStrategies()) {
+ if (strategy.supportsAudioAttributes(AudioRoutingUtils.ATTRIBUTES_MEDIA)) {
+ return strategy;
+ }
+ }
+ return null;
+ }
+
+ private AudioRoutingUtils() {
+ // no-op to prevent instantiation.
+ }
+}
diff --git a/services/core/java/com/android/server/media/BluetoothRouteController.java b/services/core/java/com/android/server/media/BluetoothRouteController.java
index 2b01001fd7d1..74fdf6ee1d7f 100644
--- a/services/core/java/com/android/server/media/BluetoothRouteController.java
+++ b/services/core/java/com/android/server/media/BluetoothRouteController.java
@@ -44,19 +44,11 @@ import java.util.Objects;
@NonNull
static BluetoothRouteController createInstance(@NonNull Context context,
@NonNull BluetoothRouteController.BluetoothRoutesUpdatedListener listener) {
- Objects.requireNonNull(context);
Objects.requireNonNull(listener);
+ BluetoothAdapter btAdapter = context.getSystemService(BluetoothManager.class).getAdapter();
- BluetoothManager bluetoothManager = (BluetoothManager)
- context.getSystemService(Context.BLUETOOTH_SERVICE);
- BluetoothAdapter btAdapter = bluetoothManager.getAdapter();
-
- if (btAdapter == null) {
+ if (btAdapter == null || Flags.enableAudioPoliciesDeviceAndBluetoothController()) {
return new NoOpBluetoothRouteController();
- }
-
- if (Flags.enableAudioPoliciesDeviceAndBluetoothController()) {
- return new AudioPoliciesBluetoothRouteController(context, btAdapter, listener);
} else {
return new LegacyBluetoothRouteController(context, btAdapter, listener);
}
@@ -74,17 +66,6 @@ import java.util.Objects;
*/
void stop();
-
- /**
- * Selects the route with the given {@code deviceAddress}.
- *
- * @param deviceAddress The physical address of the device to select. May be null to unselect
- * the currently selected device.
- * @return Whether the selection succeeds. If the selection fails, the state of the instance
- * remains unaltered.
- */
- boolean selectRoute(@Nullable String deviceAddress);
-
/**
* Transfers Bluetooth output to the given route.
*
@@ -158,12 +139,6 @@ import java.util.Objects;
}
@Override
- public boolean selectRoute(String deviceAddress) {
- // no op
- return false;
- }
-
- @Override
public void transferTo(String routeId) {
// no op
}
diff --git a/services/core/java/com/android/server/media/DeviceRouteController.java b/services/core/java/com/android/server/media/DeviceRouteController.java
index 0fdaaa7604e5..9f175a9a0277 100644
--- a/services/core/java/com/android/server/media/DeviceRouteController.java
+++ b/services/core/java/com/android/server/media/DeviceRouteController.java
@@ -16,17 +16,25 @@
package com.android.server.media;
+import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.media.AudioManager;
-import android.media.IAudioRoutesObserver;
import android.media.IAudioService;
import android.media.MediaRoute2Info;
+import android.media.audiopolicy.AudioProductStrategy;
+import android.os.Looper;
import android.os.ServiceManager;
+import android.os.UserHandle;
import com.android.media.flags.Flags;
+import java.util.List;
+
/**
* Controls device routes.
*
@@ -37,44 +45,65 @@ import com.android.media.flags.Flags;
*/
/* package */ interface DeviceRouteController {
- /**
- * Returns a new instance of {@link DeviceRouteController}.
- */
- /* package */ static DeviceRouteController createInstance(@NonNull Context context,
+ /** Returns a new instance of {@link DeviceRouteController}. */
+ @RequiresPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)
+ /* package */ static DeviceRouteController createInstance(
+ @NonNull Context context,
+ @NonNull Looper looper,
@NonNull OnDeviceRouteChangedListener onDeviceRouteChangedListener) {
AudioManager audioManager = context.getSystemService(AudioManager.class);
- IAudioService audioService = IAudioService.Stub.asInterface(
- ServiceManager.getService(Context.AUDIO_SERVICE));
+ AudioProductStrategy strategyForMedia = AudioRoutingUtils.getMediaAudioProductStrategy();
- if (Flags.enableAudioPoliciesDeviceAndBluetoothController()) {
- return new AudioPoliciesDeviceRouteController(context,
+ BluetoothManager bluetoothManager = context.getSystemService(BluetoothManager.class);
+ BluetoothAdapter btAdapter =
+ bluetoothManager != null ? bluetoothManager.getAdapter() : null;
+
+ // TODO: b/305199571 - Make the audio policies implementation work without the need for a
+ // bluetooth adapter or a strategy for media. If no strategy for media is available we can
+ // disallow media router transfers, and without a bluetooth adapter we can remove support
+ // for transfers to inactive bluetooth routes.
+ if (strategyForMedia != null
+ && btAdapter != null
+ && Flags.enableAudioPoliciesDeviceAndBluetoothController()) {
+ return new AudioPoliciesDeviceRouteController(
+ context,
audioManager,
- audioService,
+ looper,
+ strategyForMedia,
+ btAdapter,
onDeviceRouteChangedListener);
} else {
- return new LegacyDeviceRouteController(context,
- audioManager,
- audioService,
- onDeviceRouteChangedListener);
+ IAudioService audioService =
+ IAudioService.Stub.asInterface(
+ ServiceManager.getService(Context.AUDIO_SERVICE));
+ return new LegacyDeviceRouteController(
+ context, audioManager, audioService, onDeviceRouteChangedListener);
}
}
+ /** Returns the currently selected device (built-in or wired) route. */
+ @NonNull
+ MediaRoute2Info getSelectedRoute();
+
/**
- * Select the route with the given built-in or wired {@link MediaRoute2Info.Type}.
- *
- * <p>If the type is {@code null} then unselects the route and falls back to the default device
- * route observed from
- * {@link com.android.server.audio.AudioService#startWatchingRoutes(IAudioRoutesObserver)}.
+ * Returns all available routes.
*
- * @param type device type. May be {@code null} to unselect currently selected route.
- * @return whether the selection succeeds. If the selection fails the state of the controller
- * remains intact.
+ * <p>Note that this method returns available routes including the selected route because (a)
+ * this interface doesn't guarantee that the internal state of the controller won't change
+ * between calls to {@link #getSelectedRoute()} and this method and (b) {@link
+ * #getSelectedRoute()} may be treated as a transferable route (not a selected route) if the
+ * selected route is from {@link BluetoothRouteController}.
*/
- boolean selectRoute(@Nullable @MediaRoute2Info.Type Integer type);
+ List<MediaRoute2Info> getAvailableRoutes();
- /** Returns the currently selected device (built-in or wired) route. */
- @NonNull
- MediaRoute2Info getSelectedRoute();
+ /**
+ * Transfers device output to the given route.
+ *
+ * <p>If the route is {@code null} then active route will be deactivated.
+ *
+ * @param routeId to switch to or {@code null} to unset the active device.
+ */
+ void transferTo(@Nullable String routeId);
/**
* Updates device route volume.
@@ -85,6 +114,18 @@ import com.android.media.flags.Flags;
boolean updateVolume(int volume);
/**
+ * Starts listening for changes in the system to keep an up to date view of available and
+ * selected devices.
+ */
+ void start(UserHandle mUser);
+
+ /**
+ * Stops keeping the internal state up to date with the system, releasing any resources acquired
+ * in {@link #start}
+ */
+ void stop();
+
+ /**
* Interface for receiving events when device route has changed.
*/
interface OnDeviceRouteChangedListener {
diff --git a/services/core/java/com/android/server/media/LegacyBluetoothRouteController.java b/services/core/java/com/android/server/media/LegacyBluetoothRouteController.java
index ba3cecf7c091..041fceaf8d3d 100644
--- a/services/core/java/com/android/server/media/LegacyBluetoothRouteController.java
+++ b/services/core/java/com/android/server/media/LegacyBluetoothRouteController.java
@@ -132,12 +132,6 @@ class LegacyBluetoothRouteController implements BluetoothRouteController {
mContext.unregisterReceiver(mDeviceStateChangedReceiver);
}
- @Override
- public boolean selectRoute(String deviceAddress) {
- // No-op as the class decides if a route is selected based on Bluetooth events.
- return false;
- }
-
/**
* Transfers to a given bluetooth route.
* The dedicated BT device with the route would be activated.
diff --git a/services/core/java/com/android/server/media/LegacyDeviceRouteController.java b/services/core/java/com/android/server/media/LegacyDeviceRouteController.java
index 65874e23dcdc..c0f28346705c 100644
--- a/services/core/java/com/android/server/media/LegacyDeviceRouteController.java
+++ b/services/core/java/com/android/server/media/LegacyDeviceRouteController.java
@@ -35,11 +35,13 @@ import android.media.IAudioRoutesObserver;
import android.media.IAudioService;
import android.media.MediaRoute2Info;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.util.Slog;
import com.android.internal.R;
-import com.android.internal.annotations.VisibleForTesting;
+import java.util.Collections;
+import java.util.List;
import java.util.Objects;
/**
@@ -73,7 +75,6 @@ import java.util.Objects;
private int mDeviceVolume;
private MediaRoute2Info mDeviceRoute;
- @VisibleForTesting
/* package */ LegacyDeviceRouteController(@NonNull Context context,
@NonNull AudioManager audioManager,
@NonNull IAudioService audioService,
@@ -100,9 +101,13 @@ import java.util.Objects;
}
@Override
- public boolean selectRoute(@Nullable Integer type) {
- // No-op as the controller does not support selection from the outside of the class.
- return false;
+ public void start(UserHandle mUser) {
+ // Nothing to do.
+ }
+
+ @Override
+ public void stop() {
+ // Nothing to do.
}
@Override
@@ -112,6 +117,17 @@ import java.util.Objects;
}
@Override
+ public synchronized List<MediaRoute2Info> getAvailableRoutes() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public synchronized void transferTo(@Nullable String routeId) {
+ // Unsupported. This implementation doesn't support transferable routes (always exposes a
+ // single non-bluetooth route).
+ }
+
+ @Override
public synchronized boolean updateVolume(int volume) {
if (mDeviceVolume == volume) {
return false;
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
index c8dba800a017..86d78334d546 100644
--- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
@@ -16,15 +16,12 @@
package com.android.server.media;
-import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.media.AudioAttributes;
-import android.media.AudioDeviceAttributes;
import android.media.AudioManager;
import android.media.MediaRoute2Info;
import android.media.MediaRoute2ProviderInfo;
@@ -51,7 +48,8 @@ import java.util.Set;
*/
// TODO: check thread safety. We may need to use lock to protect variables.
class SystemMediaRoute2Provider extends MediaRoute2Provider {
- private static final String TAG = "MR2SystemProvider";
+ // Package-visible to use this tag for all system routing logic (done across multiple classes).
+ /* package */ static final String TAG = "MR2SystemProvider";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final ComponentName COMPONENT_NAME = new ComponentName(
@@ -77,26 +75,6 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
private final AudioManagerBroadcastReceiver mAudioReceiver =
new AudioManagerBroadcastReceiver();
- private final AudioManager.OnDevicesForAttributesChangedListener
- mOnDevicesForAttributesChangedListener =
- new AudioManager.OnDevicesForAttributesChangedListener() {
- @Override
- public void onDevicesForAttributesChanged(@NonNull AudioAttributes attributes,
- @NonNull List<AudioDeviceAttributes> devices) {
- if (attributes.getUsage() != AudioAttributes.USAGE_MEDIA) {
- return;
- }
-
- mHandler.post(() -> {
- updateSelectedAudioDevice(devices);
- notifyProviderState();
- if (updateSessionInfosIfNeeded()) {
- notifySessionInfoUpdated();
- }
- });
- }
- };
-
private final Object mRequestLock = new Object();
@GuardedBy("mRequestLock")
private volatile SessionCreationRequest mPendingSessionCreationRequest;
@@ -106,7 +84,8 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
mIsSystemRouteProvider = true;
mContext = context;
mUser = user;
- mHandler = new Handler(Looper.getMainLooper());
+ Looper looper = Looper.getMainLooper();
+ mHandler = new Handler(looper);
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
@@ -123,25 +102,15 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
mDeviceRouteController =
DeviceRouteController.createInstance(
context,
- () -> {
- mHandler.post(
- () -> {
- publishProviderState();
- if (updateSessionInfosIfNeeded()) {
- notifySessionInfoUpdated();
- }
- });
- });
-
- mAudioManager.addOnDevicesForAttributesChangedListener(
- AudioAttributesUtils.ATTRIBUTES_MEDIA, mContext.getMainExecutor(),
- mOnDevicesForAttributesChangedListener);
-
- // These methods below should be called after all fields are initialized, as they
- // access the fields inside.
- List<AudioDeviceAttributes> devices =
- mAudioManager.getDevicesForAttributes(AudioAttributesUtils.ATTRIBUTES_MEDIA);
- updateSelectedAudioDevice(devices);
+ looper,
+ () ->
+ mHandler.post(
+ () -> {
+ publishProviderState();
+ if (updateSessionInfosIfNeeded()) {
+ notifySessionInfoUpdated();
+ }
+ }));
updateProviderState();
updateSessionInfosIfNeeded();
}
@@ -151,20 +120,21 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
intentFilter.addAction(AudioManager.STREAM_DEVICES_CHANGED_ACTION);
mContext.registerReceiverAsUser(mAudioReceiver, mUser,
intentFilter, null, null);
-
- mHandler.post(() -> {
- mBluetoothRouteController.start(mUser);
- notifyProviderState();
- });
- updateVolume();
+ mHandler.post(
+ () -> {
+ mDeviceRouteController.start(mUser);
+ mBluetoothRouteController.start(mUser);
+ });
}
public void stop() {
mContext.unregisterReceiver(mAudioReceiver);
- mHandler.post(() -> {
- mBluetoothRouteController.stop();
- notifyProviderState();
- });
+ mHandler.post(
+ () -> {
+ mBluetoothRouteController.stop();
+ mDeviceRouteController.stop();
+ notifyProviderState();
+ });
}
@Override
@@ -225,13 +195,26 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
public void transferToRoute(long requestId, String sessionId, String routeId) {
if (TextUtils.equals(routeId, MediaRoute2Info.ROUTE_ID_DEFAULT)) {
// The currently selected route is the default route.
+ Log.w(TAG, "Ignoring transfer to " + MediaRoute2Info.ROUTE_ID_DEFAULT);
return;
}
-
MediaRoute2Info selectedDeviceRoute = mDeviceRouteController.getSelectedRoute();
- if (TextUtils.equals(routeId, selectedDeviceRoute.getId())) {
+ boolean isAvailableDeviceRoute =
+ mDeviceRouteController.getAvailableRoutes().stream()
+ .anyMatch(it -> it.getId().equals(routeId));
+ boolean isSelectedDeviceRoute = TextUtils.equals(routeId, selectedDeviceRoute.getId());
+
+ if (isSelectedDeviceRoute || isAvailableDeviceRoute) {
+ // The requested route is managed by the device route controller. Note that the selected
+ // device route doesn't necessarily match mSelectedRouteId (which is the selected route
+ // of the routing session). If the selected device route is transferred to, we need to
+ // make the bluetooth routes inactive so that the device route becomes the selected
+ // route of the routing session.
+ mDeviceRouteController.transferTo(routeId);
mBluetoothRouteController.transferTo(null);
} else {
+ // The requested route is managed by the bluetooth route controller.
+ mDeviceRouteController.transferTo(null);
mBluetoothRouteController.transferTo(routeId);
}
}
@@ -280,33 +263,22 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
MediaRoute2Info selectedDeviceRoute = mDeviceRouteController.getSelectedRoute();
- RoutingSessionInfo.Builder builder = new RoutingSessionInfo.Builder(
- SYSTEM_SESSION_ID, packageName).setSystemSession(true);
+ RoutingSessionInfo.Builder builder =
+ new RoutingSessionInfo.Builder(SYSTEM_SESSION_ID, packageName)
+ .setSystemSession(true);
builder.addSelectedRoute(selectedDeviceRoute.getId());
for (MediaRoute2Info route : mBluetoothRouteController.getAllBluetoothRoutes()) {
builder.addTransferableRoute(route.getId());
}
- return builder.setProviderId(mUniqueId).build();
- }
- }
- private void updateSelectedAudioDevice(@NonNull List<AudioDeviceAttributes> devices) {
- if (devices.isEmpty()) {
- Slog.w(TAG, "The list of preferred devices was empty.");
- return;
- }
-
- AudioDeviceAttributes audioDeviceAttributes = devices.get(0);
-
- if (AudioAttributesUtils.isDeviceOutputAttributes(audioDeviceAttributes)) {
- mDeviceRouteController.selectRoute(
- AudioAttributesUtils.mapToMediaRouteType(audioDeviceAttributes));
- mBluetoothRouteController.selectRoute(null);
- } else if (AudioAttributesUtils.isBluetoothOutputAttributes(audioDeviceAttributes)) {
- mDeviceRouteController.selectRoute(null);
- mBluetoothRouteController.selectRoute(audioDeviceAttributes.getAddress());
- } else {
- Slog.w(TAG, "Unknown audio attributes: " + audioDeviceAttributes);
+ if (Flags.enableAudioPoliciesDeviceAndBluetoothController()) {
+ for (MediaRoute2Info route : mDeviceRouteController.getAvailableRoutes()) {
+ if (!TextUtils.equals(selectedDeviceRoute.getId(), route.getId())) {
+ builder.addTransferableRoute(route.getId());
+ }
+ }
+ }
+ return builder.setProviderId(mUniqueId).build();
}
}
@@ -314,7 +286,15 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
MediaRoute2ProviderInfo.Builder builder = new MediaRoute2ProviderInfo.Builder();
// We must have a device route in the provider info.
- builder.addRoute(mDeviceRouteController.getSelectedRoute());
+ if (Flags.enableAudioPoliciesDeviceAndBluetoothController()) {
+ List<MediaRoute2Info> deviceRoutes = mDeviceRouteController.getAvailableRoutes();
+ for (MediaRoute2Info route : deviceRoutes) {
+ builder.addRoute(route);
+ }
+ setProviderState(builder.build());
+ } else {
+ builder.addRoute(mDeviceRouteController.getSelectedRoute());
+ }
for (MediaRoute2Info route : mBluetoothRouteController.getAllBluetoothRoutes()) {
builder.addRoute(route);
@@ -352,7 +332,12 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
.setProviderId(mUniqueId)
.build();
builder.addSelectedRoute(mSelectedRouteId);
-
+ for (MediaRoute2Info route : mDeviceRouteController.getAvailableRoutes()) {
+ String routeId = route.getId();
+ if (!mSelectedRouteId.equals(routeId)) {
+ builder.addTransferableRoute(routeId);
+ }
+ }
for (MediaRoute2Info route : mBluetoothRouteController.getTransferableRoutes()) {
builder.addTransferableRoute(route.getId());
}
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java
index 3b3d79e7dee1..07e0ddfac76b 100644
--- a/services/core/java/com/android/server/pm/DeletePackageHelper.java
+++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java
@@ -357,6 +357,12 @@ final class DeletePackageHelper {
final DeletePackageAction action;
synchronized (mPm.mLock) {
final PackageSetting ps = mPm.mSettings.getPackageLPr(packageName);
+ if (ps == null) {
+ if (DEBUG_REMOVE) {
+ Slog.d(TAG, "Attempted to remove non-existent package " + packageName);
+ }
+ return false;
+ }
final PackageSetting disabledPs = mPm.mSettings.getDisabledSystemPkgLPr(ps);
if (PackageManagerServiceUtils.isSystemApp(ps)
&& mPm.checkPermission(CONTROL_KEYGUARD, packageName, UserHandle.USER_SYSTEM)
diff --git a/services/core/java/com/android/server/pm/InstallRequest.java b/services/core/java/com/android/server/pm/InstallRequest.java
index 0a81b2b9fabb..5494bd9808c8 100644
--- a/services/core/java/com/android/server/pm/InstallRequest.java
+++ b/services/core/java/com/android/server/pm/InstallRequest.java
@@ -539,6 +539,12 @@ final class InstallRequest {
}
@Nullable
+ public PackageSetting getScanRequestDisabledPackageSetting() {
+ assertScanResultExists();
+ return mScanResult.mRequest.mDisabledPkgSetting;
+ }
+
+ @Nullable
public String getRealPackageName() {
assertScanResultExists();
return mScanResult.mRequest.mRealPkgName;
diff --git a/services/core/java/com/android/server/pm/SharedLibrariesImpl.java b/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
index d0fdfa9bc775..9384c13e583b 100644
--- a/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
+++ b/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
@@ -856,9 +856,9 @@ public final class SharedLibrariesImpl implements SharedLibrariesRead, Watchable
// We may not yet have disabled the updated package yet, so be sure to grab the
// current setting if that's the case.
final PackageSetting updatedSystemPs = isUpdatedSystemApp
- ? installRequest.getDisabledPackageSetting() == null
+ ? installRequest.getScanRequestDisabledPackageSetting() == null
? installRequest.getScanRequestOldPackageSetting()
- : installRequest.getDisabledPackageSetting()
+ : installRequest.getScanRequestDisabledPackageSetting()
: null;
if (isUpdatedSystemApp && (updatedSystemPs.getPkg() == null
|| updatedSystemPs.getPkg().getLibraryNames() == null)) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 73c422490330..e817df8c6e0c 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -3638,15 +3638,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return true;
}
break;
- case KeyEvent.KEYCODE_SPACE:
- // Handle keyboard layout switching. (META + SPACE)
- if (firstDown && event.isMetaPressed()) {
- int direction = (metaState & KeyEvent.META_SHIFT_MASK) != 0 ? -1 : 1;
- sendSwitchKeyboardLayout(event, direction);
- logKeyboardSystemsEvent(event, KeyboardLogEvent.LANGUAGE_SWITCH);
- return true;
- }
- break;
case KeyEvent.KEYCODE_META_LEFT:
case KeyEvent.KEYCODE_META_RIGHT:
if (down) {
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
index e3f36385ef6c..5d9085144334 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
@@ -32,7 +32,6 @@ import android.provider.Settings;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.IndentingPrintWriter;
-import android.util.KeyValueListParser;
import android.util.Slog;
import android.view.accessibility.AccessibilityManager;
@@ -41,6 +40,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.ConcurrentUtils;
+import com.android.server.utils.UserSettingDeviceConfigMediator;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -809,12 +809,13 @@ public class BatterySaverPolicy extends ContentObserver implements
private static Policy fromSettings(String settings, String deviceSpecificSettings,
DeviceConfig.Properties properties, String configSuffix, Policy defaultPolicy) {
- final KeyValueListParser parser = new KeyValueListParser(',');
+ final UserSettingDeviceConfigMediator userSettingDeviceConfigMediator =
+ new UserSettingDeviceConfigMediator.SettingsOverridesIndividualMediator(',');
configSuffix = TextUtils.emptyIfNull(configSuffix);
// Device-specific parameters.
try {
- parser.setString(deviceSpecificSettings == null ? "" : deviceSpecificSettings);
+ userSettingDeviceConfigMediator.setSettingsString(deviceSpecificSettings);
} catch (IllegalArgumentException e) {
Slog.wtf(TAG, "Bad device specific battery saver constants: "
+ deviceSpecificSettings);
@@ -822,68 +823,58 @@ public class BatterySaverPolicy extends ContentObserver implements
// Non-device-specific parameters.
try {
- parser.setString(settings == null ? "" : settings);
+ userSettingDeviceConfigMediator.setSettingsString(settings);
+ userSettingDeviceConfigMediator.setDeviceConfigProperties(properties);
} catch (IllegalArgumentException e) {
Slog.wtf(TAG, "Bad battery saver constants: " + settings);
}
// The Settings value overrides everything, since that will be set by the user.
// The DeviceConfig value takes second place, with the default as the last choice.
- final float adjustBrightnessFactor = parser.getFloat(KEY_ADJUST_BRIGHTNESS_FACTOR,
- properties.getFloat(KEY_ADJUST_BRIGHTNESS_FACTOR + configSuffix,
- defaultPolicy.adjustBrightnessFactor));
- final boolean advertiseIsEnabled = parser.getBoolean(KEY_ADVERTISE_IS_ENABLED,
- properties.getBoolean(KEY_ADVERTISE_IS_ENABLED + configSuffix,
- defaultPolicy.advertiseIsEnabled));
- final boolean deferFullBackup = parser.getBoolean(KEY_DEFER_FULL_BACKUP,
- properties.getBoolean(KEY_DEFER_FULL_BACKUP + configSuffix,
- defaultPolicy.deferFullBackup));
- final boolean deferKeyValueBackup = parser.getBoolean(KEY_DEFER_KEYVALUE_BACKUP,
- properties.getBoolean(KEY_DEFER_KEYVALUE_BACKUP + configSuffix,
- defaultPolicy.deferKeyValueBackup));
- final boolean disableAnimation = parser.getBoolean(KEY_DISABLE_ANIMATION,
- properties.getBoolean(KEY_DISABLE_ANIMATION + configSuffix,
- defaultPolicy.disableAnimation));
- final boolean disableAod = parser.getBoolean(KEY_DISABLE_AOD,
- properties.getBoolean(KEY_DISABLE_AOD + configSuffix,
- defaultPolicy.disableAod));
- final boolean disableLaunchBoost = parser.getBoolean(KEY_DISABLE_LAUNCH_BOOST,
- properties.getBoolean(KEY_DISABLE_LAUNCH_BOOST + configSuffix,
- defaultPolicy.disableLaunchBoost));
- final boolean disableOptionalSensors = parser.getBoolean(KEY_DISABLE_OPTIONAL_SENSORS,
- properties.getBoolean(KEY_DISABLE_OPTIONAL_SENSORS + configSuffix,
- defaultPolicy.disableOptionalSensors));
- final boolean disableVibrationConfig = parser.getBoolean(KEY_DISABLE_VIBRATION,
- properties.getBoolean(KEY_DISABLE_VIBRATION + configSuffix,
- defaultPolicy.disableVibration));
- final boolean enableBrightnessAdjustment = parser.getBoolean(
- KEY_ENABLE_BRIGHTNESS_ADJUSTMENT,
- properties.getBoolean(KEY_ENABLE_BRIGHTNESS_ADJUSTMENT + configSuffix,
- defaultPolicy.enableAdjustBrightness));
- final boolean enableDataSaver = parser.getBoolean(KEY_ENABLE_DATASAVER,
- properties.getBoolean(KEY_ENABLE_DATASAVER + configSuffix,
- defaultPolicy.enableDataSaver));
- final boolean enableFirewall = parser.getBoolean(KEY_ENABLE_FIREWALL,
- properties.getBoolean(KEY_ENABLE_FIREWALL + configSuffix,
- defaultPolicy.enableFirewall));
- final boolean enableNightMode = parser.getBoolean(KEY_ENABLE_NIGHT_MODE,
- properties.getBoolean(KEY_ENABLE_NIGHT_MODE + configSuffix,
- defaultPolicy.enableNightMode));
- final boolean enableQuickDoze = parser.getBoolean(KEY_ENABLE_QUICK_DOZE,
- properties.getBoolean(KEY_ENABLE_QUICK_DOZE + configSuffix,
- defaultPolicy.enableQuickDoze));
- final boolean forceAllAppsStandby = parser.getBoolean(KEY_FORCE_ALL_APPS_STANDBY,
- properties.getBoolean(KEY_FORCE_ALL_APPS_STANDBY + configSuffix,
- defaultPolicy.forceAllAppsStandby));
- final boolean forceBackgroundCheck = parser.getBoolean(KEY_FORCE_BACKGROUND_CHECK,
- properties.getBoolean(KEY_FORCE_BACKGROUND_CHECK + configSuffix,
- defaultPolicy.forceBackgroundCheck));
- final int locationMode = parser.getInt(KEY_LOCATION_MODE,
- properties.getInt(KEY_LOCATION_MODE + configSuffix,
- defaultPolicy.locationMode));
- final int soundTriggerMode = parser.getInt(KEY_SOUNDTRIGGER_MODE,
- properties.getInt(KEY_SOUNDTRIGGER_MODE + configSuffix,
- defaultPolicy.soundTriggerMode));
+ final float adjustBrightnessFactor = userSettingDeviceConfigMediator.getFloat(
+ KEY_ADJUST_BRIGHTNESS_FACTOR + configSuffix,
+ defaultPolicy.adjustBrightnessFactor);
+ final boolean advertiseIsEnabled = userSettingDeviceConfigMediator.getBoolean(
+ KEY_ADVERTISE_IS_ENABLED + configSuffix,
+ defaultPolicy.advertiseIsEnabled);
+ final boolean deferFullBackup = userSettingDeviceConfigMediator.getBoolean(
+ KEY_DEFER_FULL_BACKUP + configSuffix, defaultPolicy.deferFullBackup);
+ final boolean deferKeyValueBackup = userSettingDeviceConfigMediator.getBoolean(
+ KEY_DEFER_KEYVALUE_BACKUP + configSuffix,
+ defaultPolicy.deferKeyValueBackup);
+ final boolean disableAnimation = userSettingDeviceConfigMediator.getBoolean(
+ KEY_DISABLE_ANIMATION + configSuffix, defaultPolicy.disableAnimation);
+ final boolean disableAod = userSettingDeviceConfigMediator.getBoolean(
+ KEY_DISABLE_AOD + configSuffix, defaultPolicy.disableAod);
+ final boolean disableLaunchBoost = userSettingDeviceConfigMediator.getBoolean(
+ KEY_DISABLE_LAUNCH_BOOST + configSuffix,
+ defaultPolicy.disableLaunchBoost);
+ final boolean disableOptionalSensors = userSettingDeviceConfigMediator.getBoolean(
+ KEY_DISABLE_OPTIONAL_SENSORS + configSuffix,
+ defaultPolicy.disableOptionalSensors);
+ final boolean disableVibrationConfig = userSettingDeviceConfigMediator.getBoolean(
+ KEY_DISABLE_VIBRATION + configSuffix, defaultPolicy.disableVibration);
+ final boolean enableBrightnessAdjustment = userSettingDeviceConfigMediator.getBoolean(
+ KEY_ENABLE_BRIGHTNESS_ADJUSTMENT + configSuffix,
+ defaultPolicy.enableAdjustBrightness);
+ final boolean enableDataSaver = userSettingDeviceConfigMediator.getBoolean(
+ KEY_ENABLE_DATASAVER + configSuffix, defaultPolicy.enableDataSaver);
+ final boolean enableFirewall = userSettingDeviceConfigMediator.getBoolean(
+ KEY_ENABLE_FIREWALL + configSuffix, defaultPolicy.enableFirewall);
+ final boolean enableNightMode = userSettingDeviceConfigMediator.getBoolean(
+ KEY_ENABLE_NIGHT_MODE + configSuffix, defaultPolicy.enableNightMode);
+ final boolean enableQuickDoze = userSettingDeviceConfigMediator.getBoolean(
+ KEY_ENABLE_QUICK_DOZE + configSuffix, defaultPolicy.enableQuickDoze);
+ final boolean forceAllAppsStandby = userSettingDeviceConfigMediator.getBoolean(
+ KEY_FORCE_ALL_APPS_STANDBY + configSuffix,
+ defaultPolicy.forceAllAppsStandby);
+ final boolean forceBackgroundCheck = userSettingDeviceConfigMediator.getBoolean(
+ KEY_FORCE_BACKGROUND_CHECK + configSuffix,
+ defaultPolicy.forceBackgroundCheck);
+ final int locationMode = userSettingDeviceConfigMediator.getInt(
+ KEY_LOCATION_MODE + configSuffix, defaultPolicy.locationMode);
+ final int soundTriggerMode = userSettingDeviceConfigMediator.getInt(
+ KEY_SOUNDTRIGGER_MODE + configSuffix, defaultPolicy.soundTriggerMode);
return new Policy(
adjustBrightnessFactor,
advertiseIsEnabled,
diff --git a/services/core/java/com/android/server/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java
index dd39fb02573e..c17d6ab4c85b 100644
--- a/services/core/java/com/android/server/power/hint/HintManagerService.java
+++ b/services/core/java/com/android/server/power/hint/HintManagerService.java
@@ -51,6 +51,7 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
+import java.util.NoSuchElementException;
import java.util.Objects;
/** An hint service implementation that runs in System Server process. */
@@ -544,7 +545,11 @@ public final class HintManagerService extends SystemService {
if (mHalSessionPtr == 0) return;
mNativeWrapper.halCloseHintSession(mHalSessionPtr);
mHalSessionPtr = 0;
- mToken.unlinkToDeath(this, 0);
+ try {
+ mToken.unlinkToDeath(this, 0);
+ } catch (NoSuchElementException ignored) {
+ Slogf.d(TAG, "Death link does not exist for session with UID " + mUid);
+ }
}
synchronized (mLock) {
ArrayMap<IBinder, ArraySet<AppHintSession>> tokenMap = mActiveSessions.get(mUid);
diff --git a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
index 0656a6a7d3e9..59766ec7a175 100644
--- a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
+++ b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
@@ -35,6 +35,7 @@ import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.hardware.SensorPrivacyManager.EXTRA_ALL_SENSORS;
+import static android.hardware.SensorPrivacyManager.EXTRA_NOTIFICATION_ID;
import static android.hardware.SensorPrivacyManager.EXTRA_SENSOR;
import static android.hardware.SensorPrivacyManager.EXTRA_TOGGLE_TYPE;
import static android.hardware.SensorPrivacyManager.Sensors.CAMERA;
@@ -164,6 +165,7 @@ public final class SensorPrivacyService extends SystemService {
private final AppOpsManagerInternal mAppOpsManagerInternal;
private final TelephonyManager mTelephonyManager;
private final PackageManagerInternal mPackageManagerInternal;
+ private final NotificationManager mNotificationManager;
private CameraPrivacyLightController mCameraPrivacyLightController;
@@ -188,6 +190,7 @@ public final class SensorPrivacyService extends SystemService {
mActivityTaskManager = context.getSystemService(ActivityTaskManager.class);
mTelephonyManager = context.getSystemService(TelephonyManager.class);
mPackageManagerInternal = getLocalService(PackageManagerInternal.class);
+ mNotificationManager = mContext.getSystemService(NotificationManager.class);
mSensorPrivacyServiceImpl = new SensorPrivacyServiceImpl();
}
@@ -288,9 +291,18 @@ public final class SensorPrivacyService extends SystemService {
@Override
public void onReceive(Context context, Intent intent) {
setToggleSensorPrivacy(
- ((UserHandle) intent.getParcelableExtra(
- Intent.EXTRA_USER, android.os.UserHandle.class)).getIdentifier(), OTHER,
- intent.getIntExtra(EXTRA_SENSOR, UNKNOWN), false);
+ intent.getParcelableExtra(Intent.EXTRA_USER, UserHandle.class)
+ .getIdentifier(),
+ OTHER,
+ intent.getIntExtra(EXTRA_SENSOR, UNKNOWN),
+ false
+ );
+
+ int notificationId =
+ intent.getIntExtra(EXTRA_NOTIFICATION_ID, SystemMessage.NOTE_UNKNOWN);
+ if (notificationId != SystemMessage.NOTE_UNKNOWN) {
+ mNotificationManager.cancel(notificationId);
+ }
}
}, new IntentFilter(ACTION_DISABLE_TOGGLE_SENSOR_PRIVACY),
MANAGE_SENSOR_PRIVACY, null, Context.RECEIVER_EXPORTED);
@@ -635,8 +647,6 @@ public final class SensorPrivacyService extends SystemService {
notificationId = SystemMessage.NOTE_UNBLOCK_CAM_TOGGLE;
}
- NotificationManager notificationManager =
- mContext.getSystemService(NotificationManager.class);
NotificationChannel channel = new NotificationChannel(
SENSOR_PRIVACY_CHANNEL_ID,
getUiContext().getString(R.string.sensor_privacy_notification_channel_label),
@@ -646,7 +656,7 @@ public final class SensorPrivacyService extends SystemService {
channel.enableVibration(false);
channel.setBlockable(false);
- notificationManager.createNotificationChannel(channel);
+ mNotificationManager.createNotificationChannel(channel);
Icon icon = Icon.createWithResource(getUiContext().getResources(), iconRes);
@@ -669,10 +679,11 @@ public final class SensorPrivacyService extends SystemService {
new Intent(ACTION_DISABLE_TOGGLE_SENSOR_PRIVACY)
.setPackage(mContext.getPackageName())
.putExtra(EXTRA_SENSOR, sensor)
+ .putExtra(EXTRA_NOTIFICATION_ID, notificationId)
.putExtra(Intent.EXTRA_USER, user),
PendingIntent.FLAG_IMMUTABLE
| PendingIntent.FLAG_UPDATE_CURRENT);
- notificationManager.notify(notificationId,
+ mNotificationManager.notify(notificationId,
new Notification.Builder(mContext, SENSOR_PRIVACY_CHANNEL_ID)
.setContentTitle(contentTitle)
.setContentText(contentText)
diff --git a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
index e6273d331fce..0467d0cd351d 100644
--- a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
+++ b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
@@ -38,6 +38,7 @@ import android.media.tv.BroadcastInfoRequest;
import android.media.tv.BroadcastInfoResponse;
import android.media.tv.TvRecordingInfo;
import android.media.tv.TvTrackInfo;
+import android.media.tv.ad.ITvAdManager;
import android.media.tv.interactive.AppLinkInfo;
import android.media.tv.interactive.ITvInteractiveAppClient;
import android.media.tv.interactive.ITvInteractiveAppManager;
@@ -345,6 +346,7 @@ public class TvInteractiveAppManagerService extends SystemService {
Slogf.d(TAG, "onStart");
}
publishBinderService(Context.TV_INTERACTIVE_APP_SERVICE, new BinderService());
+ publishBinderService(Context.TV_AD_SERVICE, new TvAdBinderService());
}
@Override
@@ -688,6 +690,12 @@ public class TvInteractiveAppManagerService extends SystemService {
}
return session;
}
+ private final class TvAdBinderService extends ITvAdManager.Stub {
+ @Override
+ public void startAdService(IBinder sessionToken, int userId) {
+ }
+
+ }
private final class BinderService extends ITvInteractiveAppManager.Stub {
diff --git a/services/core/java/com/android/server/utils/UserSettingDeviceConfigMediator.java b/services/core/java/com/android/server/utils/UserSettingDeviceConfigMediator.java
new file mode 100644
index 000000000000..e5423496fb0e
--- /dev/null
+++ b/services/core/java/com/android/server/utils/UserSettingDeviceConfigMediator.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.utils;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.provider.DeviceConfig;
+import android.util.KeyValueListParser;
+
+/**
+ * Helper class to mediate the value to use when a constant exists in both a key=value pair Settings
+ * constant (that can be parsed by {@link KeyValueListParser})
+ * and the {@link DeviceConfig} properties.
+ */
+public abstract class UserSettingDeviceConfigMediator {
+ private static final String TAG = UserSettingDeviceConfigMediator.class.getSimpleName();
+
+ @Nullable
+ protected DeviceConfig.Properties mProperties;
+ @NonNull
+ protected final KeyValueListParser mSettingsParser;
+
+ /**
+ * @param keyValueListDelimiter The delimiter passed into the {@link KeyValueListParser}.
+ */
+ protected UserSettingDeviceConfigMediator(char keyValueListDelimiter) {
+ mSettingsParser = new KeyValueListParser(keyValueListDelimiter);
+ }
+
+ /**
+ * Sets the key=value list string to read from. Setting {@code null} will clear any previously
+ * set string.
+ */
+ public void setSettingsString(@Nullable String settings) {
+ mSettingsParser.setString(settings);
+ }
+
+ /**
+ * Sets the DeviceConfig Properties to read from. Setting {@code null} will clear any previously
+ * set properties.
+ */
+ public void setDeviceConfigProperties(@Nullable DeviceConfig.Properties properties) {
+ mProperties = properties;
+ }
+
+ /**
+ * Get the value for key as a boolean.
+ *
+ * @param key The key to lookup.
+ * @param defaultValue The value to return if the key was not found, or not properly defined.
+ */
+ public abstract boolean getBoolean(@NonNull String key, boolean defaultValue);
+
+ /**
+ * Get the value for key as a float.
+ *
+ * @param key The key to lookup.
+ * @param defaultValue The value to return if the key was not found, or not properly defined.
+ */
+ public abstract float getFloat(@NonNull String key, float defaultValue);
+
+ /**
+ * Get the value for key as an int.
+ *
+ * @param key The key to lookup.
+ * @param defaultValue The value to return if the key was not found, or not properly defined.
+ */
+ public abstract int getInt(@NonNull String key, int defaultValue);
+
+ /**
+ * Get the value for key as a long.
+ *
+ * @param key The key to lookup.
+ * @param defaultValue The value to return if the key was not found, or not properly defined.
+ */
+ public abstract long getLong(@NonNull String key, long defaultValue);
+
+ /**
+ * Get the value for key as a String.
+ *
+ * @param key The key to lookup.
+ * @param defaultValue The value to return if the key was not found, or not properly defined.
+ */
+ public abstract String getString(@NonNull String key, @Nullable String defaultValue);
+
+ /**
+ * A mediator in which the existence of a single settings key-value pair will override usage
+ * of DeviceConfig properties. That is, if the Settings constant has any values set,
+ * then everything in the DeviceConfig namespace will be ignored.
+ */
+ public static class SettingsOverridesAllMediator extends UserSettingDeviceConfigMediator {
+ public SettingsOverridesAllMediator(char keyValueListDelimiter) {
+ super(keyValueListDelimiter);
+ }
+
+ @Override
+ public boolean getBoolean(@NonNull String key, boolean defaultValue) {
+ if (mSettingsParser.size() == 0) {
+ return mProperties == null
+ ? defaultValue : mProperties.getBoolean(key, defaultValue);
+ }
+ return mSettingsParser.getBoolean(key, defaultValue);
+ }
+
+ @Override
+ public float getFloat(@NonNull String key, float defaultValue) {
+ if (mSettingsParser.size() == 0) {
+ return mProperties == null ? defaultValue : mProperties.getFloat(key, defaultValue);
+ }
+ return mSettingsParser.getFloat(key, defaultValue);
+ }
+
+ @Override
+ public int getInt(@NonNull String key, int defaultValue) {
+ if (mSettingsParser.size() == 0) {
+ return mProperties == null ? defaultValue : mProperties.getInt(key, defaultValue);
+ }
+ return mSettingsParser.getInt(key, defaultValue);
+ }
+
+ @Override
+ public long getLong(@NonNull String key, long defaultValue) {
+ if (mSettingsParser.size() == 0) {
+ return mProperties == null ? defaultValue : mProperties.getLong(key, defaultValue);
+ }
+ return mSettingsParser.getLong(key, defaultValue);
+ }
+
+ @Override
+ public String getString(@NonNull String key, @Nullable String defaultValue) {
+ if (mSettingsParser.size() == 0) {
+ return mProperties == null
+ ? defaultValue : mProperties.getString(key, defaultValue);
+ }
+ return mSettingsParser.getString(key, defaultValue);
+ }
+ }
+
+ /**
+ * A mediator in which only individual keys in the DeviceConfig namespace will be overridden
+ * by the same key in the Settings constant. If the Settings constant does not have a specific
+ * key set, then the DeviceConfig value will be used instead.
+ */
+ public static class SettingsOverridesIndividualMediator
+ extends UserSettingDeviceConfigMediator {
+ public SettingsOverridesIndividualMediator(char keyValueListDelimiter) {
+ super(keyValueListDelimiter);
+ }
+
+ @Override
+ public boolean getBoolean(@NonNull String key, boolean defaultValue) {
+ return mSettingsParser.getBoolean(key,
+ mProperties == null ? defaultValue : mProperties.getBoolean(key, defaultValue));
+ }
+
+ @Override
+ public float getFloat(@NonNull String key, float defaultValue) {
+ return mSettingsParser.getFloat(key,
+ mProperties == null ? defaultValue : mProperties.getFloat(key, defaultValue));
+ }
+
+ @Override
+ public int getInt(@NonNull String key, int defaultValue) {
+ return mSettingsParser.getInt(key,
+ mProperties == null ? defaultValue : mProperties.getInt(key, defaultValue));
+ }
+
+ @Override
+ public long getLong(@NonNull String key, long defaultValue) {
+ return mSettingsParser.getLong(key,
+ mProperties == null ? defaultValue : mProperties.getLong(key, defaultValue));
+ }
+
+ @Override
+ public String getString(@NonNull String key, @Nullable String defaultValue) {
+ return mSettingsParser.getString(key,
+ mProperties == null ? defaultValue : mProperties.getString(key, defaultValue));
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
index b12da61d0b3f..e9c40964aee4 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateService.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
@@ -258,6 +258,11 @@ public class WebViewUpdateService extends SystemService {
}
@Override // Binder call
+ public WebViewProviderInfo getDefaultWebViewPackage() {
+ return WebViewUpdateService.this.mImpl.getDefaultWebViewPackage();
+ }
+
+ @Override // Binder call
public WebViewProviderInfo[] getAllWebViewPackages() {
return WebViewUpdateService.this.mImpl.getWebViewPackages();
}
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
index 26c3fba23bbc..60dc4ff224bc 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
@@ -421,6 +421,13 @@ class WebViewUpdateServiceImpl implements WebViewUpdateServiceInterface {
return providers;
}
+ @Override
+ public WebViewProviderInfo getDefaultWebViewPackage() {
+ throw new IllegalStateException(
+ "getDefaultWebViewPackage shouldn't be called if update_service_v2 flag is"
+ + " disabled.");
+ }
+
private static class ProviderAndPackageInfo {
public final WebViewProviderInfo provider;
public final PackageInfo packageInfo;
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl2.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl2.java
index 89cb4c802410..29782d9b8b88 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl2.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl2.java
@@ -24,6 +24,7 @@ import android.os.AsyncTask;
import android.os.Trace;
import android.os.UserHandle;
import android.text.TextUtils;
+import android.util.AndroidRuntimeException;
import android.util.Slog;
import android.webkit.UserPackage;
import android.webkit.WebViewFactory;
@@ -374,6 +375,23 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface {
return providers;
}
+ /**
+ * Returns the default WebView provider which should be first availableByDefault option in the
+ * system config.
+ */
+ @Override
+ public WebViewProviderInfo getDefaultWebViewPackage() {
+ WebViewProviderInfo[] webviewProviders = getWebViewPackages();
+ for (WebViewProviderInfo provider : webviewProviders) {
+ if (provider.availableByDefault) {
+ return provider;
+ }
+ }
+ // This should be unreachable because the config parser enforces that there is at least one
+ // availableByDefault provider.
+ throw new AndroidRuntimeException("No available by default WebView Provider.");
+ }
+
private static class ProviderAndPackageInfo {
public final WebViewProviderInfo provider;
public final PackageInfo packageInfo;
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceInterface.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceInterface.java
index a9c3dc45842f..1772ef9c7405 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceInterface.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceInterface.java
@@ -40,6 +40,8 @@ interface WebViewUpdateServiceInterface {
WebViewProviderInfo[] getValidWebViewPackages();
+ WebViewProviderInfo getDefaultWebViewPackage();
+
PackageInfo getCurrentWebViewPackage();
boolean isMultiProcessEnabled();
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index d6302e08fedb..bbaa6912417c 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1582,6 +1582,7 @@ class ActivityStarter {
// An activity has changed order/visibility or the task is occluded by a transient
// activity, so this isn't just deliver-to-top
&& mMovedToTopActivity == null
+ && !transitionController.hasOrderChanges()
&& !transitionController.isTransientHide(startedActivityRootTask)) {
// We just delivered to top, so there isn't an actual transition here.
if (!forceTransientTransition) {
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index eafaf8cb3776..4625b4fe07ef 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -60,9 +60,9 @@ import android.widget.Toast;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.FrameworkStatsLog;
-import com.android.internal.util.Preconditions;
import com.android.server.UiThread;
import com.android.server.am.PendingIntentRecord;
+import com.android.window.flags.Flags;
import java.lang.annotation.Retention;
import java.util.HashMap;
@@ -236,6 +236,7 @@ public class BackgroundActivityStartController {
private final @ActivityManager.ProcessState int mCallingUidProcState;
private final boolean mIsCallingUidPersistentSystemProcess;
private final BackgroundStartPrivileges mBalAllowedByPiSender;
+ private final BackgroundStartPrivileges mBalAllowedByPiCreatorWithHardening;
private final BackgroundStartPrivileges mBalAllowedByPiCreator;
private final String mRealCallingPackage;
private final int mRealCallingUid;
@@ -267,20 +268,33 @@ public class BackgroundActivityStartController {
mIntent = intent;
mRealCallingPackage = mService.getPackageNameIfUnique(realCallingUid, realCallingPid);
if (originatingPendingIntent == null) {
- // grant creator BAL privileges unless explicitly opted out
- mBalAllowedByPiCreator =
+ // grant BAL privileges unless explicitly opted out
+ mBalAllowedByPiCreatorWithHardening = mBalAllowedByPiCreator =
checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
== ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED
? BackgroundStartPrivileges.NONE
: BackgroundStartPrivileges.ALLOW_BAL;
+ mBalAllowedByPiSender =
+ checkedOptions.getPendingIntentBackgroundActivityStartMode()
+ == ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED
+ ? BackgroundStartPrivileges.NONE
+ : BackgroundStartPrivileges.ALLOW_BAL;
} else {
// for PendingIntents we restrict BAL based on target_sdk
- mBalAllowedByPiCreator = getBackgroundStartPrivilegesAllowedByCreator(
+ mBalAllowedByPiCreatorWithHardening = getBackgroundStartPrivilegesAllowedByCreator(
callingUid, callingPackage, checkedOptions);
+ final BackgroundStartPrivileges mBalAllowedByPiCreatorWithoutHardening =
+ checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
+ == ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED
+ ? BackgroundStartPrivileges.NONE
+ : BackgroundStartPrivileges.ALLOW_BAL;
+ mBalAllowedByPiCreator = balRequireOptInByPendingIntentCreator()
+ ? mBalAllowedByPiCreatorWithHardening
+ : mBalAllowedByPiCreatorWithoutHardening;
+ mBalAllowedByPiSender =
+ PendingIntentRecord.getBackgroundStartPrivilegesAllowedByCaller(
+ checkedOptions, realCallingUid, mRealCallingPackage);
}
- mBalAllowedByPiSender =
- PendingIntentRecord.getBackgroundStartPrivilegesAllowedByCaller(
- checkedOptions, realCallingUid, mRealCallingPackage);
mAppSwitchState = mService.getBalAppSwitchesState();
mCallingUidProcState = mService.mActiveUids.getUidState(callingUid);
mIsCallingUidPersistentSystemProcess =
@@ -319,10 +333,6 @@ public class BackgroundActivityStartController {
return BackgroundStartPrivileges.NONE;
case ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED:
// no explicit choice by the app - let us decide what to do
- if (!balRequireOptInByPendingIntentCreator()) {
- // if feature is disabled allow
- return BackgroundStartPrivileges.ALLOW_BAL;
- }
if (callingPackage != null) {
// determine based on the calling/creating package
boolean changeEnabled = CompatChanges.isChangeEnabled(
@@ -367,11 +377,6 @@ public class BackgroundActivityStartController {
return mOriginatingPendingIntent != null && hasRealCaller();
}
- private String dump(BalVerdict resultIfPiCreatorAllowsBal) {
- Preconditions.checkState(!isPendingIntent());
- return dump(resultIfPiCreatorAllowsBal, null);
- }
-
private boolean callerIsRealCaller() {
return mCallingUid == mRealCallingUid;
}
@@ -396,6 +401,8 @@ public class BackgroundActivityStartController {
sb.append("; inVisibleTask: ").append(mCallerApp.hasActivityInVisibleTask());
}
sb.append("; balAllowedByPiCreator: ").append(mBalAllowedByPiCreator);
+ sb.append("; balAllowedByPiCreatorWithHardening: ")
+ .append(mBalAllowedByPiCreatorWithHardening);
sb.append("; resultIfPiCreatorAllowsBal: ").append(resultIfPiCreatorAllowsBal);
sb.append("; hasRealCaller: ").append(hasRealCaller());
sb.append("; isPendingIntent: ").append(isPendingIntent());
@@ -579,11 +586,12 @@ public class BackgroundActivityStartController {
resultForCaller.allows() && resultForRealCaller.blocks());
}
+ // Handle cases with explicit opt-in
if (resultForCaller.allows()
&& checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
== ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED) {
if (DEBUG_ACTIVITY_STARTS) {
- Slog.d(TAG, "Activity start explicitly allowed by PI creator. "
+ Slog.d(TAG, "Activity start explicitly allowed by caller. "
+ state.dump(resultForCaller, resultForRealCaller));
}
return statsLog(resultForCaller, state);
@@ -592,11 +600,12 @@ public class BackgroundActivityStartController {
&& checkedOptions.getPendingIntentBackgroundActivityStartMode()
== ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED) {
if (DEBUG_ACTIVITY_STARTS) {
- Slog.d(TAG, "Activity start explicitly allowed by PI sender. "
+ Slog.d(TAG, "Activity start explicitly allowed by real caller. "
+ state.dump(resultForCaller, resultForRealCaller));
}
return statsLog(resultForRealCaller, state);
}
+ // Handle PendingIntent cases with default behavior next
boolean callerCanAllow = resultForCaller.allows()
&& checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
== ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED;
@@ -807,13 +816,29 @@ public class BackgroundActivityStartController {
"realCallingUid has BAL permission.");
}
- // don't abort if the realCallingUid has a visible window
- // TODO(b/171459802): We should check appSwitchAllowed also
- if (state.mRealCallingUidHasAnyVisibleWindow) {
- return new BalVerdict(BAL_ALLOW_PENDING_INTENT,
- /*background*/ false,
- "realCallingUid has visible (non-toast) window.");
+ // Normal apps with visible app window will be allowed to start activity if app switching
+ // is allowed, or apps like live wallpaper with non app visible window will be allowed.
+ final boolean appSwitchAllowedOrFg = state.mAppSwitchState == APP_SWITCH_ALLOW
+ || state.mAppSwitchState == APP_SWITCH_FG_ONLY;
+ if (Flags.balImproveRealCallerVisibilityCheck()) {
+ if (appSwitchAllowedOrFg && state.mRealCallingUidHasAnyVisibleWindow) {
+ return new BalVerdict(BAL_ALLOW_PENDING_INTENT,
+ /*background*/ false, "realCallingUid has visible window");
+ }
+ if (mService.mActiveUids.hasNonAppVisibleWindow(state.mRealCallingUid)) {
+ return new BalVerdict(BAL_ALLOW_PENDING_INTENT,
+ /*background*/ false, "realCallingUid has non-app visible window");
+ }
+ } else {
+ // don't abort if the realCallingUid has a visible window
+ // TODO(b/171459802): We should check appSwitchAllowed also
+ if (state.mRealCallingUidHasAnyVisibleWindow) {
+ return new BalVerdict(BAL_ALLOW_PENDING_INTENT,
+ /*background*/ false,
+ "realCallingUid has visible (non-toast) window.");
+ }
}
+
// if the realCallingUid is a persistent system process, abort if the IntentSender
// wasn't allowed to start an activity
if (state.mForcedBalByPiSender.allowsBackgroundActivityStarts()
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index de802b9b0e4d..5f082124dbcb 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -422,6 +422,11 @@ class Task extends TaskFragment {
// TODO: remove this once the recents animation is moved to the Shell
SurfaceControl mLastRecentsAnimationOverlay;
+ // A surface that is used by TaskFragmentOrganizer to place content on top of own activities and
+ // trusted TaskFragments.
+ @Nullable
+ DecorSurfaceContainer mDecorSurfaceContainer;
+
static final int LAYER_RANK_INVISIBLE = -1;
// Ranking (from top) of this task among all visible tasks. (-1 means it's not visible)
// This number will be assigned when we evaluate OOM scores for all visible tasks.
@@ -1540,6 +1545,11 @@ class Task extends TaskFragment {
mAtmService.getTaskChangeNotificationController().notifyTaskStackChanged();
}
+ if (mDecorSurfaceContainer != null && r == mDecorSurfaceContainer.mOwnerTaskFragment) {
+ // Remove the decor surface if the owner TaskFragment is removed;
+ removeDecorSurface();
+ }
+
if (hasChild()) {
updateEffectiveIntent();
@@ -2638,6 +2648,9 @@ class Task extends TaskFragment {
}
// If applicable let the TaskOrganizer know the Task is vanishing.
setTaskOrganizer(null);
+ if (mDecorSurfaceContainer != null) {
+ mDecorSurfaceContainer.release();
+ }
super.removeImmediately();
mRemoving = false;
@@ -3644,7 +3657,8 @@ class Task extends TaskFragment {
*/
TaskFragmentParentInfo getTaskFragmentParentInfo() {
return new TaskFragmentParentInfo(getConfiguration(), getDisplayId(),
- shouldBeVisible(null /* starting */), hasNonFinishingDirectActivity());
+ shouldBeVisible(null /* starting */), hasNonFinishingDirectActivity(),
+ getDecorSurface());
}
@Override
@@ -3666,6 +3680,62 @@ class Task extends TaskFragment {
}
}
+ @Override
+ void assignChildLayers(@NonNull SurfaceControl.Transaction t) {
+ int layer = 0;
+ boolean decorSurfacePlaced = false;
+
+ // We use two passes as a way to promote children which
+ // need Z-boosting to the end of the list.
+ for (int j = 0; j < mChildren.size(); ++j) {
+ final WindowContainer wc = mChildren.get(j);
+ wc.assignChildLayers(t);
+ if (!wc.needsZBoost()) {
+ // Place the decor surface under any untrusted content.
+ if (mDecorSurfaceContainer != null && !decorSurfacePlaced
+ && shouldPlaceDecorSurfaceBelowContainer(wc)) {
+ mDecorSurfaceContainer.assignLayer(t, layer++);
+ decorSurfacePlaced = true;
+ }
+ wc.assignLayer(t, layer++);
+
+ // Place the decor surface just above the owner TaskFragment.
+ if (mDecorSurfaceContainer != null && !decorSurfacePlaced
+ && wc == mDecorSurfaceContainer.mOwnerTaskFragment) {
+ mDecorSurfaceContainer.assignLayer(t, layer++);
+ decorSurfacePlaced = true;
+ }
+ }
+ }
+
+ // If not placed yet, the decor surface should be on top of all non-boosted children.
+ if (mDecorSurfaceContainer != null && !decorSurfacePlaced) {
+ mDecorSurfaceContainer.assignLayer(t, layer++);
+ decorSurfacePlaced = true;
+ }
+
+ for (int j = 0; j < mChildren.size(); ++j) {
+ final WindowContainer wc = mChildren.get(j);
+ if (wc.needsZBoost()) {
+ wc.assignLayer(t, layer++);
+ }
+ }
+ if (mOverlayHost != null) {
+ mOverlayHost.setLayer(t, layer++);
+ }
+ }
+
+ boolean shouldPlaceDecorSurfaceBelowContainer(@NonNull WindowContainer wc) {
+ boolean isOwnActivity =
+ wc.asActivityRecord() != null
+ && wc.asActivityRecord().isUid(effectiveUid);
+ boolean isTrustedTaskFragment =
+ wc.asTaskFragment() != null
+ && wc.asTaskFragment().isEmbedded()
+ && wc.asTaskFragment().isAllowedToBeEmbeddedInTrustedMode();
+ return !isOwnActivity && !isTrustedTaskFragment;
+ }
+
boolean isTaskId(int taskId) {
return mTaskId == taskId;
}
@@ -6673,4 +6743,77 @@ class Task extends TaskFragment {
mOverlayHost.dispatchInsetsChanged(s, mTmpRect);
}
}
+
+ /**
+ * Associates the decor surface with the given TF, or create one if there
+ * isn't one in the Task yet. The surface will be removed with the TF,
+ * and become invisible if the TF is invisible. */
+ void moveOrCreateDecorSurfaceFor(TaskFragment taskFragment) {
+ if (mDecorSurfaceContainer != null) {
+ mDecorSurfaceContainer.mOwnerTaskFragment = taskFragment;
+ } else {
+ mDecorSurfaceContainer = new DecorSurfaceContainer(taskFragment);
+ assignChildLayers();
+ sendTaskFragmentParentInfoChangedIfNeeded();
+ }
+ }
+
+ void removeDecorSurface() {
+ if (mDecorSurfaceContainer == null) {
+ return;
+ }
+ mDecorSurfaceContainer.release();
+ mDecorSurfaceContainer = null;
+ sendTaskFragmentParentInfoChangedIfNeeded();
+ }
+
+ @Nullable SurfaceControl getDecorSurface() {
+ return mDecorSurfaceContainer != null ? mDecorSurfaceContainer.mDecorSurface : null;
+ }
+
+ /**
+ * A decor surface that is requested by a {@code TaskFragmentOrganizer} which will be placed
+ * below children windows except for own Activities and TaskFragment in fully trusted mode.
+ */
+ @VisibleForTesting
+ class DecorSurfaceContainer {
+ @VisibleForTesting
+ @NonNull final SurfaceControl mContainerSurface;
+
+ @VisibleForTesting
+ @NonNull final SurfaceControl mDecorSurface;
+
+ // The TaskFragment that requested the decor surface. If it is destroyed, the decor surface
+ // is also released.
+ @VisibleForTesting
+ @NonNull TaskFragment mOwnerTaskFragment;
+
+ private DecorSurfaceContainer(@NonNull TaskFragment initialOwner) {
+ mOwnerTaskFragment = initialOwner;
+ mContainerSurface = makeSurface().setContainerLayer()
+ .setParent(mSurfaceControl)
+ .setName(mSurfaceControl + " - decor surface container")
+ .setEffectLayer()
+ .setHidden(false)
+ .setCallsite("Task.DecorSurfaceContainer")
+ .build();
+
+ mDecorSurface = makeSurface()
+ .setParent(mContainerSurface)
+ .setName(mSurfaceControl + " - decor surface")
+ .setHidden(false)
+ .setCallsite("Task.DecorSurfaceContainer")
+ .build();
+ }
+
+ private void assignLayer(@NonNull SurfaceControl.Transaction t, int layer) {
+ t.setLayer(mContainerSurface, layer);
+ t.setVisibility(mContainerSurface, mOwnerTaskFragment.isVisible());
+ }
+
+ private void release() {
+ mDecorSurface.release();
+ mContainerSurface.release();
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 8bc461f05387..39b4480a7da0 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -316,7 +316,8 @@ class TaskFragment extends WindowContainer<WindowContainer> {
/** Organizer that organizing this TaskFragment. */
@Nullable
private ITaskFragmentOrganizer mTaskFragmentOrganizer;
- private int mTaskFragmentOrganizerUid = INVALID_UID;
+ @VisibleForTesting
+ int mTaskFragmentOrganizerUid = INVALID_UID;
private @Nullable String mTaskFragmentOrganizerProcessName;
/** Client assigned unique token for this TaskFragment if this is created by an organizer. */
diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
index e7a1cf106a44..707f9fc9ea5f 100644
--- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
@@ -762,6 +762,8 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
.setTask(task)
.build());
}
+ // Make sure the parent info changed event will be dispatched if there are no other changes.
+ mAtmService.mWindowManager.mWindowPlacerLocked.requestTraversal();
}
boolean isSystemOrganizer(@NonNull IBinder organizerToken) {
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 642d22f0bb9a..e5604eca3df0 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -1756,6 +1756,27 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
}
/**
+ * Checks if the transition contains order changes.
+ *
+ * This is a shallow check that doesn't account for collection in parallel, unlike
+ * {@code collectOrderChanges}
+ */
+ boolean hasOrderChanges() {
+ ArrayList<Task> onTopTasks = new ArrayList<>();
+ // Iterate over target displays to get up to date on top tasks.
+ // Cannot use `mOnTopTasksAtReady` as it's not populated before the `applyReady` is called.
+ for (DisplayContent dc : mTargetDisplays) {
+ addOnTopTasks(dc, onTopTasks);
+ }
+ for (Task task : onTopTasks) {
+ if (!mOnTopTasksStart.contains(task)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
* Collect tasks which moved-to-top as part of this transition. This also updates the
* controller's latest-reported when relevant.
*
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index bacfda5fc528..e648d6417e88 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -792,6 +792,12 @@ class TransitionController {
mCollectingTransition.recordTaskOrder(wc);
}
+ /** @see Transition#hasOrderChanges */
+ boolean hasOrderChanges() {
+ if (mCollectingTransition == null) return false;
+ return mCollectingTransition.hasOrderChanges();
+ }
+
/**
* Collects the window containers which need to be synced with the changing display area into
* the current collecting transition.
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 208df6c768bf..2af656942a2a 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -23,7 +23,9 @@ import static android.app.WindowConfiguration.WINDOW_CONFIG_BOUNDS;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.window.TaskFragmentOperation.OP_TYPE_CLEAR_ADJACENT_TASK_FRAGMENTS;
import static android.window.TaskFragmentOperation.OP_TYPE_CREATE_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_CREATE_TASK_FRAGMENT_DECOR_SURFACE;
import static android.window.TaskFragmentOperation.OP_TYPE_DELETE_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE;
import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_BOTTOM_OF_TASK;
import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_FRONT;
import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_TOP_OF_TASK;
@@ -1468,6 +1470,16 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
}
break;
}
+ case OP_TYPE_CREATE_TASK_FRAGMENT_DECOR_SURFACE: {
+ final Task task = taskFragment.getTask();
+ task.moveOrCreateDecorSurfaceFor(taskFragment);
+ break;
+ }
+ case OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE: {
+ final Task task = taskFragment.getTask();
+ task.removeDecorSurface();
+ break;
+ }
}
return effects;
}
@@ -1507,6 +1519,19 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
return false;
}
+ // TODO (b/293654166) remove the decor surface checks once we clear security reviews
+ if ((opType == OP_TYPE_CREATE_TASK_FRAGMENT_DECOR_SURFACE
+ || opType == OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE)
+ && !mTaskFragmentOrganizerController.isSystemOrganizer(organizer.asBinder())) {
+ final Throwable exception = new SecurityException(
+ "Only a system organizer can perform OP_TYPE_CREATE_TASK_FRAGMENT_DECOR_SURFACE"
+ + " or OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE."
+ );
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
+ opType, exception);
+ return false;
+ }
+
final IBinder secondaryFragmentToken = operation.getSecondaryFragmentToken();
return secondaryFragmentToken == null
|| validateTaskFragment(mLaunchTaskFragments.get(secondaryFragmentToken), opType,
diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd
index 8473532754e4..c625b1e1eef7 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -592,42 +592,39 @@
minOccurs="0" maxOccurs="1">
<xs:annotation name="final"/>
</xs:element>
- <!-- Sets the brightness mapping of the desired screen brightness in nits to the
- corresponding lux for the current display -->
- <xs:element name="displayBrightnessMapping" type="displayBrightnessMapping"
+ <!-- Sets the brightness mapping of the desired screen brightness to the corresponding
+ lux for the current display -->
+ <xs:element name="luxToBrightnessMapping" type="luxToBrightnessMapping"
minOccurs="0" maxOccurs="1">
<xs:annotation name="final"/>
</xs:element>
</xs:sequence>
</xs:complexType>
- <!-- Represents the brightness mapping of the desired screen brightness in nits to the
- corresponding lux for the current display -->
- <xs:complexType name="displayBrightnessMapping">
- <xs:sequence>
- <!-- Sets the list of display brightness points, each representing the desired screen
- brightness in nits to the corresponding lux for the current display
-
- The N entries of this array define N + 1 control points as follows:
- (1-based arrays)
-
- Point 1: (0, nits[1]): currentLux <= 0
- Point 2: (lux[1], nits[2]): 0 < currentLux <= lux[1]
- Point 3: (lux[2], nits[3]): lux[2] < currentLux <= lux[3]
- ...
- Point N+1: (lux[N], nits[N+1]): lux[N] < currentLux
-
- The control points must be strictly increasing. Each control point
- corresponds to an entry in the brightness backlight values arrays.
- For example, if currentLux == lux[1] (first element of the levels array)
- then the brightness will be determined by nits[2] (second element
- of the brightness values array).
- -->
- <xs:element name="displayBrightnessPoint" type="displayBrightnessPoint"
- minOccurs="1" maxOccurs="unbounded">
- <xs:annotation name="final"/>
- </xs:element>
- </xs:sequence>
+ <!-- Sets the list of display brightness points, each representing the desired screen brightness
+ in a certain lux environment.
+
+ The first value of each point is the lux value and the second value is the brightness value.
+
+ The first lux value must be 0.
+
+ The control points must be strictly increasing.
+
+ Example: if currentLux == the second lux value in the mapping then the brightness will be
+ determined by the second brightness value in the mapping. Spline interpolation is used
+ to determine the auto-brightness values for lux levels between these control points.
+
+ The brightness values must be non-negative decimals within the range between the first and
+ the last brightness values in screenBrightnessMap.
+
+ This is used in place of config_autoBrightnessLevels and config_autoBrightnessLcdBacklightValues
+ defined in the config XML resource.
+ -->
+ <xs:complexType name="luxToBrightnessMapping">
+ <xs:element name="map" type="nonNegativeFloatToFloatMap">
+ <xs:annotation name="nonnull"/>
+ <xs:annotation name="final"/>
+ </xs:element>
</xs:complexType>
<!-- Represents a point in the display brightness mapping, representing the lux level from the
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index 2437261e3a54..8c8c1230f944 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -7,14 +7,14 @@ package com.android.server.display.config {
method public final java.math.BigInteger getBrighteningLightDebounceMillis();
method public final java.math.BigInteger getDarkeningLightDebounceIdleMillis();
method public final java.math.BigInteger getDarkeningLightDebounceMillis();
- method public final com.android.server.display.config.DisplayBrightnessMapping getDisplayBrightnessMapping();
method public boolean getEnabled();
+ method public final com.android.server.display.config.LuxToBrightnessMapping getLuxToBrightnessMapping();
method public final void setBrighteningLightDebounceIdleMillis(java.math.BigInteger);
method public final void setBrighteningLightDebounceMillis(java.math.BigInteger);
method public final void setDarkeningLightDebounceIdleMillis(java.math.BigInteger);
method public final void setDarkeningLightDebounceMillis(java.math.BigInteger);
- method public final void setDisplayBrightnessMapping(com.android.server.display.config.DisplayBrightnessMapping);
method public void setEnabled(boolean);
+ method public final void setLuxToBrightnessMapping(com.android.server.display.config.LuxToBrightnessMapping);
}
public class BlockingZoneConfig {
@@ -78,11 +78,6 @@ package com.android.server.display.config {
method public java.util.List<com.android.server.display.config.Density> getDensity();
}
- public class DisplayBrightnessMapping {
- ctor public DisplayBrightnessMapping();
- method public final java.util.List<com.android.server.display.config.DisplayBrightnessPoint> getDisplayBrightnessPoint();
- }
-
public class DisplayBrightnessPoint {
ctor public DisplayBrightnessPoint();
method public final java.math.BigInteger getLux();
@@ -222,6 +217,12 @@ package com.android.server.display.config {
method @NonNull public final java.util.List<com.android.server.display.config.BrightnessLimitMap> getBrightnessLimitMap();
}
+ public class LuxToBrightnessMapping {
+ ctor public LuxToBrightnessMapping();
+ method @NonNull public final com.android.server.display.config.NonNegativeFloatToFloatMap getMap();
+ method public final void setMap(@NonNull com.android.server.display.config.NonNegativeFloatToFloatMap);
+ }
+
public class NitsMap {
ctor public NitsMap();
method public String getInterpolation();
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 0a2e80606e96..1919eb33c38c 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -2112,6 +2112,15 @@ public final class SystemServer implements Dumpable {
networkPolicy.bindConnectivityManager();
t.traceEnd();
+ t.traceBegin("StartSecurityStateManagerService");
+ try {
+ ServiceManager.addService(Context.SECURITY_STATE_SERVICE,
+ new SecurityStateManagerService(context));
+ } catch (Throwable e) {
+ reportWtf("starting SecurityStateManagerService", e);
+ }
+ t.traceEnd();
+
t.traceBegin("StartVpnManagerService");
try {
vpnManager = VpnManagerService.create(context);
diff --git a/services/robotests/src/com/android/server/media/AudioPoliciesBluetoothRouteControllerTest.java b/services/robotests/src/com/android/server/media/AudioPoliciesBluetoothRouteControllerTest.java
deleted file mode 100644
index 0ad418427183..000000000000
--- a/services/robotests/src/com/android/server/media/AudioPoliciesBluetoothRouteControllerTest.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.media;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.when;
-
-import android.app.Application;
-import android.bluetooth.BluetoothA2dp;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothManager;
-import android.bluetooth.BluetoothProfile;
-import android.content.Context;
-import android.content.Intent;
-import android.media.AudioManager;
-import android.media.MediaRoute2Info;
-import android.os.UserHandle;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.Shadows;
-import org.robolectric.shadows.ShadowBluetoothAdapter;
-import org.robolectric.shadows.ShadowBluetoothDevice;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-@RunWith(RobolectricTestRunner.class)
-public class AudioPoliciesBluetoothRouteControllerTest {
-
- private static final String DEVICE_ADDRESS_UNKNOWN = ":unknown:ip:address:";
- private static final String DEVICE_ADDRESS_SAMPLE_1 = "30:59:8B:E4:C6:35";
- private static final String DEVICE_ADDRESS_SAMPLE_2 = "0D:0D:A6:FF:8D:B6";
- private static final String DEVICE_ADDRESS_SAMPLE_3 = "2D:9B:0C:C2:6F:78";
- private static final String DEVICE_ADDRESS_SAMPLE_4 = "66:88:F9:2D:A8:1E";
-
- private Context mContext;
-
- private ShadowBluetoothAdapter mShadowBluetoothAdapter;
-
- @Mock
- private BluetoothRouteController.BluetoothRoutesUpdatedListener mListener;
-
- @Mock
- private BluetoothProfileMonitor mBluetoothProfileMonitor;
-
- private AudioPoliciesBluetoothRouteController mAudioPoliciesBluetoothRouteController;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
-
- Application application = ApplicationProvider.getApplicationContext();
- mContext = application;
-
- BluetoothManager bluetoothManager = (BluetoothManager)
- mContext.getSystemService(Context.BLUETOOTH_SERVICE);
-
- BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
- mShadowBluetoothAdapter = Shadows.shadowOf(bluetoothAdapter);
-
- mAudioPoliciesBluetoothRouteController =
- new AudioPoliciesBluetoothRouteController(mContext, bluetoothAdapter,
- mBluetoothProfileMonitor, mListener) {
- @Override
- boolean isDeviceConnected(BluetoothDevice device) {
- return true;
- }
- };
-
- // Enable A2DP profile.
- when(mBluetoothProfileMonitor.isProfileSupported(eq(BluetoothProfile.A2DP), any()))
- .thenReturn(true);
- mShadowBluetoothAdapter.setProfileConnectionState(BluetoothProfile.A2DP,
- BluetoothProfile.STATE_CONNECTED);
-
- mAudioPoliciesBluetoothRouteController.start(UserHandle.of(0));
- }
-
- @Test
- public void getSelectedRoute_noBluetoothRoutesAvailable_returnsNull() {
- assertThat(mAudioPoliciesBluetoothRouteController.getSelectedRoute()).isNull();
- }
-
- @Test
- public void selectRoute_noBluetoothRoutesAvailable_returnsFalse() {
- assertThat(mAudioPoliciesBluetoothRouteController
- .selectRoute(DEVICE_ADDRESS_UNKNOWN)).isFalse();
- }
-
- @Test
- public void selectRoute_noDeviceWithGivenAddress_returnsFalse() {
- Set<BluetoothDevice> devices = generateFakeBluetoothDevicesSet(
- DEVICE_ADDRESS_SAMPLE_1, DEVICE_ADDRESS_SAMPLE_3);
-
- mShadowBluetoothAdapter.setBondedDevices(devices);
-
- assertThat(mAudioPoliciesBluetoothRouteController
- .selectRoute(DEVICE_ADDRESS_SAMPLE_2)).isFalse();
- }
-
- @Test
- public void selectRoute_deviceIsInDevicesSet_returnsTrue() {
- Set<BluetoothDevice> devices = generateFakeBluetoothDevicesSet(
- DEVICE_ADDRESS_SAMPLE_1, DEVICE_ADDRESS_SAMPLE_2);
-
- mShadowBluetoothAdapter.setBondedDevices(devices);
-
- assertThat(mAudioPoliciesBluetoothRouteController
- .selectRoute(DEVICE_ADDRESS_SAMPLE_1)).isTrue();
- }
-
- @Test
- public void selectRoute_resetSelectedDevice_returnsTrue() {
- Set<BluetoothDevice> devices = generateFakeBluetoothDevicesSet(
- DEVICE_ADDRESS_SAMPLE_1, DEVICE_ADDRESS_SAMPLE_2);
-
- mShadowBluetoothAdapter.setBondedDevices(devices);
-
- mAudioPoliciesBluetoothRouteController.selectRoute(DEVICE_ADDRESS_SAMPLE_1);
- assertThat(mAudioPoliciesBluetoothRouteController.selectRoute(null)).isTrue();
- }
-
- @Test
- public void selectRoute_noSelectedDevice_returnsTrue() {
- Set<BluetoothDevice> devices = generateFakeBluetoothDevicesSet(
- DEVICE_ADDRESS_SAMPLE_1, DEVICE_ADDRESS_SAMPLE_2);
-
- mShadowBluetoothAdapter.setBondedDevices(devices);
-
- assertThat(mAudioPoliciesBluetoothRouteController.selectRoute(null)).isTrue();
- }
-
- @Test
- public void getSelectedRoute_updateRouteFailed_returnsNull() {
- Set<BluetoothDevice> devices = generateFakeBluetoothDevicesSet(
- DEVICE_ADDRESS_SAMPLE_1, DEVICE_ADDRESS_SAMPLE_2);
-
- mShadowBluetoothAdapter.setBondedDevices(devices);
- mAudioPoliciesBluetoothRouteController
- .selectRoute(DEVICE_ADDRESS_SAMPLE_3);
-
- assertThat(mAudioPoliciesBluetoothRouteController.getSelectedRoute()).isNull();
- }
-
- @Test
- public void getSelectedRoute_updateRouteSuccessful_returnsUpdateDevice() {
- Set<BluetoothDevice> devices = generateFakeBluetoothDevicesSet(
- DEVICE_ADDRESS_SAMPLE_1, DEVICE_ADDRESS_SAMPLE_2, DEVICE_ADDRESS_SAMPLE_4);
-
- assertThat(mAudioPoliciesBluetoothRouteController.getSelectedRoute()).isNull();
-
- mShadowBluetoothAdapter.setBondedDevices(devices);
-
- assertThat(mAudioPoliciesBluetoothRouteController
- .selectRoute(DEVICE_ADDRESS_SAMPLE_4)).isTrue();
-
- MediaRoute2Info selectedRoute = mAudioPoliciesBluetoothRouteController.getSelectedRoute();
- assertThat(selectedRoute.getAddress()).isEqualTo(DEVICE_ADDRESS_SAMPLE_4);
- }
-
- @Test
- public void getSelectedRoute_resetSelectedRoute_returnsNull() {
- Set<BluetoothDevice> devices = generateFakeBluetoothDevicesSet(
- DEVICE_ADDRESS_SAMPLE_1, DEVICE_ADDRESS_SAMPLE_2, DEVICE_ADDRESS_SAMPLE_4);
-
- mShadowBluetoothAdapter.setBondedDevices(devices);
-
- // Device is not null now.
- mAudioPoliciesBluetoothRouteController.selectRoute(DEVICE_ADDRESS_SAMPLE_4);
- // Rest the device.
- mAudioPoliciesBluetoothRouteController.selectRoute(null);
-
- assertThat(mAudioPoliciesBluetoothRouteController.getSelectedRoute())
- .isNull();
- }
-
- @Test
- public void getTransferableRoutes_noSelectedRoute_returnsAllBluetoothDevices() {
- String[] addresses = new String[] { DEVICE_ADDRESS_SAMPLE_1,
- DEVICE_ADDRESS_SAMPLE_2, DEVICE_ADDRESS_SAMPLE_4 };
- Set<BluetoothDevice> devices = generateFakeBluetoothDevicesSet(addresses);
- mShadowBluetoothAdapter.setBondedDevices(devices);
-
- // Force route controller to update bluetooth devices list.
- sendBluetoothDevicesChangedBroadcast();
-
- Set<String> transferableDevices = extractAddressesListFrom(
- mAudioPoliciesBluetoothRouteController.getTransferableRoutes());
- assertThat(transferableDevices).containsExactlyElementsIn(addresses);
- }
-
- @Test
- public void getTransferableRoutes_hasSelectedRoute_returnsRoutesWithoutSelectedDevice() {
- String[] addresses = new String[] { DEVICE_ADDRESS_SAMPLE_1,
- DEVICE_ADDRESS_SAMPLE_2, DEVICE_ADDRESS_SAMPLE_4 };
- Set<BluetoothDevice> devices = generateFakeBluetoothDevicesSet(addresses);
- mShadowBluetoothAdapter.setBondedDevices(devices);
-
- // Force route controller to update bluetooth devices list.
- sendBluetoothDevicesChangedBroadcast();
- mAudioPoliciesBluetoothRouteController.selectRoute(DEVICE_ADDRESS_SAMPLE_4);
-
- Set<String> transferableDevices = extractAddressesListFrom(
- mAudioPoliciesBluetoothRouteController.getTransferableRoutes());
- assertThat(transferableDevices).containsExactly(DEVICE_ADDRESS_SAMPLE_1,
- DEVICE_ADDRESS_SAMPLE_2);
- }
-
- @Test
- public void getAllBluetoothRoutes_hasSelectedRoute_returnsAllRoutes() {
- String[] addresses = new String[] { DEVICE_ADDRESS_SAMPLE_1,
- DEVICE_ADDRESS_SAMPLE_2, DEVICE_ADDRESS_SAMPLE_4 };
- Set<BluetoothDevice> devices = generateFakeBluetoothDevicesSet(addresses);
- mShadowBluetoothAdapter.setBondedDevices(devices);
-
- // Force route controller to update bluetooth devices list.
- sendBluetoothDevicesChangedBroadcast();
- mAudioPoliciesBluetoothRouteController.selectRoute(DEVICE_ADDRESS_SAMPLE_4);
-
- Set<String> bluetoothDevices = extractAddressesListFrom(
- mAudioPoliciesBluetoothRouteController.getAllBluetoothRoutes());
- assertThat(bluetoothDevices).containsExactlyElementsIn(addresses);
- }
-
- @Test
- public void updateVolumeForDevice_setVolumeForA2DPTo25_selectedRouteVolumeIsUpdated() {
- String[] addresses = new String[] { DEVICE_ADDRESS_SAMPLE_1,
- DEVICE_ADDRESS_SAMPLE_2, DEVICE_ADDRESS_SAMPLE_4 };
- Set<BluetoothDevice> devices = generateFakeBluetoothDevicesSet(addresses);
- mShadowBluetoothAdapter.setBondedDevices(devices);
-
- // Force route controller to update bluetooth devices list.
- sendBluetoothDevicesChangedBroadcast();
- mAudioPoliciesBluetoothRouteController.selectRoute(DEVICE_ADDRESS_SAMPLE_4);
-
- mAudioPoliciesBluetoothRouteController.updateVolumeForDevices(
- AudioManager.DEVICE_OUT_BLUETOOTH_A2DP, 25);
-
- MediaRoute2Info selectedRoute = mAudioPoliciesBluetoothRouteController.getSelectedRoute();
- assertThat(selectedRoute.getVolume()).isEqualTo(25);
- }
-
- private void sendBluetoothDevicesChangedBroadcast() {
- Intent intent = new Intent(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED);
- mContext.sendBroadcast(intent);
- }
-
- private static Set<String> extractAddressesListFrom(Collection<MediaRoute2Info> routes) {
- Set<String> addresses = new HashSet<>();
-
- for (MediaRoute2Info route: routes) {
- addresses.add(route.getAddress());
- }
-
- return addresses;
- }
-
- private static Set<BluetoothDevice> generateFakeBluetoothDevicesSet(String... addresses) {
- Set<BluetoothDevice> devices = new HashSet<>();
-
- for (String address: addresses) {
- devices.add(ShadowBluetoothDevice.newInstance(address));
- }
-
- return devices;
- }
-}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java
index 97e582607133..a2e80f0d9b9b 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java
@@ -104,7 +104,7 @@ public class BrightnessMappingStrategyTest {
468.5f,
};
- private static final int[] DISPLAY_LEVELS_BACKLIGHT = {
+ private static final int[] DISPLAY_LEVELS_INT = {
9,
30,
45,
@@ -118,6 +118,20 @@ public class BrightnessMappingStrategyTest {
255
};
+ private static final float[] DISPLAY_LEVELS = {
+ 0.03f,
+ 0.11f,
+ 0.17f,
+ 0.24f,
+ 0.3f,
+ 0.37f,
+ 0.46f,
+ 0.57f,
+ 0.7f,
+ 0.87f,
+ 1
+ };
+
private static final float[] DISPLAY_RANGE_NITS = { 2.685f, 478.5f };
private static final float[] BACKLIGHT_RANGE_ZERO_TO_ONE = { 0.0f, 1.0f };
private static final float[] DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT = { 0.03149606299f, 1.0f };
@@ -155,23 +169,23 @@ public class BrightnessMappingStrategyTest {
DisplayWhiteBalanceController mMockDwbc;
@Test
- public void testSimpleStrategyMappingAtControlPoints() {
- Resources res = createResources(DISPLAY_LEVELS_BACKLIGHT);
+ public void testSimpleStrategyMappingAtControlPoints_IntConfig() {
+ Resources res = createResources(DISPLAY_LEVELS_INT);
DisplayDeviceConfig ddc = createDdc();
BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc, mMockDwbc);
assertNotNull("BrightnessMappingStrategy should not be null", simple);
for (int i = 0; i < LUX_LEVELS.length; i++) {
final float expectedLevel = MathUtils.map(PowerManager.BRIGHTNESS_OFF + 1,
PowerManager.BRIGHTNESS_ON, PowerManager.BRIGHTNESS_MIN,
- PowerManager.BRIGHTNESS_MAX, DISPLAY_LEVELS_BACKLIGHT[i]);
+ PowerManager.BRIGHTNESS_MAX, DISPLAY_LEVELS_INT[i]);
assertEquals(expectedLevel,
simple.getBrightness(LUX_LEVELS[i]), 0.0001f /*tolerance*/);
}
}
@Test
- public void testSimpleStrategyMappingBetweenControlPoints() {
- Resources res = createResources(DISPLAY_LEVELS_BACKLIGHT);
+ public void testSimpleStrategyMappingBetweenControlPoints_IntConfig() {
+ Resources res = createResources(DISPLAY_LEVELS_INT);
DisplayDeviceConfig ddc = createDdc();
BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc, mMockDwbc);
assertNotNull("BrightnessMappingStrategy should not be null", simple);
@@ -179,14 +193,42 @@ public class BrightnessMappingStrategyTest {
final float lux = (LUX_LEVELS[i - 1] + LUX_LEVELS[i]) / 2;
final float backlight = simple.getBrightness(lux) * PowerManager.BRIGHTNESS_ON;
assertTrue("Desired brightness should be between adjacent control points.",
- backlight > DISPLAY_LEVELS_BACKLIGHT[i - 1]
- && backlight < DISPLAY_LEVELS_BACKLIGHT[i]);
+ backlight > DISPLAY_LEVELS_INT[i - 1]
+ && backlight < DISPLAY_LEVELS_INT[i]);
+ }
+ }
+
+ @Test
+ public void testSimpleStrategyMappingAtControlPoints_FloatConfig() {
+ Resources res = createResources(EMPTY_INT_ARRAY);
+ DisplayDeviceConfig ddc = createDdc(EMPTY_FLOAT_ARRAY, EMPTY_FLOAT_ARRAY, LUX_LEVELS,
+ EMPTY_FLOAT_ARRAY, DISPLAY_LEVELS);
+ BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc, mMockDwbc);
+ assertNotNull("BrightnessMappingStrategy should not be null", simple);
+ for (int i = 0; i < LUX_LEVELS.length; i++) {
+ assertEquals(DISPLAY_LEVELS[i], simple.getBrightness(LUX_LEVELS[i]),
+ /* tolerance= */ 0.0001f);
+ }
+ }
+
+ @Test
+ public void testSimpleStrategyMappingBetweenControlPoints_FloatConfig() {
+ Resources res = createResources(EMPTY_INT_ARRAY);
+ DisplayDeviceConfig ddc = createDdc(EMPTY_FLOAT_ARRAY, EMPTY_FLOAT_ARRAY, LUX_LEVELS,
+ EMPTY_FLOAT_ARRAY, DISPLAY_LEVELS);
+ BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc, mMockDwbc);
+ assertNotNull("BrightnessMappingStrategy should not be null", simple);
+ for (int i = 1; i < LUX_LEVELS.length; i++) {
+ final float lux = (LUX_LEVELS[i - 1] + LUX_LEVELS[i]) / 2;
+ final float brightness = simple.getBrightness(lux);
+ assertTrue("Desired brightness should be between adjacent control points.",
+ brightness > DISPLAY_LEVELS[i - 1] && brightness < DISPLAY_LEVELS[i]);
}
}
@Test
public void testSimpleStrategyIgnoresNewConfiguration() {
- Resources res = createResources(DISPLAY_LEVELS_BACKLIGHT);
+ Resources res = createResources(DISPLAY_LEVELS_INT);
DisplayDeviceConfig ddc = createDdc();
BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc);
@@ -201,14 +243,14 @@ public class BrightnessMappingStrategyTest {
@Test
public void testSimpleStrategyIgnoresNullConfiguration() {
- Resources res = createResources(DISPLAY_LEVELS_BACKLIGHT);
+ Resources res = createResources(DISPLAY_LEVELS_INT);
DisplayDeviceConfig ddc = createDdc();
BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc);
strategy.setBrightnessConfiguration(null);
- final int n = DISPLAY_LEVELS_BACKLIGHT.length;
+ final int n = DISPLAY_LEVELS_INT.length;
final float expectedBrightness =
- (float) DISPLAY_LEVELS_BACKLIGHT[n - 1] / PowerManager.BRIGHTNESS_ON;
+ (float) DISPLAY_LEVELS_INT[n - 1] / PowerManager.BRIGHTNESS_ON;
assertEquals(expectedBrightness,
strategy.getBrightness(LUX_LEVELS[n - 1]), 0.0001f /*tolerance*/);
}
@@ -322,7 +364,7 @@ public class BrightnessMappingStrategyTest {
@Test
public void testDefaultStrategyIsPhysical() {
- Resources res = createResources(DISPLAY_LEVELS_BACKLIGHT);
+ Resources res = createResources(DISPLAY_LEVELS_INT);
DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS,
DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, LUX_LEVELS, DISPLAY_LEVELS_NITS);
BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc);
@@ -363,13 +405,13 @@ public class BrightnessMappingStrategyTest {
BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc);
assertNull(strategy);
- res = createResources(DISPLAY_LEVELS_BACKLIGHT);
+ res = createResources(DISPLAY_LEVELS_INT);
strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc);
assertNull(strategy);
// Extra backlight level
final int[] backlight = Arrays.copyOf(
- DISPLAY_LEVELS_BACKLIGHT, DISPLAY_LEVELS_BACKLIGHT.length + 1);
+ DISPLAY_LEVELS_INT, DISPLAY_LEVELS_INT.length + 1);
backlight[backlight.length - 1] = backlight[backlight.length - 2] + 1;
res = createResources(backlight);
ddc = createDdc(DISPLAY_RANGE_NITS,
@@ -410,7 +452,7 @@ public class BrightnessMappingStrategyTest {
LUX_LEVELS, DISPLAY_LEVELS_NITS);
assertStrategyAdaptsToUserDataPoints(BrightnessMappingStrategy.create(res, ddc, mMockDwbc));
ddc = createDdc(DISPLAY_RANGE_NITS, BACKLIGHT_RANGE_ZERO_TO_ONE);
- res = createResources(DISPLAY_LEVELS_BACKLIGHT);
+ res = createResources(DISPLAY_LEVELS_INT);
assertStrategyAdaptsToUserDataPoints(BrightnessMappingStrategy.create(res, ddc, mMockDwbc));
}
@@ -546,16 +588,24 @@ public class BrightnessMappingStrategyTest {
when(mockDdc.getBrightness()).thenReturn(backlightArray);
when(mockDdc.getAutoBrightnessBrighteningLevelsLux()).thenReturn(LUX_LEVELS);
when(mockDdc.getAutoBrightnessBrighteningLevelsNits()).thenReturn(EMPTY_FLOAT_ARRAY);
+ when(mockDdc.getAutoBrightnessBrighteningLevels()).thenReturn(EMPTY_FLOAT_ARRAY);
return mockDdc;
}
private DisplayDeviceConfig createDdc(float[] nitsArray, float[] backlightArray,
float[] luxLevelsFloat, float[] brightnessLevelsNits) {
+ return createDdc(nitsArray, backlightArray, luxLevelsFloat, brightnessLevelsNits,
+ EMPTY_FLOAT_ARRAY);
+ }
+
+ private DisplayDeviceConfig createDdc(float[] nitsArray, float[] backlightArray,
+ float[] luxLevelsFloat, float[] brightnessLevelsNits, float[] brightnessLevels) {
DisplayDeviceConfig mockDdc = mock(DisplayDeviceConfig.class);
when(mockDdc.getNits()).thenReturn(nitsArray);
when(mockDdc.getBrightness()).thenReturn(backlightArray);
when(mockDdc.getAutoBrightnessBrighteningLevelsLux()).thenReturn(luxLevelsFloat);
when(mockDdc.getAutoBrightnessBrighteningLevelsNits()).thenReturn(brightnessLevelsNits);
+ when(mockDdc.getAutoBrightnessBrighteningLevels()).thenReturn(brightnessLevels);
return mockDdc;
}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
index e80e9e805369..31d7e88e671b 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
@@ -50,6 +50,7 @@ import com.android.internal.R;
import com.android.internal.display.BrightnessSynchronizer;
import com.android.server.display.config.HdrBrightnessData;
import com.android.server.display.config.ThermalStatus;
+import com.android.server.display.feature.DisplayManagerFlags;
import org.junit.Before;
import org.junit.Test;
@@ -93,10 +94,14 @@ public final class DisplayDeviceConfigTest {
@Mock
private Resources mResources;
+ @Mock
+ private DisplayManagerFlags mFlags;
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mContext.getResources()).thenReturn(mResources);
+ when(mFlags.areAutoBrightnessModesEnabled()).thenReturn(true);
mockDeviceConfigs();
}
@@ -111,10 +116,6 @@ public final class DisplayDeviceConfigTest {
assertArrayEquals(mDisplayDeviceConfig.getBrightness(), BRIGHTNESS, ZERO_DELTA);
assertArrayEquals(mDisplayDeviceConfig.getNits(), NITS, ZERO_DELTA);
assertArrayEquals(mDisplayDeviceConfig.getBacklight(), BRIGHTNESS, ZERO_DELTA);
- assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), new
- float[]{0.0f, 50.0f, 80.0f}, ZERO_DELTA);
- assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsNits(), new
- float[]{45.32f, 75.43f}, ZERO_DELTA);
// Test thresholds
assertEquals(10, mDisplayDeviceConfig.getAmbientLuxBrighteningMinThreshold(),
@@ -607,7 +608,7 @@ public final class DisplayDeviceConfigTest {
assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsNits(), new
float[]{2.0f, 200.0f, 600.0f}, ZERO_DELTA);
assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), new
- float[]{0.0f, 0.0f, 110.0f, 500.0f}, ZERO_DELTA);
+ float[]{0.0f, 110.0f, 500.0f}, ZERO_DELTA);
// Test thresholds
assertEquals(0, mDisplayDeviceConfig.getAmbientLuxBrighteningMinThreshold(), ZERO_DELTA);
@@ -727,6 +728,31 @@ public final class DisplayDeviceConfigTest {
assertEquals(0.1f, mDisplayDeviceConfig.getBrightnessCapForWearBedtimeMode(), ZERO_DELTA);
}
+ @Test
+ public void testAutoBrightnessBrighteningLevels() throws IOException {
+ setupDisplayDeviceConfigFromDisplayConfigFile(getContent(getValidLuxThrottling(),
+ getValidProxSensor(), /* includeIdleMode= */ false));
+
+ assertArrayEquals(new float[]{0.0f, 80},
+ mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), ZERO_DELTA);
+ assertArrayEquals(new float[]{0.2f, 0.3f},
+ mDisplayDeviceConfig.getAutoBrightnessBrighteningLevels(), SMALL_DELTA);
+ }
+
+ @Test
+ public void testAutoBrightnessBrighteningLevels_FeatureFlagOff() throws IOException {
+ when(mFlags.areAutoBrightnessModesEnabled()).thenReturn(false);
+ setupDisplayDeviceConfigFromConfigResourceFile();
+ setupDisplayDeviceConfigFromDisplayConfigFile(getContent(getValidLuxThrottling(),
+ getValidProxSensor(), /* includeIdleMode= */ false));
+
+ assertNull(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevels());
+ assertArrayEquals(new float[]{0, 110, 500},
+ mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), ZERO_DELTA);
+ assertArrayEquals(new float[]{2, 200, 600},
+ mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsNits(), SMALL_DELTA);
+ }
+
private String getValidLuxThrottling() {
return "<luxThrottling>\n"
+ " <brightnessLimitMap>\n"
@@ -1048,8 +1074,8 @@ public final class DisplayDeviceConfigTest {
+ "<screenBrightnessRampDecreaseMaxIdleMillis>"
+ "5000"
+ "</screenBrightnessRampDecreaseMaxIdleMillis>\n";
-
}
+
private String getContent() {
return getContent(getValidLuxThrottling(), getValidProxSensor(),
/* includeIdleMode= */ true);
@@ -1100,16 +1126,18 @@ public final class DisplayDeviceConfigTest {
+ "<brighteningLightDebounceMillis>2000</brighteningLightDebounceMillis>\n"
+ "<darkeningLightDebounceMillis>1000</darkeningLightDebounceMillis>\n"
+ (includeIdleMode ? getRampSpeedsIdle() : "")
- + "<displayBrightnessMapping>\n"
- + "<displayBrightnessPoint>\n"
- + "<lux>50</lux>\n"
- + "<nits>45.32</nits>\n"
- + "</displayBrightnessPoint>\n"
- + "<displayBrightnessPoint>\n"
- + "<lux>80</lux>\n"
- + "<nits>75.43</nits>\n"
- + "</displayBrightnessPoint>\n"
- + "</displayBrightnessMapping>\n"
+ + "<luxToBrightnessMapping>\n"
+ + "<map>\n"
+ + "<point>\n"
+ + "<first>0</first>\n"
+ + "<second>0.2</second>\n"
+ + "</point>\n"
+ + "<point>\n"
+ + "<first>80</first>\n"
+ + "<second>0.3</second>\n"
+ + "</point>\n"
+ + "</map>\n"
+ + "</luxToBrightnessMapping>\n"
+ "</autoBrightness>\n"
+ getPowerThrottlingConfig()
+ "<highBrightnessMode enabled=\"true\">\n"
@@ -1386,7 +1414,7 @@ public final class DisplayDeviceConfigTest {
private void setupDisplayDeviceConfigFromDisplayConfigFile(String content) throws IOException {
Path tempFile = Files.createTempFile("display_config", ".tmp");
Files.write(tempFile, content.getBytes(StandardCharsets.UTF_8));
- mDisplayDeviceConfig = new DisplayDeviceConfig(mContext);
+ mDisplayDeviceConfig = new DisplayDeviceConfig(mContext, mFlags);
mDisplayDeviceConfig.initFromFile(tempFile.toFile());
}
@@ -1395,25 +1423,15 @@ public final class DisplayDeviceConfigTest {
when(mResources.obtainTypedArray(
com.android.internal.R.array.config_screenBrightnessNits))
.thenReturn(screenBrightnessNits);
- TypedArray screenBrightnessBacklight = createFloatTypedArray(new
- float[]{0.0f, 120.0f, 255.0f});
- when(mResources.obtainTypedArray(
- com.android.internal.R.array.config_screenBrightnessBacklight))
- .thenReturn(screenBrightnessBacklight);
when(mResources.getIntArray(com.android.internal.R.array
.config_screenBrightnessBacklight)).thenReturn(new int[]{0, 120, 255});
- when(mResources.getIntArray(com.android.internal.R.array
- .config_autoBrightnessLevels)).thenReturn(new int[]{30, 80});
- when(mResources.getIntArray(com.android.internal.R.array
- .config_autoBrightnessDisplayValuesNits)).thenReturn(new int[]{25, 55});
-
TypedArray screenBrightnessLevelNits = createFloatTypedArray(new
float[]{2.0f, 200.0f, 600.0f});
when(mResources.obtainTypedArray(
com.android.internal.R.array.config_autoBrightnessDisplayValuesNits))
.thenReturn(screenBrightnessLevelNits);
- int[] screenBrightnessLevelLux = new int[]{0, 110, 500};
+ int[] screenBrightnessLevelLux = new int[]{110, 500};
when(mResources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLevels))
.thenReturn(screenBrightnessLevelLux);
@@ -1475,7 +1493,8 @@ public final class DisplayDeviceConfigTest {
R.integer.config_screenBrightnessCapForWearBedtimeMode))
.thenReturn(35);
- mDisplayDeviceConfig = DisplayDeviceConfig.create(mContext, true);
+ mDisplayDeviceConfig = DisplayDeviceConfig.create(mContext, /* useConfigXml= */ true,
+ mFlags);
}
private TypedArray createFloatTypedArray(float[] vals) {
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java
index 4fd8f26d91a8..dc6abf1981c0 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java
@@ -57,6 +57,9 @@ public class DisplayDeviceTest {
@Mock
private SurfaceControl.Transaction mMockTransaction;
+ @Mock
+ private DisplayAdapter mMockDisplayAdapter;
+
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
@@ -67,34 +70,39 @@ public class DisplayDeviceTest {
@Test
public void testGetDisplaySurfaceDefaultSizeLocked_notRotated() {
- DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo);
+ DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo,
+ mMockDisplayAdapter);
assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(PORTRAIT_SIZE);
}
@Test
public void testGetDisplaySurfaceDefaultSizeLocked_rotation0() {
- DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo);
+ DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo,
+ mMockDisplayAdapter);
displayDevice.setProjectionLocked(mMockTransaction, ROTATION_0, new Rect(), new Rect());
assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(PORTRAIT_SIZE);
}
@Test
public void testGetDisplaySurfaceDefaultSizeLocked_rotation90() {
- DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo);
+ DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo,
+ mMockDisplayAdapter);
displayDevice.setProjectionLocked(mMockTransaction, ROTATION_90, new Rect(), new Rect());
assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(LANDSCAPE_SIZE);
}
@Test
public void testGetDisplaySurfaceDefaultSizeLocked_rotation180() {
- DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo);
+ DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo,
+ mMockDisplayAdapter);
displayDevice.setProjectionLocked(mMockTransaction, ROTATION_180, new Rect(), new Rect());
assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(PORTRAIT_SIZE);
}
@Test
public void testGetDisplaySurfaceDefaultSizeLocked_rotation270() {
- DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo);
+ DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo,
+ mMockDisplayAdapter);
displayDevice.setProjectionLocked(mMockTransaction, ROTATION_270, new Rect(), new Rect());
assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(LANDSCAPE_SIZE);
}
@@ -102,8 +110,9 @@ public class DisplayDeviceTest {
private static class FakeDisplayDevice extends DisplayDevice {
private final DisplayDeviceInfo mDisplayDeviceInfo;
- FakeDisplayDevice(DisplayDeviceInfo displayDeviceInfo) {
- super(null, null, "", InstrumentationRegistry.getInstrumentation().getContext());
+ FakeDisplayDevice(DisplayDeviceInfo displayDeviceInfo, DisplayAdapter displayAdapter) {
+ super(displayAdapter, /* displayToken= */ null, /* uniqueId= */ "",
+ InstrumentationRegistry.getInstrumentation().getContext());
mDisplayDeviceInfo = displayDeviceInfo;
}
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 55f56e93fea5..02e3ef4d5f0b 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -212,7 +212,8 @@ public class DisplayManagerServiceTest {
new DisplayManagerService.Injector() {
@Override
VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot,
- Context context, Handler handler, DisplayAdapter.Listener listener) {
+ Context context, Handler handler, DisplayAdapter.Listener listener,
+ DisplayManagerFlags flags) {
return mMockVirtualDisplayAdapter;
}
@@ -251,7 +252,8 @@ public class DisplayManagerServiceTest {
@Override
VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context,
- Handler handler, DisplayAdapter.Listener displayAdapterListener) {
+ Handler handler, DisplayAdapter.Listener displayAdapterListener,
+ DisplayManagerFlags flags) {
return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener,
new VirtualDisplayAdapter.SurfaceControlDisplayFactory() {
@Override
@@ -263,7 +265,7 @@ public class DisplayManagerServiceTest {
@Override
public void destroyDisplay(IBinder displayToken) {
}
- });
+ }, flags);
}
@Override
@@ -329,6 +331,7 @@ public class DisplayManagerServiceTest {
@Mock SensorManager mSensorManager;
@Mock DisplayDeviceConfig mMockDisplayDeviceConfig;
@Mock PackageManagerInternal mMockPackageManagerInternal;
+ @Mock DisplayAdapter mMockDisplayAdapter;
@Captor ArgumentCaptor<ContentRecordingSession> mContentRecordingSessionCaptor;
@Mock DisplayManagerFlags mMockFlags;
@@ -788,7 +791,8 @@ public class DisplayManagerServiceTest {
new DisplayManagerService.Injector() {
@Override
VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot,
- Context context, Handler handler, DisplayAdapter.Listener listener) {
+ Context context, Handler handler, DisplayAdapter.Listener listener,
+ DisplayManagerFlags flags) {
return null; // return null for the adapter. This should cause a failure.
}
@@ -3194,7 +3198,7 @@ public class DisplayManagerServiceTest {
private DisplayDeviceInfo mDisplayDeviceInfo;
FakeDisplayDevice() {
- super(null, null, "", mContext);
+ super(mMockDisplayAdapter, /* displayToken= */ null, /* uniqueId= */ "", mContext);
}
public void setDisplayDeviceInfo(DisplayDeviceInfo displayDeviceInfo) {
diff --git a/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
index 8270845657c6..f36854b1ea78 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -1455,8 +1455,8 @@ public class LocalDisplayAdapterTest {
// mMockContext and values will be loaded from mMockResources.
@Override
public DisplayDeviceConfig createDisplayDeviceConfig(Context context,
- long physicalDisplayId, boolean isFirstDisplay) {
- return DisplayDeviceConfig.create(context, isFirstDisplay);
+ long physicalDisplayId, boolean isFirstDisplay, DisplayManagerFlags flags) {
+ return DisplayDeviceConfig.create(context, isFirstDisplay, flags);
}
}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java
index 43d2b8f741ae..28ec89629df0 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java
@@ -119,8 +119,8 @@ public class LogicalDisplayMapperTest {
@Mock IThermalService mIThermalServiceMock;
@Spy DeviceStateToLayoutMap mDeviceStateToLayoutMapSpy =
new DeviceStateToLayoutMap(mIdProducer, NON_EXISTING_FILE);
- @Mock
- DisplayManagerFlags mFlagsMock;
+ @Mock DisplayManagerFlags mFlagsMock;
+ @Mock DisplayAdapter mDisplayAdapterMock;
@Captor ArgumentCaptor<LogicalDisplay> mDisplayCaptor;
@Captor ArgumentCaptor<Integer> mDisplayEventCaptor;
@@ -1075,7 +1075,8 @@ public class LogicalDisplayMapperTest {
private int mState;
TestDisplayDevice() {
- super(null, null, "test_display_" + sUniqueTestDisplayId++, mContextMock);
+ super(mDisplayAdapterMock, /* displayToken= */ null,
+ "test_display_" + sUniqueTestDisplayId++, mContextMock);
mInfo = new DisplayDeviceInfo();
}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/PersistentDataStoreTest.java b/services/tests/displayservicetests/src/com/android/server/display/PersistentDataStoreTest.java
index 9f91916a4046..5676a388acff 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/PersistentDataStoreTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/PersistentDataStoreTest.java
@@ -32,9 +32,12 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -51,8 +54,12 @@ public class PersistentDataStoreTest {
private TestInjector mInjector;
private TestLooper mTestLooper;
+ @Mock
+ private DisplayAdapter mDisplayAdapter;
+
@Before
public void setUp() {
+ MockitoAnnotations.initMocks(this);
mInjector = new TestInjector();
mTestLooper = new TestLooper();
Handler handler = new Handler(mTestLooper.getLooper());
@@ -62,8 +69,8 @@ public class PersistentDataStoreTest {
@Test
public void testLoadBrightness() {
final String uniqueDisplayId = "test:123";
- final DisplayDevice testDisplayDevice = new DisplayDevice(
- null, null, uniqueDisplayId, null) {
+ final DisplayDevice testDisplayDevice = new DisplayDevice(mDisplayAdapter,
+ /* displayToken= */ null, uniqueDisplayId, /* context= */ null) {
@Override
public boolean hasStableUniqueId() {
return true;
@@ -100,7 +107,8 @@ public class PersistentDataStoreTest {
public void testSetBrightness_brightnessTagWithNoUserId_updatesToBrightnessTagWithUserId() {
final String uniqueDisplayId = "test:123";
final DisplayDevice testDisplayDevice =
- new DisplayDevice(null, null, uniqueDisplayId, null) {
+ new DisplayDevice(mDisplayAdapter, /* displayToken= */ null, uniqueDisplayId,
+ /* context= */ null) {
@Override
public boolean hasStableUniqueId() {
return true;
@@ -273,7 +281,8 @@ public class PersistentDataStoreTest {
assertNull(mDataStore.getBrightnessConfigurationForDisplayLocked(uniqueDisplayId,
userSerial));
- DisplayDevice testDisplayDevice = new DisplayDevice(null, null, uniqueDisplayId, null) {
+ DisplayDevice testDisplayDevice = new DisplayDevice(mDisplayAdapter,
+ /* displayToken= */ null, uniqueDisplayId, /* context= */ null) {
@Override
public boolean hasStableUniqueId() {
return true;
@@ -319,7 +328,8 @@ public class PersistentDataStoreTest {
assertNull(mDataStore.getBrightnessConfigurationForDisplayLocked(uniqueDisplayId,
userSerial));
- DisplayDevice testDisplayDevice = new DisplayDevice(null, null, uniqueDisplayId, null) {
+ DisplayDevice testDisplayDevice = new DisplayDevice(mDisplayAdapter,
+ /* displayToken= */ null, uniqueDisplayId, /* context= */ null) {
@Override
public boolean hasStableUniqueId() {
return false;
@@ -386,7 +396,8 @@ public class PersistentDataStoreTest {
@Test
public void testStoreAndRestoreResolution() {
final String uniqueDisplayId = "test:123";
- DisplayDevice testDisplayDevice = new DisplayDevice(null, null, uniqueDisplayId, null) {
+ DisplayDevice testDisplayDevice = new DisplayDevice(mDisplayAdapter,
+ /* displayToken= */ null, uniqueDisplayId, /* context= */ null) {
@Override
public boolean hasStableUniqueId() {
return true;
@@ -422,7 +433,8 @@ public class PersistentDataStoreTest {
@Test
public void testStoreAndRestoreRefreshRate() {
final String uniqueDisplayId = "test:123";
- DisplayDevice testDisplayDevice = new DisplayDevice(null, null, uniqueDisplayId, null) {
+ DisplayDevice testDisplayDevice = new DisplayDevice(mDisplayAdapter,
+ /* displayToken= */ null, uniqueDisplayId, /* context= */ null) {
@Override
public boolean hasStableUniqueId() {
return true;
@@ -455,7 +467,8 @@ public class PersistentDataStoreTest {
@Test
public void testBrightnessInitialisesWithInvalidFloat() {
final String uniqueDisplayId = "test:123";
- DisplayDevice testDisplayDevice = new DisplayDevice(null, null, uniqueDisplayId, null) {
+ DisplayDevice testDisplayDevice = new DisplayDevice(mDisplayAdapter,
+ /* displayToken= */ null, uniqueDisplayId, /* context= */ null) {
@Override
public boolean hasStableUniqueId() {
return true;
diff --git a/services/tests/displayservicetests/src/com/android/server/display/RefreshRateSettingsUtilsTest.java b/services/tests/displayservicetests/src/com/android/server/display/RefreshRateSettingsUtilsTest.java
index b7cbac5a7f18..5c50acb13f30 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/RefreshRateSettingsUtilsTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/RefreshRateSettingsUtilsTest.java
@@ -72,27 +72,14 @@ public class RefreshRateSettingsUtilsTest {
@Test
public void testFindHighestRefreshRateForDefaultDisplay() {
- when(mDisplayManagerMock.getDisplay(Display.DEFAULT_DISPLAY)).thenReturn(mDisplayMock);
- assertEquals(120,
+ when(mDisplayManagerMock.getDisplay(Display.DEFAULT_DISPLAY)).thenReturn(null);
+ assertEquals(DEFAULT_REFRESH_RATE,
RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay(mContext),
/* delta= */ 0);
- }
- @Test
- public void testFindHighestRefreshRate() {
- int displayId = 13;
- when(mDisplayManagerMock.getDisplay(displayId)).thenReturn(mDisplayMock);
+ when(mDisplayManagerMock.getDisplay(Display.DEFAULT_DISPLAY)).thenReturn(mDisplayMock);
assertEquals(120,
- RefreshRateSettingsUtils.findHighestRefreshRate(mContext, displayId),
- /* delta= */ 0);
- }
-
- @Test
- public void testFindHighestRefreshRate_DisplayIsNull() {
- when(mDisplayManagerMock.getDisplay(Display.DEFAULT_DISPLAY)).thenReturn(null);
- assertEquals(DEFAULT_REFRESH_RATE,
RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay(mContext),
/* delta= */ 0);
-
}
}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java b/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java
index 73e7ba0750e0..c01b15c17483 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java
@@ -28,6 +28,7 @@ import android.os.IBinder;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import com.android.server.display.feature.DisplayManagerFlags;
import com.android.server.testutils.TestHandler;
import org.junit.Before;
@@ -59,13 +60,17 @@ public class VirtualDisplayAdapterTest {
private VirtualDisplayAdapter mVirtualDisplayAdapter;
+ @Mock
+ private DisplayManagerFlags mFeatureFlags;
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mHandler = new TestHandler(null);
mVirtualDisplayAdapter = new VirtualDisplayAdapter(new DisplayManagerService.SyncRoot(),
- mContextMock, mHandler, mMockListener, mMockSufaceControlDisplayFactory);
+ mContextMock, mHandler, mMockListener, mMockSufaceControlDisplayFactory,
+ mFeatureFlags);
when(mMockCallback.asBinder()).thenReturn(mMockBinder);
}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java b/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
index d0859232778d..60a0c039dd03 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
@@ -290,7 +290,6 @@ public class DisplayModeDirectorTest {
};
private static final int DISPLAY_ID = Display.DEFAULT_DISPLAY;
- private static final int DISPLAY_ID_2 = Display.DEFAULT_DISPLAY + 1;
private static final int MODE_ID = 1;
private static final float TRANSITION_POINT = 0.763f;
@@ -1551,12 +1550,9 @@ public class DisplayModeDirectorTest {
public void testPeakRefreshRate_FlagEnabled() {
when(mDisplayManagerFlags.isBackUpSmoothDisplayAndForcePeakRefreshRateEnabled())
.thenReturn(true);
- float highestRefreshRate1 = 130;
- float highestRefreshRate2 = 132;
- doReturn(highestRefreshRate1).when(() ->
- RefreshRateSettingsUtils.findHighestRefreshRate(mContext, DISPLAY_ID));
- doReturn(highestRefreshRate2).when(() ->
- RefreshRateSettingsUtils.findHighestRefreshRate(mContext, DISPLAY_ID_2));
+ float highestRefreshRate = 130;
+ doReturn(highestRefreshRate).when(() ->
+ RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay(mContext));
DisplayModeDirector director =
createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
@@ -1567,14 +1563,10 @@ public class DisplayModeDirectorTest {
setPeakRefreshRate(Float.POSITIVE_INFINITY);
- Vote vote1 = director.getVote(DISPLAY_ID,
+ Vote vote = director.getVote(Display.DEFAULT_DISPLAY,
Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE);
- Vote vote2 = director.getVote(DISPLAY_ID_2,
- Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE);
- assertVoteForRenderFrameRateRange(vote1, /* frameRateLow= */ 0,
- /* frameRateHigh= */ highestRefreshRate1);
- assertVoteForRenderFrameRateRange(vote2, /* frameRateLow= */ 0,
- /* frameRateHigh= */ highestRefreshRate2);
+ assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
+ highestRefreshRate);
}
@Test
@@ -1592,54 +1584,19 @@ public class DisplayModeDirectorTest {
setPeakRefreshRate(peakRefreshRate);
- Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE);
- assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0,
- /* frameRateHigh= */ peakRefreshRate);
- }
-
- @Test
- public void testPeakRefreshRate_DisplayChanged() {
- when(mDisplayManagerFlags.isBackUpSmoothDisplayAndForcePeakRefreshRateEnabled())
- .thenReturn(true);
- float highestRefreshRate = 130;
- doReturn(highestRefreshRate).when(() ->
- RefreshRateSettingsUtils.findHighestRefreshRate(mContext, DISPLAY_ID));
- DisplayModeDirector director =
- createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
- director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
-
- Sensor lightSensor = createLightSensor();
- SensorManager sensorManager = createMockSensorManager(lightSensor);
- director.start(sensorManager);
-
- setPeakRefreshRate(Float.POSITIVE_INFINITY);
-
- Vote vote = director.getVote(DISPLAY_ID,
+ Vote vote = director.getVote(Display.DEFAULT_DISPLAY,
Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE);
- assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0,
- /* frameRateHigh= */ highestRefreshRate);
-
- // The highest refresh rate of the display changes
- highestRefreshRate = 140;
- doReturn(highestRefreshRate).when(() ->
- RefreshRateSettingsUtils.findHighestRefreshRate(mContext, DISPLAY_ID));
- director.getDisplayObserver().onDisplayChanged(DISPLAY_ID);
-
- vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE);
- assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0,
- /* frameRateHigh= */ highestRefreshRate);
+ assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
+ peakRefreshRate);
}
@Test
public void testMinRefreshRate_FlagEnabled() {
when(mDisplayManagerFlags.isBackUpSmoothDisplayAndForcePeakRefreshRateEnabled())
.thenReturn(true);
- float highestRefreshRate1 = 130;
- float highestRefreshRate2 = 132;
- doReturn(highestRefreshRate1).when(() ->
- RefreshRateSettingsUtils.findHighestRefreshRate(mContext, DISPLAY_ID));
- doReturn(highestRefreshRate2).when(() ->
- RefreshRateSettingsUtils.findHighestRefreshRate(mContext, DISPLAY_ID_2));
+ float highestRefreshRate = 130;
+ doReturn(highestRefreshRate).when(() ->
+ RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay(mContext));
DisplayModeDirector director =
createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
@@ -1650,12 +1607,9 @@ public class DisplayModeDirectorTest {
setMinRefreshRate(Float.POSITIVE_INFINITY);
- Vote vote1 = director.getVote(DISPLAY_ID, Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
- Vote vote2 = director.getVote(DISPLAY_ID_2,
+ Vote vote = director.getVote(Display.DEFAULT_DISPLAY,
Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
- assertVoteForRenderFrameRateRange(vote1, /* frameRateLow= */ highestRefreshRate1,
- /* frameRateHigh= */ Float.POSITIVE_INFINITY);
- assertVoteForRenderFrameRateRange(vote2, /* frameRateLow= */ highestRefreshRate2,
+ assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ highestRefreshRate,
/* frameRateHigh= */ Float.POSITIVE_INFINITY);
}
@@ -1674,44 +1628,13 @@ public class DisplayModeDirectorTest {
setMinRefreshRate(minRefreshRate);
- Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
+ Vote vote = director.getVote(Display.DEFAULT_DISPLAY,
+ Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ minRefreshRate,
/* frameRateHigh= */ Float.POSITIVE_INFINITY);
}
@Test
- public void testMinRefreshRate_DisplayChanged() {
- when(mDisplayManagerFlags.isBackUpSmoothDisplayAndForcePeakRefreshRateEnabled())
- .thenReturn(true);
- float highestRefreshRate = 130;
- doReturn(highestRefreshRate).when(() ->
- RefreshRateSettingsUtils.findHighestRefreshRate(mContext, DISPLAY_ID));
- DisplayModeDirector director =
- createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
- director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
-
- Sensor lightSensor = createLightSensor();
- SensorManager sensorManager = createMockSensorManager(lightSensor);
- director.start(sensorManager);
-
- setMinRefreshRate(Float.POSITIVE_INFINITY);
-
- Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
- assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ highestRefreshRate,
- /* frameRateHigh= */ Float.POSITIVE_INFINITY);
-
- // The highest refresh rate of the display changes
- highestRefreshRate = 140;
- doReturn(highestRefreshRate).when(() ->
- RefreshRateSettingsUtils.findHighestRefreshRate(mContext, DISPLAY_ID));
- director.getDisplayObserver().onDisplayChanged(DISPLAY_ID);
-
- vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
- assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ highestRefreshRate,
- /* frameRateHigh= */ Float.POSITIVE_INFINITY);
- }
-
- @Test
public void testSensorRegistration() {
// First, configure brightness zones or DMD won't register for sensor data.
final FakeDeviceConfig config = mInjector.getDeviceConfig();
@@ -3406,7 +3329,7 @@ public class DisplayModeDirectorTest {
public static class FakesInjector implements DisplayModeDirector.Injector {
private final FakeDeviceConfig mDeviceConfig;
private final DisplayInfo mDisplayInfo;
- private final Map<Integer, Display> mDisplays;
+ private final Display mDisplay;
private boolean mDisplayInfoValid = true;
private final DisplayManagerInternal mDisplayManagerInternal;
private final StatusBarManagerInternal mStatusBarManagerInternal;
@@ -3427,8 +3350,7 @@ public class DisplayModeDirectorTest {
mDisplayInfo.defaultModeId = MODE_ID;
mDisplayInfo.supportedModes = new Display.Mode[] {new Display.Mode(MODE_ID,
800, 600, /* refreshRate= */ 60)};
- mDisplays = Map.of(DISPLAY_ID, createDisplay(DISPLAY_ID),
- DISPLAY_ID_2, createDisplay(DISPLAY_ID_2));
+ mDisplay = createDisplay(DISPLAY_ID);
mDisplayManagerInternal = displayManagerInternal;
mStatusBarManagerInternal = statusBarManagerInternal;
mSensorManagerInternal = sensorManagerInternal;
@@ -3459,12 +3381,12 @@ public class DisplayModeDirectorTest {
@Override
public Display getDisplay(int displayId) {
- return mDisplays.get(displayId);
+ return mDisplay;
}
@Override
public Display[] getDisplays() {
- return mDisplays.values().toArray(new Display[0]);
+ return new Display[] { mDisplay };
}
@Override
diff --git a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
index be29163e7677..1a3a6a388392 100644
--- a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
@@ -46,6 +46,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
@@ -61,6 +62,7 @@ import static org.mockito.Mockito.verify;
import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
import android.app.IActivityManager;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
@@ -128,6 +130,8 @@ public class DeviceIdleControllerTest {
@Mock
private ConnectivityManager mConnectivityManager;
@Mock
+ private ContentResolver mContentResolver;
+ @Mock
private IActivityManager mIActivityManager;
@Mock
private LocationManager mLocationManager;
@@ -332,7 +336,7 @@ public class DeviceIdleControllerTest {
anyString(), any(Executor.class),
any(DeviceConfig.OnPropertiesChangedListener.class)));
doAnswer((Answer<DeviceConfig.Properties>) invocationOnMock
- -> mock(DeviceConfig.Properties.class))
+ -> new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_DEVICE_IDLE).build())
.when(() -> DeviceConfig.getProperties(
anyString(), ArgumentMatchers.<String>any()));
when(mPowerManager.newWakeLock(anyInt(), anyString())).thenReturn(mWakeLock);
@@ -347,6 +351,7 @@ public class DeviceIdleControllerTest {
mAppStateTracker = new AppStateTrackerForTest(getContext(), Looper.getMainLooper());
mAnyMotionDetector = new AnyMotionDetectorForTest();
mInjector = new InjectorForTest(getContext());
+ doNothing().when(mContentResolver).registerContentObserver(any(), anyBoolean(), any());
doReturn(mWearModeManagerInternal)
.when(() -> LocalServices.getService(WearModeManagerInternal.class));
@@ -366,7 +371,8 @@ public class DeviceIdleControllerTest {
mDeviceIdleController.setLightEnabledForTest(true);
// Get the same Constants object that mDeviceIdleController got.
- mConstants = mInjector.getConstants(mDeviceIdleController);
+ mConstants = mInjector.getConstants(mDeviceIdleController,
+ mInjector.getHandler(mDeviceIdleController), mContentResolver);
final ArgumentCaptor<TelephonyCallback> telephonyCallbackCaptor =
ArgumentCaptor.forClass(TelephonyCallback.class);
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/gnss/GnssLocationProviderTest.java b/services/tests/mockingservicestests/src/com/android/server/location/gnss/GnssLocationProviderTest.java
new file mode 100644
index 000000000000..c5e6824099ed
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/location/gnss/GnssLocationProviderTest.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.location.gnss;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.app.AlarmManager;
+import android.app.AppOpsManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.location.GnssCapabilities;
+import android.location.LocationManager;
+import android.location.LocationManagerInternal;
+import android.location.flags.Flags;
+import android.location.provider.ProviderRequest;
+import android.os.PowerManager;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.modules.utils.testing.ExtendedMockitoRule;
+import com.android.server.LocalServices;
+import com.android.server.location.gnss.hal.FakeGnssHal;
+import com.android.server.location.gnss.hal.GnssNative;
+import com.android.server.location.injector.Injector;
+import com.android.server.location.injector.TestInjector;
+import com.android.server.timedetector.TimeDetectorInternal;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.quality.Strictness;
+
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+@Presubmit
+@androidx.test.filters.SmallTest
+@RunWith(AndroidJUnit4.class)
+public class GnssLocationProviderTest {
+
+ @Rule
+ public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
+ .setStrictness(Strictness.WARN)
+ .mockStatic(Settings.Global.class)
+ .build();
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+ private @Mock Context mContext;
+ private @Mock LocationManagerInternal mLocationManagerInternal;
+ private @Mock LocationManager mLocationManager;
+ private @Mock TimeDetectorInternal mTimeDetectorInternal;
+ private @Mock GnssConfiguration mMockConfiguration;
+ private @Mock GnssMetrics mGnssMetrics;
+ private @Mock PowerManager mPowerManager;
+ private @Mock TelephonyManager mTelephonyManager;
+ private @Mock AppOpsManager mAppOpsManager;
+ private @Mock AlarmManager mAlarmManager;
+ private @Mock PowerManager.WakeLock mWakeLock;
+ private @Mock ContentResolver mContentResolver;
+ private @Mock UserManager mUserManager;
+ private @Mock UserHandle mUserHandle;
+ private Set<UserHandle> mUserHandleSet = new HashSet<>();
+
+ private GnssNative mGnssNative;
+
+ private GnssLocationProvider mTestProvider;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ doReturn("mypackage").when(mContext).getPackageName();
+ doReturn("attribution").when(mContext).getAttributionTag();
+ doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class);
+ doReturn(mPowerManager).when(mContext).getSystemService("power");
+ doReturn(mAppOpsManager).when(mContext).getSystemService(AppOpsManager.class);
+ doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
+ doReturn(mAlarmManager).when(mContext).getSystemService(Context.ALARM_SERVICE);
+ doReturn(mLocationManager).when(mContext).getSystemService(LocationManager.class);
+ doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
+ mUserHandleSet.add(mUserHandle);
+ doReturn(true).when(mLocationManager).isLocationEnabledForUser(eq(mUserHandle));
+ doReturn(mUserHandleSet).when(mUserManager).getVisibleUsers();
+ doReturn(mContentResolver).when(mContext).getContentResolver();
+ doReturn(mWakeLock).when(mPowerManager).newWakeLock(anyInt(), anyString());
+ LocalServices.addService(LocationManagerInternal.class, mLocationManagerInternal);
+ LocalServices.addService(TimeDetectorInternal.class, mTimeDetectorInternal);
+ FakeGnssHal fakeGnssHal = new FakeGnssHal();
+ GnssNative.setGnssHalForTest(fakeGnssHal);
+ Injector injector = new TestInjector(mContext);
+ mGnssNative = spy(Objects.requireNonNull(
+ GnssNative.create(injector, mMockConfiguration)));
+ doReturn(true).when(mGnssNative).init();
+ GnssCapabilities gnssCapabilities = new GnssCapabilities.Builder().setHasScheduling(
+ true).build();
+ doReturn(gnssCapabilities).when(mGnssNative).getCapabilities();
+
+ mTestProvider = new GnssLocationProvider(mContext, mGnssNative, mGnssMetrics);
+ mGnssNative.register();
+ }
+
+ @After
+ public void tearDown() {
+ LocalServices.removeServiceForTest(LocationManagerInternal.class);
+ LocalServices.removeServiceForTest(TimeDetectorInternal.class);
+ }
+
+ @Test
+ public void testStartNavigating() {
+ ProviderRequest providerRequest = new ProviderRequest.Builder().setIntervalMillis(
+ 0).build();
+
+ mTestProvider.onSetRequest(providerRequest);
+ verify(mGnssNative).start();
+ }
+
+ @Test
+ public void testUpdateRequirements_sameRequest() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_GNSS_CALL_STOP_BEFORE_SET_POSITION_MODE);
+ ProviderRequest providerRequest = new ProviderRequest.Builder().setIntervalMillis(
+ 0).build();
+
+ mTestProvider.onSetRequest(providerRequest);
+ verify(mGnssNative).start();
+
+ // set the same request
+ mTestProvider.onSetRequest(providerRequest);
+ verify(mGnssNative, never()).stop();
+ verify(mGnssNative, times(1)).start();
+ }
+
+ @Test
+ public void testUpdateRequirements_differentRequest() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_GNSS_CALL_STOP_BEFORE_SET_POSITION_MODE);
+ ProviderRequest providerRequest = new ProviderRequest.Builder().setIntervalMillis(
+ 0).build();
+
+ mTestProvider.onSetRequest(providerRequest);
+ verify(mGnssNative).start();
+
+ // set a different request
+ providerRequest = new ProviderRequest.Builder().setIntervalMillis(2000).build();
+ mTestProvider.onSetRequest(providerRequest);
+ verify(mGnssNative).stop();
+ verify(mGnssNative, times(2)).start();
+ }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt
index 931b38dc2951..f8fe97e9af13 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt
@@ -22,12 +22,14 @@ import android.content.pm.PackageManager.PERMISSION_DENIED
import android.content.pm.PackageManager.PERMISSION_GRANTED
import android.content.pm.UserInfo
import android.os.Build
+import android.os.UserHandle
import android.os.UserHandle.USER_SYSTEM
import android.util.Log
import com.android.server.testutils.any
import com.android.server.testutils.spy
import com.android.server.testutils.whenever
import com.google.common.truth.Truth.assertThat
+import org.junit.Assert.assertFalse
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -177,4 +179,13 @@ class DeletePackageHelperTest {
assertThat(result).isEqualTo(PackageManager.DELETE_FAILED_INTERNAL_ERROR)
}
+
+ @Test
+ fun deletePackageLIFWithNonExistantPackage_isFalse() {
+ val dph = DeletePackageHelper(mPms, mock(RemovePackageHelper::class.java),
+ mock(BroadcastHelper::class.java))
+ val result = dph.deletePackageLIF("a.nonexistent.package", UserHandle.of(USER_SYSTEM), true,
+ intArrayOf(0), 0, PackageRemovedInfo(), true)
+ assertFalse(result)
+ }
}
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java
index 7148b164efa9..2e0ba0083850 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java
@@ -82,6 +82,15 @@ public class BatteryUsageStatsProviderTest {
.isEqualTo(20 * MINUTE_IN_MS);
assertThat(uidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND))
.isEqualTo(40 * MINUTE_IN_MS);
+ assertThat(uidBatteryConsumer
+ .getTimeInProcessStateMs(UidBatteryConsumer.PROCESS_STATE_FOREGROUND))
+ .isEqualTo(20 * MINUTE_IN_MS);
+ assertThat(uidBatteryConsumer
+ .getTimeInProcessStateMs(UidBatteryConsumer.PROCESS_STATE_BACKGROUND))
+ .isEqualTo(20 * MINUTE_IN_MS);
+ assertThat(uidBatteryConsumer
+ .getTimeInProcessStateMs(UidBatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE))
+ .isEqualTo(20 * MINUTE_IN_MS);
assertThat(uidBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_AUDIO))
.isWithin(PRECISION).of(2.0);
assertThat(
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java
index 07c486c6ce58..079ea2c7832f 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java
@@ -193,14 +193,14 @@ public class BatteryUsageStatsTest {
for (UidBatteryConsumer uidBatteryConsumer : uidBatteryConsumers) {
if (uidBatteryConsumer.getUid() == APP_UID1) {
assertUidBatteryConsumer(uidBatteryConsumer, 2124, null,
- 5321, 7432, 423, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 745,
+ 5321, 6900, 532, 423, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 745,
POWER_MODEL_UNDEFINED,
956, 1167, 1478,
true, 3554, 3776, 3998, 444, 3554, 15542, 3776, 17762, 3998, 19982,
444, 1110);
} else if (uidBatteryConsumer.getUid() == APP_UID2) {
assertUidBatteryConsumer(uidBatteryConsumer, 1332, "bar",
- 1111, 2222, 333, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 444,
+ 1111, 2220, 2, 333, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 444,
BatteryConsumer.POWER_MODEL_POWER_PROFILE,
555, 666, 777,
true, 1777, 1888, 1999, 321, 1777, 7771, 1888, 8881, 1999, 9991,
@@ -269,7 +269,7 @@ public class BatteryUsageStatsTest {
.setStatsEndTimestamp(3000);
addUidBatteryConsumer(builder, batteryStats, APP_UID1, "foo",
- 1000, 2000,
+ 1000, 1500, 500,
300, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 400,
BatteryConsumer.POWER_MODEL_POWER_PROFILE, 500, 600, 800,
1777, 7771, 1888, 8881, 1999, 9991, 123, 456);
@@ -312,13 +312,13 @@ public class BatteryUsageStatsTest {
.setStatsEndTimestamp(5000);
addUidBatteryConsumer(builder, batteryStats, APP_UID1, null,
- 4321, 5432,
+ 4321, 5400, 32,
123, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 345, POWER_MODEL_ENERGY_CONSUMPTION,
456, 567, 678,
1777, 7771, 1888, 8881, 1999, 9991, 321, 654);
addUidBatteryConsumer(builder, batteryStats, APP_UID2, "bar",
- 1111, 2222,
+ 1111, 2220, 2,
333, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 444,
BatteryConsumer.POWER_MODEL_POWER_PROFILE, 555, 666, 777,
1777, 7771, 1888, 8881, 1999, 9991, 321, 654);
@@ -338,7 +338,8 @@ public class BatteryUsageStatsTest {
private void addUidBatteryConsumer(BatteryUsageStats.Builder builder,
MockBatteryStatsImpl batteryStats, int uid, String packageWithHighestDrain,
- int timeInStateForeground, int timeInStateBackground, double screenPower,
+ int timeInProcessStateForeground, int timeInProcessStateBackground,
+ int timeInProcessStateForegroundService, double screenPower,
int screenPowerModel, double cpuPower, int cpuPowerModel, double customComponentPower,
int cpuDuration, int customComponentDuration, double cpuPowerForeground,
int cpuDurationForeground, double cpuPowerBackground, int cpuDurationBackground,
@@ -348,8 +349,10 @@ public class BatteryUsageStatsTest {
builder.getOrCreateUidBatteryConsumerBuilder(batteryStatsUid);
uidBuilder
.setPackageWithHighestDrain(packageWithHighestDrain)
- .setTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND, timeInStateForeground)
- .setTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND, timeInStateBackground)
+ .setTimeInProcessStateMs(PROCESS_STATE_FOREGROUND, timeInProcessStateForeground)
+ .setTimeInProcessStateMs(PROCESS_STATE_BACKGROUND, timeInProcessStateBackground)
+ .setTimeInProcessStateMs(PROCESS_STATE_FOREGROUND_SERVICE,
+ timeInProcessStateForegroundService)
.setConsumedPower(
BatteryConsumer.POWER_COMPONENT_SCREEN, screenPower, screenPowerModel)
.setConsumedPower(
@@ -446,7 +449,7 @@ public class BatteryUsageStatsTest {
for (UidBatteryConsumer uidBatteryConsumer : uidBatteryConsumers) {
if (uidBatteryConsumer.getUid() == APP_UID1) {
assertUidBatteryConsumer(uidBatteryConsumer, 1200, "foo",
- 1000, 2000, 300, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 400,
+ 1000, 1500, 500, 300, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 400,
BatteryConsumer.POWER_MODEL_POWER_PROFILE,
500, 600, 800,
true, 1777, 1888, 1999, 123, 1777, 7771, 1888, 8881, 1999, 9991, 123, 456);
@@ -496,8 +499,9 @@ public class BatteryUsageStatsTest {
}
private void assertUidBatteryConsumer(UidBatteryConsumer uidBatteryConsumer,
- double consumedPower, String packageWithHighestDrain, int timeInStateForeground,
- int timeInStateBackground, int screenPower, int screenPowerModel, double cpuPower,
+ double consumedPower, String packageWithHighestDrain, int timeInProcessStateForeground,
+ int timeInProcessStateBackground, int timeInProcessStateForegroundService,
+ int screenPower, int screenPowerModel, double cpuPower,
int cpuPowerModel, double customComponentPower, int cpuDuration,
int customComponentDuration, boolean processStateDataIncluded,
double totalPowerForeground, double totalPowerBackground, double totalPowerFgs,
@@ -509,9 +513,16 @@ public class BatteryUsageStatsTest {
assertThat(uidBatteryConsumer.getPackageWithHighestDrain()).isEqualTo(
packageWithHighestDrain);
assertThat(uidBatteryConsumer.getTimeInStateMs(
- UidBatteryConsumer.STATE_FOREGROUND)).isEqualTo(timeInStateForeground);
+ UidBatteryConsumer.STATE_FOREGROUND)).isEqualTo(timeInProcessStateForeground);
assertThat(uidBatteryConsumer.getTimeInStateMs(
- UidBatteryConsumer.STATE_BACKGROUND)).isEqualTo(timeInStateBackground);
+ UidBatteryConsumer.STATE_BACKGROUND)).isEqualTo(
+ timeInProcessStateBackground + timeInProcessStateForegroundService);
+ assertThat(uidBatteryConsumer.getTimeInProcessStateMs(
+ PROCESS_STATE_FOREGROUND)).isEqualTo(timeInProcessStateForeground);
+ assertThat(uidBatteryConsumer.getTimeInProcessStateMs(
+ PROCESS_STATE_BACKGROUND)).isEqualTo(timeInProcessStateBackground);
+ assertThat(uidBatteryConsumer.getTimeInProcessStateMs(
+ PROCESS_STATE_FOREGROUND_SERVICE)).isEqualTo(timeInProcessStateForegroundService);
assertThat(uidBatteryConsumer.getConsumedPower(
BatteryConsumer.POWER_COMPONENT_SCREEN)).isEqualTo(screenPower);
assertThat(uidBatteryConsumer.getPowerModel(
diff --git a/services/tests/servicestests/src/com/android/server/SecurityStateTest.java b/services/tests/servicestests/src/com/android/server/SecurityStateTest.java
new file mode 100644
index 000000000000..fc91e47534f1
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/SecurityStateTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import static android.os.SecurityStateManager.KEY_KERNEL_VERSION;
+import static android.os.SecurityStateManager.KEY_SYSTEM_SPL;
+import static android.os.SecurityStateManager.KEY_VENDOR_SPL;
+
+import static com.android.server.SecurityStateManagerService.KERNEL_RELEASE_PATTERN;
+import static com.android.server.SecurityStateManagerService.VENDOR_SECURITY_PATCH_PROPERTY_KEY;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.SystemProperties;
+import android.os.VintfRuntimeInfo;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.R;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.util.regex.Matcher;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class SecurityStateTest {
+ @Rule
+ public MockitoRule mockitoRule = MockitoJUnit.rule();
+
+ @Mock
+ private Context mMockContext;
+
+ @Mock
+ private PackageManager mMockPackageManager;
+
+ @Mock
+ private Resources mMockResources;
+
+ private static final String DEFAULT_MODULE_METADATA_PROVIDER = "com.android.modulemetadata";
+ private static final String DEFAULT_MODULE_METADATA_PROVIDER_VERSION = "2023-12-01";
+ private static final String DEFAULT_SECURITY_STATE_PACKAGE = "com.google.android.gms";
+ private static final String DEFAULT_SECURITY_STATE_PACKAGE_VERSION = "2023-12-05";
+ private static final String[] SECURITY_STATE_PACKAGES =
+ new String[]{DEFAULT_SECURITY_STATE_PACKAGE};
+
+ @Before
+ public void setUp() throws Exception {
+ when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
+ when(mMockContext.getResources()).thenReturn(mMockResources);
+ when(mMockContext.getString(R.string.config_defaultModuleMetadataProvider))
+ .thenReturn(DEFAULT_MODULE_METADATA_PROVIDER);
+ when(mMockPackageManager.getPackageInfo(anyString(), anyInt()))
+ .thenReturn(new PackageInfo());
+ PackageInfo moduleMetadataPackageInfo = new PackageInfo();
+ moduleMetadataPackageInfo.versionName = DEFAULT_MODULE_METADATA_PROVIDER_VERSION;
+ when(mMockPackageManager.getPackageInfo(DEFAULT_MODULE_METADATA_PROVIDER, 0))
+ .thenReturn(moduleMetadataPackageInfo);
+ PackageInfo securityStatePackageInfo = new PackageInfo();
+ securityStatePackageInfo.versionName = DEFAULT_SECURITY_STATE_PACKAGE_VERSION;
+ when(mMockPackageManager.getPackageInfo(DEFAULT_SECURITY_STATE_PACKAGE, 0))
+ .thenReturn(securityStatePackageInfo);
+ when(mMockResources.getStringArray(R.array.config_securityStatePackages))
+ .thenReturn(SECURITY_STATE_PACKAGES);
+ }
+
+ @Test
+ public void testGetGlobalSecurityState_returnsBundle() {
+ SecurityStateManagerService securityState = new SecurityStateManagerService(mMockContext);
+
+ Bundle bundle = securityState.getGlobalSecurityState();
+
+ assertEquals(bundle.getString(KEY_SYSTEM_SPL), Build.VERSION.SECURITY_PATCH);
+ assertEquals(bundle.getString(KEY_VENDOR_SPL),
+ SystemProperties.get(VENDOR_SECURITY_PATCH_PROPERTY_KEY, ""));
+ Matcher matcher = KERNEL_RELEASE_PATTERN.matcher(VintfRuntimeInfo.getKernelVersion());
+ String kernelVersion = "";
+ if (matcher.matches()) {
+ kernelVersion = matcher.group(1);
+ }
+ assertEquals(bundle.getString(KEY_KERNEL_VERSION), kernelVersion);
+ assertEquals(bundle.getString(DEFAULT_MODULE_METADATA_PROVIDER),
+ DEFAULT_MODULE_METADATA_PROVIDER_VERSION);
+ assertEquals(bundle.getString(DEFAULT_SECURITY_STATE_PACKAGE),
+ DEFAULT_SECURITY_STATE_PACKAGE_VERSION);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/WatchdogTest.java b/services/tests/servicestests/src/com/android/server/WatchdogTest.java
new file mode 100644
index 000000000000..34ac47e1fe96
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/WatchdogTest.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2009 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;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import android.os.Handler;
+import android.os.SimpleClock;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.server.Watchdog.HandlerChecker;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.time.ZoneOffset;
+
+/** Test class for {@link Watchdog}. */
+@RunWith(AndroidJUnit4.class)
+public class WatchdogTest {
+ private static final int TIMEOUT_MS = 10;
+
+ private TestClock mClock;
+ private Handler mHandler;
+ private HandlerChecker mChecker;
+
+ @Before
+ public void setUp() {
+ mClock = new TestClock();
+ mHandler = mock(Handler.class);
+ mChecker =
+ new HandlerChecker(mHandler, "monitor thread", new Object(), mClock) {
+ @Override
+ public boolean isHandlerPolling() {
+ return false;
+ }
+ };
+ }
+
+ @Test
+ public void checkerPausedUntilResume() {
+ Watchdog.Monitor monitor = mock(Watchdog.Monitor.class);
+ mChecker.addMonitorLocked(monitor);
+
+ mChecker.pauseLocked("pausing");
+ mChecker.scheduleCheckLocked(TIMEOUT_MS);
+ verifyNoMoreInteractions(mHandler);
+ assertEquals(Watchdog.COMPLETED, mChecker.getCompletionStateLocked());
+
+ mChecker.resumeLocked("resuming");
+ mChecker.scheduleCheckLocked(10);
+ assertEquals(Watchdog.WAITING, mChecker.getCompletionStateLocked());
+ }
+
+ @Test
+ public void checkerPausedUntilDeadline() {
+ Watchdog.Monitor monitor = mock(Watchdog.Monitor.class);
+ mChecker.addMonitorLocked(monitor);
+
+ mChecker.pauseForLocked(10, "pausing");
+ mChecker.scheduleCheckLocked(TIMEOUT_MS);
+ verifyNoMoreInteractions(mHandler);
+ assertEquals(Watchdog.COMPLETED, mChecker.getCompletionStateLocked());
+
+ mClock.advanceBy(5);
+ verifyNoMoreInteractions(mHandler);
+ assertEquals(Watchdog.COMPLETED, mChecker.getCompletionStateLocked());
+
+ // Above the 10s timeout. Watchdog should not be paused anymore.
+ mClock.advanceBy(6);
+ mChecker.scheduleCheckLocked(TIMEOUT_MS);
+ assertEquals(Watchdog.WAITING, mChecker.getCompletionStateLocked());
+ }
+
+ @Test
+ public void checkerPausedDuringScheduledRun() {
+ Watchdog.Monitor monitor = mock(Watchdog.Monitor.class);
+ mChecker.addMonitorLocked(monitor);
+
+ mChecker.scheduleCheckLocked(TIMEOUT_MS);
+ mClock.advanceBy(5);
+ mChecker.pauseForLocked(10, "pausing");
+ verifyNoMoreInteractions(mHandler);
+ assertEquals(Watchdog.COMPLETED, mChecker.getCompletionStateLocked());
+
+ // Above the 10s timeout. Watchdog should not be paused anymore.
+ mClock.advanceBy(11);
+ mChecker.scheduleCheckLocked(TIMEOUT_MS);
+ assertEquals(Watchdog.WAITING, mChecker.getCompletionStateLocked());
+ }
+
+ @Test
+ public void blockedThread() {
+ mChecker.scheduleCheckLocked(TIMEOUT_MS);
+ assertEquals(mChecker.getCompletionStateLocked(), Watchdog.WAITING);
+
+ mClock.advanceBy(6);
+ assertEquals(Watchdog.WAITED_UNTIL_PRE_WATCHDOG, mChecker.getCompletionStateLocked());
+
+ // Above the 10s timeout.
+ mClock.advanceBy(6);
+ assertEquals(Watchdog.OVERDUE, mChecker.getCompletionStateLocked());
+ }
+
+ @Test
+ public void checkNothingBlocked() {
+ Watchdog.Monitor monitor = mock(Watchdog.Monitor.class);
+ mChecker.addMonitorLocked(monitor);
+
+ mChecker.scheduleCheckLocked(TIMEOUT_MS);
+ // scheduleCheckLocked calls #postAtFrontOfQueue which will call mChecker.run().
+ mChecker.run();
+ assertEquals(Watchdog.COMPLETED, mChecker.getCompletionStateLocked());
+ verify(monitor).monitor();
+ }
+
+ private static class TestClock extends SimpleClock {
+ long mNowMillis = 1;
+
+ TestClock() {
+ super(ZoneOffset.UTC);
+ }
+
+ @Override
+ public long millis() {
+ return mNowMillis;
+ }
+
+ public void advanceBy(long millis) {
+ mNowMillis += millis;
+ }
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
index 82efdd3ce40a..800350a7d326 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -85,9 +85,9 @@ import com.android.internal.compat.IPlatformCompat;
import com.android.server.LocalServices;
import com.android.server.accessibility.AccessibilityManagerService.AccessibilityDisplayListener;
import com.android.server.accessibility.magnification.FullScreenMagnificationController;
+import com.android.server.accessibility.magnification.MagnificationConnectionManager;
import com.android.server.accessibility.magnification.MagnificationController;
import com.android.server.accessibility.magnification.MagnificationProcessor;
-import com.android.server.accessibility.magnification.WindowMagnificationManager;
import com.android.server.accessibility.test.MessageCapturingHandler;
import com.android.server.pm.UserManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal;
@@ -156,7 +156,7 @@ public class AccessibilityManagerServiceTest {
@Mock private UserManagerInternal mMockUserManagerInternal;
@Mock private IBinder mMockBinder;
@Mock private IAccessibilityServiceClient mMockServiceClient;
- @Mock private WindowMagnificationManager mMockWindowMagnificationMgr;
+ @Mock private MagnificationConnectionManager mMockMagnificationConnectionManager;
@Mock private MagnificationController mMockMagnificationController;
@Mock private FullScreenMagnificationController mMockFullScreenMagnificationController;
@Mock private ProxyManager mProxyManager;
@@ -180,8 +180,8 @@ public class AccessibilityManagerServiceTest {
UserManagerInternal.class, mMockUserManagerInternal);
mInputFilter = Mockito.mock(FakeInputFilter.class);
- when(mMockMagnificationController.getWindowMagnificationMgr()).thenReturn(
- mMockWindowMagnificationMgr);
+ when(mMockMagnificationController.getMagnificationConnectionManager()).thenReturn(
+ mMockMagnificationConnectionManager);
when(mMockMagnificationController.getFullScreenMagnificationController()).thenReturn(
mMockFullScreenMagnificationController);
when(mMockMagnificationController.supportWindowMagnification()).thenReturn(true);
@@ -530,7 +530,7 @@ public class AccessibilityManagerServiceTest {
// Invokes client change to trigger onUserStateChanged.
mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false);
- verify(mMockWindowMagnificationMgr).requestConnection(true);
+ verify(mMockMagnificationConnectionManager).requestConnection(true);
}
@SmallTest
@@ -547,7 +547,7 @@ public class AccessibilityManagerServiceTest {
// Invokes client change to trigger onUserStateChanged.
mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false);
- verify(mMockWindowMagnificationMgr).requestConnection(true);
+ verify(mMockMagnificationConnectionManager).requestConnection(true);
}
@SmallTest
@@ -565,7 +565,7 @@ public class AccessibilityManagerServiceTest {
// Invokes client change to trigger onUserStateChanged.
mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false);
- verify(mMockWindowMagnificationMgr).requestConnection(false);
+ verify(mMockMagnificationConnectionManager).requestConnection(false);
}
@SmallTest
@@ -583,7 +583,7 @@ public class AccessibilityManagerServiceTest {
// Invokes client change to trigger onUserStateChanged.
mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false);
- verify(mMockWindowMagnificationMgr).requestConnection(true);
+ verify(mMockMagnificationConnectionManager).requestConnection(true);
}
@SmallTest
@@ -602,7 +602,7 @@ public class AccessibilityManagerServiceTest {
// Invokes client change to trigger onUserStateChanged.
mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false);
- verify(mMockWindowMagnificationMgr).requestConnection(false);
+ verify(mMockMagnificationConnectionManager).requestConnection(false);
}
@SmallTest
@@ -616,7 +616,7 @@ public class AccessibilityManagerServiceTest {
// Invokes client change to trigger onUserStateChanged.
mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false);
- verify(mMockWindowMagnificationMgr).requestConnection(true);
+ verify(mMockMagnificationConnectionManager).requestConnection(true);
}
@SmallTest
@@ -630,7 +630,8 @@ public class AccessibilityManagerServiceTest {
// Invokes client change to trigger onUserStateChanged.
mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false);
- verify(mMockWindowMagnificationMgr, atLeastOnce()).removeMagnificationButton(anyInt());
+ verify(mMockMagnificationConnectionManager, atLeastOnce())
+ .removeMagnificationButton(anyInt());
}
@SmallTest
@@ -644,7 +645,7 @@ public class AccessibilityManagerServiceTest {
// Invokes client change to trigger onUserStateChanged.
mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false);
- verify(mMockWindowMagnificationMgr, never()).removeMagnificationButton(anyInt());
+ verify(mMockMagnificationConnectionManager, never()).removeMagnificationButton(anyInt());
}
@SmallTest
@@ -659,7 +660,8 @@ public class AccessibilityManagerServiceTest {
// Invokes client change to trigger onUserStateChanged.
mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false);
- verify(mMockWindowMagnificationMgr, atLeastOnce()).removeMagnificationButton(anyInt());
+ verify(mMockMagnificationConnectionManager, atLeastOnce())
+ .removeMagnificationButton(anyInt());
}
@SmallTest
@@ -674,7 +676,7 @@ public class AccessibilityManagerServiceTest {
// Invokes client change to trigger onUserStateChanged.
mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false);
- verify(mMockWindowMagnificationMgr, never()).removeMagnificationButton(anyInt());
+ verify(mMockMagnificationConnectionManager, never()).removeMagnificationButton(anyInt());
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java
index a02807fe766c..7829fcc4b44d 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java
@@ -39,9 +39,9 @@ import android.accessibilityservice.MagnificationConfig;
import android.graphics.Region;
import com.android.server.accessibility.magnification.FullScreenMagnificationController;
+import com.android.server.accessibility.magnification.MagnificationConnectionManager;
import com.android.server.accessibility.magnification.MagnificationController;
import com.android.server.accessibility.magnification.MagnificationProcessor;
-import com.android.server.accessibility.magnification.WindowMagnificationManager;
import org.junit.Before;
import org.junit.Test;
@@ -66,21 +66,21 @@ public class MagnificationProcessorTest {
@Mock
private FullScreenMagnificationController mMockFullScreenMagnificationController;
@Mock
- private WindowMagnificationManager mMockWindowMagnificationManager;
+ private MagnificationConnectionManager mMockMagnificationConnectionManager;
FullScreenMagnificationControllerStub mFullScreenMagnificationControllerStub;
- WindowMagnificationManagerStub mWindowMagnificationManagerStub;
+ MagnificationManagerStub mMagnificationManagerStub;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mFullScreenMagnificationControllerStub = new FullScreenMagnificationControllerStub(
mMockFullScreenMagnificationController);
- mWindowMagnificationManagerStub = new WindowMagnificationManagerStub(
- mMockWindowMagnificationManager);
+ mMagnificationManagerStub = new MagnificationManagerStub(
+ mMockMagnificationConnectionManager);
when(mMockMagnificationController.getFullScreenMagnificationController()).thenReturn(
mMockFullScreenMagnificationController);
- when(mMockMagnificationController.getWindowMagnificationMgr()).thenReturn(
- mMockWindowMagnificationManager);
+ when(mMockMagnificationController.getMagnificationConnectionManager()).thenReturn(
+ mMockMagnificationConnectionManager);
mMagnificationProcessor = new MagnificationProcessor(mMockMagnificationController);
}
@@ -194,7 +194,7 @@ public class MagnificationProcessorTest {
doAnswer((invocation) -> {
((Region) invocation.getArguments()[1]).set(region);
return null;
- }).when(mMockWindowMagnificationManager).getMagnificationSourceBounds(eq(TEST_DISPLAY),
+ }).when(mMockMagnificationConnectionManager).getMagnificationSourceBounds(eq(TEST_DISPLAY),
any());
final Region result = new Region();
@@ -286,7 +286,7 @@ public class MagnificationProcessorTest {
mMagnificationProcessor.resetCurrentMagnification(TEST_DISPLAY, /* animate= */false);
- verify(mMockWindowMagnificationManager).disableWindowMagnification(TEST_DISPLAY, false,
+ verify(mMockMagnificationConnectionManager).disableWindowMagnification(TEST_DISPLAY, false,
null);
}
@@ -296,7 +296,7 @@ public class MagnificationProcessorTest {
mMagnificationProcessor.resetAllIfNeeded(connectionId);
verify(mMockFullScreenMagnificationController).resetAllIfNeeded(eq(connectionId));
- verify(mMockWindowMagnificationManager).resetAllIfNeeded(eq(connectionId));
+ verify(mMockMagnificationConnectionManager).resetAllIfNeeded(eq(connectionId));
}
@Test
@@ -450,7 +450,7 @@ public class MagnificationProcessorTest {
.setActivated(false).build();
mMagnificationProcessor.setMagnificationConfig(TEST_DISPLAY, config, false, SERVICE_ID);
- verify(mMockWindowMagnificationManager)
+ verify(mMockMagnificationConnectionManager)
.disableWindowMagnification(eq(TEST_DISPLAY), anyBoolean());
}
@@ -481,11 +481,11 @@ public class MagnificationProcessorTest {
mFullScreenMagnificationControllerStub.resetAndStubMethods();
mMockFullScreenMagnificationController.setScaleAndCenter(displayId, config.getScale(),
config.getCenterX(), config.getCenterY(), false, SERVICE_ID);
- mWindowMagnificationManagerStub.deactivateIfNeed();
+ mMagnificationManagerStub.deactivateIfNeed();
} else if (config.getMode() == MAGNIFICATION_MODE_WINDOW) {
- mWindowMagnificationManagerStub.resetAndStubMethods();
- mMockWindowMagnificationManager.enableWindowMagnification(displayId, config.getScale(),
- config.getCenterX(), config.getCenterY());
+ mMagnificationManagerStub.resetAndStubMethods();
+ mMockMagnificationConnectionManager.enableWindowMagnification(
+ displayId, config.getScale(), config.getCenterX(), config.getCenterY());
mFullScreenMagnificationControllerStub.deactivateIfNeed();
}
}
@@ -568,26 +568,26 @@ public class MagnificationProcessorTest {
}
}
- private static class WindowMagnificationManagerStub {
- private final WindowMagnificationManager mWindowMagnificationManager;
+ private static class MagnificationManagerStub {
+ private final MagnificationConnectionManager mMagnificationConnectionManager;
private float mScale = 1.0f;
private float mCenterX = 0;
private float mCenterY = 0;
private boolean mIsEnabled = false;
- WindowMagnificationManagerStub(
- WindowMagnificationManager windowMagnificationManager) {
- mWindowMagnificationManager = windowMagnificationManager;
+ MagnificationManagerStub(
+ MagnificationConnectionManager magnificationConnectionManager) {
+ mMagnificationConnectionManager = magnificationConnectionManager;
}
private void stubMethods() {
- doAnswer(invocation -> mScale).when(mWindowMagnificationManager).getScale(
+ doAnswer(invocation -> mScale).when(mMagnificationConnectionManager).getScale(
TEST_DISPLAY);
- doAnswer(invocation -> mCenterX).when(mWindowMagnificationManager).getCenterX(
+ doAnswer(invocation -> mCenterX).when(mMagnificationConnectionManager).getCenterX(
TEST_DISPLAY);
- doAnswer(invocation -> mCenterY).when(mWindowMagnificationManager).getCenterY(
+ doAnswer(invocation -> mCenterY).when(mMagnificationConnectionManager).getCenterY(
TEST_DISPLAY);
- doAnswer(invocation -> mIsEnabled).when(mWindowMagnificationManager)
+ doAnswer(invocation -> mIsEnabled).when(mMagnificationConnectionManager)
.isWindowMagnifierEnabled(TEST_DISPLAY);
Answer enableWindowMagnificationStubAnswer = invocation -> {
@@ -598,10 +598,10 @@ public class MagnificationProcessorTest {
return true;
};
doAnswer(enableWindowMagnificationStubAnswer).when(
- mWindowMagnificationManager).enableWindowMagnification(eq(TEST_DISPLAY),
+ mMagnificationConnectionManager).enableWindowMagnification(eq(TEST_DISPLAY),
anyFloat(), anyFloat(), anyFloat());
doAnswer(enableWindowMagnificationStubAnswer).when(
- mWindowMagnificationManager).enableWindowMagnification(eq(TEST_DISPLAY),
+ mMagnificationConnectionManager).enableWindowMagnification(eq(TEST_DISPLAY),
anyFloat(), anyFloat(), anyFloat(), any(), anyInt());
Answer disableWindowMagnificationStubAnswer = invocation -> {
@@ -609,15 +609,15 @@ public class MagnificationProcessorTest {
return true;
};
doAnswer(disableWindowMagnificationStubAnswer).when(
- mWindowMagnificationManager).disableWindowMagnification(eq(TEST_DISPLAY),
+ mMagnificationConnectionManager).disableWindowMagnification(eq(TEST_DISPLAY),
anyBoolean());
doAnswer(disableWindowMagnificationStubAnswer).when(
- mWindowMagnificationManager).disableWindowMagnification(eq(TEST_DISPLAY),
+ mMagnificationConnectionManager).disableWindowMagnification(eq(TEST_DISPLAY),
anyBoolean(), any());
}
public void resetAndStubMethods() {
- Mockito.reset(mWindowMagnificationManager);
+ Mockito.reset(mMagnificationConnectionManager);
stubMethods();
}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java
index 24ad976f6e45..3843e2507df6 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java
@@ -33,8 +33,6 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import static java.lang.Float.NaN;
@@ -76,7 +74,7 @@ import org.mockito.invocation.InvocationOnMock;
/**
* Tests for WindowMagnificationManager.
*/
-public class WindowMagnificationManagerTest {
+public class MagnificationConnectionManagerTest {
private static final int CURRENT_USER_ID = UserHandle.USER_SYSTEM;
private static final int SERVICE_ID = 1;
@@ -91,9 +89,9 @@ public class WindowMagnificationManagerTest {
@Mock
private MagnificationAnimationCallback mAnimationCallback;
@Mock
- private WindowMagnificationManager.Callback mMockCallback;
+ private MagnificationConnectionManager.Callback mMockCallback;
private MockContentResolver mResolver;
- private WindowMagnificationManager mWindowMagnificationManager;
+ private MagnificationConnectionManager mMagnificationConnectionManager;
@Before
public void setUp() throws RemoteException {
@@ -102,7 +100,7 @@ public class WindowMagnificationManagerTest {
LocalServices.addService(StatusBarManagerInternal.class, mMockStatusBarManagerInternal);
mResolver = new MockContentResolver();
mMockConnection = new MockWindowMagnificationConnection();
- mWindowMagnificationManager = new WindowMagnificationManager(mContext, new Object(),
+ mMagnificationConnectionManager = new MagnificationConnectionManager(mContext, new Object(),
mMockCallback, mMockTrace, new MagnificationScaleProvider(mContext));
when(mContext.getContentResolver()).thenReturn(mResolver);
@@ -122,11 +120,11 @@ public class WindowMagnificationManagerTest {
final Context context = ApplicationProvider.getApplicationContext();
context.getMainThreadHandler().postDelayed(
() -> {
- mWindowMagnificationManager.setConnection(
+ mMagnificationConnectionManager.setConnection(
connect ? mMockConnection.getConnection() : null);
}, 10);
} else {
- mWindowMagnificationManager.setConnection(
+ mMagnificationConnectionManager.setConnection(
connect ? mMockConnection.getConnection() : null);
}
return true;
@@ -135,17 +133,17 @@ public class WindowMagnificationManagerTest {
@Test
public void setConnection_connectionIsNull_wrapperIsNullAndLinkToDeath() {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- assertNotNull(mWindowMagnificationManager.mConnectionWrapper);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ assertTrue(mMagnificationConnectionManager.isConnected());
verify(mMockConnection.asBinder()).linkToDeath(any(IBinder.DeathRecipient.class), eq(0));
}
@Test
public void setConnection_connectionIsNull_setMirrorWindowCallbackAndHasWrapper()
throws RemoteException {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
- assertNotNull(mWindowMagnificationManager.mConnectionWrapper);
+ assertTrue(mMagnificationConnectionManager.isConnected());
verify(mMockConnection.asBinder()).linkToDeath(any(IBinder.DeathRecipient.class), eq(0));
verify(mMockConnection.getConnection()).setConnectionCallback(
any(IWindowMagnificationConnectionCallback.class));
@@ -153,31 +151,31 @@ public class WindowMagnificationManagerTest {
@Test
public void binderDied_hasConnection_wrapperIsNullAndUnlinkToDeath() {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
mMockConnection.getDeathRecipient().binderDied();
- assertNull(mWindowMagnificationManager.mConnectionWrapper);
+ assertFalse(mMagnificationConnectionManager.isConnected());
verify(mMockConnection.asBinder()).unlinkToDeath(mMockConnection.getDeathRecipient(),
0);
}
/**
- * This test simulates {@link WindowMagnificationManager#setConnection} is called by thread A
- * and then the former connection is called by thread B. In this situation we should keep the
+ * This test simulates {@link MagnificationConnectionManager#setConnection} is called by thread
+ * A and then the former connection is called by thread B. In this situation we should keep the
* new connection.
*/
@Test
public void setSecondConnectionAndFormerConnectionBinderDead_hasWrapperAndNotCallUnlinkToDeath()
throws RemoteException {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
MockWindowMagnificationConnection secondConnection =
new MockWindowMagnificationConnection();
- mWindowMagnificationManager.setConnection(secondConnection.getConnection());
+ mMagnificationConnectionManager.setConnection(secondConnection.getConnection());
mMockConnection.getDeathRecipient().binderDied();
- assertNotNull(mWindowMagnificationManager.mConnectionWrapper);
+ assertTrue(mMagnificationConnectionManager.isConnected());
verify(mMockConnection.asBinder()).unlinkToDeath(mMockConnection.getDeathRecipient(), 0);
verify(secondConnection.asBinder(), never()).unlinkToDeath(
secondConnection.getDeathRecipient(), 0);
@@ -185,20 +183,20 @@ public class WindowMagnificationManagerTest {
@Test
public void setNullConnection_hasConnection_wrapperIsNull() throws RemoteException {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.setConnection(null);
+ mMagnificationConnectionManager.setConnection(null);
- assertNull(mWindowMagnificationManager.mConnectionWrapper);
+ assertFalse(mMagnificationConnectionManager.isConnected());
verify(mMockConnection.getConnection()).setConnectionCallback(null);
}
@Test
public void enableWithAnimation_hasConnection_enableWindowMagnification()
throws RemoteException {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2f, 200f, 300f);
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2f, 200f, 300f);
verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(2f),
eq(200f), eq(300f), eq(0f), eq(0f), notNull());
@@ -207,9 +205,9 @@ public class WindowMagnificationManagerTest {
@Test
public void enableWithCallback_hasConnection_enableWindowMagnification()
throws RemoteException {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2f, 200f, 300f,
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2f, 200f, 300f,
mAnimationCallback, SERVICE_ID);
verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(2f),
@@ -221,10 +219,10 @@ public class WindowMagnificationManagerTest {
@Test
public void disable_hasConnectionAndEnabled_disableWindowMagnification()
throws RemoteException {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN);
- mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false);
+ mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false);
verify(mMockConnection.getConnection()).disableWindowMagnification(eq(TEST_DISPLAY),
notNull());
@@ -233,10 +231,10 @@ public class WindowMagnificationManagerTest {
@Test
public void disableWithCallback_hasConnectionAndEnabled_disableWindowMagnification()
throws RemoteException {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN);
- mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false,
+ mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false,
mAnimationCallback);
verify(mMockConnection.getConnection()).disableWindowMagnification(eq(TEST_DISPLAY),
@@ -246,28 +244,28 @@ public class WindowMagnificationManagerTest {
@Test
public void isWindowMagnifierEnabled_hasConnectionAndEnabled_returnExpectedValue() {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2f, NaN, NaN);
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2f, NaN, NaN);
- assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+ assertTrue(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
}
@Test
public void getPersistedScale() {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
- assertEquals(mWindowMagnificationManager.getPersistedScale(TEST_DISPLAY), 2.5f);
+ assertEquals(mMagnificationConnectionManager.getPersistedScale(TEST_DISPLAY), 2.5f);
}
@Test
public void persistScale_setValue_expectedValueInProvider() {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2.0f, NaN, NaN);
- mWindowMagnificationManager.setScale(TEST_DISPLAY, 2.5f);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2.0f, NaN, NaN);
+ mMagnificationConnectionManager.setScale(TEST_DISPLAY, 2.5f);
- mWindowMagnificationManager.persistScale(TEST_DISPLAY);
+ mMagnificationConnectionManager.persistScale(TEST_DISPLAY);
assertEquals(Settings.Secure.getFloatForUser(mResolver,
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 0f,
@@ -276,11 +274,12 @@ public class WindowMagnificationManagerTest {
@Test
public void persistScale_setValueWhenScaleIsOne_nothingChanged() {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- final float persistedScale = mWindowMagnificationManager.getPersistedScale(TEST_DISPLAY);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ final float persistedScale =
+ mMagnificationConnectionManager.getPersistedScale(TEST_DISPLAY);
- mWindowMagnificationManager.setScale(TEST_DISPLAY, 1.0f);
- mWindowMagnificationManager.persistScale(TEST_DISPLAY);
+ mMagnificationConnectionManager.setScale(TEST_DISPLAY, 1.0f);
+ mMagnificationConnectionManager.persistScale(TEST_DISPLAY);
assertEquals(Settings.Secure.getFloatForUser(mResolver,
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 0f,
@@ -289,50 +288,53 @@ public class WindowMagnificationManagerTest {
@Test
public void scaleSetterGetter_enabledOnTestDisplay_expectedValue() {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2.0f, NaN, NaN);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2.0f, NaN, NaN);
- mWindowMagnificationManager.setScale(TEST_DISPLAY, 2.5f);
+ mMagnificationConnectionManager.setScale(TEST_DISPLAY, 2.5f);
- assertEquals(mWindowMagnificationManager.getScale(TEST_DISPLAY), 2.5f);
+ assertEquals(mMagnificationConnectionManager.getScale(TEST_DISPLAY), 2.5f);
}
@Test
public void scaleSetterGetter_scaleIsOutOfRang_getNormalizeValue() {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2.5f, NaN, NaN);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2.5f, NaN, NaN);
- mWindowMagnificationManager.setScale(TEST_DISPLAY, 10.0f);
+ mMagnificationConnectionManager.setScale(TEST_DISPLAY, 10.0f);
- assertEquals(mWindowMagnificationManager.getScale(TEST_DISPLAY),
+ assertEquals(mMagnificationConnectionManager.getScale(TEST_DISPLAY),
MagnificationScaleProvider.MAX_SCALE);
}
@FlakyTest(bugId = 297879435)
@Test
public void logTrackingTypingFocus_processScroll_logDuration() {
- WindowMagnificationManager spyWindowMagnificationManager = spy(mWindowMagnificationManager);
- spyWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
- spyWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, /* shown */ true);
+ MagnificationConnectionManager spyMagnificationConnectionManager = spy(
+ mMagnificationConnectionManager);
+ spyMagnificationConnectionManager.enableWindowMagnification(
+ TEST_DISPLAY, 3.0f, 50f, 50f);
+ spyMagnificationConnectionManager.onImeWindowVisibilityChanged(
+ TEST_DISPLAY, /* shown */ true);
- spyWindowMagnificationManager.processScroll(TEST_DISPLAY, 10f, 10f);
+ spyMagnificationConnectionManager.processScroll(TEST_DISPLAY, 10f, 10f);
- verify(spyWindowMagnificationManager).logTrackingTypingFocus(anyLong());
+ verify(spyMagnificationConnectionManager).logTrackingTypingFocus(anyLong());
}
@Test
public void onRectangleOnScreenRequested_trackingDisabledByOnDrag_withoutMovingMagnifier()
throws RemoteException {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
- mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+ mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
final Region outRegion = new Region();
- mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
+ mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
final Rect requestedRect = outRegion.getBounds();
requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
mMockConnection.getConnectionCallback().onMove(TEST_DISPLAY);
- mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+ mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY,
requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
verify(mMockConnection.getConnection(), never())
@@ -345,16 +347,16 @@ public class WindowMagnificationManagerTest {
throws RemoteException {
final float distanceX = 10f;
final float distanceY = 10f;
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
- mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+ mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
final Region outRegion = new Region();
- mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
+ mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
final Rect requestedRect = outRegion.getBounds();
requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
- mWindowMagnificationManager.processScroll(TEST_DISPLAY, distanceX, distanceY);
+ mMagnificationConnectionManager.processScroll(TEST_DISPLAY, distanceX, distanceY);
- mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+ mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY,
requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
verify(mMockConnection.getConnection(), never())
@@ -364,15 +366,15 @@ public class WindowMagnificationManagerTest {
@Test
public void onRectangleOnScreenRequested_requestRectangleInBound_withoutMovingMagnifier()
throws RemoteException {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
- mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+ mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
final Region outRegion = new Region();
- mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
+ mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
final Rect requestedRect = outRegion.getBounds();
requestedRect.inset(-10, -10);
- mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+ mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY,
requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
verify(mMockConnection.getConnection(), never())
@@ -381,14 +383,14 @@ public class WindowMagnificationManagerTest {
@Test
public void onRectangleOnScreenRequested_imeVisibilityDefaultInvisible_withoutMovingMagnifier()
throws RemoteException {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
final Region outRegion = new Region();
- mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
+ mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
final Rect requestedRect = outRegion.getBounds();
requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
- mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+ mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY,
requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
verify(mMockConnection.getConnection(), never())
@@ -398,15 +400,15 @@ public class WindowMagnificationManagerTest {
@Test
public void onRectangleOnScreenRequested_trackingEnabledByDefault_movingMagnifier()
throws RemoteException {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
- mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+ mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
final Region outRegion = new Region();
- mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
+ mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
final Rect requestedRect = outRegion.getBounds();
requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
- mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+ mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY,
requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
verify(mMockConnection.getConnection()).moveWindowMagnifierToPosition(eq(TEST_DISPLAY),
@@ -417,16 +419,16 @@ public class WindowMagnificationManagerTest {
@Test
public void onRectangleOnScreenRequested_imeInvisible_withoutMovingMagnifier()
throws RemoteException {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
- mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+ mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
final Region outRegion = new Region();
- mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
+ mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
final Rect requestedRect = outRegion.getBounds();
requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
- mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, false);
+ mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, false);
- mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+ mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY,
requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
verify(mMockConnection.getConnection(), never())
@@ -436,17 +438,17 @@ public class WindowMagnificationManagerTest {
@Test
public void onRectangleOnScreenRequested_trackingEnabledByDragAndReset_movingMagnifier()
throws RemoteException {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
- mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+ mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
mMockConnection.getConnectionCallback().onMove(TEST_DISPLAY);
- mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+ mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
final Region outRegion = new Region();
- mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
+ mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
final Rect requestedRect = outRegion.getBounds();
requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
- mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+ mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY,
requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
verify(mMockConnection.getConnection()).moveWindowMagnifierToPosition(eq(TEST_DISPLAY),
@@ -456,58 +458,58 @@ public class WindowMagnificationManagerTest {
@Test
public void onRectangleOnScreenRequested_followTypingIsDisabled_withoutMovingMagnifier() {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
- mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+ mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
final Region beforeRegion = new Region();
- mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion);
+ mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion);
final Rect requestedRect = beforeRegion.getBounds();
requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
- mWindowMagnificationManager.setMagnificationFollowTypingEnabled(false);
+ mMagnificationConnectionManager.setMagnificationFollowTypingEnabled(false);
- mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+ mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY,
requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
final Region afterRegion = new Region();
- mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, afterRegion);
+ mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, afterRegion);
assertEquals(afterRegion, beforeRegion);
}
@Test
public void onRectangleOnScreenRequested_trackingDisabled_withoutMovingMagnifier() {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
- mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
- mWindowMagnificationManager.setTrackingTypingFocusEnabled(TEST_DISPLAY, false);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+ mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+ mMagnificationConnectionManager.setTrackingTypingFocusEnabled(TEST_DISPLAY, false);
final Region beforeRegion = new Region();
- mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion);
+ mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion);
final Rect requestedRect = beforeRegion.getBounds();
requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
- mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+ mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY,
requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
final Region afterRegion = new Region();
- mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, afterRegion);
+ mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, afterRegion);
assertEquals(afterRegion, beforeRegion);
}
@Test
public void onRectangleOnScreenRequested_trackingDisabledAndEnabledMagnifier_movingMagnifier()
throws RemoteException {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
- mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
- mWindowMagnificationManager.setTrackingTypingFocusEnabled(TEST_DISPLAY, false);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+ mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+ mMagnificationConnectionManager.setTrackingTypingFocusEnabled(TEST_DISPLAY, false);
final Region beforeRegion = new Region();
- mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion);
+ mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion);
final Rect requestedRect = beforeRegion.getBounds();
requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
- mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false);
+ mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false);
// Enabling a window magnifier again will turn on the tracking typing focus functionality.
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, NaN, NaN, NaN);
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, NaN, NaN, NaN);
- mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+ mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY,
requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
verify(mMockConnection.getConnection()).moveWindowMagnifierToPosition(eq(TEST_DISPLAY),
@@ -517,43 +519,43 @@ public class WindowMagnificationManagerTest {
@Test
public void moveWindowMagnifier_enabled_invokeConnectionMethod() throws RemoteException {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2f, NaN, NaN);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2f, NaN, NaN);
- mWindowMagnificationManager.moveWindowMagnification(TEST_DISPLAY, 200, 300);
+ mMagnificationConnectionManager.moveWindowMagnification(TEST_DISPLAY, 200, 300);
verify(mMockConnection.getConnection()).moveWindowMagnifier(TEST_DISPLAY, 200, 300);
}
@Test
public void showMagnificationButton_hasConnection_invokeConnectionMethod()
throws RemoteException {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.showMagnificationButton(TEST_DISPLAY,
+ mMagnificationConnectionManager.showMagnificationButton(TEST_DISPLAY,
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
verify(mMockConnection.getConnection()).showMagnificationButton(TEST_DISPLAY,
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
- mWindowMagnificationManager.removeMagnificationButton(TEST_DISPLAY);
+ mMagnificationConnectionManager.removeMagnificationButton(TEST_DISPLAY);
verify(mMockConnection.getConnection()).removeMagnificationButton(TEST_DISPLAY);
}
@Test
public void removeMagnificationSettingsPanel_hasConnection_invokeConnectionMethod()
throws RemoteException {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.removeMagnificationSettingsPanel(TEST_DISPLAY);
+ mMagnificationConnectionManager.removeMagnificationSettingsPanel(TEST_DISPLAY);
verify(mMockConnection.getConnection()).removeMagnificationSettingsPanel(TEST_DISPLAY);
}
@Test
public void onUserMagnificationScaleChanged_hasConnection_invokeConnectionMethod()
throws RemoteException {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
final float testScale = 3f;
- mWindowMagnificationManager.onUserMagnificationScaleChanged(
+ mMagnificationConnectionManager.onUserMagnificationScaleChanged(
CURRENT_USER_ID, TEST_DISPLAY, testScale);
verify(mMockConnection.getConnection()).onUserMagnificationScaleChanged(
eq(CURRENT_USER_ID), eq(TEST_DISPLAY), eq(testScale));
@@ -561,8 +563,8 @@ public class WindowMagnificationManagerTest {
@Test
public void pointersInWindow_magnifierEnabled_returnCorrectValue() throws RemoteException {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
mMockConnection.getConnectionCallback().onWindowMagnifierBoundsChanged(TEST_DISPLAY,
new Rect(0, 0, 500, 500));
PointF[] pointersLocation = new PointF[2];
@@ -570,15 +572,15 @@ public class WindowMagnificationManagerTest {
pointersLocation[1] = new PointF(300, 400);
MotionEvent event = generatePointersDownEvent(pointersLocation);
- assertEquals(mWindowMagnificationManager.pointersInWindow(TEST_DISPLAY, event), 1);
+ assertEquals(mMagnificationConnectionManager.pointersInWindow(TEST_DISPLAY, event), 1);
}
@Test
public void onPerformScaleAction_magnifierEnabled_notifyAction() throws RemoteException {
final float newScale = 4.0f;
final boolean updatePersistence = true;
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
mMockConnection.getConnectionCallback().onPerformScaleAction(
TEST_DISPLAY, newScale, updatePersistence);
@@ -590,8 +592,8 @@ public class WindowMagnificationManagerTest {
@Test
public void onAccessibilityActionPerformed_magnifierEnabled_notifyAction()
throws RemoteException {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
mMockConnection.getConnectionCallback().onAccessibilityActionPerformed(TEST_DISPLAY);
@@ -600,22 +602,22 @@ public class WindowMagnificationManagerTest {
@Test
public void binderDied_windowMagnifierIsEnabled_resetState() throws RemoteException {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN);
mMockConnection.getDeathRecipient().binderDied();
- assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+ assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
}
@Test
public void
requestConnectionToNull_disableAllMagnifiersAndRequestWindowMagnificationConnection()
throws RemoteException {
- assertTrue(mWindowMagnificationManager.requestConnection(true));
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN);
+ assertTrue(mMagnificationConnectionManager.requestConnection(true));
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN);
- assertTrue(mWindowMagnificationManager.requestConnection(false));
+ assertTrue(mMagnificationConnectionManager.requestConnection(false));
verify(mMockConnection.getConnection()).disableWindowMagnification(TEST_DISPLAY, null);
verify(mMockStatusBarManagerInternal).requestWindowMagnificationConnection(false);
@@ -623,40 +625,40 @@ public class WindowMagnificationManagerTest {
@Test
public void requestConnection_requestWindowMagnificationConnection() throws RemoteException {
- assertTrue(mWindowMagnificationManager.requestConnection(true));
+ assertTrue(mMagnificationConnectionManager.requestConnection(true));
verify(mMockStatusBarManagerInternal).requestWindowMagnificationConnection(true);
}
@Test
public void isConnected_requestConnection_expectedValue() throws RemoteException {
- mWindowMagnificationManager.requestConnection(true);
- assertTrue(mWindowMagnificationManager.isConnected());
+ mMagnificationConnectionManager.requestConnection(true);
+ assertTrue(mMagnificationConnectionManager.isConnected());
- mWindowMagnificationManager.requestConnection(false);
- assertFalse(mWindowMagnificationManager.isConnected());
+ mMagnificationConnectionManager.requestConnection(false);
+ assertFalse(mMagnificationConnectionManager.isConnected());
}
@Test
public void requestConnection_registerAndUnregisterBroadcastReceiver() {
- assertTrue(mWindowMagnificationManager.requestConnection(true));
+ assertTrue(mMagnificationConnectionManager.requestConnection(true));
verify(mContext).registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class));
- assertTrue(mWindowMagnificationManager.requestConnection(false));
+ assertTrue(mMagnificationConnectionManager.requestConnection(false));
verify(mContext).unregisterReceiver(any(BroadcastReceiver.class));
}
@Test
public void requestConnectionToNull_expectedGetterResults() {
- mWindowMagnificationManager.requestConnection(true);
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, 1, 1);
+ mMagnificationConnectionManager.requestConnection(true);
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, 1, 1);
- mWindowMagnificationManager.requestConnection(false);
+ mMagnificationConnectionManager.requestConnection(false);
- assertEquals(1f, mWindowMagnificationManager.getScale(TEST_DISPLAY), 0);
- assertTrue(Float.isNaN(mWindowMagnificationManager.getCenterX(TEST_DISPLAY)));
- assertTrue(Float.isNaN(mWindowMagnificationManager.getCenterY(TEST_DISPLAY)));
+ assertEquals(1f, mMagnificationConnectionManager.getScale(TEST_DISPLAY), 0);
+ assertTrue(Float.isNaN(mMagnificationConnectionManager.getCenterX(TEST_DISPLAY)));
+ assertTrue(Float.isNaN(mMagnificationConnectionManager.getCenterY(TEST_DISPLAY)));
final Region bounds = new Region();
- mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, bounds);
+ mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, bounds);
assertTrue(bounds.isEmpty());
}
@@ -664,9 +666,10 @@ public class WindowMagnificationManagerTest {
public void enableWindowMagnification_connecting_invokeConnectionMethodAfterConnected()
throws RemoteException {
stubSetConnection(true);
- mWindowMagnificationManager.requestConnection(true);
+ mMagnificationConnectionManager.requestConnection(true);
- assertTrue(mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, 1, 1));
+ assertTrue(mMagnificationConnectionManager.enableWindowMagnification(
+ TEST_DISPLAY, 3f, 1, 1));
// Invoke enableWindowMagnification if the connection is connected.
verify(mMockConnection.getConnection()).enableWindowMagnification(
@@ -676,69 +679,73 @@ public class WindowMagnificationManagerTest {
@Test
public void resetAllMagnification_enabledBySameId_windowMagnifiersDisabled() {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f,
- 100f, 200f, null, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER, SERVICE_ID);
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY_2, 3f,
- 100f, 200f, null, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER, SERVICE_ID);
- assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
- assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY_2));
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f,
+ 100f, 200f, null,
+ MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER, SERVICE_ID);
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY_2, 3f,
+ 100f, 200f, null,
+ MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER, SERVICE_ID);
+ assertTrue(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+ assertTrue(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY_2));
- mWindowMagnificationManager.resetAllIfNeeded(SERVICE_ID);
+ mMagnificationConnectionManager.resetAllIfNeeded(SERVICE_ID);
- assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
- assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY_2));
+ assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+ assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY_2));
}
@Test
public void resetAllMagnification_enabledByDifferentId_windowMagnifierDisabled() {
final int serviceId2 = SERVICE_ID + 1;
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f,
- 100f, 200f, null, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER, SERVICE_ID);
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY_2, 3f,
- 100f, 200f, null, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER, serviceId2);
- assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
- assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY_2));
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f,
+ 100f, 200f, null,
+ MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER, SERVICE_ID);
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY_2, 3f,
+ 100f, 200f, null,
+ MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER, serviceId2);
+ assertTrue(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+ assertTrue(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY_2));
- mWindowMagnificationManager.resetAllIfNeeded(SERVICE_ID);
+ mMagnificationConnectionManager.resetAllIfNeeded(SERVICE_ID);
- assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
- assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY_2));
+ assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+ assertTrue(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY_2));
}
@Test
public void onScreenOff_windowMagnifierIsEnabled_removeButtonAndDisableWindowMagnification()
throws RemoteException {
- mWindowMagnificationManager.requestConnection(true);
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2.5f, NaN, NaN);
+ mMagnificationConnectionManager.requestConnection(true);
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2.5f, NaN, NaN);
- mWindowMagnificationManager.mScreenStateReceiver.onReceive(mContext,
+ mMagnificationConnectionManager.mScreenStateReceiver.onReceive(mContext,
new Intent(Intent.ACTION_SCREEN_OFF));
verify(mMockConnection.getConnection()).removeMagnificationButton(TEST_DISPLAY);
verify(mMockConnection.getConnection()).disableWindowMagnification(TEST_DISPLAY, null);
- assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+ assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
}
@Test
public void centerGetter_enabledOnTestDisplay_expectedValues() {
- mWindowMagnificationManager.requestConnection(true);
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, 100f, 200f);
+ mMagnificationConnectionManager.requestConnection(true);
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, 100f, 200f);
- assertEquals(mWindowMagnificationManager.getCenterX(TEST_DISPLAY), 100f);
- assertEquals(mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 200f);
+ assertEquals(mMagnificationConnectionManager.getCenterX(TEST_DISPLAY), 100f);
+ assertEquals(mMagnificationConnectionManager.getCenterY(TEST_DISPLAY), 200f);
}
@Test
public void centerGetter_enabledOnTestDisplayWindowAtCenter_expectedValues()
throws RemoteException {
- mWindowMagnificationManager.requestConnection(true);
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f,
- 100f, 200f, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER);
+ mMagnificationConnectionManager.requestConnection(true);
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f,
+ 100f, 200f, MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER);
- assertEquals(mWindowMagnificationManager.getCenterX(TEST_DISPLAY), 100f);
- assertEquals(mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 200f);
+ assertEquals(mMagnificationConnectionManager.getCenterX(TEST_DISPLAY), 100f);
+ assertEquals(mMagnificationConnectionManager.getCenterY(TEST_DISPLAY), 200f);
verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(3f),
eq(100f), eq(200f), eq(0f), eq(0f), notNull());
@@ -747,12 +754,12 @@ public class WindowMagnificationManagerTest {
@Test
public void centerGetter_enabledOnTestDisplayWindowAtLeftTop_expectedValues()
throws RemoteException {
- mWindowMagnificationManager.requestConnection(true);
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f,
- 100f, 200f, WindowMagnificationManager.WINDOW_POSITION_AT_TOP_LEFT);
+ mMagnificationConnectionManager.requestConnection(true);
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f,
+ 100f, 200f, MagnificationConnectionManager.WINDOW_POSITION_AT_TOP_LEFT);
- assertEquals(mWindowMagnificationManager.getCenterX(TEST_DISPLAY), 100f);
- assertEquals(mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 200f);
+ assertEquals(mMagnificationConnectionManager.getCenterX(TEST_DISPLAY), 100f);
+ assertEquals(mMagnificationConnectionManager.getCenterY(TEST_DISPLAY), 200f);
verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(3f),
eq(100f), eq(200f), eq(-1f), eq(-1f), notNull());
@@ -760,48 +767,48 @@ public class WindowMagnificationManagerTest {
@Test
public void magnifierGetters_disabled_expectedValues() {
- mWindowMagnificationManager.requestConnection(true);
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f,
- 100f, 200f, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER);
+ mMagnificationConnectionManager.requestConnection(true);
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f,
+ 100f, 200f, MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER);
- mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false);
+ mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false);
- assertEquals(1f, mWindowMagnificationManager.getScale(TEST_DISPLAY), 0);
- assertTrue(Float.isNaN(mWindowMagnificationManager.getCenterX(TEST_DISPLAY)));
- assertTrue(Float.isNaN(mWindowMagnificationManager.getCenterY(TEST_DISPLAY)));
+ assertEquals(1f, mMagnificationConnectionManager.getScale(TEST_DISPLAY), 0);
+ assertTrue(Float.isNaN(mMagnificationConnectionManager.getCenterX(TEST_DISPLAY)));
+ assertTrue(Float.isNaN(mMagnificationConnectionManager.getCenterY(TEST_DISPLAY)));
final Region bounds = new Region();
- mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, bounds);
+ mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, bounds);
assertTrue(bounds.isEmpty());
}
@Test
public void onDisplayRemoved_enabledOnTestDisplay_disabled() {
- mWindowMagnificationManager.requestConnection(true);
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, 100f, 200f);
+ mMagnificationConnectionManager.requestConnection(true);
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, 100f, 200f);
- mWindowMagnificationManager.onDisplayRemoved(TEST_DISPLAY);
+ mMagnificationConnectionManager.onDisplayRemoved(TEST_DISPLAY);
- assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+ assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
}
@Test
public void onWindowMagnificationActivationState_magnifierEnabled_notifyActivatedState() {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
verify(mMockCallback).onWindowMagnificationActivationState(TEST_DISPLAY, true);
}
@Test
public void onWindowMagnificationActivationState_magnifierDisabled_notifyDeactivatedState() {
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
- mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false);
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
+ mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false);
verify(mMockCallback).onWindowMagnificationActivationState(TEST_DISPLAY, false);
Mockito.reset(mMockCallback);
- mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false);
+ mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false);
verify(mMockCallback, never()).onWindowMagnificationActivationState(eq(TEST_DISPLAY),
anyBoolean());
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionWrapperTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionWrapperTest.java
index cfd0289e5650..8f85f11b7c49 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionWrapperTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionWrapperTest.java
@@ -39,7 +39,7 @@ import org.mockito.MockitoAnnotations;
/**
* Tests for MagnificationConnectionWrapper. We don't test {@code
* MagnificationConnectionWrapper#linkToDeath(IBinder.DeathRecipient)} since it's tested in
- * {@link WindowMagnificationManagerTest}.
+ * {@link MagnificationConnectionManagerTest}.
*/
public class MagnificationConnectionWrapperTest {
@@ -73,9 +73,9 @@ public class MagnificationConnectionWrapperTest {
}
@Test
- public void setScale() throws RemoteException {
- mConnectionWrapper.setScale(TEST_DISPLAY, 3.0f);
- verify(mConnection).setScale(TEST_DISPLAY, 3.0f);
+ public void setScaleForWindowMagnification() throws RemoteException {
+ mConnectionWrapper.setScaleForWindowMagnification(TEST_DISPLAY, 3.0f);
+ verify(mConnection).setScaleForWindowMagnification(TEST_DISPLAY, 3.0f);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
index d4c6fad99645..e8cdf35dee13 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
@@ -131,7 +131,7 @@ public class MagnificationControllerTest {
private ArgumentCaptor<MagnificationAnimationCallback> mCallbackArgumentCaptor;
private MockWindowMagnificationConnection mMockConnection;
- private WindowMagnificationManager mWindowMagnificationManager;
+ private MagnificationConnectionManager mMagnificationConnectionManager;
private MockContentResolver mMockResolver;
private MagnificationController mMagnificationController;
private final WindowMagnificationMgrCallbackDelegate
@@ -205,13 +205,14 @@ public class MagnificationControllerTest {
));
mScreenMagnificationController.register(TEST_DISPLAY);
- mWindowMagnificationManager = spy(new WindowMagnificationManager(mContext, globalLock,
- mWindowMagnificationCallbackDelegate, mTraceManager, mScaleProvider));
+ mMagnificationConnectionManager = spy(
+ new MagnificationConnectionManager(mContext, globalLock,
+ mWindowMagnificationCallbackDelegate, mTraceManager, mScaleProvider));
mMockConnection = new MockWindowMagnificationConnection(true);
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
mMagnificationController = spy(new MagnificationController(mService, globalLock, mContext,
- mScreenMagnificationController, mWindowMagnificationManager, mScaleProvider,
+ mScreenMagnificationController, mMagnificationConnectionManager, mScaleProvider,
ConcurrentUtils.DIRECT_EXECUTOR));
mMagnificationController.setMagnificationCapabilities(
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL);
@@ -254,8 +255,10 @@ public class MagnificationControllerTest {
mCallbackArgumentCaptor.getValue().onResult(true);
mMockConnection.invokeCallbacks();
verify(mTransitionCallBack).onResult(TEST_DISPLAY, true);
- assertEquals(MAGNIFIED_CENTER_X, mWindowMagnificationManager.getCenterX(TEST_DISPLAY), 0);
- assertEquals(MAGNIFIED_CENTER_Y, mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 0);
+ assertEquals(MAGNIFIED_CENTER_X,
+ mMagnificationConnectionManager.getCenterX(TEST_DISPLAY), 0);
+ assertEquals(MAGNIFIED_CENTER_Y,
+ mMagnificationConnectionManager.getCenterY(TEST_DISPLAY), 0);
}
@Test
@@ -297,8 +300,10 @@ public class MagnificationControllerTest {
mMockConnection.invokeCallbacks();
verify(mTransitionCallBack).onResult(TEST_DISPLAY, true);
- assertEquals(MAGNIFIED_CENTER_X, mWindowMagnificationManager.getCenterX(TEST_DISPLAY), 0);
- assertEquals(MAGNIFIED_CENTER_Y, mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 0);
+ assertEquals(MAGNIFIED_CENTER_X,
+ mMagnificationConnectionManager.getCenterX(TEST_DISPLAY), 0);
+ assertEquals(MAGNIFIED_CENTER_Y,
+ mMagnificationConnectionManager.getCenterY(TEST_DISPLAY), 0);
}
@Test
@@ -316,7 +321,7 @@ public class MagnificationControllerTest {
// The first time is triggered when window mode is activated.
// The second time is triggered when activating the window mode again.
// The third time is triggered when the transition is completed.
- verify(mWindowMagnificationManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
+ verify(mMagnificationConnectionManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_WINDOW));
}
@@ -330,7 +335,7 @@ public class MagnificationControllerTest {
mTransitionCallBack);
mMockConnection.invokeCallbacks();
- assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+ assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
verify(mScreenMagnificationController).setScaleAndCenter(TEST_DISPLAY,
DEFAULT_SCALE, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y,
true, MAGNIFICATION_GESTURE_HANDLER_ID);
@@ -350,7 +355,7 @@ public class MagnificationControllerTest {
mTransitionCallBack);
mMockConnection.invokeCallbacks();
- assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+ assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
verify(mScreenMagnificationController).setScaleAndCenter(TEST_DISPLAY, DEFAULT_SCALE,
magnificationBounds.exactCenterX(), magnificationBounds.exactCenterY(), true,
MAGNIFICATION_GESTURE_HANDLER_ID);
@@ -386,11 +391,11 @@ public class MagnificationControllerTest {
mTransitionCallBack);
// Enable window magnification while animating.
- mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, DEFAULT_SCALE,
+ mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, DEFAULT_SCALE,
Float.NaN, Float.NaN, null, TEST_SERVICE_ID);
mMockConnection.invokeCallbacks();
- assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+ assertTrue(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
verify(mScreenMagnificationController, never()).setScaleAndCenter(TEST_DISPLAY,
DEFAULT_SCALE, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y,
true, MAGNIFICATION_GESTURE_HANDLER_ID);
@@ -408,8 +413,10 @@ public class MagnificationControllerTest {
verify(mScreenMagnificationController).reset(eq(TEST_DISPLAY), eq(false));
mMockConnection.invokeCallbacks();
- assertEquals(MAGNIFIED_CENTER_X, mWindowMagnificationManager.getCenterX(TEST_DISPLAY), 0);
- assertEquals(MAGNIFIED_CENTER_Y, mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 0);
+ assertEquals(MAGNIFIED_CENTER_X,
+ mMagnificationConnectionManager.getCenterX(TEST_DISPLAY), 0);
+ assertEquals(MAGNIFIED_CENTER_Y,
+ mMagnificationConnectionManager.getCenterY(TEST_DISPLAY), 0);
}
@Test
@@ -438,7 +445,7 @@ public class MagnificationControllerTest {
animate, TEST_SERVICE_ID);
mMockConnection.invokeCallbacks();
- assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+ assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
verify(mScreenMagnificationController).setScaleAndCenter(eq(TEST_DISPLAY),
eq(DEFAULT_SCALE), eq(MAGNIFIED_CENTER_X), eq(MAGNIFIED_CENTER_Y),
any(MagnificationAnimationCallback.class), eq(TEST_SERVICE_ID));
@@ -564,7 +571,7 @@ public class MagnificationControllerTest {
mMagnificationController.onDisplayRemoved(TEST_DISPLAY);
verify(mScreenMagnificationController).onDisplayRemoved(TEST_DISPLAY);
- verify(mWindowMagnificationManager).onDisplayRemoved(TEST_DISPLAY);
+ verify(mMagnificationConnectionManager).onDisplayRemoved(TEST_DISPLAY);
verify(mScaleProvider).onDisplayRemoved(TEST_DISPLAY);
}
@@ -573,7 +580,7 @@ public class MagnificationControllerTest {
mMagnificationController.updateUserIdIfNeeded(SECOND_USER_ID);
verify(mScreenMagnificationController).resetAllIfNeeded(false);
- verify(mWindowMagnificationManager).disableAllWindowMagnifiers();
+ verify(mMagnificationConnectionManager).disableAllWindowMagnifiers();
verify(mScaleProvider).onUserChanged(SECOND_USER_ID);
}
@@ -584,7 +591,7 @@ public class MagnificationControllerTest {
mMagnificationController.onRequestMagnificationSpec(TEST_DISPLAY, TEST_SERVICE_ID);
mMockConnection.invokeCallbacks();
- assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+ assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
}
@Test
@@ -594,11 +601,11 @@ public class MagnificationControllerTest {
// The first time is trigger when fullscreen mode is activated.
// The second time is triggered when magnification spec is changed.
- verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
+ verify(mMagnificationConnectionManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_FULLSCREEN));
// Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel
// in current capability and mode, and the magnification is activated.
- verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel(
+ verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel(
eq(TEST_DISPLAY));
}
@@ -625,8 +632,8 @@ public class MagnificationControllerTest {
mMagnificationController.onPerformScaleAction(TEST_DISPLAY, newScale, updatePersistence);
- verify(mWindowMagnificationManager).setScale(eq(TEST_DISPLAY), eq(newScale));
- verify(mWindowMagnificationManager, never()).persistScale(eq(TEST_DISPLAY));
+ verify(mMagnificationConnectionManager).setScale(eq(TEST_DISPLAY), eq(newScale));
+ verify(mMagnificationConnectionManager, never()).persistScale(eq(TEST_DISPLAY));
}
@Test
@@ -669,7 +676,7 @@ public class MagnificationControllerTest {
assertEquals(config.getCenterY(), actualConfig.getCenterY(), 0);
assertEquals(config.getScale(), actualConfig.getScale(), 0);
- verify(mWindowMagnificationManager).onUserMagnificationScaleChanged(
+ verify(mMagnificationConnectionManager).onUserMagnificationScaleChanged(
/* userId= */ anyInt(), eq(TEST_DISPLAY), eq(config.getScale()));
}
@@ -677,11 +684,11 @@ public class MagnificationControllerTest {
public void onSourceBoundChanged_windowEnabled_notifyMagnificationChanged()
throws RemoteException {
setMagnificationEnabled(MODE_WINDOW);
- reset(mWindowMagnificationManager);
+ reset(mMagnificationConnectionManager);
mMagnificationController.onSourceBoundsChanged(TEST_DISPLAY, TEST_RECT);
- verify(mWindowMagnificationManager).onUserMagnificationScaleChanged(
+ verify(mMagnificationConnectionManager).onUserMagnificationScaleChanged(
/* userId= */ anyInt(), eq(TEST_DISPLAY), eq(DEFAULT_SCALE));
}
@@ -780,11 +787,11 @@ public class MagnificationControllerTest {
// The first time is triggered when window mode is activated.
// The second time is triggered when accessibility action performed.
- verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
+ verify(mMagnificationConnectionManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_WINDOW));
// Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel
// in current capability and mode, and the magnification is activated.
- verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel(
+ verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel(
eq(TEST_DISPLAY));
}
@@ -799,10 +806,11 @@ public class MagnificationControllerTest {
// The first time is triggered when window mode is activated.
// The second time is triggered when accessibility action performed.
- verify(mWindowMagnificationManager, times(2)).removeMagnificationButton(eq(TEST_DISPLAY));
+ verify(mMagnificationConnectionManager, times(2))
+ .removeMagnificationButton(eq(TEST_DISPLAY));
// Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel
// in current capability and mode, and the magnification is activated.
- verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel(
+ verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel(
eq(TEST_DISPLAY));
}
@@ -816,7 +824,7 @@ public class MagnificationControllerTest {
public void deactivateWindowMagnification_windowActivated_triggerCallbackAndLogUsage()
throws RemoteException {
setMagnificationEnabled(MODE_WINDOW);
- mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, /* clear= */ true);
+ mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, /* clear= */ true);
verify(mMagnificationController).onWindowMagnificationActivationState(
eq(TEST_DISPLAY), eq(false));
@@ -828,7 +836,7 @@ public class MagnificationControllerTest {
public void setPreferenceMagnificationFollowTypingEnabled_setPrefDisabled_disableAll() {
mMagnificationController.setMagnificationFollowTypingEnabled(false);
- verify(mWindowMagnificationManager).setMagnificationFollowTypingEnabled(eq(false));
+ verify(mMagnificationConnectionManager).setMagnificationFollowTypingEnabled(eq(false));
verify(mScreenMagnificationController).setMagnificationFollowTypingEnabled(eq(false));
}
@@ -850,7 +858,7 @@ public class MagnificationControllerTest {
verify(mScreenMagnificationController).onRectangleOnScreenRequested(eq(TEST_DISPLAY),
eq(TEST_RECT.left), eq(TEST_RECT.top), eq(TEST_RECT.right), eq(TEST_RECT.bottom));
- verify(mWindowMagnificationManager, never()).onRectangleOnScreenRequested(anyInt(),
+ verify(mMagnificationConnectionManager, never()).onRectangleOnScreenRequested(anyInt(),
anyInt(), anyInt(), anyInt(), anyInt());
}
@@ -867,7 +875,7 @@ public class MagnificationControllerTest {
verify(mScreenMagnificationController, never()).onRectangleOnScreenRequested(anyInt(),
anyInt(), anyInt(), anyInt(), anyInt());
- verify(mWindowMagnificationManager, never()).onRectangleOnScreenRequested(anyInt(),
+ verify(mMagnificationConnectionManager, never()).onRectangleOnScreenRequested(anyInt(),
anyInt(), anyInt(), anyInt(), anyInt());
}
@@ -880,7 +888,7 @@ public class MagnificationControllerTest {
verify(mScreenMagnificationController, never()).onRectangleOnScreenRequested(
eq(TEST_DISPLAY), anyInt(), anyInt(), anyInt(), anyInt());
- verify(mWindowMagnificationManager, never()).onRectangleOnScreenRequested(anyInt(),
+ verify(mMagnificationConnectionManager, never()).onRectangleOnScreenRequested(anyInt(),
anyInt(), anyInt(), anyInt(), anyInt());
}
@@ -895,7 +903,7 @@ public class MagnificationControllerTest {
verify(mScreenMagnificationController, never()).onRectangleOnScreenRequested(
eq(TEST_DISPLAY), anyInt(), anyInt(), anyInt(), anyInt());
- verify(mWindowMagnificationManager, never()).onRectangleOnScreenRequested(anyInt(),
+ verify(mMagnificationConnectionManager, never()).onRectangleOnScreenRequested(anyInt(),
anyInt(), anyInt(), anyInt(), anyInt());
}
@@ -970,7 +978,8 @@ public class MagnificationControllerTest {
mMagnificationController.onFullScreenMagnificationActivationState(TEST_DISPLAY, true);
- verify(mWindowMagnificationManager).disableWindowMagnification(eq(TEST_DISPLAY), eq(false));
+ verify(mMagnificationConnectionManager)
+ .disableWindowMagnification(eq(TEST_DISPLAY), eq(false));
}
@Test
@@ -983,11 +992,11 @@ public class MagnificationControllerTest {
// The first time is triggered when fullscreen mode is activated.
// The second time is triggered when magnification spec is changed.
// The third time is triggered when user interaction changed.
- verify(mWindowMagnificationManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
+ verify(mMagnificationConnectionManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_FULLSCREEN));
// Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel
// in current capability and mode, and the magnification is activated.
- verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel(
+ verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel(
eq(TEST_DISPLAY));
}
@@ -1001,11 +1010,11 @@ public class MagnificationControllerTest {
// The first time is triggered when fullscreen mode is activated.
// The second time is triggered when magnification spec is changed.
// The third time is triggered when user interaction changed.
- verify(mWindowMagnificationManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
+ verify(mMagnificationConnectionManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_FULLSCREEN));
// Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel
// in current capability and mode, and the magnification is activated.
- verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel(
+ verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel(
eq(TEST_DISPLAY));
}
@@ -1018,11 +1027,11 @@ public class MagnificationControllerTest {
// The first time is triggered when the window mode is activated.
// The second time is triggered when user interaction changed.
- verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
+ verify(mMagnificationConnectionManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_WINDOW));
// Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel
// in current capability and mode, and the magnification is activated.
- verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel(
+ verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel(
eq(TEST_DISPLAY));
}
@@ -1035,11 +1044,11 @@ public class MagnificationControllerTest {
// The first time is triggered when the window mode is activated.
// The second time is triggered when user interaction changed.
- verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
+ verify(mMagnificationConnectionManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_WINDOW));
// Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel
// in current capability and mode, and the magnification is activated.
- verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel(
+ verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel(
eq(TEST_DISPLAY));
}
@@ -1053,11 +1062,11 @@ public class MagnificationControllerTest {
mMagnificationController.onTouchInteractionStart(TEST_DISPLAY, MODE_FULLSCREEN);
mMagnificationController.onTouchInteractionEnd(TEST_DISPLAY, MODE_FULLSCREEN);
- verify(mWindowMagnificationManager, never()).showMagnificationButton(eq(TEST_DISPLAY),
+ verify(mMagnificationConnectionManager, never()).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_FULLSCREEN));
// The first time is triggered when fullscreen mode is activated.
// The second time is triggered when magnification spec is changed.
- verify(mWindowMagnificationManager, times(2)).removeMagnificationSettingsPanel(
+ verify(mMagnificationConnectionManager, times(2)).removeMagnificationSettingsPanel(
eq(TEST_DISPLAY));
}
@@ -1071,9 +1080,9 @@ public class MagnificationControllerTest {
mMagnificationController.onTouchInteractionStart(TEST_DISPLAY, MODE_FULLSCREEN);
mMagnificationController.onTouchInteractionEnd(TEST_DISPLAY, MODE_FULLSCREEN);
- verify(mWindowMagnificationManager, never()).showMagnificationButton(eq(TEST_DISPLAY),
+ verify(mMagnificationConnectionManager, never()).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_FULLSCREEN));
- verify(mWindowMagnificationManager, times(2)).removeMagnificationSettingsPanel(
+ verify(mMagnificationConnectionManager, times(2)).removeMagnificationSettingsPanel(
eq(TEST_DISPLAY));
}
@@ -1082,11 +1091,11 @@ public class MagnificationControllerTest {
throws RemoteException {
setMagnificationEnabled(MODE_WINDOW);
- verify(mWindowMagnificationManager).showMagnificationButton(eq(TEST_DISPLAY),
+ verify(mMagnificationConnectionManager).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_WINDOW));
// Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel
// in current capability and mode, and the magnification is activated.
- verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel(
+ verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel(
eq(TEST_DISPLAY));
}
@@ -1100,11 +1109,11 @@ public class MagnificationControllerTest {
// The first time is triggered when fullscreen mode is activated.
// The second time is triggered when magnification spec is changed.
// The third time is triggered when fullscreen mode activation state is updated.
- verify(mWindowMagnificationManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
+ verify(mMagnificationConnectionManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_FULLSCREEN));
// Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel
// in current capability and mode, and the magnification is activated.
- verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel(
+ verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel(
eq(TEST_DISPLAY));
}
@@ -1113,10 +1122,10 @@ public class MagnificationControllerTest {
throws RemoteException {
setMagnificationEnabled(MODE_WINDOW);
- mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false);
+ mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false);
- verify(mWindowMagnificationManager).removeMagnificationButton(eq(TEST_DISPLAY));
- verify(mWindowMagnificationManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
+ verify(mMagnificationConnectionManager).removeMagnificationButton(eq(TEST_DISPLAY));
+ verify(mMagnificationConnectionManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
}
@Test
@@ -1126,8 +1135,8 @@ public class MagnificationControllerTest {
setMagnificationEnabled(MODE_FULLSCREEN);
mScreenMagnificationController.reset(TEST_DISPLAY, /* animate= */ true);
- verify(mWindowMagnificationManager).removeMagnificationButton(eq(TEST_DISPLAY));
- verify(mWindowMagnificationManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
+ verify(mMagnificationConnectionManager).removeMagnificationButton(eq(TEST_DISPLAY));
+ verify(mMagnificationConnectionManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
}
@Test
@@ -1142,10 +1151,10 @@ public class MagnificationControllerTest {
// The first time is triggered when fullscreen mode is activated.
// The second time is triggered when magnification spec is changed.
// The third time is triggered when the disable-magnification callback is triggered.
- verify(mWindowMagnificationManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
+ verify(mMagnificationConnectionManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_FULLSCREEN));
// It is triggered when the disable-magnification callback is triggered.
- verify(mWindowMagnificationManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
+ verify(mMagnificationConnectionManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
}
@Test
@@ -1163,10 +1172,10 @@ public class MagnificationControllerTest {
// The first time is triggered when window mode is activated.
// The second time is triggered when the disable-magnification callback is triggered.
- verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
+ verify(mMagnificationConnectionManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_WINDOW));
// It is triggered when the disable-magnification callback is triggered.
- verify(mWindowMagnificationManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
+ verify(mMagnificationConnectionManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
}
@Test
@@ -1174,9 +1183,9 @@ public class MagnificationControllerTest {
throws RemoteException {
setMagnificationEnabled(MODE_WINDOW);
- mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false);
+ mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false);
- verify(mWindowMagnificationManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
+ verify(mMagnificationConnectionManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
}
@Test
@@ -1185,7 +1194,7 @@ public class MagnificationControllerTest {
setMagnificationEnabled(MODE_FULLSCREEN);
mScreenMagnificationController.reset(TEST_DISPLAY, /* animate= */ true);
- verify(mWindowMagnificationManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
+ verify(mMagnificationConnectionManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
}
@Test
@@ -1260,17 +1269,17 @@ public class MagnificationControllerTest {
private void activateMagnifier(int displayId, int mode, float centerX, float centerY)
throws RemoteException {
- final boolean windowMagnifying = mWindowMagnificationManager.isWindowMagnifierEnabled(
+ final boolean windowMagnifying = mMagnificationConnectionManager.isWindowMagnifierEnabled(
displayId);
if (windowMagnifying) {
- mWindowMagnificationManager.disableWindowMagnification(displayId, false);
+ mMagnificationConnectionManager.disableWindowMagnification(displayId, false);
mMockConnection.invokeCallbacks();
}
if (mode == MODE_FULLSCREEN) {
mScreenMagnificationController.setScaleAndCenter(displayId, DEFAULT_SCALE, centerX,
centerY, true, AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
} else {
- mWindowMagnificationManager.enableWindowMagnification(displayId, DEFAULT_SCALE,
+ mMagnificationConnectionManager.enableWindowMagnification(displayId, DEFAULT_SCALE,
centerX, centerY, null, TEST_SERVICE_ID);
mMockConnection.invokeCallbacks();
}
@@ -1304,10 +1313,10 @@ public class MagnificationControllerTest {
}
private static class WindowMagnificationMgrCallbackDelegate implements
- WindowMagnificationManager.Callback {
- private WindowMagnificationManager.Callback mCallback;
+ MagnificationConnectionManager.Callback {
+ private MagnificationConnectionManager.Callback mCallback;
- public void setDelegate(WindowMagnificationManager.Callback callback) {
+ public void setDelegate(MagnificationConnectionManager.Callback callback) {
mCallback = callback;
}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java
index 612a091a6b1b..c4be51f9ecbd 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java
@@ -92,7 +92,7 @@ public class WindowMagnificationGestureHandlerTest {
public final TestableContext mContext = new TestableContext(
InstrumentationRegistry.getInstrumentation().getContext());
- private WindowMagnificationManager mWindowMagnificationManager;
+ private MagnificationConnectionManager mMagnificationConnectionManager;
private MockWindowMagnificationConnection mMockConnection;
private SpyWindowMagnificationGestureHandler mWindowMagnificationGestureHandler;
private WindowMagnificationGestureHandler mMockWindowMagnificationGestureHandler;
@@ -104,23 +104,23 @@ public class WindowMagnificationGestureHandlerTest {
@Before
public void setUp() throws RemoteException {
MockitoAnnotations.initMocks(this);
- mWindowMagnificationManager = new WindowMagnificationManager(mContext, new Object(),
- mock(WindowMagnificationManager.Callback.class), mMockTrace,
+ mMagnificationConnectionManager = new MagnificationConnectionManager(mContext, new Object(),
+ mock(MagnificationConnectionManager.Callback.class), mMockTrace,
new MagnificationScaleProvider(mContext));
mMockConnection = new MockWindowMagnificationConnection();
mWindowMagnificationGestureHandler = new SpyWindowMagnificationGestureHandler(
- mContext, mWindowMagnificationManager, mMockTrace, mMockCallback,
+ mContext, mMagnificationConnectionManager, mMockTrace, mMockCallback,
/** detectSingleFingerTripleTap= */ true, /** detectTwoFingerTripleTap= */ true,
/** detectShortcutTrigger= */ true, DISPLAY_0);
mMockWindowMagnificationGestureHandler =
mWindowMagnificationGestureHandler.getMockGestureHandler();
- mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
mWindowMagnificationGestureHandler.setNext(strictMock(EventStreamTransformation.class));
}
@After
public void tearDown() {
- mWindowMagnificationManager.disableWindowMagnification(DISPLAY_0, true);
+ mMagnificationConnectionManager.disableWindowMagnification(DISPLAY_0, true);
}
@Test
@@ -378,7 +378,7 @@ public class WindowMagnificationGestureHandlerTest {
}
break;
case STATE_SHOW_MAGNIFIER_SHORTCUT: {
- mWindowMagnificationManager.disableWindowMagnification(DISPLAY_0, false);
+ mMagnificationConnectionManager.disableWindowMagnification(DISPLAY_0, false);
}
break;
case STATE_TWO_FINGERS_DOWN: {
@@ -423,7 +423,7 @@ public class WindowMagnificationGestureHandlerTest {
}
private boolean isWindowMagnifierEnabled(int displayId) {
- return mWindowMagnificationManager.isWindowMagnifierEnabled(displayId);
+ return mMagnificationConnectionManager.isWindowMagnifierEnabled(displayId);
}
private static String stateToString(int state) {
@@ -495,13 +495,14 @@ public class WindowMagnificationGestureHandlerTest {
private final WindowMagnificationGestureHandler mMockWindowMagnificationGestureHandler;
SpyWindowMagnificationGestureHandler(@UiContext Context context,
- WindowMagnificationManager windowMagnificationMgr,
+ MagnificationConnectionManager magnificationConnectionManager,
AccessibilityTraceManager trace,
Callback callback,
boolean detectSingleFingerTripleTap, boolean detectTwoFingerTripleTap,
boolean detectShortcutTrigger, int displayId) {
- super(context, windowMagnificationMgr, trace, callback, detectSingleFingerTripleTap,
- detectTwoFingerTripleTap, detectShortcutTrigger, displayId);
+ super(context, magnificationConnectionManager, trace, callback,
+ detectSingleFingerTripleTap, detectTwoFingerTripleTap,
+ detectShortcutTrigger, displayId);
mMockWindowMagnificationGestureHandler = mock(WindowMagnificationGestureHandler.class);
}
diff --git a/services/tests/servicestests/src/com/android/server/audio/LoudnessCodecHelperTest.java b/services/tests/servicestests/src/com/android/server/audio/LoudnessCodecHelperTest.java
index 749b07d16ebe..9c8276aac4dd 100644
--- a/services/tests/servicestests/src/com/android/server/audio/LoudnessCodecHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/LoudnessCodecHelperTest.java
@@ -19,6 +19,16 @@ import static android.media.AudioManager.GET_DEVICES_OUTPUTS;
import static android.media.AudioPlaybackConfiguration.PLAYER_UPDATE_DEVICE_ID;
import static android.media.LoudnessCodecInfo.CodecMetadataType.CODEC_METADATA_TYPE_MPEG_4;
import static android.media.LoudnessCodecInfo.CodecMetadataType.CODEC_METADATA_TYPE_MPEG_D;
+import static android.media.MediaFormat.KEY_AAC_DRC_EFFECT_TYPE;
+import static android.media.MediaFormat.KEY_AAC_DRC_HEAVY_COMPRESSION;
+import static android.media.MediaFormat.KEY_AAC_DRC_TARGET_REFERENCE_LEVEL;
+
+import static com.android.server.audio.LoudnessCodecHelper.SPL_RANGE_LARGE;
+import static com.android.server.audio.LoudnessCodecHelper.SPL_RANGE_MEDIUM;
+import static com.android.server.audio.LoudnessCodecHelper.SPL_RANGE_SMALL;
+import static com.android.server.audio.LoudnessCodecHelper.SPL_RANGE_UNKNOWN;
+
+import static junit.framework.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.any;
@@ -34,11 +44,15 @@ import android.media.ILoudnessCodecUpdatesDispatcher;
import android.media.LoudnessCodecInfo;
import android.media.PlayerBase;
import android.os.IBinder;
+import android.os.PersistableBundle;
import android.platform.test.annotations.Presubmit;
import android.util.Log;
import androidx.test.ext.junit.runners.AndroidJUnit4;
+import com.android.server.audio.LoudnessCodecHelper.DeviceSplRange;
+import com.android.server.audio.LoudnessCodecHelper.LoudnessCodecInputProperties;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -84,8 +98,7 @@ public class LoudnessCodecHelperTest {
mLoudnessHelper.registerLoudnessCodecUpdatesDispatcher(mDispatcher);
mLoudnessHelper.startLoudnessCodecUpdates(mInitialApcPiid,
- List.of(getLoudnessInfo(/*mediaCodecHash=*/111, /*isDownmixing=*/true,
- CODEC_METADATA_TYPE_MPEG_4)));
+ List.of(getLoudnessInfo(/*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_4)));
verify(mDispatcher).dispatchLoudnessCodecParameterChange(eq(mInitialApcPiid), any());
}
@@ -96,8 +109,7 @@ public class LoudnessCodecHelperTest {
mLoudnessHelper.unregisterLoudnessCodecUpdatesDispatcher(mDispatcher);
mLoudnessHelper.startLoudnessCodecUpdates(mInitialApcPiid,
- List.of(getLoudnessInfo(/*mediaCodecHash=*/222, /*isDownmixing=*/false,
- CODEC_METADATA_TYPE_MPEG_D)));
+ List.of(getLoudnessInfo(/*isDownmixing=*/false, CODEC_METADATA_TYPE_MPEG_D)));
verify(mDispatcher, times(0)).dispatchLoudnessCodecParameterChange(eq(mInitialApcPiid),
any());
@@ -108,11 +120,9 @@ public class LoudnessCodecHelperTest {
mLoudnessHelper.registerLoudnessCodecUpdatesDispatcher(mDispatcher);
mLoudnessHelper.startLoudnessCodecUpdates(mInitialApcPiid,
- List.of(getLoudnessInfo(/*mediaCodecHash=*/111, /*isDownmixing=*/true,
- CODEC_METADATA_TYPE_MPEG_4)));
- mLoudnessHelper.addLoudnessCodecInfo(mInitialApcPiid,
- getLoudnessInfo(/*mediaCodecHash=*/222, /*isDownmixing=*/true,
- CODEC_METADATA_TYPE_MPEG_D));
+ List.of(getLoudnessInfo(/*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_4)));
+ mLoudnessHelper.addLoudnessCodecInfo(mInitialApcPiid, /*mediaCodecHash=*/222,
+ getLoudnessInfo(/*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_D));
verify(mDispatcher, times(2)).dispatchLoudnessCodecParameterChange(eq(mInitialApcPiid),
any());
@@ -124,11 +134,10 @@ public class LoudnessCodecHelperTest {
mLoudnessHelper.registerLoudnessCodecUpdatesDispatcher(mDispatcher);
mLoudnessHelper.startLoudnessCodecUpdates(mInitialApcPiid,
- List.of(getLoudnessInfo(/*mediaCodecHash=*/111, /*isDownmixing=*/true,
+ List.of(getLoudnessInfo(/*isDownmixing=*/true,
CODEC_METADATA_TYPE_MPEG_4)));
- mLoudnessHelper.addLoudnessCodecInfo(newPiid,
- getLoudnessInfo(/*mediaCodecHash=*/222, /*isDownmixing=*/true,
- CODEC_METADATA_TYPE_MPEG_D));
+ mLoudnessHelper.addLoudnessCodecInfo(newPiid, /*mediaCodecHash=*/222,
+ getLoudnessInfo(/*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_D));
verify(mDispatcher, times(1)).dispatchLoudnessCodecParameterChange(eq(mInitialApcPiid),
any());
@@ -140,12 +149,10 @@ public class LoudnessCodecHelperTest {
mLoudnessHelper.registerLoudnessCodecUpdatesDispatcher(mDispatcher);
mLoudnessHelper.startLoudnessCodecUpdates(mInitialApcPiid,
- List.of(getLoudnessInfo(/*mediaCodecHash=*/111, /*isDownmixing=*/true,
- CODEC_METADATA_TYPE_MPEG_4)));
+ List.of(getLoudnessInfo(/*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_4)));
//does not trigger dispatch since active apc list does not contain newPiid
mLoudnessHelper.startLoudnessCodecUpdates(newPiid,
- List.of(getLoudnessInfo(/*mediaCodecHash=*/222, /*isDownmixing=*/true,
- CODEC_METADATA_TYPE_MPEG_D)));
+ List.of(getLoudnessInfo(/*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_D)));
verify(mDispatcher, times(1)).dispatchLoudnessCodecParameterChange(eq(mInitialApcPiid),
any());
@@ -157,9 +164,8 @@ public class LoudnessCodecHelperTest {
@Test
public void updateCodecParameters_noStartedPiids_noDispatch() throws Exception {
mLoudnessHelper.registerLoudnessCodecUpdatesDispatcher(mDispatcher);
- mLoudnessHelper.addLoudnessCodecInfo(mInitialApcPiid,
- getLoudnessInfo(/*mediaCodecHash=*/222, /*isDownmixing=*/true,
- CODEC_METADATA_TYPE_MPEG_D));
+ mLoudnessHelper.addLoudnessCodecInfo(mInitialApcPiid, /*mediaCodecHash=*/222,
+ getLoudnessInfo(/*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_D));
mLoudnessHelper.updateCodecParameters(getApcListForPiids(mInitialApcPiid));
@@ -170,8 +176,8 @@ public class LoudnessCodecHelperTest {
@Test
public void updateCodecParameters_removedCodecInfo_noDispatch() throws Exception {
- final LoudnessCodecInfo info = getLoudnessInfo(/*mediaCodecHash=*/111,
- /*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_4);
+ final LoudnessCodecInfo info = getLoudnessInfo(/*isDownmixing=*/true,
+ CODEC_METADATA_TYPE_MPEG_4);
mLoudnessHelper.registerLoudnessCodecUpdatesDispatcher(mDispatcher);
mLoudnessHelper.startLoudnessCodecUpdates(mInitialApcPiid, List.of(info));
@@ -186,8 +192,8 @@ public class LoudnessCodecHelperTest {
@Test
public void updateCodecParameters_stoppedPiids_noDispatch() throws Exception {
- final LoudnessCodecInfo info = getLoudnessInfo(/*mediaCodecHash=*/111,
- /*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_4);
+ final LoudnessCodecInfo info = getLoudnessInfo(/*isDownmixing=*/true,
+ CODEC_METADATA_TYPE_MPEG_4);
mLoudnessHelper.registerLoudnessCodecUpdatesDispatcher(mDispatcher);
mLoudnessHelper.startLoudnessCodecUpdates(mInitialApcPiid, List.of(info));
@@ -200,6 +206,108 @@ public class LoudnessCodecHelperTest {
any());
}
+ @Test
+ public void checkParcelableBundle_forMpeg4CodecInputProperties() {
+ PersistableBundle loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/true,
+ SPL_RANGE_SMALL).createLoudnessParameters();
+ assertEquals(64, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(1, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/false,
+ SPL_RANGE_SMALL).createLoudnessParameters();
+ assertEquals(64, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(1, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/true,
+ SPL_RANGE_MEDIUM).createLoudnessParameters();
+ assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(1, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/false,
+ SPL_RANGE_MEDIUM).createLoudnessParameters();
+ assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(0, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/true,
+ SPL_RANGE_LARGE).createLoudnessParameters();
+ assertEquals(124, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(0, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/false,
+ SPL_RANGE_LARGE).createLoudnessParameters();
+ assertEquals(124, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(0, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/true,
+ SPL_RANGE_UNKNOWN).createLoudnessParameters();
+ assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(1, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/false,
+ SPL_RANGE_UNKNOWN).createLoudnessParameters();
+ assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(0, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+ }
+
+ @Test
+ public void checkParcelableBundle_forMpegDCodecInputProperties() {
+ PersistableBundle loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/true,
+ SPL_RANGE_SMALL).createLoudnessParameters();
+ assertEquals(64, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(3, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/false,
+ SPL_RANGE_SMALL).createLoudnessParameters();
+ assertEquals(64, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(3, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/true,
+ SPL_RANGE_MEDIUM).createLoudnessParameters();
+ assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/false,
+ SPL_RANGE_MEDIUM).createLoudnessParameters();
+ assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/true,
+ SPL_RANGE_LARGE).createLoudnessParameters();
+ assertEquals(124, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/false,
+ SPL_RANGE_LARGE).createLoudnessParameters();
+ assertEquals(124, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/true,
+ SPL_RANGE_UNKNOWN).createLoudnessParameters();
+ assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/false,
+ SPL_RANGE_UNKNOWN).createLoudnessParameters();
+ assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+ }
+
private List<AudioPlaybackConfiguration> getApcListForPiids(int... piids) {
final ArrayList<AudioPlaybackConfiguration> apcList = new ArrayList<>();
@@ -220,11 +328,15 @@ public class LoudnessCodecHelperTest {
return apcList;
}
- private static LoudnessCodecInfo getLoudnessInfo(int mediaCodecHash, boolean isDownmixing,
- int metadataType) {
+ private static LoudnessCodecInputProperties createInputProperties(
+ int metadataType, boolean isDownmixing, @DeviceSplRange int splRange) {
+ return new LoudnessCodecInputProperties.Builder().setMetadataType(
+ metadataType).setIsDownmixing(isDownmixing).setDeviceSplRange(splRange).build();
+ }
+
+ private static LoudnessCodecInfo getLoudnessInfo(boolean isDownmixing, int metadataType) {
LoudnessCodecInfo info = new LoudnessCodecInfo();
info.isDownmixing = isDownmixing;
- info.mediaCodecHashCode = mediaCodecHash;
info.metadataType = metadataType;
return info;
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/camera/VirtualCameraControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/camera/VirtualCameraControllerTest.java
index 01922e08d71d..edfe1b416f22 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/camera/VirtualCameraControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/camera/VirtualCameraControllerTest.java
@@ -40,6 +40,7 @@ import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.Surface;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -77,6 +78,11 @@ public class VirtualCameraControllerTest {
when(mVirtualCameraServiceMock.registerCamera(any(), any())).thenReturn(true);
}
+ @After
+ public void tearDown() throws Exception {
+ mVirtualCameraController.close();
+ }
+
@Test
public void registerCamera_registersCamera() throws Exception {
mVirtualCameraController.registerCamera(createVirtualCameraConfig(
@@ -95,6 +101,8 @@ public class VirtualCameraControllerTest {
public void unregisterCamera_unregistersCamera() throws Exception {
VirtualCameraConfig config = createVirtualCameraConfig(
CAMERA_WIDTH_1, CAMERA_HEIGHT_1, CAMERA_FORMAT, CAMERA_DISPLAY_NAME_RES_ID_1);
+ mVirtualCameraController.registerCamera(config);
+
mVirtualCameraController.unregisterCamera(config);
verify(mVirtualCameraServiceMock).unregisterCamera(any());
@@ -107,9 +115,10 @@ public class VirtualCameraControllerTest {
mVirtualCameraController.registerCamera(createVirtualCameraConfig(
CAMERA_WIDTH_2, CAMERA_HEIGHT_2, CAMERA_FORMAT, CAMERA_DISPLAY_NAME_RES_ID_2));
+ mVirtualCameraController.close();
+
ArgumentCaptor<VirtualCameraConfiguration> configurationCaptor =
ArgumentCaptor.forClass(VirtualCameraConfiguration.class);
- mVirtualCameraController.close();
verify(mVirtualCameraServiceMock, times(2)).registerCamera(any(),
configurationCaptor.capture());
List<VirtualCameraConfiguration> virtualCameraConfigurations =
diff --git a/services/tests/servicestests/src/com/android/server/media/AudioPoliciesDeviceRouteControllerTest.java b/services/tests/servicestests/src/com/android/server/media/AudioPoliciesDeviceRouteControllerTest.java
deleted file mode 100644
index 5aef7a320930..000000000000
--- a/services/tests/servicestests/src/com/android/server/media/AudioPoliciesDeviceRouteControllerTest.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.media;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.media.AudioManager;
-import android.media.AudioRoutesInfo;
-import android.media.IAudioRoutesObserver;
-import android.media.MediaRoute2Info;
-import android.os.RemoteException;
-
-import com.android.internal.R;
-import com.android.server.audio.AudioService;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(JUnit4.class)
-public class AudioPoliciesDeviceRouteControllerTest {
-
- private static final String ROUTE_NAME_DEFAULT = "default";
- private static final String ROUTE_NAME_DOCK = "dock";
- private static final String ROUTE_NAME_HEADPHONES = "headphones";
-
- private static final int VOLUME_SAMPLE_1 = 25;
-
- @Mock
- private Context mContext;
- @Mock
- private Resources mResources;
- @Mock
- private AudioManager mAudioManager;
- @Mock
- private AudioService mAudioService;
- @Mock
- private DeviceRouteController.OnDeviceRouteChangedListener mOnDeviceRouteChangedListener;
-
- @Captor
- private ArgumentCaptor<IAudioRoutesObserver.Stub> mAudioRoutesObserverCaptor;
-
- private AudioPoliciesDeviceRouteController mController;
-
- private IAudioRoutesObserver.Stub mAudioRoutesObserver;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
-
- when(mContext.getResources()).thenReturn(mResources);
- when(mResources.getText(anyInt())).thenReturn(ROUTE_NAME_DEFAULT);
-
- // Setting built-in speaker as default speaker.
- AudioRoutesInfo audioRoutesInfo = new AudioRoutesInfo();
- audioRoutesInfo.mainType = AudioRoutesInfo.MAIN_SPEAKER;
- when(mAudioService.startWatchingRoutes(mAudioRoutesObserverCaptor.capture()))
- .thenReturn(audioRoutesInfo);
-
- mController = new AudioPoliciesDeviceRouteController(
- mContext, mAudioManager, mAudioService, mOnDeviceRouteChangedListener);
-
- mAudioRoutesObserver = mAudioRoutesObserverCaptor.getValue();
- }
-
- @Test
- public void getDeviceRoute_noSelectedRoutes_returnsDefaultDevice() {
- MediaRoute2Info route2Info = mController.getSelectedRoute();
-
- assertThat(route2Info.getName()).isEqualTo(ROUTE_NAME_DEFAULT);
- assertThat(route2Info.getType()).isEqualTo(MediaRoute2Info.TYPE_BUILTIN_SPEAKER);
- }
-
- @Test
- public void getDeviceRoute_audioRouteHasChanged_returnsRouteFromAudioService() {
- when(mResources.getText(R.string.default_audio_route_name_headphones))
- .thenReturn(ROUTE_NAME_HEADPHONES);
-
- AudioRoutesInfo audioRoutesInfo = new AudioRoutesInfo();
- audioRoutesInfo.mainType = AudioRoutesInfo.MAIN_HEADPHONES;
- callAudioRoutesObserver(audioRoutesInfo);
-
- MediaRoute2Info route2Info = mController.getSelectedRoute();
- assertThat(route2Info.getName()).isEqualTo(ROUTE_NAME_HEADPHONES);
- assertThat(route2Info.getType()).isEqualTo(MediaRoute2Info.TYPE_WIRED_HEADPHONES);
- }
-
- @Test
- public void getDeviceRoute_selectDevice_returnsSelectedRoute() {
- when(mResources.getText(R.string.default_audio_route_name_dock_speakers))
- .thenReturn(ROUTE_NAME_DOCK);
-
- mController.selectRoute(MediaRoute2Info.TYPE_DOCK);
-
- MediaRoute2Info route2Info = mController.getSelectedRoute();
- assertThat(route2Info.getName()).isEqualTo(ROUTE_NAME_DOCK);
- assertThat(route2Info.getType()).isEqualTo(MediaRoute2Info.TYPE_DOCK);
- }
-
- @Test
- public void getDeviceRoute_hasSelectedAndAudioServiceRoutes_returnsSelectedRoute() {
- when(mResources.getText(R.string.default_audio_route_name_headphones))
- .thenReturn(ROUTE_NAME_HEADPHONES);
- when(mResources.getText(R.string.default_audio_route_name_dock_speakers))
- .thenReturn(ROUTE_NAME_DOCK);
-
- AudioRoutesInfo audioRoutesInfo = new AudioRoutesInfo();
- audioRoutesInfo.mainType = AudioRoutesInfo.MAIN_HEADPHONES;
- callAudioRoutesObserver(audioRoutesInfo);
-
- mController.selectRoute(MediaRoute2Info.TYPE_DOCK);
-
- MediaRoute2Info route2Info = mController.getSelectedRoute();
- assertThat(route2Info.getName()).isEqualTo(ROUTE_NAME_DOCK);
- assertThat(route2Info.getType()).isEqualTo(MediaRoute2Info.TYPE_DOCK);
- }
-
- @Test
- public void getDeviceRoute_unselectRoute_returnsAudioServiceRoute() {
- when(mResources.getText(R.string.default_audio_route_name_headphones))
- .thenReturn(ROUTE_NAME_HEADPHONES);
- when(mResources.getText(R.string.default_audio_route_name_dock_speakers))
- .thenReturn(ROUTE_NAME_DOCK);
-
- mController.selectRoute(MediaRoute2Info.TYPE_DOCK);
-
- AudioRoutesInfo audioRoutesInfo = new AudioRoutesInfo();
- audioRoutesInfo.mainType = AudioRoutesInfo.MAIN_HEADPHONES;
- callAudioRoutesObserver(audioRoutesInfo);
-
- mController.selectRoute(null);
-
- MediaRoute2Info route2Info = mController.getSelectedRoute();
- assertThat(route2Info.getName()).isEqualTo(ROUTE_NAME_HEADPHONES);
- assertThat(route2Info.getType()).isEqualTo(MediaRoute2Info.TYPE_WIRED_HEADPHONES);
- }
-
- @Test
- public void getDeviceRoute_selectRouteFails_returnsAudioServiceRoute() {
- when(mResources.getText(R.string.default_audio_route_name_headphones))
- .thenReturn(ROUTE_NAME_HEADPHONES);
-
- AudioRoutesInfo audioRoutesInfo = new AudioRoutesInfo();
- audioRoutesInfo.mainType = AudioRoutesInfo.MAIN_HEADPHONES;
- callAudioRoutesObserver(audioRoutesInfo);
-
- mController.selectRoute(MediaRoute2Info.TYPE_BLUETOOTH_A2DP);
-
- MediaRoute2Info route2Info = mController.getSelectedRoute();
- assertThat(route2Info.getName()).isEqualTo(ROUTE_NAME_HEADPHONES);
- assertThat(route2Info.getType()).isEqualTo(MediaRoute2Info.TYPE_WIRED_HEADPHONES);
- }
-
- @Test
- public void selectRoute_selectWiredRoute_returnsTrue() {
- assertThat(mController.selectRoute(MediaRoute2Info.TYPE_HDMI)).isTrue();
- }
-
- @Test
- public void selectRoute_selectBluetoothRoute_returnsFalse() {
- assertThat(mController.selectRoute(MediaRoute2Info.TYPE_BLUETOOTH_A2DP)).isFalse();
- }
-
- @Test
- public void selectRoute_unselectRoute_returnsTrue() {
- assertThat(mController.selectRoute(null)).isTrue();
- }
-
- @Test
- public void updateVolume_noSelectedRoute_deviceRouteVolumeChanged() {
- when(mResources.getText(R.string.default_audio_route_name_headphones))
- .thenReturn(ROUTE_NAME_HEADPHONES);
-
- AudioRoutesInfo audioRoutesInfo = new AudioRoutesInfo();
- audioRoutesInfo.mainType = AudioRoutesInfo.MAIN_HEADPHONES;
- callAudioRoutesObserver(audioRoutesInfo);
-
- mController.updateVolume(VOLUME_SAMPLE_1);
-
- MediaRoute2Info route2Info = mController.getSelectedRoute();
- assertThat(route2Info.getType()).isEqualTo(MediaRoute2Info.TYPE_WIRED_HEADPHONES);
- assertThat(route2Info.getVolume()).isEqualTo(VOLUME_SAMPLE_1);
- }
-
- @Test
- public void updateVolume_connectSelectedRouteLater_selectedRouteVolumeChanged() {
- when(mResources.getText(R.string.default_audio_route_name_headphones))
- .thenReturn(ROUTE_NAME_HEADPHONES);
- when(mResources.getText(R.string.default_audio_route_name_dock_speakers))
- .thenReturn(ROUTE_NAME_DOCK);
-
- AudioRoutesInfo audioRoutesInfo = new AudioRoutesInfo();
- audioRoutesInfo.mainType = AudioRoutesInfo.MAIN_HEADPHONES;
- callAudioRoutesObserver(audioRoutesInfo);
-
- mController.updateVolume(VOLUME_SAMPLE_1);
-
- mController.selectRoute(MediaRoute2Info.TYPE_DOCK);
-
- MediaRoute2Info route2Info = mController.getSelectedRoute();
- assertThat(route2Info.getType()).isEqualTo(MediaRoute2Info.TYPE_DOCK);
- assertThat(route2Info.getVolume()).isEqualTo(VOLUME_SAMPLE_1);
- }
-
- /**
- * Simulates {@link IAudioRoutesObserver.Stub#dispatchAudioRoutesChanged(AudioRoutesInfo)}
- * from {@link AudioService}. This happens when there is a wired route change,
- * like a wired headset being connected.
- *
- * @param audioRoutesInfo updated state of connected wired device
- */
- private void callAudioRoutesObserver(AudioRoutesInfo audioRoutesInfo) {
- try {
- // this is a captured observer implementation
- // from WiredRoutesController's AudioService#startWatchingRoutes call
- mAudioRoutesObserver.dispatchAudioRoutesChanged(audioRoutesInfo);
- } catch (RemoteException exception) {
- // Should not happen since the object is mocked.
- assertWithMessage("An unexpected RemoteException happened.").fail();
- }
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/media/DeviceRouteControllerTest.java b/services/tests/servicestests/src/com/android/server/media/DeviceRouteControllerTest.java
index 14b121d3945c..0961b7d97177 100644
--- a/services/tests/servicestests/src/com/android/server/media/DeviceRouteControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/media/DeviceRouteControllerTest.java
@@ -19,6 +19,7 @@ package com.android.server.media;
import static com.android.media.flags.Flags.FLAG_ENABLE_AUDIO_POLICIES_DEVICE_AND_BLUETOOTH_CONTROLLER;
import android.content.Context;
+import android.os.Looper;
import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
@@ -56,7 +57,8 @@ public class DeviceRouteControllerTest {
@RequiresFlagsDisabled(FLAG_ENABLE_AUDIO_POLICIES_DEVICE_AND_BLUETOOTH_CONTROLLER)
public void createInstance_audioPoliciesFlagIsDisabled_createsLegacyController() {
DeviceRouteController deviceRouteController =
- DeviceRouteController.createInstance(mContext, mOnDeviceRouteChangedListener);
+ DeviceRouteController.createInstance(
+ mContext, Looper.getMainLooper(), mOnDeviceRouteChangedListener);
Truth.assertThat(deviceRouteController).isInstanceOf(LegacyDeviceRouteController.class);
}
@@ -65,7 +67,8 @@ public class DeviceRouteControllerTest {
@RequiresFlagsEnabled(FLAG_ENABLE_AUDIO_POLICIES_DEVICE_AND_BLUETOOTH_CONTROLLER)
public void createInstance_audioPoliciesFlagIsEnabled_createsAudioPoliciesController() {
DeviceRouteController deviceRouteController =
- DeviceRouteController.createInstance(mContext, mOnDeviceRouteChangedListener);
+ DeviceRouteController.createInstance(
+ mContext, Looper.getMainLooper(), mOnDeviceRouteChangedListener);
Truth.assertThat(deviceRouteController)
.isInstanceOf(AudioPoliciesDeviceRouteController.class);
diff --git a/services/tests/servicestests/src/com/android/server/utils/UserSettingDeviceConfigMediatorTest.java b/services/tests/servicestests/src/com/android/server/utils/UserSettingDeviceConfigMediatorTest.java
new file mode 100644
index 000000000000..377e4c3d6810
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/utils/UserSettingDeviceConfigMediatorTest.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.utils;
+
+import static org.junit.Assert.assertEquals;
+
+import android.provider.DeviceConfig;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Unit tests for {@link UserSettingDeviceConfigMediator}
+ */
+@RunWith(AndroidJUnit4.class)
+public class UserSettingDeviceConfigMediatorTest {
+ @Test
+ public void testDeviceConfigOnly() {
+ UserSettingDeviceConfigMediator mediator =
+ new UserSettingDeviceConfigMediator.SettingsOverridesIndividualMediator(',');
+
+ DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder("test")
+ .setInt("int", 1)
+ .setFloat("float", .5f)
+ .setBoolean("boolean", true)
+ .setLong("long", 123456789)
+ .setString("string", "abc123")
+ .build();
+
+ mediator.setDeviceConfigProperties(properties);
+
+ assertEquals(1, mediator.getInt("int", 123));
+ assertEquals(123, mediator.getInt("invalidKey", 123));
+ assertEquals(.5f, mediator.getFloat("float", .8f), 0.001);
+ assertEquals(.8f, mediator.getFloat("invalidKey", .8f), 0.001);
+ assertEquals(true, mediator.getBoolean("boolean", false));
+ assertEquals(true, mediator.getBoolean("invalidKey", true));
+ assertEquals(123456789, mediator.getLong("long", 987654321));
+ assertEquals(987654321, mediator.getInt("invalidKey", 987654321));
+ assertEquals("abc123", mediator.getString("string", "xyz987"));
+ assertEquals("xyz987", mediator.getString("invalidKey", "xyz987"));
+
+ // Clear the properties
+ mediator.setDeviceConfigProperties(null);
+
+ assertEquals(123, mediator.getInt("int", 123));
+ assertEquals(123, mediator.getInt("invalidKey", 123));
+ assertEquals(.8f, mediator.getFloat("float", .8f), 0.001);
+ assertEquals(.8f, mediator.getFloat("invalidKey", .8f), 0.001);
+ assertEquals(false, mediator.getBoolean("boolean", false));
+ assertEquals(true, mediator.getBoolean("invalidKey", true));
+ assertEquals(987654321, mediator.getLong("long", 987654321));
+ assertEquals(987654321, mediator.getInt("invalidKey", 987654321));
+ assertEquals("xyz987", mediator.getString("string", "xyz987"));
+ assertEquals("xyz987", mediator.getString("invalidKey", "xyz987"));
+ }
+
+ @Test
+ public void testSettingsOnly() {
+ UserSettingDeviceConfigMediator mediator =
+ new UserSettingDeviceConfigMediator.SettingsOverridesIndividualMediator(',');
+
+ String settings = "int=1,float=.5f,boolean=true,long=123456789,string=abc123";
+
+ mediator.setSettingsString(settings);
+
+ assertEquals(1, mediator.getInt("int", 123));
+ assertEquals(123, mediator.getInt("invalidKey", 123));
+ assertEquals(.5f, mediator.getFloat("float", .8f), 0.001);
+ assertEquals(.8f, mediator.getFloat("invalidKey", .8f), 0.001);
+ assertEquals(true, mediator.getBoolean("boolean", false));
+ assertEquals(true, mediator.getBoolean("invalidKey", true));
+ assertEquals(123456789, mediator.getLong("long", 987654321));
+ assertEquals(987654321, mediator.getInt("invalidKey", 987654321));
+ assertEquals("abc123", mediator.getString("string", "xyz987"));
+ assertEquals("xyz987", mediator.getString("invalidKey", "xyz987"));
+
+ // Clear the settings
+ mediator.setSettingsString(null);
+
+ assertEquals(123, mediator.getInt("int", 123));
+ assertEquals(123, mediator.getInt("invalidKey", 123));
+ assertEquals(.8f, mediator.getFloat("float", .8f), 0.001);
+ assertEquals(.8f, mediator.getFloat("invalidKey", .8f), 0.001);
+ assertEquals(false, mediator.getBoolean("boolean", false));
+ assertEquals(true, mediator.getBoolean("invalidKey", true));
+ assertEquals(987654321, mediator.getLong("long", 987654321));
+ assertEquals(987654321, mediator.getInt("invalidKey", 987654321));
+ assertEquals("xyz987", mediator.getString("string", "xyz987"));
+ assertEquals("xyz987", mediator.getString("invalidKey", "xyz987"));
+ }
+
+ @Test
+ public void testSettingsOverridesAll() {
+ UserSettingDeviceConfigMediator mediator =
+ new UserSettingDeviceConfigMediator.SettingsOverridesAllMediator(',');
+
+ String settings = "int=1,float=.5f,boolean=true,long=123456789,string=abc123,"
+ + "intOnlyInSettings=9,floatOnlyInSettings=.25f,booleanOnlyInSettings=true,"
+ + "longOnlyInSettings=53771465,stringOnlyInSettings=settingsString";
+ DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder("test")
+ .setInt("int", 10)
+ .setInt("intOnlyInDeviceConfig", 9001)
+ .setFloat("float", .7f)
+ .setFloat("floatOnlyInDeviceConfig", .9f)
+ .setBoolean("boolean", false)
+ .setBoolean("booleanOnlyInDeviceConfig", true)
+ .setLong("long", 60000001)
+ .setLong("longOnlyInDeviceConfig", 7357)
+ .setString("string", "xyz987")
+ .setString("stringOnlyInDeviceConfig", "deviceConfigString")
+ .build();
+
+ mediator.setSettingsString(settings);
+ mediator.setDeviceConfigProperties(properties);
+
+ // Since settings overrides all, anything in DeviceConfig should be ignored,
+ // even if settings doesn't have a value for it.
+ assertEquals(1, mediator.getInt("int", 123));
+ assertEquals(9, mediator.getInt("intOnlyInSettings", 123));
+ assertEquals(123, mediator.getInt("intOnlyInDeviceConfig", 123));
+ assertEquals(.5f, mediator.getFloat("float", .8f), 0.001);
+ assertEquals(.25f, mediator.getFloat("floatOnlyInSettings", .8f), 0.001);
+ assertEquals(.8f, mediator.getFloat("floatOnlyInDeviceConfig", .8f), 0.001);
+ assertEquals(true, mediator.getBoolean("boolean", false));
+ assertEquals(true, mediator.getBoolean("booleanOnlyInSettings", false));
+ assertEquals(false, mediator.getBoolean("booleanOnlyInDeviceConfig", false));
+ assertEquals(123456789, mediator.getLong("long", 987654321));
+ assertEquals(53771465, mediator.getLong("longOnlyInSettings", 987654321));
+ assertEquals(987654321, mediator.getLong("longOnlyInDeviceConfig", 987654321));
+ assertEquals("abc123", mediator.getString("string", "default"));
+ assertEquals("settingsString", mediator.getString("stringOnlyInSettings", "default"));
+ assertEquals("default", mediator.getString("stringOnlyInDeviceConfig", "default"));
+
+ // Nothing in settings, do DeviceConfig can be used.
+ mediator.setSettingsString("");
+
+ assertEquals(10, mediator.getInt("int", 123));
+ assertEquals(123, mediator.getInt("intOnlyInSettings", 123));
+ assertEquals(9001, mediator.getInt("intOnlyInDeviceConfig", 123));
+ assertEquals(.7f, mediator.getFloat("float", .8f), 0.001);
+ assertEquals(.8f, mediator.getFloat("floatOnlyInSettings", .8f), 0.001);
+ assertEquals(.9f, mediator.getFloat("floatOnlyInDeviceConfig", .8f), 0.001);
+ assertEquals(false, mediator.getBoolean("boolean", false));
+ assertEquals(false, mediator.getBoolean("booleanOnlyInSettings", false));
+ assertEquals(true, mediator.getBoolean("booleanOnlyInDeviceConfig", false));
+ assertEquals(60000001, mediator.getLong("long", 987654321));
+ assertEquals(987654321, mediator.getLong("longOnlyInSettings", 987654321));
+ assertEquals(7357, mediator.getLong("longOnlyInDeviceConfig", 987654321));
+ assertEquals("xyz987", mediator.getString("string", "default"));
+ assertEquals("default", mediator.getString("stringOnlyInSettings", "default"));
+ assertEquals("deviceConfigString",
+ mediator.getString("stringOnlyInDeviceConfig", "default"));
+
+ // Nothing in settings, do DeviceConfig can be used.
+ mediator.setSettingsString(null);
+
+ assertEquals(10, mediator.getInt("int", 123));
+ assertEquals(123, mediator.getInt("intOnlyInSettings", 123));
+ assertEquals(9001, mediator.getInt("intOnlyInDeviceConfig", 123));
+ assertEquals(.7f, mediator.getFloat("float", .8f), 0.001);
+ assertEquals(.8f, mediator.getFloat("floatOnlyInSettings", .8f), 0.001);
+ assertEquals(.9f, mediator.getFloat("floatOnlyInDeviceConfig", .8f), 0.001);
+ assertEquals(false, mediator.getBoolean("boolean", false));
+ assertEquals(false, mediator.getBoolean("booleanOnlyInSettings", false));
+ assertEquals(true, mediator.getBoolean("booleanOnlyInDeviceConfig", false));
+ assertEquals(60000001, mediator.getLong("long", 987654321));
+ assertEquals(987654321, mediator.getLong("longOnlyInSettings", 987654321));
+ assertEquals(7357, mediator.getLong("longOnlyInDeviceConfig", 987654321));
+ assertEquals("xyz987", mediator.getString("string", "default"));
+ assertEquals("default", mediator.getString("stringOnlyInSettings", "default"));
+ assertEquals("deviceConfigString",
+ mediator.getString("stringOnlyInDeviceConfig", "default"));
+ }
+
+ @Test
+ public void testSettingsOverridesIndividual() {
+ UserSettingDeviceConfigMediator mediator =
+ new UserSettingDeviceConfigMediator.SettingsOverridesIndividualMediator(',');
+
+ String settings = "int=1,float=.5f,boolean=true,long=123456789,string=abc123,"
+ + "intOnlyInSettings=9,floatOnlyInSettings=.25f,booleanOnlyInSettings=true,"
+ + "longOnlyInSettings=53771465,stringOnlyInSettings=settingsString";
+ DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder("test")
+ .setInt("int", 10)
+ .setInt("intOnlyInDeviceConfig", 9001)
+ .setFloat("float", .7f)
+ .setFloat("floatOnlyInDeviceConfig", .9f)
+ .setBoolean("boolean", false)
+ .setBoolean("booleanOnlyInDeviceConfig", true)
+ .setLong("long", 60000001)
+ .setLong("longOnlyInDeviceConfig", 7357)
+ .setString("string", "xyz987")
+ .setString("stringOnlyInDeviceConfig", "deviceConfigString")
+ .build();
+
+ mediator.setSettingsString(settings);
+ mediator.setDeviceConfigProperties(properties);
+
+ // Since settings overrides individual, anything in DeviceConfig that doesn't exist in
+ // settings should be used.
+ assertEquals(1, mediator.getInt("int", 123));
+ assertEquals(9, mediator.getInt("intOnlyInSettings", 123));
+ assertEquals(9001, mediator.getInt("intOnlyInDeviceConfig", 123));
+ assertEquals(.5f, mediator.getFloat("float", .8f), 0.001);
+ assertEquals(.25f, mediator.getFloat("floatOnlyInSettings", .8f), 0.001);
+ assertEquals(.9f, mediator.getFloat("floatOnlyInDeviceConfig", .8f), 0.001);
+ assertEquals(true, mediator.getBoolean("boolean", false));
+ assertEquals(true, mediator.getBoolean("booleanOnlyInSettings", false));
+ assertEquals(true, mediator.getBoolean("booleanOnlyInDeviceConfig", false));
+ assertEquals(123456789, mediator.getLong("long", 987654321));
+ assertEquals(53771465, mediator.getLong("longOnlyInSettings", 987654321));
+ assertEquals(7357, mediator.getLong("longOnlyInDeviceConfig", 987654321));
+ assertEquals("abc123", mediator.getString("string", "default"));
+ assertEquals("settingsString", mediator.getString("stringOnlyInSettings", "default"));
+ assertEquals("deviceConfigString",
+ mediator.getString("stringOnlyInDeviceConfig", "default"));
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
index d00060564e74..32082e3d857e 100644
--- a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
@@ -28,6 +28,7 @@ import android.content.pm.Signature;
import android.os.Build;
import android.os.Bundle;
import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.test.suitebuilder.annotation.MediumTest;
@@ -1449,4 +1450,21 @@ public class WebViewUpdateServiceTest {
checkPreparationPhasesForPackage(currentSdkPackage.packageName,
1 /* first preparation phase */);
}
+
+ @Test
+ @RequiresFlagsEnabled("android.webkit.update_service_v2")
+ public void testDefaultWebViewPackageIsTheFirstAvailableByDefault() {
+ String nonDefaultPackage = "nonDefaultPackage";
+ String defaultPackage1 = "defaultPackage1";
+ String defaultPackage2 = "defaultPackage2";
+ WebViewProviderInfo[] packages =
+ new WebViewProviderInfo[] {
+ new WebViewProviderInfo(nonDefaultPackage, "", false, false, null),
+ new WebViewProviderInfo(defaultPackage1, "", true, false, null),
+ new WebViewProviderInfo(defaultPackage2, "", true, false, null)
+ };
+ setupWithPackages(packages);
+ assertEquals(
+ defaultPackage1, mWebViewUpdateServiceImpl.getDefaultWebViewPackage().packageName);
+ }
}
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index f2a1fe859634..c3074bb0fee8 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -93,8 +93,6 @@
android:showWhenLocked="true"/>
<activity android:name="android.view.cts.surfacevalidator.CapturedActivity"/>
- <activity android:name="com.android.server.wm.SurfaceControlViewHostTests$TestActivity" />
-
<activity android:name="com.android.server.wm.SurfaceSyncGroupTests$TestActivity"
android:screenOrientation="locked"
android:turnScreenOn="true"
@@ -122,6 +120,13 @@
<activity android:name="com.android.server.wm.ActivityRecordInputSinkTests$TestActivity"
android:exported="true">
</activity>
+
+ <activity android:name="com.android.server.wm.utils.TestActivity"
+ android:screenOrientation="locked"
+ android:turnScreenOn="true"
+ android:showWhenLocked="true"
+ android:theme="@style/WhiteBackgroundTheme"
+ android:exported="true" />
</application>
<instrumentation
diff --git a/services/tests/wmtests/AndroidTest.xml b/services/tests/wmtests/AndroidTest.xml
index f8ebeaddcb7e..46e87dceb8d4 100644
--- a/services/tests/wmtests/AndroidTest.xml
+++ b/services/tests/wmtests/AndroidTest.xml
@@ -30,4 +30,8 @@
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
<option name="hidden-api-checks" value="false" />
</test>
+
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command" value="settings put secure immersive_mode_confirmations confirmed" />
+ </target_preparer>
</configuration>
diff --git a/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java
index 2c35cf0c4151..8d236eda5dc5 100644
--- a/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java
@@ -110,24 +110,6 @@ public class ModifierShortcutTests extends ShortcutKeyTestBase {
}
/**
- * META + SPACE to switch keyboard layout.
- */
- @Test
- public void testMetaSpace() {
- sendKeyCombination(new int[]{KEYCODE_META_LEFT, KEYCODE_SPACE}, 0);
- mPhoneWindowManager.assertSwitchKeyboardLayout(1);
- }
-
- /**
- * META + SHIFT + SPACE to switch keyboard layout backwards.
- */
- @Test
- public void testMetaShiftSpace() {
- sendKeyCombination(new int[]{KEYCODE_META_LEFT, KEYCODE_SHIFT_LEFT, KEYCODE_SPACE}, 0);
- mPhoneWindowManager.assertSwitchKeyboardLayout(-1);
- }
-
- /**
* CTRL + ALT + Z to enable accessibility service.
*/
@Test
diff --git a/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
index 71098aa5e883..360fdf3ae3f7 100644
--- a/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
@@ -132,13 +132,6 @@ public class ShortcutLoggingTests extends ShortcutKeyTestBase {
{"LANGUAGE_SWITCH key -> Switch Keyboard Language",
new int[]{KeyEvent.KEYCODE_LANGUAGE_SWITCH},
KeyboardLogEvent.LANGUAGE_SWITCH, KeyEvent.KEYCODE_LANGUAGE_SWITCH, 0},
- {"Meta + Space -> Switch Keyboard Language",
- new int[]{META_KEY, KeyEvent.KEYCODE_SPACE},
- KeyboardLogEvent.LANGUAGE_SWITCH, KeyEvent.KEYCODE_SPACE, META_ON},
- {"Meta + Shift + Space -> Switch Keyboard Language",
- new int[]{META_KEY, SHIFT_KEY, KeyEvent.KEYCODE_SPACE},
- KeyboardLogEvent.LANGUAGE_SWITCH, KeyEvent.KEYCODE_SPACE,
- META_ON | SHIFT_ON},
{"META key -> Open App Drawer in Accessibility mode", new int[]{META_KEY},
KeyboardLogEvent.ACCESSIBILITY_ALL_APPS, META_KEY, META_ON},
{"Meta + Alt -> Toggle CapsLock", new int[]{META_KEY, ALT_KEY},
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceControlViewHostTests.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceControlViewHostTests.java
index 8119fd486a87..3b9ed2652610 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceControlViewHostTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceControlViewHostTests.java
@@ -23,15 +23,14 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static org.junit.Assert.assertTrue;
-import android.app.Activity;
import android.app.Instrumentation;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.PixelFormat;
-import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
+import android.server.wm.BuildUtils;
import android.view.Gravity;
import android.view.IWindow;
import android.view.SurfaceControl;
@@ -46,12 +45,12 @@ import android.widget.Button;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
import com.android.server.wm.utils.CommonUtils;
+import com.android.server.wm.utils.TestActivity;
import org.junit.After;
import org.junit.Before;
@@ -59,11 +58,14 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
@Presubmit
@SmallTest
@RunWith(WindowTestRunner.class)
public class SurfaceControlViewHostTests {
+ private static final long WAIT_TIME_S = 5L * BuildUtils.HW_TIMEOUT_MULTIPLIER;
+
private static final String TAG = "SurfaceControlViewHostTests";
private final ActivityTestRule<TestActivity> mActivityRule = new ActivityTestRule<>(
@@ -76,6 +78,8 @@ public class SurfaceControlViewHostTests {
private SurfaceControlViewHost mScvh1;
private SurfaceControlViewHost mScvh2;
+ private SurfaceView mSurfaceView;
+
@Before
public void setUp() throws Exception {
mInstrumentation = InstrumentationRegistry.getInstrumentation();
@@ -96,15 +100,17 @@ public class SurfaceControlViewHostTests {
mView1 = new Button(mActivity);
mView2 = new Button(mActivity);
- mInstrumentation.runOnMainSync(() -> {
- try {
- mActivity.attachToSurfaceView(sc);
- } catch (InterruptedException e) {
- }
+ CountDownLatch svReadyLatch = new CountDownLatch(1);
+ mActivity.runOnUiThread(() -> addSurfaceView(svReadyLatch));
+ assertTrue("Failed to wait for SV to get created",
+ svReadyLatch.await(WAIT_TIME_S, TimeUnit.SECONDS));
+ new SurfaceControl.Transaction().reparent(sc, mSurfaceView.getSurfaceControl())
+ .show(sc).apply();
+ mInstrumentation.runOnMainSync(() -> {
TestWindowlessWindowManager wwm = new TestWindowlessWindowManager(
mActivity.getResources().getConfiguration(), sc,
- mActivity.mSurfaceView.getHostToken());
+ mSurfaceView.getHostToken());
mScvh1 = new SurfaceControlViewHost(mActivity, mActivity.getDisplay(),
wwm, "requestFocusWithMultipleWindows");
@@ -135,7 +141,7 @@ public class SurfaceControlViewHostTests {
}
assertTrue("Failed to wait for view2", wasVisible);
- IWindow window = IWindow.Stub.asInterface(mActivity.mSurfaceView.getWindowToken());
+ IWindow window = IWindow.Stub.asInterface(mSurfaceView.getWindowToken());
WindowManagerGlobal.getWindowSession().grantEmbeddedWindowFocus(window,
mScvh1.getInputTransferToken(), true);
@@ -162,43 +168,30 @@ public class SurfaceControlViewHostTests {
}
}
- public static class TestActivity extends Activity implements SurfaceHolder.Callback {
- private SurfaceView mSurfaceView;
- private final CountDownLatch mSvReadyLatch = new CountDownLatch(1);
+ private void addSurfaceView(CountDownLatch svReadyLatch) {
+ final FrameLayout content = mActivity.getParentLayout();
+ mSurfaceView = new SurfaceView(mActivity);
+ mSurfaceView.setZOrderOnTop(true);
+ final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(500, 500,
+ Gravity.LEFT | Gravity.TOP);
+ mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceCreated(@NonNull SurfaceHolder holder) {
+ svReadyLatch.countDown();
+ }
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- final FrameLayout content = new FrameLayout(this);
- mSurfaceView = new SurfaceView(this);
- mSurfaceView.setBackgroundColor(Color.BLACK);
- mSurfaceView.setZOrderOnTop(true);
- final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(500, 500,
- Gravity.LEFT | Gravity.TOP);
- content.addView(mSurfaceView, lp);
- setContentView(content);
- mSurfaceView.getHolder().addCallback(this);
- }
+ @Override
+ public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width,
+ int height) {
- @Override
- public void surfaceCreated(@NonNull SurfaceHolder holder) {
- mSvReadyLatch.countDown();
- }
+ }
- @Override
- public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width,
- int height) {
- }
+ @Override
+ public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
- @Override
- public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
- }
-
- public void attachToSurfaceView(SurfaceControl sc) throws InterruptedException {
- mSvReadyLatch.await();
- new SurfaceControl.Transaction().reparent(sc, mSurfaceView.getSurfaceControl())
- .show(sc).apply();
- }
+ }
+ });
+ content.addView(mSurfaceView, lp);
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
index 8a90f127f4eb..06f29c262b42 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
@@ -25,7 +25,9 @@ import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.window.TaskFragmentOperation.OP_TYPE_CREATE_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_CREATE_TASK_FRAGMENT_DECOR_SURFACE;
import static android.window.TaskFragmentOperation.OP_TYPE_DELETE_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE;
import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_BOTTOM_OF_TASK;
import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_FRONT;
import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_TOP_OF_TASK;
@@ -1759,6 +1761,40 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
}
@Test
+ public void testApplyTransaction_createTaskFragmentDecorSurface() {
+ // TODO(b/293654166) remove system organizer requirement once security review is cleared.
+ mController.unregisterOrganizer(mIOrganizer);
+ mController.registerOrganizerInternal(mIOrganizer, true /* isSystemOrganizer */);
+ final Task task = createTask(mDisplayContent);
+
+ final TaskFragment tf = createTaskFragment(task);
+ final TaskFragmentOperation operation = new TaskFragmentOperation.Builder(
+ OP_TYPE_CREATE_TASK_FRAGMENT_DECOR_SURFACE).build();
+ mTransaction.addTaskFragmentOperation(tf.getFragmentToken(), operation);
+
+ assertApplyTransactionAllowed(mTransaction);
+
+ verify(task).moveOrCreateDecorSurfaceFor(tf);
+ }
+
+ @Test
+ public void testApplyTransaction_removeTaskFragmentDecorSurface() {
+ // TODO(b/293654166) remove system organizer requirement once security review is cleared.
+ mController.unregisterOrganizer(mIOrganizer);
+ mController.registerOrganizerInternal(mIOrganizer, true /* isSystemOrganizer */);
+ final Task task = createTask(mDisplayContent);
+ final TaskFragment tf = createTaskFragment(task);
+
+ final TaskFragmentOperation operation = new TaskFragmentOperation.Builder(
+ OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE).build();
+ mTransaction.addTaskFragmentOperation(tf.getFragmentToken(), operation);
+
+ assertApplyTransactionAllowed(mTransaction);
+
+ verify(task).removeDecorSurface();
+ }
+
+ @Test
public void testApplyTransaction_reorderToBottomOfTask_failsIfNotSystemOrganizer() {
testApplyTransaction_reorder_failsIfNotSystemOrganizer_common(
OP_TYPE_REORDER_TO_BOTTOM_OF_TASK);
@@ -1966,7 +2002,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
/** Setups the mock Task as the parent of the given TaskFragment. */
private static void setupMockParent(TaskFragment taskFragment, Task mockParent) {
doReturn(mockParent).when(taskFragment).getTask();
- doReturn(new TaskFragmentParentInfo(new Configuration(), DEFAULT_DISPLAY, true, true))
+ doReturn(new TaskFragmentParentInfo(
+ new Configuration(), DEFAULT_DISPLAY, true, true, null /* decorSurface */))
.when(mockParent).getTaskFragmentParentInfo();
// Task needs to be visible
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index 5e531b4cbc4f..da7612b17dc9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -63,6 +63,7 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.same;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import android.app.ActivityManager;
@@ -82,6 +83,7 @@ import android.util.DisplayMetrics;
import android.util.Xml;
import android.view.Display;
import android.view.DisplayInfo;
+import android.view.SurfaceControl;
import android.window.TaskFragmentOrganizer;
import androidx.test.filters.MediumTest;
@@ -1619,6 +1621,185 @@ public class TaskTests extends WindowTestsBase {
assertFalse(task.isDragResizing());
}
+ @Test
+ public void testMoveOrCreateDecorSurface() {
+ final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
+ final Task task = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
+ final ActivityRecord activity = task.getTopMostActivity();
+ final TaskFragment fragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
+ doNothing().when(task).sendTaskFragmentParentInfoChangedIfNeeded();
+
+ // Decor surface should not be present initially.
+ assertNull(task.mDecorSurfaceContainer);
+ assertNull(task.getDecorSurface());
+ assertNull(task.getTaskFragmentParentInfo().getDecorSurface());
+
+ // Decor surface should be created.
+ clearInvocations(task);
+ task.moveOrCreateDecorSurfaceFor(fragment);
+
+ assertNotNull(task.mDecorSurfaceContainer);
+ assertNotNull(task.getDecorSurface());
+ verify(task).sendTaskFragmentParentInfoChangedIfNeeded();
+ assertNotNull(task.getTaskFragmentParentInfo().getDecorSurface());
+ assertEquals(fragment, task.mDecorSurfaceContainer.mOwnerTaskFragment);
+
+ // Decor surface should be removed.
+ clearInvocations(task);
+ task.removeDecorSurface();
+
+ assertNull(task.mDecorSurfaceContainer);
+ assertNull(task.getDecorSurface());
+ verify(task).sendTaskFragmentParentInfoChangedIfNeeded();
+ assertNull(task.getTaskFragmentParentInfo().getDecorSurface());
+ }
+
+ @Test
+ public void testMoveOrCreateDecorSurface_whenOwnerTaskFragmentRemoved() {
+ final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
+ final Task task = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
+ final ActivityRecord activity = task.getTopMostActivity();
+ final TaskFragment fragment1 = createTaskFragmentWithEmbeddedActivity(task, organizer);
+ final TaskFragment fragment2 = createTaskFragmentWithEmbeddedActivity(task, organizer);
+ doNothing().when(task).sendTaskFragmentParentInfoChangedIfNeeded();
+
+ task.moveOrCreateDecorSurfaceFor(fragment1);
+
+ assertNotNull(task.mDecorSurfaceContainer);
+ assertNotNull(task.getDecorSurface());
+ assertEquals(fragment1, task.mDecorSurfaceContainer.mOwnerTaskFragment);
+
+ // Transfer ownership
+ task.moveOrCreateDecorSurfaceFor(fragment2);
+
+ assertNotNull(task.mDecorSurfaceContainer);
+ assertNotNull(task.getDecorSurface());
+ assertEquals(fragment2, task.mDecorSurfaceContainer.mOwnerTaskFragment);
+
+ // Safe surface should be removed when the owner TaskFragment is removed.
+ task.removeChild(fragment2);
+
+ verify(task).removeDecorSurface();
+ assertNull(task.mDecorSurfaceContainer);
+ assertNull(task.getDecorSurface());
+ }
+
+ @Test
+ public void testAssignChildLayers_decorSurfacePlacement() {
+ final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
+ final Task task = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
+ final ActivityRecord unembeddedActivity = task.getTopMostActivity();
+
+ final TaskFragment fragment1 = createTaskFragmentWithEmbeddedActivity(task, organizer);
+ final TaskFragment fragment2 = createTaskFragmentWithEmbeddedActivity(task, organizer);
+ final SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
+
+ doNothing().when(task).sendTaskFragmentParentInfoChangedIfNeeded();
+ spyOn(unembeddedActivity);
+ spyOn(fragment1);
+ spyOn(fragment2);
+
+ // Initially, the decor surface should not be placed.
+ task.assignChildLayers(t);
+ verify(unembeddedActivity).assignLayer(t, 0);
+ verify(fragment1).assignLayer(t, 1);
+ verify(fragment2).assignLayer(t, 2);
+
+ clearInvocations(t);
+ clearInvocations(unembeddedActivity);
+ clearInvocations(fragment1);
+ clearInvocations(fragment2);
+
+ // The decor surface should be placed just above the owner TaskFragment.
+ doReturn(true).when(unembeddedActivity).isUid(task.effectiveUid);
+ doReturn(true).when(fragment1).isAllowedToBeEmbeddedInTrustedMode();
+ doReturn(true).when(fragment2).isAllowedToBeEmbeddedInTrustedMode();
+ doReturn(true).when(fragment1).isVisible();
+
+ task.moveOrCreateDecorSurfaceFor(fragment1);
+ task.assignChildLayers(t);
+
+ verify(unembeddedActivity).assignLayer(t, 0);
+ verify(fragment1).assignLayer(t, 1);
+ verify(t).setLayer(task.mDecorSurfaceContainer.mContainerSurface, 2);
+ verify(fragment2).assignLayer(t, 3);
+ verify(t).setVisibility(task.mDecorSurfaceContainer.mContainerSurface, true);
+ verify(t, never()).setLayer(eq(task.getDecorSurface()), anyInt());
+
+ clearInvocations(t);
+ clearInvocations(unembeddedActivity);
+ clearInvocations(fragment1);
+ clearInvocations(fragment2);
+
+ // The decor surface should be invisible if the owner TaskFragment is invisible.
+ doReturn(true).when(unembeddedActivity).isUid(task.effectiveUid);
+ doReturn(true).when(fragment1).isAllowedToBeEmbeddedInTrustedMode();
+ doReturn(true).when(fragment2).isAllowedToBeEmbeddedInTrustedMode();
+ doReturn(false).when(fragment1).isVisible();
+
+ task.assignChildLayers(t);
+
+ verify(unembeddedActivity).assignLayer(t, 0);
+ verify(fragment1).assignLayer(t, 1);
+ verify(t).setLayer(task.mDecorSurfaceContainer.mContainerSurface, 2);
+ verify(fragment2).assignLayer(t, 3);
+ verify(t).setVisibility(task.mDecorSurfaceContainer.mContainerSurface, false);
+ verify(t, never()).setLayer(eq(task.getDecorSurface()), anyInt());
+
+ clearInvocations(t);
+ clearInvocations(unembeddedActivity);
+ clearInvocations(fragment1);
+ clearInvocations(fragment2);
+
+ // The decor surface should be placed on below activity from a different UID.
+ doReturn(false).when(unembeddedActivity).isUid(task.effectiveUid);
+ doReturn(true).when(fragment1).isAllowedToBeEmbeddedInTrustedMode();
+ doReturn(true).when(fragment2).isAllowedToBeEmbeddedInTrustedMode();
+ doReturn(true).when(fragment1).isVisible();
+
+ task.assignChildLayers(t);
+
+ verify(t).setLayer(task.mDecorSurfaceContainer.mContainerSurface, 0);
+ verify(unembeddedActivity).assignLayer(t, 1);
+ verify(fragment1).assignLayer(t, 2);
+ verify(fragment2).assignLayer(t, 3);
+ verify(t).setVisibility(task.mDecorSurfaceContainer.mContainerSurface, true);
+ verify(t, never()).setLayer(eq(task.getDecorSurface()), anyInt());
+
+ clearInvocations(t);
+ clearInvocations(unembeddedActivity);
+ clearInvocations(fragment1);
+ clearInvocations(fragment2);
+
+ // The decor surface should be placed below untrusted embedded TaskFragment.
+ doReturn(true).when(unembeddedActivity).isUid(task.effectiveUid);
+ doReturn(true).when(fragment1).isAllowedToBeEmbeddedInTrustedMode();
+ doReturn(false).when(fragment2).isAllowedToBeEmbeddedInTrustedMode();
+ doReturn(true).when(fragment1).isVisible();
+
+ task.assignChildLayers(t);
+
+ verify(unembeddedActivity).assignLayer(t, 0);
+ verify(fragment1).assignLayer(t, 1);
+ verify(t).setLayer(task.mDecorSurfaceContainer.mContainerSurface, 2);
+ verify(fragment2).assignLayer(t, 3);
+ verify(t).setVisibility(task.mDecorSurfaceContainer.mContainerSurface, true);
+ verify(t, never()).setLayer(eq(task.getDecorSurface()), anyInt());
+
+ clearInvocations(t);
+ clearInvocations(unembeddedActivity);
+ clearInvocations(fragment1);
+ clearInvocations(fragment2);
+
+ // The decor surface should not be placed after removal.
+ task.removeDecorSurface();
+ task.assignChildLayers(t);
+
+ verify(unembeddedActivity).assignLayer(t, 0);
+ verify(fragment1).assignLayer(t, 1);
+ verify(fragment2).assignLayer(t, 2);
+ }
+
private Task getTestTask() {
return new TaskBuilder(mSupervisor).setCreateActivity(true).build();
}
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 dade3b91e0eb..71447e72de8c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -2015,6 +2015,9 @@ public class TransitionTests extends WindowTestsBase {
transition.collect(leafTaskA);
rootTaskA.moveToFront("test", leafTaskA);
+ // Test has order changes, a shallow check of order changes
+ assertTrue(transition.hasOrderChanges());
+
// All the tasks were already visible, so there shouldn't be any changes
ArrayList<Transition.ChangeInfo> targets = Transition.calculateTargets(
participants, changes);
diff --git a/services/tests/wmtests/src/com/android/server/wm/utils/TestActivity.java b/services/tests/wmtests/src/com/android/server/wm/utils/TestActivity.java
new file mode 100644
index 000000000000..c12dcddd1b36
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/utils/TestActivity.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.utils;
+
+import static android.view.WindowInsets.Type.displayCutout;
+import static android.view.WindowInsets.Type.systemBars;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import android.app.Activity;
+import android.app.KeyguardManager;
+import android.os.Bundle;
+import android.view.WindowInsetsController;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
+
+import androidx.annotation.Nullable;
+
+/**
+ * TestActivity that will ensure it dismisses keyguard and shows as a fullscreen activity.
+ */
+public class TestActivity extends Activity {
+ private static final int sTypeMask = systemBars() | displayCutout();
+ private FrameLayout mParentLayout;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mParentLayout = new FrameLayout(this);
+ FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
+ FrameLayout.LayoutParams.MATCH_PARENT,
+ FrameLayout.LayoutParams.MATCH_PARENT);
+ setContentView(mParentLayout, layoutParams);
+
+ WindowInsetsController windowInsetsController = getWindow().getInsetsController();
+ windowInsetsController.hide(sTypeMask);
+ WindowManager.LayoutParams params = getWindow().getAttributes();
+ params.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+ getWindow().setAttributes(params);
+ getWindow().setDecorFitsSystemWindows(false);
+
+ final KeyguardManager keyguardManager = getInstrumentation().getContext().getSystemService(
+ KeyguardManager.class);
+ if (keyguardManager != null && keyguardManager.isKeyguardLocked()) {
+ keyguardManager.requestDismissKeyguard(this, null);
+ }
+ }
+
+ public FrameLayout getParentLayout() {
+ return mParentLayout;
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt
index 356e1fa1327c..8354d985abfd 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt
@@ -39,5 +39,5 @@ class AndroidHeuristicsFilter(
private fun ClassNodes.isAidlClass(className: String): Boolean {
return hasClass(className) &&
hasClass("$className\$Stub") &&
- hasClass("$className\$Proxy")
+ hasClass("$className\$Stub\$Proxy")
} \ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt
index 214de59bbb4d..3956893ee7ed 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt
@@ -223,16 +223,16 @@ RuntimeVisibleAnnotations:
java.lang.annotation.Target(
value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD]
)
-## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy.class
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy.class
Compiled from "IPretendingAidl.java"
-public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy
+public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy
minor version: 0
major version: 61
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
- this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
+ this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 3
- public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy();
+ public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
Code:
@@ -243,7 +243,7 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy
LineNumberTable:
LocalVariableTable:
Start Length Slot Name Signature
- 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy;
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy;
public static int addTwo(int);
descriptor: (I)I
@@ -262,7 +262,8 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy
SourceFile: "IPretendingAidl.java"
NestHost: class com/android/hoststubgen/test/tinyframework/IPretendingAidl
InnerClasses:
- public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub.class
Compiled from "IPretendingAidl.java"
public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub
@@ -303,6 +304,7 @@ SourceFile: "IPretendingAidl.java"
NestHost: class com/android/hoststubgen/test/tinyframework/IPretendingAidl
InnerClasses:
public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl.class
Compiled from "IPretendingAidl.java"
public interface com.android.hoststubgen.test.tinyframework.IPretendingAidl
@@ -315,11 +317,11 @@ public interface com.android.hoststubgen.test.tinyframework.IPretendingAidl
}
SourceFile: "IPretendingAidl.java"
NestMembers:
- com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+ com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
InnerClasses:
- public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
- public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.class
Compiled from "TinyFrameworkCallerCheck.java"
class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt
index 90312289db1c..9349355d4d02 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt
@@ -1,13 +1,13 @@
-## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy.class
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy.class
Compiled from "IPretendingAidl.java"
-public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy
+public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy
minor version: 0
major version: 61
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
- this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
+ this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 4
- public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy();
+ public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
Code:
@@ -30,7 +30,8 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy
x: athrow
}
InnerClasses:
- public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
SourceFile: "IPretendingAidl.java"
RuntimeVisibleAnnotations:
x: #x()
@@ -71,6 +72,7 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub
}
InnerClasses:
public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
SourceFile: "IPretendingAidl.java"
RuntimeVisibleAnnotations:
x: #x()
@@ -89,8 +91,8 @@ public interface com.android.hoststubgen.test.tinyframework.IPretendingAidl
interfaces: 0, fields: 0, methods: 0, attributes: 4
}
InnerClasses:
- public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
- public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
SourceFile: "IPretendingAidl.java"
RuntimeVisibleAnnotations:
x: #x()
@@ -98,8 +100,8 @@ RuntimeVisibleAnnotations:
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
NestMembers:
- com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+ com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.class
Compiled from "TinyFrameworkCallerCheck.java"
class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt
index e01f49baf320..4f8c408eb7d9 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt
@@ -205,16 +205,16 @@ RuntimeVisibleAnnotations:
java.lang.annotation.Retention(
value=Ljava/lang/annotation/RetentionPolicy;.CLASS
)
-## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy.class
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy.class
Compiled from "IPretendingAidl.java"
-public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy
+public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy
minor version: 0
major version: 61
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
- this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
+ this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 4
- public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy();
+ public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
Code:
@@ -225,7 +225,7 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy
LineNumberTable:
LocalVariableTable:
Start Length Slot Name Signature
- 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy;
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy;
public static int addTwo(int);
descriptor: (I)I
@@ -242,7 +242,8 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy
0 4 0 a I
}
InnerClasses:
- public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
SourceFile: "IPretendingAidl.java"
RuntimeVisibleAnnotations:
x: #x()
@@ -288,6 +289,7 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub
}
InnerClasses:
public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
SourceFile: "IPretendingAidl.java"
RuntimeVisibleAnnotations:
x: #x()
@@ -306,8 +308,8 @@ public interface com.android.hoststubgen.test.tinyframework.IPretendingAidl
interfaces: 0, fields: 0, methods: 0, attributes: 4
}
InnerClasses:
- public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
- public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
SourceFile: "IPretendingAidl.java"
RuntimeVisibleAnnotations:
x: #x()
@@ -315,8 +317,8 @@ RuntimeVisibleAnnotations:
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
NestMembers:
- com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+ com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.class
Compiled from "TinyFrameworkCallerCheck.java"
class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt
index 90312289db1c..9349355d4d02 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt
@@ -1,13 +1,13 @@
-## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy.class
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy.class
Compiled from "IPretendingAidl.java"
-public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy
+public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy
minor version: 0
major version: 61
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
- this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
+ this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 4
- public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy();
+ public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
Code:
@@ -30,7 +30,8 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy
x: athrow
}
InnerClasses:
- public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
SourceFile: "IPretendingAidl.java"
RuntimeVisibleAnnotations:
x: #x()
@@ -71,6 +72,7 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub
}
InnerClasses:
public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
SourceFile: "IPretendingAidl.java"
RuntimeVisibleAnnotations:
x: #x()
@@ -89,8 +91,8 @@ public interface com.android.hoststubgen.test.tinyframework.IPretendingAidl
interfaces: 0, fields: 0, methods: 0, attributes: 4
}
InnerClasses:
- public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
- public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
SourceFile: "IPretendingAidl.java"
RuntimeVisibleAnnotations:
x: #x()
@@ -98,8 +100,8 @@ RuntimeVisibleAnnotations:
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
NestMembers:
- com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+ com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.class
Compiled from "TinyFrameworkCallerCheck.java"
class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt
index 5246355fb777..5ff3cded38b3 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt
@@ -289,13 +289,13 @@ RuntimeVisibleAnnotations:
java.lang.annotation.Retention(
value=Ljava/lang/annotation/RetentionPolicy;.CLASS
)
-## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy.class
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy.class
Compiled from "IPretendingAidl.java"
-public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy
+public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy
minor version: 0
major version: 61
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
- this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
+ this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 3, attributes: 4
private static {};
@@ -303,17 +303,17 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
Code:
stack=2, locals=0, args_size=0
- x: ldc #x // class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
x: return
- public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy();
+ public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
Code:
stack=4, locals=1, args_size=1
- x: ldc #x // class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
x: ldc #x // String <init>
x: ldc #x // String ()V
x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
@@ -324,14 +324,14 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy
LineNumberTable:
LocalVariableTable:
Start Length Slot Name Signature
- 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy;
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy;
public static int addTwo(int);
descriptor: (I)I
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
Code:
stack=4, locals=1, args_size=1
- x: ldc #x // class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
x: ldc #x // String addTwo
x: ldc #x // String (I)I
x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
@@ -346,7 +346,8 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy
11 4 0 a I
}
InnerClasses:
- public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
SourceFile: "IPretendingAidl.java"
RuntimeVisibleAnnotations:
x: #x()
@@ -412,6 +413,7 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub
}
InnerClasses:
public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
SourceFile: "IPretendingAidl.java"
RuntimeVisibleAnnotations:
x: #x()
@@ -439,8 +441,8 @@ public interface com.android.hoststubgen.test.tinyframework.IPretendingAidl
x: return
}
InnerClasses:
- public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
SourceFile: "IPretendingAidl.java"
RuntimeVisibleAnnotations:
x: #x()
@@ -448,8 +450,8 @@ RuntimeVisibleAnnotations:
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
NestMembers:
- com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+ com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.class
Compiled from "TinyFrameworkCallerCheck.java"
class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/IPretendingAidl.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/IPretendingAidl.java
index 583e13c5573b..0a07c2b91fc3 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/IPretendingAidl.java
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/IPretendingAidl.java
@@ -25,11 +25,12 @@ public interface IPretendingAidl {
public static int addOne(int a) {
return a + 1;
}
- }
- public static class Proxy {
- public static int addTwo(int a) {
- return a + 2;
+ public static class Proxy {
+ public static int addTwo(int a) {
+ return a + 2;
+ }
}
}
+
}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java
index 0d527915ef63..d3501057163d 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java
@@ -289,6 +289,6 @@ public class TinyFrameworkClassTest {
@Test
public void testAidlHeuristics() {
assertThat(IPretendingAidl.Stub.addOne(1)).isEqualTo(2);
- assertThat(IPretendingAidl.Proxy.addTwo(1)).isEqualTo(3);
+ assertThat(IPretendingAidl.Stub.Proxy.addTwo(1)).isEqualTo(3);
}
}