summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AconfigFlags.bp9
-rw-r--r--cmds/svc/src/com/android/commands/svc/PowerCommand.java12
-rw-r--r--core/api/system-current.txt16
-rw-r--r--core/api/test-current.txt19
-rw-r--r--core/java/android/app/ActivityThread.java46
-rw-r--r--core/java/android/app/ClientTransactionHandler.java7
-rw-r--r--core/java/android/app/LocalActivityManager.java4
-rw-r--r--core/java/android/app/LocaleConfig.java3
-rw-r--r--core/java/android/app/NotificationManager.java6
-rw-r--r--core/java/android/app/admin/AccountTypePolicyKey.java4
-rw-r--r--core/java/android/app/admin/BundlePolicyValue.java5
-rw-r--r--core/java/android/app/admin/ComponentNamePolicyValue.java5
-rw-r--r--core/java/android/app/admin/IntentFilterPolicyKey.java4
-rw-r--r--core/java/android/app/admin/LockTaskPolicy.java5
-rw-r--r--core/java/android/app/admin/PackagePermissionPolicyKey.java4
-rw-r--r--core/java/android/app/admin/PackagePolicyKey.java4
-rw-r--r--core/java/android/app/admin/StringPolicyValue.java5
-rw-r--r--core/java/android/app/admin/StringSetPolicyValue.java5
-rw-r--r--core/java/android/app/admin/UserRestrictionPolicyKey.java4
-rw-r--r--core/java/android/app/admin/flags/flags.aconfig9
-rw-r--r--core/java/android/app/servertransaction/ClientTransactionListenerController.java65
-rw-r--r--core/java/android/app/servertransaction/DestroyActivityItem.java16
-rw-r--r--core/java/android/app/servertransaction/PauseActivityItem.java15
-rw-r--r--core/java/android/app/servertransaction/StopActivityItem.java41
-rw-r--r--core/java/android/app/servertransaction/TransactionExecutor.java6
-rw-r--r--core/java/android/app/servertransaction/TransactionExecutorHelper.java2
-rw-r--r--core/java/android/companion/virtual/VirtualDeviceInternal.java21
-rw-r--r--core/java/android/content/pm/UserInfo.java7
-rw-r--r--core/java/android/content/pm/flags.aconfig8
-rw-r--r--core/java/android/credentials/CredentialManager.java3
-rw-r--r--core/java/android/credentials/selection/IntentFactory.java106
-rw-r--r--core/java/android/hardware/biometrics/BiometricPrompt.java3
-rw-r--r--core/java/android/hardware/biometrics/SensorProperties.java7
-rw-r--r--core/java/android/hardware/camera2/CameraCharacteristics.java14
-rw-r--r--core/java/android/hardware/camera2/CameraMetadata.java4
-rw-r--r--core/java/android/hardware/camera2/params/MandatoryStreamCombination.java2
-rw-r--r--core/java/android/hardware/face/FaceManager.java27
-rw-r--r--core/java/android/hardware/face/FaceSensorProperties.java6
-rw-r--r--core/java/android/hardware/face/IFaceService.aidl2
-rw-r--r--core/java/android/hardware/input/IInputManager.aidl6
-rw-r--r--core/java/android/hardware/input/InputManager.java8
-rw-r--r--core/java/android/hardware/input/KeyboardLayoutSelectionResult.aidl19
-rw-r--r--core/java/android/hardware/input/KeyboardLayoutSelectionResult.java260
-rw-r--r--core/java/android/os/BatteryConsumer.java2
-rw-r--r--core/java/android/os/BatteryStats.java6
-rw-r--r--core/java/android/os/GraphicsEnvironment.java11
-rw-r--r--core/java/android/os/HwParcel.java2
-rw-r--r--core/java/android/os/UserManager.java5
-rw-r--r--core/java/android/os/flags.aconfig2
-rw-r--r--core/java/android/os/health/HealthStatsWriter.java2
-rw-r--r--core/java/android/os/image/DynamicSystemClient.java2
-rw-r--r--core/java/android/os/image/DynamicSystemManager.java2
-rw-r--r--core/java/android/os/storage/StorageManager.java2
-rw-r--r--core/java/android/os/storage/StorageVolume.java2
-rw-r--r--core/java/android/permission/PermissionManager.java27
-rw-r--r--core/java/android/provider/Settings.java9
-rw-r--r--core/java/android/service/notification/ZenAdapters.java (renamed from services/core/java/com/android/server/notification/ZenAdapters.java)74
-rw-r--r--core/java/android/service/notification/ZenModeConfig.java69
-rw-r--r--core/java/android/service/ondeviceintelligence/IOnDeviceIntelligenceService.aidl2
-rw-r--r--core/java/android/service/ondeviceintelligence/IOnDeviceTrustedInferenceService.aidl6
-rw-r--r--core/java/android/service/ondeviceintelligence/IProcessingUpdateStatusCallback.aidl14
-rw-r--r--core/java/android/service/ondeviceintelligence/IRemoteProcessingService.aidl31
-rw-r--r--core/java/android/service/ondeviceintelligence/OnDeviceIntelligenceService.java118
-rw-r--r--core/java/android/service/ondeviceintelligence/OnDeviceTrustedInferenceService.java61
-rw-r--r--core/java/android/service/voice/VoiceInteractionService.java21
-rw-r--r--core/java/android/view/ScrollFeedbackProvider.java7
-rw-r--r--core/java/android/view/ViewRootImpl.java6
-rw-r--r--core/java/android/view/inputmethod/ImeTracker.java1
-rw-r--r--core/java/android/widget/RemoteViews.java144
-rw-r--r--core/java/android/widget/RemoteViewsService.java25
-rw-r--r--core/java/com/android/internal/widget/IRemoteViewsFactory.aidl2
-rw-r--r--core/jni/Android.bp1
-rw-r--r--core/res/AndroidManifest.xml4
-rw-r--r--core/res/res/values-fa/strings.xml4
-rw-r--r--core/res/res/values/config.xml29
-rw-r--r--core/res/res/values/config_telephony.xml5
-rw-r--r--core/res/res/values/symbols.xml3
-rw-r--r--core/tests/coretests/src/android/app/activity/ActivityThreadTest.java121
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/ClientTransactionItemTest.java8
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/ClientTransactionListenerControllerTest.java34
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java6
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java2
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java14
-rw-r--r--core/tests/coretests/src/android/widget/RemoteViewsAdapterTest.java2
-rw-r--r--core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java6
-rw-r--r--data/etc/Android.bp6
-rw-r--r--data/etc/CleanSpec.mk2
-rw-r--r--data/etc/package-shareduid-allowlist.xml35
-rw-r--r--data/fonts/font_fallback.xml8
-rw-r--r--data/fonts/font_fallback_cjkvf.xml8
-rw-r--r--data/fonts/fonts.xml8
-rw-r--r--data/fonts/fonts_cjkvf.xml8
-rw-r--r--graphics/java/android/graphics/text/MeasuredText.java50
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java119
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java90
-rw-r--r--libs/WindowManager/Shell/res/drawable/desktop_mode_header_ic_close.xml26
-rw-r--r--libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml20
-rw-r--r--libs/WindowManager/Shell/res/values/config.xml3
-rw-r--r--libs/WindowManager/Shell/res/values/dimen.xml21
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/OWNERS2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt150
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/OWNERS2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java146
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java25
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt15
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt21
-rw-r--r--libs/hostgraphics/ADisplay.cpp159
-rw-r--r--libs/hostgraphics/Android.bp12
-rw-r--r--libs/hwui/Android.bp23
-rw-r--r--libs/hwui/FrameInfoVisualizer.cpp2
-rw-r--r--libs/hwui/JankTracker.cpp7
-rw-r--r--libs/hwui/RenderProperties.h27
-rw-r--r--libs/hwui/VectorDrawable.cpp6
-rw-r--r--packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/CredentialKtx.kt7
-rw-r--r--packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/CredentialEntryInfo.kt6
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt27
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt14
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/common/ui/Entry.kt9
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt2
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt28
-rw-r--r--packages/CredentialManager/tests/robotests/screenshot/src/com/android/credentialmanager/GetCredScreenshotTest.kt7
-rw-r--r--packages/PackageInstaller/res/values-el/strings.xml2
-rw-r--r--packages/SettingsLib/DataStore/tests/Android.bp24
-rw-r--r--packages/SettingsLib/DataStore/tests/AndroidManifest.xml6
-rw-r--r--packages/SettingsLib/DataStore/tests/config/robolectric.properties1
-rw-r--r--packages/SettingsLib/DataStore/tests/src/com/android/settingslib/datastore/ObserverTest.kt109
-rw-r--r--packages/SettingsLib/res/values-af/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-am/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ar/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-as/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-az/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-b+sr+Latn/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-be/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-bg/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-bn/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-bs/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ca/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-cs/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-da/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-de/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-el/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-en-rAU/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-en-rGB/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-en-rIN/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-es-rUS/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-es/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-et/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-eu/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-fa/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-fi/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-fr-rCA/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-fr/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-gl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-gu/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-hi/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-hr/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-hu/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-hy/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-in/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-is/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-it/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ja/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ka/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-kk/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-km/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-kn/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ko/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ky/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-lo/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-mk/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ml/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-mn/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-mr/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ms/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-my/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-nb/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ne/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-nl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-or/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-pa/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-pl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-pt-rBR/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-pt-rPT/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-pt/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ro/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ru/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-si/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sk/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sq/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sr/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sv/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sw/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ta/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-te/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-th/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-tl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-tr/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-uk/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ur/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-uz/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-vi/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-zh-rCN/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-zh-rHK/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-zh-rTW/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-zu/strings.xml3
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java14
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/MediaManager.java19
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt2
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaManagerTest.java27
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java1
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java1
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java56
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java24
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java22
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java65
-rw-r--r--packages/SystemUI/aconfig/predictive_back.aconfig8
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt79
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyboard/stickykeys/ui/view/StickyKeysIndicator.kt33
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/mediaoutput/ui/composable/MediaOutputComponent.kt16
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraAutoRotateRepositoryImplTest.kt125
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraSensorPrivacyRepositoryImplTest.kt104
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepositoryTest.kt78
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepositoryTest.kt75
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt25
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt2
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt19
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt2
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractorTest.kt227
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractorTest.kt96
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapperTest.kt190
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModelTest.kt2
-rw-r--r--packages/SystemUI/res/layout/notif_half_shelf.xml6
-rw-r--r--packages/SystemUI/res/layout/scene_window_root.xml2
-rw-r--r--packages/SystemUI/res/values-af/strings.xml6
-rw-r--r--packages/SystemUI/res/values-af/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-am/strings.xml6
-rw-r--r--packages/SystemUI/res/values-am/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ar/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-as/strings.xml6
-rw-r--r--packages/SystemUI/res/values-as/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-az/strings.xml6
-rw-r--r--packages/SystemUI/res/values-az/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml6
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-be/strings.xml6
-rw-r--r--packages/SystemUI/res/values-be/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml6
-rw-r--r--packages/SystemUI/res/values-bg/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml6
-rw-r--r--packages/SystemUI/res/values-bn/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml6
-rw-r--r--packages/SystemUI/res/values-bs/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ca/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml6
-rw-r--r--packages/SystemUI/res/values-cs/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-da/strings.xml6
-rw-r--r--packages/SystemUI/res/values-da/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-de/strings.xml6
-rw-r--r--packages/SystemUI/res/values-de/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-el/strings.xml6
-rw-r--r--packages/SystemUI/res/values-el/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml15
-rw-r--r--packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml15
-rw-r--r--packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml15
-rw-r--r--packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml15
-rw-r--r--packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-es/strings.xml6
-rw-r--r--packages/SystemUI/res/values-es/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-et/strings.xml6
-rw-r--r--packages/SystemUI/res/values-et/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml10
-rw-r--r--packages/SystemUI/res/values-eu/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml6
-rw-r--r--packages/SystemUI/res/values-fa/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml6
-rw-r--r--packages/SystemUI/res/values-fi/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml6
-rw-r--r--packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml6
-rw-r--r--packages/SystemUI/res/values-fr/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml6
-rw-r--r--packages/SystemUI/res/values-gl/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml6
-rw-r--r--packages/SystemUI/res/values-gu/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml6
-rw-r--r--packages/SystemUI/res/values-hi/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml6
-rw-r--r--packages/SystemUI/res/values-hr/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml6
-rw-r--r--packages/SystemUI/res/values-hu/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml6
-rw-r--r--packages/SystemUI/res/values-hy/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-in/strings.xml6
-rw-r--r--packages/SystemUI/res/values-in/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-is/strings.xml6
-rw-r--r--packages/SystemUI/res/values-is/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-it/strings.xml6
-rw-r--r--packages/SystemUI/res/values-it/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml6
-rw-r--r--packages/SystemUI/res/values-iw/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml15
-rw-r--r--packages/SystemUI/res/values-ja/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ka/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml6
-rw-r--r--packages/SystemUI/res/values-kk/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-km/strings.xml6
-rw-r--r--packages/SystemUI/res/values-km/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml6
-rw-r--r--packages/SystemUI/res/values-kn/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ko/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ky/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml9
-rw-r--r--packages/SystemUI/res/values-lo/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml6
-rw-r--r--packages/SystemUI/res/values-lt/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-lv/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml6
-rw-r--r--packages/SystemUI/res/values-mk/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml9
-rw-r--r--packages/SystemUI/res/values-ml/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml6
-rw-r--r--packages/SystemUI/res/values-mn/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml6
-rw-r--r--packages/SystemUI/res/values-mr/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ms/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-my/strings.xml6
-rw-r--r--packages/SystemUI/res/values-my/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml6
-rw-r--r--packages/SystemUI/res/values-nb/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ne/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml6
-rw-r--r--packages/SystemUI/res/values-nl/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-or/strings.xml8
-rw-r--r--packages/SystemUI/res/values-or/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml6
-rw-r--r--packages/SystemUI/res/values-pa/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml6
-rw-r--r--packages/SystemUI/res/values-pl/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml6
-rw-r--r--packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml15
-rw-r--r--packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml6
-rw-r--r--packages/SystemUI/res/values-pt/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ro/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ru/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-si/strings.xml6
-rw-r--r--packages/SystemUI/res/values-si/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sk/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sl/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sq/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sr/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sv/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sw/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ta/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-te/strings.xml6
-rw-r--r--packages/SystemUI/res/values-te/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-th/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-tl/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml6
-rw-r--r--packages/SystemUI/res/values-tr/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml6
-rw-r--r--packages/SystemUI/res/values-uk/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml15
-rw-r--r--packages/SystemUI/res/values-ur/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml6
-rw-r--r--packages/SystemUI/res/values-uz/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml6
-rw-r--r--packages/SystemUI/res/values-vi/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml6
-rw-r--r--packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml6
-rw-r--r--packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml6
-rw-r--r--packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml6
-rw-r--r--packages/SystemUI/res/values-zu/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values/ids.xml1
-rw-r--r--packages/SystemUI/res/values/strings.xml6
-rw-r--r--packages/SystemUI/res/values/styles.xml4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java5
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java19
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java1
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/camera/CameraRotationModule.kt33
-rw-r--r--packages/SystemUI/src/com/android/systemui/camera/data/repository/CameraAutoRotateRepository.kt70
-rw-r--r--packages/SystemUI/src/com/android/systemui/camera/data/repository/CameraSensorPrivacyRepository.kt76
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeyDialogFactory.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBottomAreaInteractor.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBlueprintViewBinder.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt42
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractor.kt94
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractor.kt56
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/model/RotationLockTileModel.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapper.kt107
-rw-r--r--packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockNewModule.kt73
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSoundController.kt40
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java59
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java66
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java41
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTaskLogger.kt62
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractor.kt54
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt36
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimation.kt88
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/kotlin/BatteryControllerExt.kt37
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/kotlin/RotationLockControllerExt.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputActionsInteractor.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/DeviceIconViewModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModel.kt5
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorTest.kt8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt24
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt (renamed from packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt)133
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotSoundControllerTest.kt63
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorTest.kt85
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java7
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepository.kt37
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepositoryKosmos.kt (renamed from packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/MediaOutputComponentKosmos.kt)9
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepository.kt36
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepositoryKosmos.kt22
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt8
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt1
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/rotation/RotationLockTileKosmos.kt24
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorKosmos.kt29
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelKosmos.kt6
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/DevicePostureControllerKosmos.kt22
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeRotationLockController.java23
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/volume/MediaOutputKosmos.kt3
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java20
-rw-r--r--services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java15
-rw-r--r--services/autofill/java/com/android/server/autofill/Session.java2
-rw-r--r--services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java13
-rw-r--r--services/core/java/com/android/server/SystemConfig.java21
-rw-r--r--services/core/java/com/android/server/TEST_MAPPING3
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java36
-rw-r--r--services/core/java/com/android/server/am/flags.aconfig7
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/FaceService.java2
-rw-r--r--services/core/java/com/android/server/connectivity/TEST_MAPPING7
-rw-r--r--services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java9
-rw-r--r--services/core/java/com/android/server/flags/services.aconfig8
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java7
-rw-r--r--services/core/java/com/android/server/input/KeyboardLayoutManager.java115
-rw-r--r--services/core/java/com/android/server/input/KeyboardMetricsCollector.java67
-rw-r--r--services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java11
-rw-r--r--services/core/java/com/android/server/inputmethod/ImeBindingState.java109
-rw-r--r--services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java2
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java160
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java11
-rw-r--r--services/core/java/com/android/server/notification/ZenModeEventLogger.java7
-rw-r--r--services/core/java/com/android/server/notification/ZenModeHelper.java1
-rw-r--r--services/core/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java56
-rw-r--r--services/core/java/com/android/server/os/BugreportManagerServiceImpl.java81
-rw-r--r--services/core/java/com/android/server/pm/InstallPackageHelper.java4
-rw-r--r--services/core/java/com/android/server/pm/ReconcilePackageUtils.java28
-rw-r--r--services/core/java/com/android/server/pm/ShortcutService.java3
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerServiceInterface.java3
-rw-r--r--services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java3
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java25
-rw-r--r--services/core/java/com/android/server/wm/SnapshotCache.java5
-rw-r--r--services/core/java/com/android/server/wm/TaskFragment.java2
-rw-r--r--services/credentials/java/com/android/server/credentials/CredentialManagerUi.java4
-rw-r--r--services/credentials/java/com/android/server/credentials/GetCandidateRequestSession.java7
-rw-r--r--services/credentials/java/com/android/server/credentials/RequestSession.java40
-rw-r--r--services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java2
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java14
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java14
-rw-r--r--services/java/com/android/server/SystemServer.java9
-rw-r--r--services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt84
-rw-r--r--services/permission/java/com/android/server/permission/access/permission/PermissionFlags.kt15
-rw-r--r--services/permission/java/com/android/server/permission/access/permission/PermissionService.kt135
-rw-r--r--services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyTest.kt18
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java14
-rw-r--r--services/tests/servicestests/src/com/android/server/os/BugreportManagerServiceImplTest.java72
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenAdaptersTest.java2
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java1
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java2
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java19
-rw-r--r--telecomm/java/android/telecom/TelecomManager.java13
-rw-r--r--telephony/java/android/telephony/TelephonyFrameworkInitializer.java27
-rw-r--r--tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTest.kt1
-rw-r--r--tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt78
-rw-r--r--tests/Input/src/com/android/server/input/KeyboardMetricsCollectorTests.kt17
-rw-r--r--tools/aapt2/Android.bp7
-rw-r--r--tools/aapt2/Android.mk4
531 files changed, 6240 insertions, 2490 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 20471682dd2e..eed248bcd2b9 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -310,6 +310,8 @@ java_aconfig_library {
aconfig_declarations {
name: "android.os.flags-aconfig",
package: "android.os",
+ exportable: true,
+ container: "system",
srcs: ["core/java/android/os/*.aconfig"],
}
@@ -326,6 +328,13 @@ java_aconfig_library {
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+java_aconfig_library {
+ name: "android.os.flags-aconfig-java-export",
+ aconfig_declarations: "android.os.flags-aconfig",
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+ mode: "exported",
+}
+
// VirtualDeviceManager
cc_aconfig_library {
name: "android.companion.virtualdevice.flags-aconfig-cc",
diff --git a/cmds/svc/src/com/android/commands/svc/PowerCommand.java b/cmds/svc/src/com/android/commands/svc/PowerCommand.java
index a7560b23c6bd..12b79f4c42f8 100644
--- a/cmds/svc/src/com/android/commands/svc/PowerCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/PowerCommand.java
@@ -23,8 +23,6 @@ import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.sysprop.InitProperties;
public class PowerCommand extends Svc.Command {
private static final int FORCE_SUSPEND_DELAY_DEFAULT_MILLIS = 0;
@@ -142,12 +140,10 @@ public class PowerCommand extends Svc.Command {
// Check if remote exception is benign during shutdown. Pm can be killed
// before system server during shutdown, so remote exception can be ignored
// if it is already in shutdown flow.
+ // sys.powerctl is no longer set to avoid a possible DOS attack (see
+ // bionic/libc/bionic/system_property_set.cpp) so we have no real way of knowing if a
+ // remote exception is real or simply because pm is killed (b/318323013)
+ // So we simply do not display anything.
private void maybeLogRemoteException(String msg) {
- String powerProp = SystemProperties.get("sys.powerctl");
- // Also check if userspace reboot is ongoing, since in case of userspace reboot value of the
- // sys.powerctl property will be reset.
- if (powerProp.isEmpty() && !InitProperties.userspace_reboot_in_progress().orElse(false)) {
- System.err.println(msg);
- }
}
}
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 2922dd9ef5ae..afb796b7687a 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -10758,7 +10758,7 @@ package android.os {
method public final double readDouble();
method public final java.util.ArrayList<java.lang.Double> readDoubleVector();
method public final android.os.HwBlob readEmbeddedBuffer(long, long, long, boolean);
- method @NonNull @Nullable public final android.os.HidlMemory readEmbeddedHidlMemory(long, long, long);
+ method @NonNull public final android.os.HidlMemory readEmbeddedHidlMemory(long, long, long);
method @Nullable public final android.os.NativeHandle readEmbeddedNativeHandle(long, long);
method public final float readFloat();
method public final java.util.ArrayList<java.lang.Float> readFloatVector();
@@ -12963,9 +12963,22 @@ package android.service.ondeviceintelligence {
method public abstract void onGetReadOnlyFeatureFileDescriptorMap(@NonNull android.app.ondeviceintelligence.Feature, @NonNull java.util.function.Consumer<java.util.Map<java.lang.String,android.os.ParcelFileDescriptor>>);
method public abstract void onGetVersion(@NonNull java.util.function.LongConsumer);
method public abstract void onListFeatures(@NonNull android.os.OutcomeReceiver<java.util.List<android.app.ondeviceintelligence.Feature>,android.app.ondeviceintelligence.OnDeviceIntelligenceManager.OnDeviceIntelligenceManagerException>);
+ method public final void updateProcessingState(@NonNull android.os.Bundle, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.os.PersistableBundle,android.service.ondeviceintelligence.OnDeviceIntelligenceService.OnDeviceUpdateProcessingException>);
field public static final String SERVICE_INTERFACE = "android.service.ondeviceintelligence.OnDeviceIntelligenceService";
}
+ public static class OnDeviceIntelligenceService.OnDeviceIntelligenceServiceException extends java.lang.Exception {
+ ctor public OnDeviceIntelligenceService.OnDeviceIntelligenceServiceException(int);
+ ctor public OnDeviceIntelligenceService.OnDeviceIntelligenceServiceException(int, @NonNull String);
+ method public int getErrorCode();
+ }
+
+ public static class OnDeviceIntelligenceService.OnDeviceUpdateProcessingException extends android.service.ondeviceintelligence.OnDeviceIntelligenceService.OnDeviceIntelligenceServiceException {
+ ctor public OnDeviceIntelligenceService.OnDeviceUpdateProcessingException(int);
+ ctor public OnDeviceIntelligenceService.OnDeviceUpdateProcessingException(int, @NonNull String);
+ field public static final int PROCESSING_UPDATE_STATUS_CONNECTION_FAILED = 1; // 0x1
+ }
+
@FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public abstract class OnDeviceTrustedInferenceService extends android.app.Service {
ctor public OnDeviceTrustedInferenceService();
method public final void fetchFeatureFileInputStreamMap(@NonNull android.app.ondeviceintelligence.Feature, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.util.Map<java.lang.String,java.io.FileInputStream>>);
@@ -12973,6 +12986,7 @@ package android.service.ondeviceintelligence {
method @NonNull public abstract void onCountTokens(@NonNull android.app.ondeviceintelligence.Feature, @NonNull android.app.ondeviceintelligence.Content, @Nullable android.os.CancellationSignal, @NonNull android.os.OutcomeReceiver<java.lang.Long,android.app.ondeviceintelligence.OnDeviceIntelligenceManager.OnDeviceIntelligenceManagerProcessingException>);
method @NonNull public abstract void onProcessRequest(@NonNull android.app.ondeviceintelligence.Feature, @NonNull android.app.ondeviceintelligence.Content, int, @Nullable android.os.CancellationSignal, @Nullable android.app.ondeviceintelligence.ProcessingSignal, @NonNull android.os.OutcomeReceiver<android.app.ondeviceintelligence.Content,android.app.ondeviceintelligence.OnDeviceIntelligenceManager.OnDeviceIntelligenceManagerProcessingException>);
method @NonNull public abstract void onProcessRequestStreaming(@NonNull android.app.ondeviceintelligence.Feature, @NonNull android.app.ondeviceintelligence.Content, int, @Nullable android.os.CancellationSignal, @Nullable android.app.ondeviceintelligence.ProcessingSignal, @NonNull android.app.ondeviceintelligence.StreamingResponseReceiver<android.app.ondeviceintelligence.Content,android.app.ondeviceintelligence.Content,android.app.ondeviceintelligence.OnDeviceIntelligenceManager.OnDeviceIntelligenceManagerProcessingException>);
+ method public abstract void onUpdateProcessingState(@NonNull android.os.Bundle, @NonNull android.os.OutcomeReceiver<android.os.PersistableBundle,android.service.ondeviceintelligence.OnDeviceIntelligenceService.OnDeviceUpdateProcessingException>);
method public final java.io.FileInputStream openFileInput(@NonNull String) throws java.io.FileNotFoundException;
method public final void openFileInputAsync(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.io.FileInputStream>) throws java.io.FileNotFoundException;
field public static final String SERVICE_INTERFACE = "android.service.ondeviceintelligence.OnDeviceTrustedInferenceService";
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index a28dc497c508..6fb6b0d1d5bf 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1366,7 +1366,7 @@ package android.credentials.selection {
}
@FlaggedApi("android.credentials.flags.configurable_selector_ui_enabled") public class IntentFactory {
- method @NonNull public static android.content.Intent createCancelUiIntent(@NonNull android.os.IBinder, boolean, @NonNull String);
+ method @NonNull public static android.content.Intent createCancelUiIntent(@NonNull android.content.Context, @NonNull android.os.IBinder, boolean, @NonNull String);
method @NonNull public static android.content.Intent createCredentialSelectorIntent(@NonNull android.content.Context, @NonNull android.credentials.selection.RequestInfo, @NonNull java.util.ArrayList<android.credentials.selection.ProviderData>, @NonNull java.util.ArrayList<android.credentials.selection.DisabledProviderData>, @NonNull android.os.ResultReceiver);
}
@@ -1547,10 +1547,6 @@ package android.hardware.biometrics {
method public boolean isAllowBackgroundAuthentication();
}
- public abstract static class BiometricPrompt.AuthenticationCallback {
- method @FlaggedApi("android.hardware.biometrics.face_background_authentication") public void onAuthenticationAcquired(int);
- }
-
public static class BiometricPrompt.Builder {
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.TEST_BIOMETRIC, "android.permission.USE_BIOMETRIC_INTERNAL"}) public android.hardware.biometrics.BiometricPrompt.Builder setAllowBackgroundAuthentication(boolean);
method @FlaggedApi("android.multiuser.enable_biometrics_to_unlock_private_space") @NonNull @RequiresPermission(anyOf={android.Manifest.permission.TEST_BIOMETRIC, "android.permission.USE_BIOMETRIC_INTERNAL"}) public android.hardware.biometrics.BiometricPrompt.Builder setAllowBackgroundAuthentication(boolean, boolean);
@@ -1569,7 +1565,6 @@ package android.hardware.biometrics {
}
public class SensorProperties {
- ctor @FlaggedApi("android.hardware.biometrics.face_background_authentication") public SensorProperties(int, int, @NonNull java.util.List<android.hardware.biometrics.SensorProperties.ComponentInfo>);
method @NonNull public java.util.List<android.hardware.biometrics.SensorProperties.ComponentInfo> getComponentInfo();
method public int getSensorId();
method public int getSensorStrength();
@@ -1714,18 +1709,6 @@ package android.hardware.display {
}
-package android.hardware.face {
-
- @FlaggedApi("android.hardware.biometrics.face_background_authentication") public class FaceManager {
- method @FlaggedApi("android.hardware.biometrics.face_background_authentication") @NonNull @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public android.hardware.biometrics.BiometricTestSession createTestSession(int);
- method @FlaggedApi("android.hardware.biometrics.face_background_authentication") @NonNull public java.util.List<android.hardware.face.FaceSensorProperties> getSensorProperties();
- }
-
- @FlaggedApi("android.hardware.biometrics.face_background_authentication") public class FaceSensorProperties extends android.hardware.biometrics.SensorProperties {
- }
-
-}
-
package android.hardware.fingerprint {
@Deprecated public class FingerprintManager {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 41151c0dc647..1d39186de183 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -40,6 +40,7 @@ import static android.window.ConfigurationHelper.shouldUpdateResources;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
import static com.android.internal.os.SafeZipPathValidatorCallback.VALIDATE_ZIP_PATH_FOR_PATH_TRAVERSAL;
import static com.android.sdksandbox.flags.Flags.sandboxActivitySdkBasedContext;
+import static com.android.window.flags.Flags.activityWindowInfoFlag;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -63,6 +64,7 @@ import android.app.servertransaction.ActivityLifecycleItem.LifecycleState;
import android.app.servertransaction.ActivityRelaunchItem;
import android.app.servertransaction.ActivityResultItem;
import android.app.servertransaction.ClientTransaction;
+import android.app.servertransaction.ClientTransactionListenerController;
import android.app.servertransaction.DestroyActivityItem;
import android.app.servertransaction.PauseActivityItem;
import android.app.servertransaction.PendingTransactionActions;
@@ -606,6 +608,8 @@ public final class ActivityThread extends ClientTransactionHandler
Configuration overrideConfig;
@NonNull
private ActivityWindowInfo mActivityWindowInfo;
+ @Nullable
+ private ActivityWindowInfo mLastReportedActivityWindowInfo;
// Used for consolidating configs before sending on to Activity.
private final Configuration tmpConfig = new Configuration();
@@ -4180,6 +4184,9 @@ public final class ActivityThread extends ClientTransactionHandler
pendingActions.setRestoreInstanceState(true);
pendingActions.setCallOnPostCreate(true);
}
+
+ // Trigger ActivityWindowInfo callback if first launch or change from relaunch.
+ handleActivityWindowInfoChanged(r);
} else {
// If there was an error, for any reason, tell the activity manager to stop us.
ActivityClient.getInstance().finishActivity(r.token, Activity.RESULT_CANCELED,
@@ -4558,7 +4565,7 @@ public final class ActivityThread extends ClientTransactionHandler
private void schedulePauseWithUserLeavingHint(ActivityClientRecord r) {
final ClientTransaction transaction = ClientTransaction.obtain(mAppThread);
final PauseActivityItem pauseActivityItem = PauseActivityItem.obtain(r.token,
- r.activity.isFinishing(), /* userLeaving */ true, r.activity.mConfigChangeFlags,
+ r.activity.isFinishing(), /* userLeaving */ true,
/* dontReport */ false, /* autoEnteringPip */ false);
transaction.addTransactionItem(pauseActivityItem);
executeTransaction(transaction);
@@ -5432,13 +5439,12 @@ public final class ActivityThread extends ClientTransactionHandler
@Override
public void handlePauseActivity(ActivityClientRecord r, boolean finished, boolean userLeaving,
- int configChanges, boolean autoEnteringPip, PendingTransactionActions pendingActions,
+ boolean autoEnteringPip, PendingTransactionActions pendingActions,
String reason) {
if (userLeaving) {
performUserLeavingActivity(r);
}
- r.activity.mConfigChangeFlags |= configChanges;
if (autoEnteringPip) {
// Set mIsInPictureInPictureMode earlier in case of auto-enter-pip, see also
// {@link Activity#enterPictureInPictureMode(PictureInPictureParams)}.
@@ -5687,9 +5693,8 @@ public final class ActivityThread extends ClientTransactionHandler
}
@Override
- public void handleStopActivity(ActivityClientRecord r, int configChanges,
+ public void handleStopActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {
- r.activity.mConfigChangeFlags |= configChanges;
final StopInfo stopInfo = new StopInfo();
performStopActivityInner(r, stopInfo, true /* saveState */, finalStateRequest,
@@ -5859,11 +5864,10 @@ public final class ActivityThread extends ClientTransactionHandler
/** Core implementation of activity destroy call. */
void performDestroyActivity(ActivityClientRecord r, boolean finishing,
- int configChanges, boolean getNonConfigInstance, String reason) {
+ boolean getNonConfigInstance, String reason) {
Class<? extends Activity> activityClass;
if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
activityClass = r.activity.getClass();
- r.activity.mConfigChangeFlags |= configChanges;
if (finishing) {
r.activity.mFinished = true;
}
@@ -5928,9 +5932,9 @@ public final class ActivityThread extends ClientTransactionHandler
}
@Override
- public void handleDestroyActivity(ActivityClientRecord r, boolean finishing, int configChanges,
+ public void handleDestroyActivity(ActivityClientRecord r, boolean finishing,
boolean getNonConfigInstance, String reason) {
- performDestroyActivity(r, finishing, configChanges, getNonConfigInstance, reason);
+ performDestroyActivity(r, finishing, getNonConfigInstance, reason);
cleanUpPendingRemoveWindows(r, finishing);
WindowManager wm = r.activity.getWindowManager();
View v = r.activity.mDecor;
@@ -6130,7 +6134,7 @@ public final class ActivityThread extends ClientTransactionHandler
r.activity.mChangingConfigurations = true;
- handleRelaunchActivityInner(r, configChanges, tmp.pendingResults, tmp.pendingIntents,
+ handleRelaunchActivityInner(r, tmp.pendingResults, tmp.pendingIntents,
pendingActions, tmp.startsNotResumed, tmp.overrideConfig, tmp.mActivityWindowInfo,
"handleRelaunchActivity");
}
@@ -6199,7 +6203,7 @@ public final class ActivityThread extends ClientTransactionHandler
executeTransaction(transaction);
}
- private void handleRelaunchActivityInner(@NonNull ActivityClientRecord r, int configChanges,
+ private void handleRelaunchActivityInner(@NonNull ActivityClientRecord r,
@Nullable List<ResultInfo> pendingResults,
@Nullable List<ReferrerIntent> pendingIntents,
@NonNull PendingTransactionActions pendingActions, boolean startsNotResumed,
@@ -6215,7 +6219,7 @@ public final class ActivityThread extends ClientTransactionHandler
callActivityOnStop(r, true /* saveState */, reason);
}
- handleDestroyActivity(r, false, configChanges, true, reason);
+ handleDestroyActivity(r, false /* finishing */, true /* getNonConfigInstance */, reason);
r.activity = null;
r.window = null;
@@ -6740,7 +6744,7 @@ public final class ActivityThread extends ClientTransactionHandler
// Perform updates.
r.overrideConfig = overrideConfig;
r.mActivityWindowInfo = activityWindowInfo;
- // TODO(b/287582673): notify on ActivityWindowInfo change
+
final ViewRootImpl viewRoot = r.activity.mDecor != null
? r.activity.mDecor.getViewRootImpl() : null;
@@ -6763,6 +6767,22 @@ public final class ActivityThread extends ClientTransactionHandler
viewRoot.updateConfiguration(displayId);
}
mSomeActivitiesChanged = true;
+
+ // Trigger ActivityWindowInfo callback if changed.
+ handleActivityWindowInfoChanged(r);
+ }
+
+ private void handleActivityWindowInfoChanged(@NonNull ActivityClientRecord r) {
+ if (!activityWindowInfoFlag()) {
+ return;
+ }
+ if (r.mActivityWindowInfo == null
+ || r.mActivityWindowInfo.equals(r.mLastReportedActivityWindowInfo)) {
+ return;
+ }
+ r.mLastReportedActivityWindowInfo = r.mActivityWindowInfo;
+ ClientTransactionListenerController.getInstance().onActivityWindowInfoChanged(r.token,
+ r.mActivityWindowInfo);
}
final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
diff --git a/core/java/android/app/ClientTransactionHandler.java b/core/java/android/app/ClientTransactionHandler.java
index b5b3669c1d80..01153c9e7efc 100644
--- a/core/java/android/app/ClientTransactionHandler.java
+++ b/core/java/android/app/ClientTransactionHandler.java
@@ -114,11 +114,11 @@ public abstract class ClientTransactionHandler {
/** Destroy the activity. */
public abstract void handleDestroyActivity(@NonNull ActivityClientRecord r, boolean finishing,
- int configChanges, boolean getNonConfigInstance, String reason);
+ boolean getNonConfigInstance, String reason);
/** Pause the activity. */
public abstract void handlePauseActivity(@NonNull ActivityClientRecord r, boolean finished,
- boolean userLeaving, int configChanges, boolean autoEnteringPip,
+ boolean userLeaving, boolean autoEnteringPip,
PendingTransactionActions pendingActions, String reason);
/**
@@ -146,14 +146,13 @@ public abstract class ClientTransactionHandler {
/**
* Stop the activity.
* @param r Target activity record.
- * @param configChanges Activity configuration changes.
* @param pendingActions Pending actions to be used on this or later stages of activity
* transaction.
* @param finalStateRequest Flag indicating if this call is handling final lifecycle state
* request for a transaction.
* @param reason Reason for performing this operation.
*/
- public abstract void handleStopActivity(@NonNull ActivityClientRecord r, int configChanges,
+ public abstract void handleStopActivity(@NonNull ActivityClientRecord r,
PendingTransactionActions pendingActions, boolean finalStateRequest, String reason);
/** Report that activity was stopped to server. */
diff --git a/core/java/android/app/LocalActivityManager.java b/core/java/android/app/LocalActivityManager.java
index 1b19ecdd5931..095cfc5a7303 100644
--- a/core/java/android/app/LocalActivityManager.java
+++ b/core/java/android/app/LocalActivityManager.java
@@ -413,7 +413,7 @@ public class LocalActivityManager {
if (localLOGV) Log.v(TAG, r.id + ": destroying");
final ActivityClientRecord clientRecord = mActivityThread.getActivityClient(r);
if (clientRecord != null) {
- mActivityThread.performDestroyActivity(clientRecord, finish, 0 /* configChanges */,
+ mActivityThread.performDestroyActivity(clientRecord, finish,
false /* getNonConfigInstance */, "LocalActivityManager::performDestroy");
}
r.activity = null;
@@ -684,7 +684,7 @@ public class LocalActivityManager {
if (localLOGV) Log.v(TAG, r.id + ": no corresponding record");
continue;
}
- mActivityThread.performDestroyActivity(clientRecord, finishing, 0 /* configChanges */,
+ mActivityThread.performDestroyActivity(clientRecord, finishing,
false /* getNonConfigInstance */, "LocalActivityManager::dispatchDestroy");
}
mActivities.clear();
diff --git a/core/java/android/app/LocaleConfig.java b/core/java/android/app/LocaleConfig.java
index b2be27f70ccc..4a06f7d1a1c3 100644
--- a/core/java/android/app/LocaleConfig.java
+++ b/core/java/android/app/LocaleConfig.java
@@ -248,7 +248,8 @@ public class LocaleConfig implements Parcelable {
}
/**
- * Returns the default locale if specified, otherwise null
+ * Returns the locale the strings in values/strings.xml (the default strings in the directory
+ * with no locale qualifier) are in if specified, otherwise null
*
* @return The default Locale or null
*/
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index d49a2542eed8..283e21aab39c 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -2052,10 +2052,12 @@ public class NotificationManager {
/** Notification senders to prioritize for calls. One of:
* PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
+ @PrioritySenders
public final int priorityCallSenders;
/** Notification senders to prioritize for messages. One of:
* PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
+ @PrioritySenders
public final int priorityMessageSenders;
/**
@@ -2063,6 +2065,7 @@ public class NotificationManager {
* {@link #CONVERSATION_SENDERS_NONE}, {@link #CONVERSATION_SENDERS_IMPORTANT},
* {@link #CONVERSATION_SENDERS_ANYONE}.
*/
+ @ConversationSenders
public final int priorityConversationSenders;
/**
@@ -2630,16 +2633,19 @@ public class NotificationManager {
}
/** @hide **/
+ @PrioritySenders
public int allowCallsFrom() {
return priorityCallSenders;
}
/** @hide **/
+ @PrioritySenders
public int allowMessagesFrom() {
return priorityMessageSenders;
}
/** @hide **/
+ @ConversationSenders
public int allowConversationsFrom() {
return priorityConversationSenders;
}
diff --git a/core/java/android/app/admin/AccountTypePolicyKey.java b/core/java/android/app/admin/AccountTypePolicyKey.java
index d81eb20512a2..51f313755e59 100644
--- a/core/java/android/app/admin/AccountTypePolicyKey.java
+++ b/core/java/android/app/admin/AccountTypePolicyKey.java
@@ -19,12 +19,12 @@ package android.app.admin;
import static android.app.admin.PolicyUpdateReceiver.EXTRA_ACCOUNT_TYPE;
import static android.app.admin.PolicyUpdateReceiver.EXTRA_POLICY_BUNDLE_KEY;
import static android.app.admin.PolicyUpdateReceiver.EXTRA_POLICY_KEY;
-import static android.app.admin.flags.Flags.devicePolicySizeTrackingEnabled;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
+import android.app.admin.flags.Flags;
import android.os.Bundle;
import android.os.Parcel;
@@ -54,7 +54,7 @@ public final class AccountTypePolicyKey extends PolicyKey {
@TestApi
public AccountTypePolicyKey(@NonNull String key, @NonNull String accountType) {
super(key);
- if (devicePolicySizeTrackingEnabled()) {
+ if (Flags.devicePolicySizeTrackingInternalEnabled()) {
PolicySizeVerifier.enforceMaxStringLength(accountType, "accountType");
}
mAccountType = Objects.requireNonNull((accountType));
diff --git a/core/java/android/app/admin/BundlePolicyValue.java b/core/java/android/app/admin/BundlePolicyValue.java
index cc5e75fac0ea..4f7060461091 100644
--- a/core/java/android/app/admin/BundlePolicyValue.java
+++ b/core/java/android/app/admin/BundlePolicyValue.java
@@ -16,10 +16,9 @@
package android.app.admin;
-import static android.app.admin.flags.Flags.devicePolicySizeTrackingEnabled;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.admin.flags.Flags;
import android.os.Bundle;
import android.os.Parcel;
@@ -32,7 +31,7 @@ public final class BundlePolicyValue extends PolicyValue<Bundle> {
public BundlePolicyValue(Bundle value) {
super(value);
- if (devicePolicySizeTrackingEnabled()) {
+ if (Flags.devicePolicySizeTrackingInternalEnabled()) {
PolicySizeVerifier.enforceMaxParcelableFieldsLength(value);
}
}
diff --git a/core/java/android/app/admin/ComponentNamePolicyValue.java b/core/java/android/app/admin/ComponentNamePolicyValue.java
index 4d36195613ad..a957dbf132bb 100644
--- a/core/java/android/app/admin/ComponentNamePolicyValue.java
+++ b/core/java/android/app/admin/ComponentNamePolicyValue.java
@@ -16,10 +16,9 @@
package android.app.admin;
-import static android.app.admin.flags.Flags.devicePolicySizeTrackingEnabled;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.admin.flags.Flags;
import android.content.ComponentName;
import android.os.Parcel;
@@ -32,7 +31,7 @@ public final class ComponentNamePolicyValue extends PolicyValue<ComponentName> {
public ComponentNamePolicyValue(@NonNull ComponentName value) {
super(value);
- if (devicePolicySizeTrackingEnabled()) {
+ if (Flags.devicePolicySizeTrackingInternalEnabled()) {
PolicySizeVerifier.enforceMaxComponentNameLength(value);
}
}
diff --git a/core/java/android/app/admin/IntentFilterPolicyKey.java b/core/java/android/app/admin/IntentFilterPolicyKey.java
index de7ff9f0ad0f..63c3a4cb499f 100644
--- a/core/java/android/app/admin/IntentFilterPolicyKey.java
+++ b/core/java/android/app/admin/IntentFilterPolicyKey.java
@@ -19,12 +19,12 @@ package android.app.admin;
import static android.app.admin.PolicyUpdateReceiver.EXTRA_INTENT_FILTER;
import static android.app.admin.PolicyUpdateReceiver.EXTRA_POLICY_BUNDLE_KEY;
import static android.app.admin.PolicyUpdateReceiver.EXTRA_POLICY_KEY;
-import static android.app.admin.flags.Flags.devicePolicySizeTrackingEnabled;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
+import android.app.admin.flags.Flags;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Parcel;
@@ -60,7 +60,7 @@ public final class IntentFilterPolicyKey extends PolicyKey {
@TestApi
public IntentFilterPolicyKey(@NonNull String identifier, @NonNull IntentFilter filter) {
super(identifier);
- if (devicePolicySizeTrackingEnabled()) {
+ if (Flags.devicePolicySizeTrackingInternalEnabled()) {
PolicySizeVerifier.enforceMaxParcelableFieldsLength(filter);
}
mFilter = Objects.requireNonNull(filter);
diff --git a/core/java/android/app/admin/LockTaskPolicy.java b/core/java/android/app/admin/LockTaskPolicy.java
index 9d6ce243a19b..a36ea0508a95 100644
--- a/core/java/android/app/admin/LockTaskPolicy.java
+++ b/core/java/android/app/admin/LockTaskPolicy.java
@@ -16,11 +16,10 @@
package android.app.admin;
-import static android.app.admin.flags.Flags.devicePolicySizeTrackingEnabled;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.app.admin.flags.Flags;
import android.os.Parcel;
import android.os.Parcelable;
@@ -136,7 +135,7 @@ public final class LockTaskPolicy extends PolicyValue<LockTaskPolicy> {
}
private void setPackagesInternal(Set<String> packages) {
- if (devicePolicySizeTrackingEnabled()) {
+ if (Flags.devicePolicySizeTrackingInternalEnabled()) {
for (String p : packages) {
PolicySizeVerifier.enforceMaxPackageNameLength(p);
}
diff --git a/core/java/android/app/admin/PackagePermissionPolicyKey.java b/core/java/android/app/admin/PackagePermissionPolicyKey.java
index 2241fddb7320..389585f036db 100644
--- a/core/java/android/app/admin/PackagePermissionPolicyKey.java
+++ b/core/java/android/app/admin/PackagePermissionPolicyKey.java
@@ -20,12 +20,12 @@ import static android.app.admin.PolicyUpdateReceiver.EXTRA_PACKAGE_NAME;
import static android.app.admin.PolicyUpdateReceiver.EXTRA_PERMISSION_NAME;
import static android.app.admin.PolicyUpdateReceiver.EXTRA_POLICY_BUNDLE_KEY;
import static android.app.admin.PolicyUpdateReceiver.EXTRA_POLICY_KEY;
-import static android.app.admin.flags.Flags.devicePolicySizeTrackingEnabled;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
+import android.app.admin.flags.Flags;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -59,7 +59,7 @@ public final class PackagePermissionPolicyKey extends PolicyKey {
public PackagePermissionPolicyKey(@NonNull String identifier, @NonNull String packageName,
@NonNull String permissionName) {
super(identifier);
- if (devicePolicySizeTrackingEnabled()) {
+ if (Flags.devicePolicySizeTrackingInternalEnabled()) {
PolicySizeVerifier.enforceMaxPackageNameLength(packageName);
PolicySizeVerifier.enforceMaxStringLength(permissionName, "permissionName");
}
diff --git a/core/java/android/app/admin/PackagePolicyKey.java b/core/java/android/app/admin/PackagePolicyKey.java
index 2ea17a18f6a6..68dc797f6513 100644
--- a/core/java/android/app/admin/PackagePolicyKey.java
+++ b/core/java/android/app/admin/PackagePolicyKey.java
@@ -19,12 +19,12 @@ package android.app.admin;
import static android.app.admin.PolicyUpdateReceiver.EXTRA_PACKAGE_NAME;
import static android.app.admin.PolicyUpdateReceiver.EXTRA_POLICY_BUNDLE_KEY;
import static android.app.admin.PolicyUpdateReceiver.EXTRA_POLICY_KEY;
-import static android.app.admin.flags.Flags.devicePolicySizeTrackingEnabled;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
+import android.app.admin.flags.Flags;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -55,7 +55,7 @@ public final class PackagePolicyKey extends PolicyKey {
@TestApi
public PackagePolicyKey(@NonNull String key, @NonNull String packageName) {
super(key);
- if (devicePolicySizeTrackingEnabled()) {
+ if (Flags.devicePolicySizeTrackingInternalEnabled()) {
PolicySizeVerifier.enforceMaxPackageNameLength(packageName);
}
mPackageName = Objects.requireNonNull((packageName));
diff --git a/core/java/android/app/admin/StringPolicyValue.java b/core/java/android/app/admin/StringPolicyValue.java
index f4d4adcfcedb..8995c0f20de8 100644
--- a/core/java/android/app/admin/StringPolicyValue.java
+++ b/core/java/android/app/admin/StringPolicyValue.java
@@ -16,10 +16,9 @@
package android.app.admin;
-import static android.app.admin.flags.Flags.devicePolicySizeTrackingEnabled;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.admin.flags.Flags;
import android.os.Parcel;
import java.util.Objects;
@@ -31,7 +30,7 @@ public final class StringPolicyValue extends PolicyValue<String> {
public StringPolicyValue(@NonNull String value) {
super(value);
- if (devicePolicySizeTrackingEnabled()) {
+ if (Flags.devicePolicySizeTrackingInternalEnabled()) {
PolicySizeVerifier.enforceMaxStringLength(value, "policyValue");
}
}
diff --git a/core/java/android/app/admin/StringSetPolicyValue.java b/core/java/android/app/admin/StringSetPolicyValue.java
index 82fe761a414f..f37dfee0f9dc 100644
--- a/core/java/android/app/admin/StringSetPolicyValue.java
+++ b/core/java/android/app/admin/StringSetPolicyValue.java
@@ -16,10 +16,9 @@
package android.app.admin;
-import static android.app.admin.flags.Flags.devicePolicySizeTrackingEnabled;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.admin.flags.Flags;
import android.os.Parcel;
import java.util.HashSet;
@@ -33,7 +32,7 @@ public final class StringSetPolicyValue extends PolicyValue<Set<String>> {
public StringSetPolicyValue(@NonNull Set<String> value) {
super(value);
- if (devicePolicySizeTrackingEnabled()) {
+ if (Flags.devicePolicySizeTrackingInternalEnabled()) {
for (String str : value) {
PolicySizeVerifier.enforceMaxStringLength(str, "policyValue");
}
diff --git a/core/java/android/app/admin/UserRestrictionPolicyKey.java b/core/java/android/app/admin/UserRestrictionPolicyKey.java
index d69a5f08ce2e..ee90ccd9417f 100644
--- a/core/java/android/app/admin/UserRestrictionPolicyKey.java
+++ b/core/java/android/app/admin/UserRestrictionPolicyKey.java
@@ -17,11 +17,11 @@
package android.app.admin;
import static android.app.admin.PolicyUpdateReceiver.EXTRA_POLICY_KEY;
-import static android.app.admin.flags.Flags.devicePolicySizeTrackingEnabled;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.TestApi;
+import android.app.admin.flags.Flags;
import android.os.Bundle;
import android.os.Parcel;
@@ -45,7 +45,7 @@ public final class UserRestrictionPolicyKey extends PolicyKey {
@TestApi
public UserRestrictionPolicyKey(@NonNull String identifier, @NonNull String restriction) {
super(identifier);
- if (devicePolicySizeTrackingEnabled()) {
+ if (Flags.devicePolicySizeTrackingInternalEnabled()) {
PolicySizeVerifier.enforceMaxStringLength(restriction, "restriction");
}
mRestriction = Objects.requireNonNull(restriction);
diff --git a/core/java/android/app/admin/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig
index e1a69139d88d..19270199696e 100644
--- a/core/java/android/app/admin/flags/flags.aconfig
+++ b/core/java/android/app/admin/flags/flags.aconfig
@@ -10,7 +10,14 @@ flag {
flag {
name: "device_policy_size_tracking_enabled"
namespace: "enterprise"
- description: "Add feature to track the total policy size and have a max threshold."
+ description: "Add feature to track the total policy size and have a max threshold - public API changes"
+ bug: "281543351"
+}
+
+flag {
+ name: "device_policy_size_tracking_internal_enabled"
+ namespace: "enterprise"
+ description: "Add feature to track the total policy size and have a max threshold - internal changes"
bug: "281543351"
}
diff --git a/core/java/android/app/servertransaction/ClientTransactionListenerController.java b/core/java/android/app/servertransaction/ClientTransactionListenerController.java
index 1a8136e06c28..7383d07c82e9 100644
--- a/core/java/android/app/servertransaction/ClientTransactionListenerController.java
+++ b/core/java/android/app/servertransaction/ClientTransactionListenerController.java
@@ -16,16 +16,24 @@
package android.app.servertransaction;
+import static com.android.window.flags.Flags.activityWindowInfoFlag;
import static com.android.window.flags.Flags.bundleClientTransactionFlag;
import static java.util.Objects.requireNonNull;
import android.annotation.NonNull;
+import android.app.Activity;
import android.app.ActivityThread;
import android.hardware.display.DisplayManagerGlobal;
+import android.os.IBinder;
+import android.util.ArraySet;
+import android.window.ActivityWindowInfo;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import java.util.function.BiConsumer;
+
/**
* Singleton controller to manage listeners to individual {@link ClientTransaction}.
*
@@ -35,8 +43,14 @@ public class ClientTransactionListenerController {
private static ClientTransactionListenerController sController;
+ private final Object mLock = new Object();
private final DisplayManagerGlobal mDisplayManager;
+ /** Listeners registered via {@link #registerActivityWindowInfoChangedListener(BiConsumer)}. */
+ @GuardedBy("mLock")
+ private final ArraySet<BiConsumer<IBinder, ActivityWindowInfo>>
+ mActivityWindowInfoChangedListeners = new ArraySet<>();
+
/** Gets the singleton controller. */
@NonNull
public static ClientTransactionListenerController getInstance() {
@@ -62,6 +76,57 @@ public class ClientTransactionListenerController {
}
/**
+ * Registers to listen on activity {@link ActivityWindowInfo} change.
+ * The listener will be invoked with two parameters: {@link Activity#getActivityToken()} and
+ * {@link ActivityWindowInfo}.
+ */
+ public void registerActivityWindowInfoChangedListener(
+ @NonNull BiConsumer<IBinder, ActivityWindowInfo> listener) {
+ if (!activityWindowInfoFlag()) {
+ return;
+ }
+ synchronized (mLock) {
+ mActivityWindowInfoChangedListeners.add(listener);
+ }
+ }
+
+ /**
+ * Unregisters the listener that was previously registered via
+ * {@link #registerActivityWindowInfoChangedListener(BiConsumer)}
+ */
+ public void unregisterActivityWindowInfoChangedListener(
+ @NonNull BiConsumer<IBinder, ActivityWindowInfo> listener) {
+ if (!activityWindowInfoFlag()) {
+ return;
+ }
+ synchronized (mLock) {
+ mActivityWindowInfoChangedListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Called when receives a {@link ClientTransaction} that is updating an activity's
+ * {@link ActivityWindowInfo}.
+ */
+ public void onActivityWindowInfoChanged(@NonNull IBinder activityToken,
+ @NonNull ActivityWindowInfo activityWindowInfo) {
+ if (!activityWindowInfoFlag()) {
+ return;
+ }
+ final Object[] activityWindowInfoChangedListeners;
+ synchronized (mLock) {
+ if (mActivityWindowInfoChangedListeners.isEmpty()) {
+ return;
+ }
+ activityWindowInfoChangedListeners = mActivityWindowInfoChangedListeners.toArray();
+ }
+ for (Object activityWindowInfoChangedListener : activityWindowInfoChangedListeners) {
+ ((BiConsumer<IBinder, ActivityWindowInfo>) activityWindowInfoChangedListener)
+ .accept(activityToken, activityWindowInfo);
+ }
+ }
+
+ /**
* Called when receives a {@link ClientTransaction} that is updating display-related
* window configuration.
*/
diff --git a/core/java/android/app/servertransaction/DestroyActivityItem.java b/core/java/android/app/servertransaction/DestroyActivityItem.java
index f9cf075d6062..b0213d7356df 100644
--- a/core/java/android/app/servertransaction/DestroyActivityItem.java
+++ b/core/java/android/app/servertransaction/DestroyActivityItem.java
@@ -33,7 +33,6 @@ import android.os.Trace;
public class DestroyActivityItem extends ActivityLifecycleItem {
private boolean mFinished;
- private int mConfigChanges;
@Override
public void preExecute(@NonNull ClientTransactionHandler client) {
@@ -44,7 +43,7 @@ public class DestroyActivityItem extends ActivityLifecycleItem {
public void execute(@NonNull ClientTransactionHandler client, @NonNull ActivityClientRecord r,
@NonNull PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
- client.handleDestroyActivity(r, mFinished, mConfigChanges,
+ client.handleDestroyActivity(r, mFinished,
false /* getNonConfigInstance */, "DestroyActivityItem");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -67,15 +66,13 @@ public class DestroyActivityItem extends ActivityLifecycleItem {
/** Obtain an instance initialized with provided params. */
@NonNull
- public static DestroyActivityItem obtain(@NonNull IBinder activityToken, boolean finished,
- int configChanges) {
+ public static DestroyActivityItem obtain(@NonNull IBinder activityToken, boolean finished) {
DestroyActivityItem instance = ObjectPool.obtain(DestroyActivityItem.class);
if (instance == null) {
instance = new DestroyActivityItem();
}
instance.setActivityToken(activityToken);
instance.mFinished = finished;
- instance.mConfigChanges = configChanges;
return instance;
}
@@ -84,7 +81,6 @@ public class DestroyActivityItem extends ActivityLifecycleItem {
public void recycle() {
super.recycle();
mFinished = false;
- mConfigChanges = 0;
ObjectPool.recycle(this);
}
@@ -95,14 +91,12 @@ public class DestroyActivityItem extends ActivityLifecycleItem {
public void writeToParcel(@NonNull Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeBoolean(mFinished);
- dest.writeInt(mConfigChanges);
}
/** Read from Parcel. */
private DestroyActivityItem(@NonNull Parcel in) {
super(in);
mFinished = in.readBoolean();
- mConfigChanges = in.readInt();
}
public static final @NonNull Creator<DestroyActivityItem> CREATOR = new Creator<>() {
@@ -124,7 +118,7 @@ public class DestroyActivityItem extends ActivityLifecycleItem {
return false;
}
final DestroyActivityItem other = (DestroyActivityItem) o;
- return mFinished == other.mFinished && mConfigChanges == other.mConfigChanges;
+ return mFinished == other.mFinished;
}
@Override
@@ -132,14 +126,12 @@ public class DestroyActivityItem extends ActivityLifecycleItem {
int result = 17;
result = 31 * result + super.hashCode();
result = 31 * result + (mFinished ? 1 : 0);
- result = 31 * result + mConfigChanges;
return result;
}
@Override
public String toString() {
return "DestroyActivityItem{" + super.toString()
- + ",finished=" + mFinished
- + ",mConfigChanges=" + mConfigChanges + "}";
+ + ",finished=" + mFinished + "}";
}
}
diff --git a/core/java/android/app/servertransaction/PauseActivityItem.java b/core/java/android/app/servertransaction/PauseActivityItem.java
index 8f1e90b985e6..d230284287b6 100644
--- a/core/java/android/app/servertransaction/PauseActivityItem.java
+++ b/core/java/android/app/servertransaction/PauseActivityItem.java
@@ -37,7 +37,6 @@ public class PauseActivityItem extends ActivityLifecycleItem {
private boolean mFinished;
private boolean mUserLeaving;
- private int mConfigChanges;
private boolean mDontReport;
private boolean mAutoEnteringPip;
@@ -45,7 +44,7 @@ public class PauseActivityItem extends ActivityLifecycleItem {
public void execute(@NonNull ClientTransactionHandler client, @NonNull ActivityClientRecord r,
@NonNull PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
- client.handlePauseActivity(r, mFinished, mUserLeaving, mConfigChanges, mAutoEnteringPip,
+ client.handlePauseActivity(r, mFinished, mUserLeaving, mAutoEnteringPip,
pendingActions, "PAUSE_ACTIVITY_ITEM");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -72,7 +71,7 @@ public class PauseActivityItem extends ActivityLifecycleItem {
/** Obtain an instance initialized with provided params. */
@NonNull
public static PauseActivityItem obtain(@NonNull IBinder activityToken, boolean finished,
- boolean userLeaving, int configChanges, boolean dontReport, boolean autoEnteringPip) {
+ boolean userLeaving, boolean dontReport, boolean autoEnteringPip) {
PauseActivityItem instance = ObjectPool.obtain(PauseActivityItem.class);
if (instance == null) {
instance = new PauseActivityItem();
@@ -80,7 +79,6 @@ public class PauseActivityItem extends ActivityLifecycleItem {
instance.setActivityToken(activityToken);
instance.mFinished = finished;
instance.mUserLeaving = userLeaving;
- instance.mConfigChanges = configChanges;
instance.mDontReport = dontReport;
instance.mAutoEnteringPip = autoEnteringPip;
@@ -91,7 +89,7 @@ public class PauseActivityItem extends ActivityLifecycleItem {
@NonNull
public static PauseActivityItem obtain(@NonNull IBinder activityToken) {
return obtain(activityToken, false /* finished */, false /* userLeaving */,
- 0 /* configChanges */, true /* dontReport */, false /* autoEnteringPip*/);
+ true /* dontReport */, false /* autoEnteringPip*/);
}
@Override
@@ -99,7 +97,6 @@ public class PauseActivityItem extends ActivityLifecycleItem {
super.recycle();
mFinished = false;
mUserLeaving = false;
- mConfigChanges = 0;
mDontReport = false;
mAutoEnteringPip = false;
ObjectPool.recycle(this);
@@ -113,7 +110,6 @@ public class PauseActivityItem extends ActivityLifecycleItem {
super.writeToParcel(dest, flags);
dest.writeBoolean(mFinished);
dest.writeBoolean(mUserLeaving);
- dest.writeInt(mConfigChanges);
dest.writeBoolean(mDontReport);
dest.writeBoolean(mAutoEnteringPip);
}
@@ -123,7 +119,6 @@ public class PauseActivityItem extends ActivityLifecycleItem {
super(in);
mFinished = in.readBoolean();
mUserLeaving = in.readBoolean();
- mConfigChanges = in.readInt();
mDontReport = in.readBoolean();
mAutoEnteringPip = in.readBoolean();
}
@@ -148,7 +143,7 @@ public class PauseActivityItem extends ActivityLifecycleItem {
}
final PauseActivityItem other = (PauseActivityItem) o;
return mFinished == other.mFinished && mUserLeaving == other.mUserLeaving
- && mConfigChanges == other.mConfigChanges && mDontReport == other.mDontReport
+ && mDontReport == other.mDontReport
&& mAutoEnteringPip == other.mAutoEnteringPip;
}
@@ -158,7 +153,6 @@ public class PauseActivityItem extends ActivityLifecycleItem {
result = 31 * result + super.hashCode();
result = 31 * result + (mFinished ? 1 : 0);
result = 31 * result + (mUserLeaving ? 1 : 0);
- result = 31 * result + mConfigChanges;
result = 31 * result + (mDontReport ? 1 : 0);
result = 31 * result + (mAutoEnteringPip ? 1 : 0);
return result;
@@ -169,7 +163,6 @@ public class PauseActivityItem extends ActivityLifecycleItem {
return "PauseActivityItem{" + super.toString()
+ ",finished=" + mFinished
+ ",userLeaving=" + mUserLeaving
- + ",configChanges=" + mConfigChanges
+ ",dontReport=" + mDontReport
+ ",autoEnteringPip=" + mAutoEnteringPip + "}";
}
diff --git a/core/java/android/app/servertransaction/StopActivityItem.java b/core/java/android/app/servertransaction/StopActivityItem.java
index b8ce52da5a0c..def7b3fd9987 100644
--- a/core/java/android/app/servertransaction/StopActivityItem.java
+++ b/core/java/android/app/servertransaction/StopActivityItem.java
@@ -19,7 +19,6 @@ package android.app.servertransaction;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.os.IBinder;
@@ -34,13 +33,11 @@ public class StopActivityItem extends ActivityLifecycleItem {
private static final String TAG = "StopActivityItem";
- private int mConfigChanges;
-
@Override
public void execute(@NonNull ClientTransactionHandler client, @NonNull ActivityClientRecord r,
@NonNull PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
- client.handleStopActivity(r, mConfigChanges, pendingActions,
+ client.handleStopActivity(r, pendingActions,
true /* finalStateRequest */, "STOP_ACTIVITY_ITEM");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -63,16 +60,14 @@ public class StopActivityItem extends ActivityLifecycleItem {
/**
* Obtain an instance initialized with provided params.
* @param activityToken the activity that stops.
- * @param configChanges Configuration pieces that changed.
*/
@NonNull
- public static StopActivityItem obtain(@NonNull IBinder activityToken, int configChanges) {
+ public static StopActivityItem obtain(@NonNull IBinder activityToken) {
StopActivityItem instance = ObjectPool.obtain(StopActivityItem.class);
if (instance == null) {
instance = new StopActivityItem();
}
instance.setActivityToken(activityToken);
- instance.mConfigChanges = configChanges;
return instance;
}
@@ -80,23 +75,14 @@ public class StopActivityItem extends ActivityLifecycleItem {
@Override
public void recycle() {
super.recycle();
- mConfigChanges = 0;
ObjectPool.recycle(this);
}
// Parcelable implementation
- /** Write to Parcel. */
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- super.writeToParcel(dest, flags);
- dest.writeInt(mConfigChanges);
- }
-
/** Read from Parcel. */
private StopActivityItem(@NonNull Parcel in) {
super(in);
- mConfigChanges = in.readInt();
}
public static final @NonNull Creator<StopActivityItem> CREATOR = new Creator<>() {
@@ -110,28 +96,7 @@ public class StopActivityItem extends ActivityLifecycleItem {
};
@Override
- public boolean equals(@Nullable Object o) {
- if (this == o) {
- return true;
- }
- if (!super.equals(o)) {
- return false;
- }
- final StopActivityItem other = (StopActivityItem) o;
- return mConfigChanges == other.mConfigChanges;
- }
-
- @Override
- public int hashCode() {
- int result = 17;
- result = 31 * result + super.hashCode();
- result = 31 * result + mConfigChanges;
- return result;
- }
-
- @Override
public String toString() {
- return "StopActivityItem{" + super.toString()
- + ",configChanges=" + mConfigChanges + "}";
+ return "StopActivityItem{" + super.toString() + "}";
}
}
diff --git a/core/java/android/app/servertransaction/TransactionExecutor.java b/core/java/android/app/servertransaction/TransactionExecutor.java
index fa73c99be2b8..c83719149821 100644
--- a/core/java/android/app/servertransaction/TransactionExecutor.java
+++ b/core/java/android/app/servertransaction/TransactionExecutor.java
@@ -334,18 +334,18 @@ public class TransactionExecutor {
break;
case ON_PAUSE:
mTransactionHandler.handlePauseActivity(r, false /* finished */,
- false /* userLeaving */, 0 /* configChanges */,
+ false /* userLeaving */,
false /* autoEnteringPip */, mPendingActions,
"LIFECYCLER_PAUSE_ACTIVITY");
break;
case ON_STOP:
- mTransactionHandler.handleStopActivity(r, 0 /* configChanges */,
+ mTransactionHandler.handleStopActivity(r,
mPendingActions, false /* finalStateRequest */,
"LIFECYCLER_STOP_ACTIVITY");
break;
case ON_DESTROY:
mTransactionHandler.handleDestroyActivity(r, false /* finishing */,
- 0 /* configChanges */, false /* getNonConfigInstance */,
+ false /* getNonConfigInstance */,
"performLifecycleSequence. cycling to:" + path.get(size - 1));
break;
case ON_RESTART:
diff --git a/core/java/android/app/servertransaction/TransactionExecutorHelper.java b/core/java/android/app/servertransaction/TransactionExecutorHelper.java
index 475c6fb9a48a..710261ab4c97 100644
--- a/core/java/android/app/servertransaction/TransactionExecutorHelper.java
+++ b/core/java/android/app/servertransaction/TransactionExecutorHelper.java
@@ -200,7 +200,7 @@ public class TransactionExecutorHelper {
lifecycleItem = PauseActivityItem.obtain(r.token);
break;
case ON_STOP:
- lifecycleItem = StopActivityItem.obtain(r.token, 0 /* configChanges */);
+ lifecycleItem = StopActivityItem.obtain(r.token);
break;
default:
lifecycleItem = ResumeActivityItem.obtain(r.token, false /* isForward */,
diff --git a/core/java/android/companion/virtual/VirtualDeviceInternal.java b/core/java/android/companion/virtual/VirtualDeviceInternal.java
index 39f6de75928a..00d534370fa1 100644
--- a/core/java/android/companion/virtual/VirtualDeviceInternal.java
+++ b/core/java/android/companion/virtual/VirtualDeviceInternal.java
@@ -16,6 +16,9 @@
package android.companion.virtual;
+import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_CUSTOM;
+import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_AUDIO;
+
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -352,12 +355,20 @@ public class VirtualDeviceInternal {
@Nullable Executor executor,
@Nullable VirtualAudioDevice.AudioConfigurationChangeCallback callback) {
if (mVirtualAudioDevice == null) {
- Context context = mContext;
- if (Flags.deviceAwareRecordAudioPermission()) {
- context = mContext.createDeviceContext(getDeviceId());
+ try {
+ Context context = mContext;
+ if (Flags.deviceAwareRecordAudioPermission()) {
+ // When using a default policy for audio device-aware RECORD_AUDIO permission
+ // should not take effect, thus register policies with the default context.
+ if (mVirtualDevice.getDevicePolicy(POLICY_TYPE_AUDIO) == DEVICE_POLICY_CUSTOM) {
+ context = mContext.createDeviceContext(getDeviceId());
+ }
+ }
+ mVirtualAudioDevice = new VirtualAudioDevice(context, mVirtualDevice, display,
+ executor, callback, () -> mVirtualAudioDevice = null);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
- mVirtualAudioDevice = new VirtualAudioDevice(context, mVirtualDevice, display,
- executor, callback, () -> mVirtualAudioDevice = null);
}
return mVirtualAudioDevice;
}
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index 3e9f260566bd..8a3a3ad56a7b 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -112,6 +112,12 @@ public class UserInfo implements Parcelable {
/**
* Indicates that this user is disabled.
*
+ * <p> This is currently used to indicate that a Managed Profile, when created via
+ * DevicePolicyManager, has not yet been provisioned; once the DPC provisions it, a DPM call
+ * will manually set it to enabled.
+ *
+ * <p>Users that are slated for deletion are also generally set to disabled.
+ *
* <p>Note: If an ephemeral user is disabled, it shouldn't be later re-enabled. Ephemeral users
* are disabled as their removal is in progress to indicate that they shouldn't be re-entered.
*/
@@ -398,6 +404,7 @@ public class UserInfo implements Parcelable {
return UserManager.isUserTypePrivateProfile(userType);
}
+ /** See {@link #FLAG_DISABLED}*/
@UnsupportedAppUsage
public boolean isEnabled() {
return (flags & FLAG_DISABLED) != FLAG_DISABLED;
diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig
index 5e9d8f0a9b7e..610057bffdbf 100644
--- a/core/java/android/content/pm/flags.aconfig
+++ b/core/java/android/content/pm/flags.aconfig
@@ -208,6 +208,14 @@ flag {
}
flag {
+ name: "restrict_nonpreloads_system_shareduids"
+ namespace: "package_manager_service"
+ description: "Feature flag to restrict apps from joining system shared uids"
+ bug: "308573169"
+ is_fixed_read_only: true
+}
+
+flag {
name: "min_target_sdk_24"
namespace: "responsible_apis"
description: "Feature flag to bump min target sdk to 24"
diff --git a/core/java/android/credentials/CredentialManager.java b/core/java/android/credentials/CredentialManager.java
index 2e63664df7aa..3a9a0f911660 100644
--- a/core/java/android/credentials/CredentialManager.java
+++ b/core/java/android/credentials/CredentialManager.java
@@ -23,6 +23,7 @@ import android.annotation.Hide;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresFeature;
import android.annotation.RequiresPermission;
import android.annotation.SystemService;
import android.annotation.TestApi;
@@ -31,6 +32,7 @@ import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.IntentSender;
+import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.CancellationSignal;
@@ -57,6 +59,7 @@ import java.util.concurrent.Executor;
* to authenticate to the app.
*/
@SystemService(Context.CREDENTIAL_SERVICE)
+@RequiresFeature(PackageManager.FEATURE_CREDENTIALS)
public final class CredentialManager {
private static final String TAG = "CredentialManager";
private static final Bundle OPTIONS_SENDER_BAL_OPTIN = ActivityOptions.makeBasic()
diff --git a/core/java/android/credentials/selection/IntentFactory.java b/core/java/android/credentials/selection/IntentFactory.java
index 4b0fa6d32af7..79fba9b19250 100644
--- a/core/java/android/credentials/selection/IntentFactory.java
+++ b/core/java/android/credentials/selection/IntentFactory.java
@@ -80,17 +80,7 @@ public class IntentFactory {
ArrayList<DisabledProviderData> disabledProviderDataList,
@NonNull ResultReceiver resultReceiver) {
Intent intent = new Intent();
- ComponentName componentName =
- ComponentName.unflattenFromString(
- Resources.getSystem()
- .getString(
- com.android.internal.R.string
- .config_credentialManagerDialogComponent));
- ComponentName oemOverrideComponentName = getOemOverrideComponentName(context);
- if (oemOverrideComponentName != null) {
- componentName = oemOverrideComponentName;
- }
- intent.setComponent(componentName);
+ setCredentialSelectorUiComponentName(context, intent);
intent.putParcelableArrayListExtra(
ProviderData.EXTRA_DISABLED_PROVIDER_DATA_LIST, disabledProviderDataList);
intent.putExtra(RequestInfo.EXTRA_REQUEST_INFO, requestInfo);
@@ -100,6 +90,24 @@ public class IntentFactory {
return intent;
}
+ private static void setCredentialSelectorUiComponentName(@NonNull Context context,
+ @NonNull Intent intent) {
+ if (configurableSelectorUiEnabled()) {
+ ComponentName componentName = getOemOverrideComponentName(context);
+ if (componentName == null) {
+ componentName = ComponentName.unflattenFromString(Resources.getSystem().getString(
+ com.android.internal.R.string
+ .config_fallbackCredentialManagerDialogComponent));
+ }
+ intent.setComponent(componentName);
+ } else {
+ ComponentName componentName = ComponentName.unflattenFromString(Resources.getSystem()
+ .getString(com.android.internal.R.string
+ .config_fallbackCredentialManagerDialogComponent));
+ intent.setComponent(componentName);
+ }
+ }
+
/**
* Returns null if there is not an enabled and valid oem override component. It means the
* default platform UI component name should be used instead.
@@ -107,44 +115,39 @@ public class IntentFactory {
@Nullable
private static ComponentName getOemOverrideComponentName(@NonNull Context context) {
ComponentName result = null;
- if (configurableSelectorUiEnabled()) {
- if (Resources.getSystem().getBoolean(
- com.android.internal.R.bool.config_enableOemCredentialManagerDialogComponent)) {
- String oemComponentString =
- Resources.getSystem()
- .getString(
- com.android.internal.R.string
- .config_oemCredentialManagerDialogComponent);
- if (!TextUtils.isEmpty(oemComponentString)) {
- ComponentName oemComponentName = ComponentName.unflattenFromString(
- oemComponentString);
- if (oemComponentName != null) {
- try {
- ActivityInfo info = context.getPackageManager().getActivityInfo(
- oemComponentName,
- PackageManager.ComponentInfoFlags.of(
- PackageManager.MATCH_SYSTEM_ONLY));
- if (info.enabled && info.exported) {
- Slog.i(TAG,
- "Found enabled oem CredMan UI component."
- + oemComponentString);
- result = oemComponentName;
- } else {
- Slog.i(TAG,
- "Found enabled oem CredMan UI component but it was not "
- + "enabled.");
- }
- } catch (PackageManager.NameNotFoundException e) {
- Slog.i(TAG, "Unable to find oem CredMan UI component: "
- + oemComponentString + ".");
- }
+ String oemComponentString =
+ Resources.getSystem()
+ .getString(
+ com.android.internal.R.string
+ .config_oemCredentialManagerDialogComponent);
+ if (!TextUtils.isEmpty(oemComponentString)) {
+ ComponentName oemComponentName = ComponentName.unflattenFromString(
+ oemComponentString);
+ if (oemComponentName != null) {
+ try {
+ ActivityInfo info = context.getPackageManager().getActivityInfo(
+ oemComponentName,
+ PackageManager.ComponentInfoFlags.of(
+ PackageManager.MATCH_SYSTEM_ONLY));
+ if (info.enabled && info.exported) {
+ Slog.i(TAG,
+ "Found enabled oem CredMan UI component."
+ + oemComponentString);
+ result = oemComponentName;
} else {
- Slog.i(TAG, "Invalid OEM ComponentName format.");
+ Slog.i(TAG,
+ "Found enabled oem CredMan UI component but it was not "
+ + "enabled.");
}
- } else {
- Slog.i(TAG, "Invalid empty OEM component name.");
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.i(TAG, "Unable to find oem CredMan UI component: "
+ + oemComponentString + ".");
}
+ } else {
+ Slog.i(TAG, "Invalid OEM ComponentName format.");
}
+ } else {
+ Slog.i(TAG, "Invalid empty OEM component name.");
}
return result;
}
@@ -186,16 +189,11 @@ public class IntentFactory {
* Creates an Intent that cancels any UI matching the given request token id.
*/
@NonNull
- public static Intent createCancelUiIntent(@NonNull IBinder requestToken,
- boolean shouldShowCancellationUi, @NonNull String appPackageName) {
+ public static Intent createCancelUiIntent(@NonNull Context context,
+ @NonNull IBinder requestToken, boolean shouldShowCancellationUi,
+ @NonNull String appPackageName) {
Intent intent = new Intent();
- ComponentName componentName =
- ComponentName.unflattenFromString(
- Resources.getSystem()
- .getString(
- com.android.internal.R.string
- .config_credentialManagerDialogComponent));
- intent.setComponent(componentName);
+ setCredentialSelectorUiComponentName(context, intent);
intent.putExtra(CancelSelectionRequest.EXTRA_CANCEL_UI_REQUEST,
new CancelSelectionRequest(new RequestToken(requestToken), shouldShowCancellationUi,
appPackageName));
diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java
index d9d4305cc630..0208fed6040f 100644
--- a/core/java/android/hardware/biometrics/BiometricPrompt.java
+++ b/core/java/android/hardware/biometrics/BiometricPrompt.java
@@ -23,7 +23,6 @@ import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
import static android.hardware.biometrics.BiometricManager.Authenticators;
import static android.hardware.biometrics.Flags.FLAG_ADD_KEY_AGREEMENT_CRYPTO_OBJECT;
import static android.hardware.biometrics.Flags.FLAG_CUSTOM_BIOMETRIC_PROMPT;
-import static android.hardware.biometrics.Flags.FLAG_FACE_BACKGROUND_AUTHENTICATION;
import static android.hardware.biometrics.Flags.FLAG_GET_OP_ID_CRYPTO_OBJECT;
import static android.multiuser.Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE;
@@ -1128,8 +1127,6 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
* @hide
*/
@Override
- @TestApi
- @FlaggedApi(FLAG_FACE_BACKGROUND_AUTHENTICATION)
public void onAuthenticationAcquired(int acquireInfo) {}
/**
diff --git a/core/java/android/hardware/biometrics/SensorProperties.java b/core/java/android/hardware/biometrics/SensorProperties.java
index 16f71414c8c9..3b9cad49250f 100644
--- a/core/java/android/hardware/biometrics/SensorProperties.java
+++ b/core/java/android/hardware/biometrics/SensorProperties.java
@@ -16,9 +16,6 @@
package android.hardware.biometrics;
-import static android.hardware.biometrics.Flags.FLAG_FACE_BACKGROUND_AUTHENTICATION;
-
-import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.TestApi;
@@ -144,10 +141,8 @@ public class SensorProperties {
/**
* @hide
*/
- @TestApi
- @FlaggedApi(FLAG_FACE_BACKGROUND_AUTHENTICATION)
public SensorProperties(int sensorId, @Strength int sensorStrength,
- @NonNull List<ComponentInfo> componentInfo) {
+ List<ComponentInfo> componentInfo) {
mSensorId = sensorId;
mSensorStrength = sensorStrength;
mComponentInfo = componentInfo;
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 57b437f4bacf..dc8f4b448931 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -3521,7 +3521,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* <p>When the key is present, only a PRIVATE/YUV output of the specified size is guaranteed
* to be supported by the camera HAL in the secure camera mode. Any other format or
* resolutions might not be supported. Use
- * {@link CameraManager#isSessionConfigurationWithParametersSupported }
+ * {@link CameraDevice#isSessionConfigurationSupported }
* API to query if a secure session configuration is supported if the device supports this
* API.</p>
* <p>If this key returns null on a device with SECURE_IMAGE_DATA capability, the application
@@ -5046,18 +5046,18 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
/**
* <p>The version of the session configuration query
- * {@link android.hardware.camera2.CameraManager#isSessionConfigurationWithParametersSupported }
+ * {@link android.hardware.camera2.CameraDevice.CameraDeviceSetup#isSessionConfigurationSupported }
* API</p>
* <p>The possible values in this key correspond to the values defined in
* android.os.Build.VERSION_CODES. Each version defines a set of feature combinations the
* camera device must reliably report whether they are supported via
- * {@link android.hardware.camera2.CameraManager#isSessionConfigurationWithParametersSupported }
+ * {@link android.hardware.camera2.CameraDevice.CameraDeviceSetup#isSessionConfigurationSupported }
* API. And the version is always less or equal to android.os.Build.VERSION.SDK_INT.</p>
* <p>If set to UPSIDE_DOWN_CAKE, this camera device doesn't support
- * {@link android.hardware.camera2.CameraManager#isSessionConfigurationWithParametersSupported }.
+ * {@link android.hardware.camera2.CameraDevice.CameraDeviceSetup#isSessionConfigurationSupported }.
* Calling the method for this camera ID throws an UnsupportedOperationException.</p>
* <p>If set to VANILLA_ICE_CREAM, the application can call
- * {@link android.hardware.camera2.CameraManager#isSessionConfigurationWithParametersSupported }
+ * {@link android.hardware.camera2.CameraDevice.CameraDeviceSetup#isSessionConfigurationSupported }
* to check if the combinations of below features are supported.</p>
* <ul>
* <li>A subset of LIMITED-level device stream combinations.</li>
@@ -6082,11 +6082,11 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
/**
* <p>Minimum and maximum padding zoom factors supported by this camera device for
- * {@link android.hardware.camera2.ExtensionCaptureRequest#EFV_PADDING_ZOOM_FACTOR } used for the
+ * android.efv.paddingZoomFactor used for the
* {@link android.hardware.camera2.CameraExtensionCharacteristics#EXTENSION_EYES_FREE_VIDEOGRAPHY }
* extension.</p>
* <p>The minimum and maximum padding zoom factors supported by the device for
- * {@link android.hardware.camera2.ExtensionCaptureRequest#EFV_PADDING_ZOOM_FACTOR } used as part of the
+ * android.efv.paddingZoomFactor used as part of the
* {@link android.hardware.camera2.CameraExtensionCharacteristics#EXTENSION_EYES_FREE_VIDEOGRAPHY }
* extension feature. This extension specific camera characteristic can be queried using
* {@link android.hardware.camera2.CameraExtensionCharacteristics#get }.</p>
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index e24c98e98c5d..9fb561bb4211 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -911,10 +911,10 @@ public abstract class CameraMetadata<TKey> {
* </ul>
* <p>Combinations of logical and physical streams, or physical streams from different
* physical cameras are not guaranteed. However, if the camera device supports
- * {@link CameraManager#isSessionConfigurationWithParametersSupported },
+ * {@link CameraDevice#isSessionConfigurationSupported },
* application must be able to query whether a stream combination involving physical
* streams is supported by calling
- * {@link CameraManager#isSessionConfigurationWithParametersSupported }.</p>
+ * {@link CameraDevice#isSessionConfigurationSupported }.</p>
* <p>Camera application shouldn't assume that there are at most 1 rear camera and 1 front
* camera in the system. For an application that switches between front and back cameras,
* the recommendation is to switch between the first rear camera and the first front
diff --git a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
index 9fbe348f1e9a..f3b7b919d87d 100644
--- a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
+++ b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
@@ -260,7 +260,7 @@ public final class MandatoryStreamCombination {
* smaller sizes, then the resulting
* {@link android.hardware.camera2.params.SessionConfiguration session configuration} can
* be tested either by calling {@link CameraDevice#createCaptureSession} or
- * {@link CameraManager#isSessionConfigurationWithParametersSupported}.
+ * {@link CameraDeviceSetup#isSessionConfigurationSupported}.
*
* @return non-modifiable ascending list of available sizes.
*/
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 1b0a485bdbda..066c45f03ec4 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -18,7 +18,6 @@ package android.hardware.face;
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
import static android.Manifest.permission.MANAGE_BIOMETRIC;
-import static android.Manifest.permission.TEST_BIOMETRIC;
import static android.Manifest.permission.USE_BACKGROUND_FACE_AUTHENTICATION;
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_LOCKOUT_NONE;
@@ -30,7 +29,6 @@ import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
-import android.annotation.TestApi;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.biometrics.BiometricAuthenticator;
@@ -38,7 +36,6 @@ import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricFaceConstants;
import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.BiometricStateListener;
-import android.hardware.biometrics.BiometricTestSession;
import android.hardware.biometrics.CryptoObject;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.os.Binder;
@@ -72,7 +69,6 @@ import java.util.concurrent.Executor;
*/
@FlaggedApi(FLAG_FACE_BACKGROUND_AUTHENTICATION)
@SystemApi
-@TestApi
@SystemService(Context.FACE_SERVICE)
public class FaceManager implements BiometricAuthenticator, BiometricFaceConstants {
@@ -784,8 +780,6 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
* @hide
*/
@NonNull
- @TestApi
- @FlaggedApi(FLAG_FACE_BACKGROUND_AUTHENTICATION)
public List<FaceSensorProperties> getSensorProperties() {
final List<FaceSensorProperties> properties = new ArrayList<>();
final List<FaceSensorPropertiesInternal> internalProperties
@@ -1634,23 +1628,4 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
Slog.w(TAG, "Unknown enrollment acquired message: " + acquireInfo + ", " + vendorCode);
return null;
}
-
- /**
- * Retrieves a test session for FaceManager.
- *
- * @hide
- */
- @TestApi
- @NonNull
- @RequiresPermission(TEST_BIOMETRIC)
- @FlaggedApi(FLAG_FACE_BACKGROUND_AUTHENTICATION)
- public BiometricTestSession createTestSession(int sensorId) {
- try {
- return new BiometricTestSession(mContext, sensorId,
- (context, sensorId1, callback) -> mService
- .createTestSession(sensorId1, callback, context.getOpPackageName()));
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-} \ No newline at end of file
+}
diff --git a/core/java/android/hardware/face/FaceSensorProperties.java b/core/java/android/hardware/face/FaceSensorProperties.java
index a1ddb0e3495b..f61312785919 100644
--- a/core/java/android/hardware/face/FaceSensorProperties.java
+++ b/core/java/android/hardware/face/FaceSensorProperties.java
@@ -16,12 +16,8 @@
package android.hardware.face;
-import static android.hardware.biometrics.Flags.FLAG_FACE_BACKGROUND_AUTHENTICATION;
-
-import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
-import android.annotation.TestApi;
import android.hardware.biometrics.ComponentInfoInternal;
import android.hardware.biometrics.SensorProperties;
@@ -34,8 +30,6 @@ import java.util.List;
* Container for face sensor properties.
* @hide
*/
-@TestApi
-@FlaggedApi(FLAG_FACE_BACKGROUND_AUTHENTICATION)
public class FaceSensorProperties extends SensorProperties {
/**
* @hide
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index 6515312e337c..b98c0cb41ac9 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -39,7 +39,7 @@ import android.view.Surface;
interface IFaceService {
// Creates a test session with the specified sensorId
- @EnforcePermission("TEST_BIOMETRIC")
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
ITestSession createTestSession(int sensorId, ITestSessionCallback callback, String opPackageName);
// Requests a proto dump of the specified sensor
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index 1f5495999416..2816f777e8ab 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -27,6 +27,7 @@ import android.hardware.input.IKeyboardBacklightListener;
import android.hardware.input.IKeyboardBacklightState;
import android.hardware.input.IStickyModifierStateListener;
import android.hardware.input.ITabletModeChangedListener;
+import android.hardware.input.KeyboardLayoutSelectionResult;
import android.hardware.input.TouchCalibration;
import android.os.CombinedVibration;
import android.hardware.input.IInputSensorEventListener;
@@ -120,8 +121,9 @@ interface IInputManager {
String keyboardLayoutDescriptor);
// New Keyboard layout config APIs
- String getKeyboardLayoutForInputDevice(in InputDeviceIdentifier identifier, int userId,
- in InputMethodInfo imeInfo, in InputMethodSubtype imeSubtype);
+ KeyboardLayoutSelectionResult getKeyboardLayoutForInputDevice(
+ in InputDeviceIdentifier identifier, int userId, in InputMethodInfo imeInfo,
+ in InputMethodSubtype imeSubtype);
@EnforcePermission("SET_KEYBOARD_LAYOUT")
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 744dfae97108..a1242fb43bbd 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -784,10 +784,10 @@ public final class InputManager {
*
* @hide
*/
- @Nullable
- public String getKeyboardLayoutForInputDevice(@NonNull InputDeviceIdentifier identifier,
- @UserIdInt int userId, @NonNull InputMethodInfo imeInfo,
- @Nullable InputMethodSubtype imeSubtype) {
+ @NonNull
+ public KeyboardLayoutSelectionResult getKeyboardLayoutForInputDevice(
+ @NonNull InputDeviceIdentifier identifier, @UserIdInt int userId,
+ @NonNull InputMethodInfo imeInfo, @Nullable InputMethodSubtype imeSubtype) {
try {
return mIm.getKeyboardLayoutForInputDevice(identifier, userId, imeInfo, imeSubtype);
} catch (RemoteException ex) {
diff --git a/core/java/android/hardware/input/KeyboardLayoutSelectionResult.aidl b/core/java/android/hardware/input/KeyboardLayoutSelectionResult.aidl
new file mode 100644
index 000000000000..13be2ff5ffb7
--- /dev/null
+++ b/core/java/android/hardware/input/KeyboardLayoutSelectionResult.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input;
+
+parcelable KeyboardLayoutSelectionResult;
diff --git a/core/java/android/hardware/input/KeyboardLayoutSelectionResult.java b/core/java/android/hardware/input/KeyboardLayoutSelectionResult.java
new file mode 100644
index 000000000000..5a1c9478f629
--- /dev/null
+++ b/core/java/android/hardware/input/KeyboardLayoutSelectionResult.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcelable;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodSubtype;
+
+import com.android.internal.util.DataClass;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Provides information about the selected layout and the selection criteria when the caller calls
+ * {@link InputManager#getKeyboardLayoutForInputDevice(InputDeviceIdentifier, int, InputMethodInfo,
+ * InputMethodSubtype)}
+ *
+ * @hide
+ */
+
+@DataClass(genParcelable = true, genToString = true, genEqualsHashCode = true)
+public final class KeyboardLayoutSelectionResult implements Parcelable {
+ @Nullable
+ private final String mLayoutDescriptor;
+
+ /** Unspecified layout selection criteria */
+ public static final int LAYOUT_SELECTION_CRITERIA_UNSPECIFIED = 0;
+
+ /** Manual selection by user */
+ public static final int LAYOUT_SELECTION_CRITERIA_USER = 1;
+
+ /** Auto-detection based on device provided language tag and layout type */
+ public static final int LAYOUT_SELECTION_CRITERIA_DEVICE = 2;
+
+ /** Auto-detection based on IME provided language tag and layout type */
+ public static final int LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD = 3;
+
+ /** Default selection */
+ public static final int LAYOUT_SELECTION_CRITERIA_DEFAULT = 4;
+
+ /** Failed layout selection */
+ public static final KeyboardLayoutSelectionResult FAILED = new KeyboardLayoutSelectionResult(
+ null, LAYOUT_SELECTION_CRITERIA_UNSPECIFIED);
+
+ @LayoutSelectionCriteria
+ private final int mSelectionCriteria;
+
+
+
+ // Code below generated by codegen v1.0.23.
+ //
+ // DO NOT MODIFY!
+ // CHECKSTYLE:OFF Generated code
+ //
+ // To regenerate run:
+ // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/hardware/input/KeyboardLayoutSelectionResult.java
+ //
+ // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+ // Settings > Editor > Code Style > Formatter Control
+ //@formatter:off
+
+
+ @IntDef(prefix = "LAYOUT_SELECTION_CRITERIA_", value = {
+ LAYOUT_SELECTION_CRITERIA_UNSPECIFIED,
+ LAYOUT_SELECTION_CRITERIA_USER,
+ LAYOUT_SELECTION_CRITERIA_DEVICE,
+ LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD,
+ LAYOUT_SELECTION_CRITERIA_DEFAULT
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @DataClass.Generated.Member
+ public @interface LayoutSelectionCriteria {}
+
+ @DataClass.Generated.Member
+ public static String layoutSelectionCriteriaToString(@LayoutSelectionCriteria int value) {
+ switch (value) {
+ case LAYOUT_SELECTION_CRITERIA_UNSPECIFIED:
+ return "LAYOUT_SELECTION_CRITERIA_UNSPECIFIED";
+ case LAYOUT_SELECTION_CRITERIA_USER:
+ return "LAYOUT_SELECTION_CRITERIA_USER";
+ case LAYOUT_SELECTION_CRITERIA_DEVICE:
+ return "LAYOUT_SELECTION_CRITERIA_DEVICE";
+ case LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD:
+ return "LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD";
+ case LAYOUT_SELECTION_CRITERIA_DEFAULT:
+ return "LAYOUT_SELECTION_CRITERIA_DEFAULT";
+ default: return Integer.toHexString(value);
+ }
+ }
+
+ @DataClass.Generated.Member
+ public KeyboardLayoutSelectionResult(
+ @Nullable String layoutDescriptor,
+ @LayoutSelectionCriteria int selectionCriteria) {
+ this.mLayoutDescriptor = layoutDescriptor;
+ this.mSelectionCriteria = selectionCriteria;
+
+ if (!(mSelectionCriteria == LAYOUT_SELECTION_CRITERIA_UNSPECIFIED)
+ && !(mSelectionCriteria == LAYOUT_SELECTION_CRITERIA_USER)
+ && !(mSelectionCriteria == LAYOUT_SELECTION_CRITERIA_DEVICE)
+ && !(mSelectionCriteria == LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD)
+ && !(mSelectionCriteria == LAYOUT_SELECTION_CRITERIA_DEFAULT)) {
+ throw new java.lang.IllegalArgumentException(
+ "selectionCriteria was " + mSelectionCriteria + " but must be one of: "
+ + "LAYOUT_SELECTION_CRITERIA_UNSPECIFIED(" + LAYOUT_SELECTION_CRITERIA_UNSPECIFIED + "), "
+ + "LAYOUT_SELECTION_CRITERIA_USER(" + LAYOUT_SELECTION_CRITERIA_USER + "), "
+ + "LAYOUT_SELECTION_CRITERIA_DEVICE(" + LAYOUT_SELECTION_CRITERIA_DEVICE + "), "
+ + "LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD(" + LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD + "), "
+ + "LAYOUT_SELECTION_CRITERIA_DEFAULT(" + LAYOUT_SELECTION_CRITERIA_DEFAULT + ")");
+ }
+
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ @DataClass.Generated.Member
+ public @Nullable String getLayoutDescriptor() {
+ return mLayoutDescriptor;
+ }
+
+ @DataClass.Generated.Member
+ public @LayoutSelectionCriteria int getSelectionCriteria() {
+ return mSelectionCriteria;
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public String toString() {
+ // You can override field toString logic by defining methods like:
+ // String fieldNameToString() { ... }
+
+ return "KeyboardLayoutSelectionResult { " +
+ "layoutDescriptor = " + mLayoutDescriptor + ", " +
+ "selectionCriteria = " + layoutSelectionCriteriaToString(mSelectionCriteria) +
+ " }";
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public boolean equals(@Nullable Object o) {
+ // You can override field equality logic by defining either of the methods like:
+ // boolean fieldNameEquals(KeyboardLayoutSelectionResult other) { ... }
+ // boolean fieldNameEquals(FieldType otherValue) { ... }
+
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ @SuppressWarnings("unchecked")
+ KeyboardLayoutSelectionResult that = (KeyboardLayoutSelectionResult) o;
+ //noinspection PointlessBooleanExpression
+ return true
+ && java.util.Objects.equals(mLayoutDescriptor, that.mLayoutDescriptor)
+ && mSelectionCriteria == that.mSelectionCriteria;
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public int hashCode() {
+ // You can override field hashCode logic by defining methods like:
+ // int fieldNameHashCode() { ... }
+
+ int _hash = 1;
+ _hash = 31 * _hash + java.util.Objects.hashCode(mLayoutDescriptor);
+ _hash = 31 * _hash + mSelectionCriteria;
+ return _hash;
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
+ // You can override field parcelling by defining methods like:
+ // void parcelFieldName(Parcel dest, int flags) { ... }
+
+ byte flg = 0;
+ if (mLayoutDescriptor != null) flg |= 0x1;
+ dest.writeByte(flg);
+ if (mLayoutDescriptor != null) dest.writeString(mLayoutDescriptor);
+ dest.writeInt(mSelectionCriteria);
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public int describeContents() { return 0; }
+
+ /** @hide */
+ @SuppressWarnings({"unchecked", "RedundantCast"})
+ @DataClass.Generated.Member
+ /* package-private */ KeyboardLayoutSelectionResult(@NonNull android.os.Parcel in) {
+ // You can override field unparcelling by defining methods like:
+ // static FieldType unparcelFieldName(Parcel in) { ... }
+
+ byte flg = in.readByte();
+ String layoutDescriptor = (flg & 0x1) == 0 ? null : in.readString();
+ int selectionCriteria = in.readInt();
+
+ this.mLayoutDescriptor = layoutDescriptor;
+ this.mSelectionCriteria = selectionCriteria;
+
+ if (!(mSelectionCriteria == LAYOUT_SELECTION_CRITERIA_UNSPECIFIED)
+ && !(mSelectionCriteria == LAYOUT_SELECTION_CRITERIA_USER)
+ && !(mSelectionCriteria == LAYOUT_SELECTION_CRITERIA_DEVICE)
+ && !(mSelectionCriteria == LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD)
+ && !(mSelectionCriteria == LAYOUT_SELECTION_CRITERIA_DEFAULT)) {
+ throw new java.lang.IllegalArgumentException(
+ "selectionCriteria was " + mSelectionCriteria + " but must be one of: "
+ + "LAYOUT_SELECTION_CRITERIA_UNSPECIFIED(" + LAYOUT_SELECTION_CRITERIA_UNSPECIFIED + "), "
+ + "LAYOUT_SELECTION_CRITERIA_USER(" + LAYOUT_SELECTION_CRITERIA_USER + "), "
+ + "LAYOUT_SELECTION_CRITERIA_DEVICE(" + LAYOUT_SELECTION_CRITERIA_DEVICE + "), "
+ + "LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD(" + LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD + "), "
+ + "LAYOUT_SELECTION_CRITERIA_DEFAULT(" + LAYOUT_SELECTION_CRITERIA_DEFAULT + ")");
+ }
+
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ @DataClass.Generated.Member
+ public static final @NonNull Parcelable.Creator<KeyboardLayoutSelectionResult> CREATOR
+ = new Parcelable.Creator<KeyboardLayoutSelectionResult>() {
+ @Override
+ public KeyboardLayoutSelectionResult[] newArray(int size) {
+ return new KeyboardLayoutSelectionResult[size];
+ }
+
+ @Override
+ public KeyboardLayoutSelectionResult createFromParcel(@NonNull android.os.Parcel in) {
+ return new KeyboardLayoutSelectionResult(in);
+ }
+ };
+
+ @DataClass.Generated(
+ time = 1709568115865L,
+ codegenVersion = "1.0.23",
+ sourceFile = "frameworks/base/core/java/android/hardware/input/KeyboardLayoutSelectionResult.java",
+ inputSignatures = "private final @android.annotation.Nullable java.lang.String mLayoutDescriptor\npublic static final int LAYOUT_SELECTION_CRITERIA_UNSPECIFIED\npublic static final int LAYOUT_SELECTION_CRITERIA_USER\npublic static final int LAYOUT_SELECTION_CRITERIA_DEVICE\npublic static final int LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD\npublic static final int LAYOUT_SELECTION_CRITERIA_DEFAULT\npublic static final android.hardware.input.KeyboardLayoutSelectionResult FAILED\nprivate final @android.hardware.input.KeyboardLayoutSelectionResult.LayoutSelectionCriteria int mSelectionCriteria\nclass KeyboardLayoutSelectionResult extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genToString=true, genEqualsHashCode=true)")
+ @Deprecated
+ private void __metadata() {}
+
+
+ //@formatter:on
+ // End of generated code
+
+}
diff --git a/core/java/android/os/BatteryConsumer.java b/core/java/android/os/BatteryConsumer.java
index 05a1abeaf479..b41753413baf 100644
--- a/core/java/android/os/BatteryConsumer.java
+++ b/core/java/android/os/BatteryConsumer.java
@@ -240,7 +240,7 @@ public abstract class BatteryConsumer {
new Dimensions(POWER_COMPONENT_ANY, PROCESS_STATE_ANY);
/**
- * Identifies power attribution dimensions that are captured by an data element of
+ * Identifies power attribution dimensions that are captured by a data element of
* a BatteryConsumer. These Keys are used to access those values and to set them using
* Builders. See for example {@link #getConsumedPower(Key)}.
*
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index e09094203ad4..c611cb972b2c 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -1587,7 +1587,7 @@ public abstract class BatteryStats {
outNumOfInterest[0] = numOfInterest;
}
- // The estimated time is the average time we spend in each level, multipled
+ // The estimated time is the average time we spend in each level, multiplied
// by 100 -- the total number of battery levels
return (total / numOfInterest) * 100;
}
@@ -2019,7 +2019,7 @@ public abstract class BatteryStats {
public static final int EVENT_TOP = 0x0003;
// Event is about active sync operations.
public static final int EVENT_SYNC = 0x0004;
- // Events for all additional wake locks aquired/release within a wake block.
+ // Events for all additional wake locks acquired/release within a wake block.
// These are not generated by default.
public static final int EVENT_WAKE_LOCK = 0x0005;
// Event is about an application executing a scheduled job.
@@ -3419,7 +3419,7 @@ public abstract class BatteryStats {
* incoming service calls from apps. The result is returned as an array of longs,
* organized as a sequence like this:
* <pre>
- * cluster1-speeed1, cluster1-speed2, ..., cluster2-speed1, cluster2-speed2, ...
+ * cluster1-speed1, cluster1-speed2, ..., cluster2-speed1, cluster2-speed2, ...
* </pre>
*
* @see com.android.internal.os.CpuScalingPolicies#getPolicies
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index 3149de4c39e7..beb9a935a6ee 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -120,7 +120,6 @@ public class GraphicsEnvironment {
private ClassLoader mClassLoader;
private String mLibrarySearchPaths;
private String mLibraryPermittedPaths;
- private GameManager mGameManager;
private int mAngleOptInIndex = -1;
private boolean mShouldUseAngle = false;
@@ -134,8 +133,6 @@ public class GraphicsEnvironment {
final ApplicationInfo appInfoWithMetaData =
getAppInfoWithMetadata(context, pm, packageName);
- mGameManager = context.getSystemService(GameManager.class);
-
Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "setupGpuLayers");
setupGpuLayers(context, coreSettings, pm, packageName, appInfoWithMetaData);
Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
@@ -161,9 +158,11 @@ public class GraphicsEnvironment {
Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "notifyGraphicsEnvironmentSetup");
- if (mGameManager != null
- && appInfoWithMetaData.category == ApplicationInfo.CATEGORY_GAME) {
- mGameManager.notifyGraphicsEnvironmentSetup();
+ if (appInfoWithMetaData.category == ApplicationInfo.CATEGORY_GAME) {
+ final GameManager gameManager = context.getSystemService(GameManager.class);
+ if (gameManager != null) {
+ gameManager.notifyGraphicsEnvironmentSetup();
+ }
}
Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
}
diff --git a/core/java/android/os/HwParcel.java b/core/java/android/os/HwParcel.java
index 9fd37d4548ac..fb500a96c737 100644
--- a/core/java/android/os/HwParcel.java
+++ b/core/java/android/os/HwParcel.java
@@ -618,7 +618,7 @@ public class HwParcel {
*/
@FastNative
@NonNull
- public native final @Nullable
+ public native final
HidlMemory readEmbeddedHidlMemory(long fieldHandle, long parentHandle, long offset);
/**
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index ccb534eb1019..9757a1096a30 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -4708,6 +4708,9 @@ public class UserManager {
* Sets the user as enabled, if such an user exists.
*
* <p>Note that the default is true, it's only that managed profiles might not be enabled.
+ * (Managed profiles created by DevicePolicyManager will start out disabled, and DPM will later
+ * toggle them to enabled once they are provisioned. This is the primary purpose of the
+ * {@link UserInfo#FLAG_DISABLED} flag.)
* Also ephemeral users can be disabled to indicate that their removal is in progress and they
* shouldn't be re-entered. Therefore ephemeral users should not be re-enabled once disabled.
*
@@ -5259,7 +5262,7 @@ public class UserManager {
/**
* Returns list of the profiles of userId including userId itself.
- * Note that this returns only enabled.
+ * Note that this returns only {@link UserInfo#isEnabled() enabled} profiles.
* <p>Note that this includes all profile types (not including Restricted profiles).
*
* <p>Requires {@link android.Manifest.permission#MANAGE_USERS} or
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index abfa4e3dd8dc..d9400accb4bd 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -1,4 +1,5 @@
package: "android.os"
+container: "system"
flag {
name: "android_os_build_vanilla_ice_cream"
@@ -40,6 +41,7 @@ flag {
namespace: "profile_experiences"
description: "Guards a new Private Profile type in UserManager - everything from its setup to config to deletion."
bug: "299069460"
+ is_exported: true
}
flag {
diff --git a/core/java/android/os/health/HealthStatsWriter.java b/core/java/android/os/health/HealthStatsWriter.java
index d4d10b056c5c..4118775af28a 100644
--- a/core/java/android/os/health/HealthStatsWriter.java
+++ b/core/java/android/os/health/HealthStatsWriter.java
@@ -58,7 +58,7 @@ public class HealthStatsWriter {
* Construct a HealthStatsWriter object with the given constants.
*
* The "getDataType()" of the resulting HealthStats object will be the
- * short name of the java class that the Constants object was initalized
+ * short name of the java class that the Constants object was initialized
* with.
*/
public HealthStatsWriter(HealthKeys.Constants constants) {
diff --git a/core/java/android/os/image/DynamicSystemClient.java b/core/java/android/os/image/DynamicSystemClient.java
index 88096ab91261..ada708bda34c 100644
--- a/core/java/android/os/image/DynamicSystemClient.java
+++ b/core/java/android/os/image/DynamicSystemClient.java
@@ -52,7 +52,7 @@ import java.util.concurrent.Executor;
*
* After the installation is completed, the device will be running in the new system on next the
* reboot. Then, when the user reboots the device again, it will leave {@code DynamicSystem} and go
- * back to the original system. While running in {@code DynamicSystem}, persitent storage for
+ * back to the original system. While running in {@code DynamicSystem}, persistent storage for
* factory reset protection (FRP) remains unchanged. Since the user is running the new system with
* a temporarily created data partition, their original user data are kept unchanged.</p>
*
diff --git a/core/java/android/os/image/DynamicSystemManager.java b/core/java/android/os/image/DynamicSystemManager.java
index 536795bafb1c..8ce87e97da9c 100644
--- a/core/java/android/os/image/DynamicSystemManager.java
+++ b/core/java/android/os/image/DynamicSystemManager.java
@@ -172,7 +172,7 @@ public class DynamicSystemManager {
}
}
/**
- * Finish a previously started installation. Installations without a cooresponding
+ * Finish a previously started installation. Installations without a corresponding
* finishInstallation() will be cleaned up during device boot.
*/
@RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 5a095410bef6..d45a17f7194e 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -1395,7 +1395,7 @@ public class StorageManager {
// Package name can be null if the activity thread is running but the app
// hasn't bound yet. In this case we fall back to the first package in the
// current UID. This works for runtime permissions as permission state is
- // per UID and permission realted app ops are updated for all UID packages.
+ // per UID and permission related app ops are updated for all UID packages.
String[] packageNames = ActivityThread.getPackageManager().getPackagesForUid(
android.os.Process.myUid());
if (packageNames == null || packageNames.length <= 0) {
diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java
index e1f112af41e7..4cf2fd4dce69 100644
--- a/core/java/android/os/storage/StorageVolume.java
+++ b/core/java/android/os/storage/StorageVolume.java
@@ -62,7 +62,7 @@ import java.util.UUID;
* <li>To get access to standard directories (like the {@link Environment#DIRECTORY_PICTURES}), they
* can use the {@link #createAccessIntent(String)}. This is the recommend way, since it provides a
* simpler API and narrows the access to the given directory (and its descendants).
- * <li>To get access to any directory (and its descendants), they can use the Storage Acess
+ * <li>To get access to any directory (and its descendants), they can use the Storage Access
* Framework APIs (such as {@link Intent#ACTION_OPEN_DOCUMENT} and
* {@link Intent#ACTION_OPEN_DOCUMENT_TREE}, although these APIs do not guarantee the user will
* select this specific volume.
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index fa9f03da6372..410f51045b9d 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -1788,6 +1788,9 @@ public final class PermissionManager {
/**
* Gets the permission states for requested package and persistent device.
+ * <p>
+ * <strong>Note: </strong>Default device permissions are not inherited in this API. Returns the
+ * exact permission states for the requested device.
*
* @param packageName name of the package you are checking against
* @param persistentDeviceId id of the persistent device you are checking against
@@ -2073,5 +2076,29 @@ public final class PermissionManager {
return new PermissionState[size];
}
};
+
+ /** @hide */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ PermissionState that = (PermissionState) o;
+ return mGranted == that.mGranted && mFlags == that.mFlags;
+ }
+
+ /** @hide */
+ @Override
+ public int hashCode() {
+ return Objects.hash(mGranted, mFlags);
+ }
+
+ /** @hide */
+ @Override
+ public String toString() {
+ return "PermissionState{"
+ + "mGranted=" + mGranted
+ + ", mFlags=" + mFlags
+ + '}';
+ }
}
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 51585af10f5d..eea6464c9047 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -11576,6 +11576,15 @@ public final class Settings {
"extra_low_power_warning_acknowledged";
/**
+ * Whether the emergency thermal alert would be disabled
+ * (0: default) or not (1).
+ *
+ * @hide
+ */
+ public static final String EMERGENCY_THERMAL_ALERT_DISABLED =
+ "emergency_thermal_alert_disabled";
+
+ /**
* 0 (default) Auto battery saver suggestion has not been suppressed. 1) it has been
* suppressed.
* @hide
diff --git a/services/core/java/com/android/server/notification/ZenAdapters.java b/core/java/android/service/notification/ZenAdapters.java
index 37b263c3e3bd..b249815ce8db 100644
--- a/services/core/java/com/android/server/notification/ZenAdapters.java
+++ b/core/java/android/service/notification/ZenAdapters.java
@@ -14,25 +14,28 @@
* limitations under the License.
*/
-package com.android.server.notification;
+package android.service.notification;
+import android.annotation.NonNull;
import android.app.Flags;
import android.app.NotificationManager.Policy;
-import android.service.notification.ZenModeConfig;
-import android.service.notification.ZenPolicy;
/**
* Converters between different Zen representations.
+ * @hide
*/
-class ZenAdapters {
+public class ZenAdapters {
- static ZenPolicy notificationPolicyToZenPolicy(Policy policy) {
+ /** Maps {@link Policy} to {@link ZenPolicy}. */
+ @NonNull
+ public static ZenPolicy notificationPolicyToZenPolicy(@NonNull Policy policy) {
ZenPolicy.Builder zenPolicyBuilder = new ZenPolicy.Builder()
.allowAlarms(policy.allowAlarms())
.allowCalls(
policy.allowCalls()
- ? ZenModeConfig.getZenPolicySenders(policy.allowCallsFrom())
- : ZenPolicy.PEOPLE_TYPE_NONE)
+ ? notificationPolicySendersToZenPolicyPeopleType(
+ policy.allowCallsFrom())
+ : ZenPolicy.PEOPLE_TYPE_NONE)
.allowConversations(
policy.allowConversations()
? notificationPolicyConversationSendersToZenPolicy(
@@ -42,7 +45,8 @@ class ZenAdapters {
.allowMedia(policy.allowMedia())
.allowMessages(
policy.allowMessages()
- ? ZenModeConfig.getZenPolicySenders(policy.allowMessagesFrom())
+ ? notificationPolicySendersToZenPolicyPeopleType(
+ policy.allowMessagesFrom())
: ZenPolicy.PEOPLE_TYPE_NONE)
.allowReminders(policy.allowReminders())
.allowRepeatCallers(policy.allowRepeatCallers())
@@ -65,9 +69,58 @@ class ZenAdapters {
return zenPolicyBuilder.build();
}
+ /** Maps {@link ZenPolicy.PeopleType} enum to {@link Policy.PrioritySenders}. */
+ @Policy.PrioritySenders
+ public static int zenPolicyPeopleTypeToNotificationPolicySenders(
+ @ZenPolicy.PeopleType int zpPeopleType, @Policy.PrioritySenders int defaultResult) {
+ switch (zpPeopleType) {
+ case ZenPolicy.PEOPLE_TYPE_ANYONE:
+ return Policy.PRIORITY_SENDERS_ANY;
+ case ZenPolicy.PEOPLE_TYPE_CONTACTS:
+ return Policy.PRIORITY_SENDERS_CONTACTS;
+ case ZenPolicy.PEOPLE_TYPE_STARRED:
+ return Policy.PRIORITY_SENDERS_STARRED;
+ default:
+ return defaultResult;
+ }
+ }
+
+ /** Maps {@link Policy.PrioritySenders} enum to {@link ZenPolicy.PeopleType}. */
+ @ZenPolicy.PeopleType
+ public static int notificationPolicySendersToZenPolicyPeopleType(
+ @Policy.PrioritySenders int npPrioritySenders) {
+ switch (npPrioritySenders) {
+ case Policy.PRIORITY_SENDERS_ANY:
+ return ZenPolicy.PEOPLE_TYPE_ANYONE;
+ case Policy.PRIORITY_SENDERS_CONTACTS:
+ return ZenPolicy.PEOPLE_TYPE_CONTACTS;
+ case Policy.PRIORITY_SENDERS_STARRED:
+ default:
+ return ZenPolicy.PEOPLE_TYPE_STARRED;
+ }
+ }
+
+ /** Maps {@link ZenPolicy.ConversationSenders} enum to {@link Policy.ConversationSenders}. */
+ @Policy.ConversationSenders
+ public static int zenPolicyConversationSendersToNotificationPolicy(
+ @ZenPolicy.ConversationSenders int zpConversationSenders,
+ @Policy.ConversationSenders int defaultResult) {
+ switch (zpConversationSenders) {
+ case ZenPolicy.CONVERSATION_SENDERS_ANYONE:
+ return Policy.CONVERSATION_SENDERS_ANYONE;
+ case ZenPolicy.CONVERSATION_SENDERS_IMPORTANT:
+ return Policy.CONVERSATION_SENDERS_IMPORTANT;
+ case ZenPolicy.CONVERSATION_SENDERS_NONE:
+ return Policy.CONVERSATION_SENDERS_NONE;
+ default:
+ return defaultResult;
+ }
+ }
+
+ /** Maps {@link Policy.ConversationSenders} enum to {@link ZenPolicy.ConversationSenders}. */
@ZenPolicy.ConversationSenders
private static int notificationPolicyConversationSendersToZenPolicy(
- int npPriorityConversationSenders) {
+ @Policy.ConversationSenders int npPriorityConversationSenders) {
switch (npPriorityConversationSenders) {
case Policy.CONVERSATION_SENDERS_ANYONE:
return ZenPolicy.CONVERSATION_SENDERS_ANYONE;
@@ -75,8 +128,7 @@ class ZenAdapters {
return ZenPolicy.CONVERSATION_SENDERS_IMPORTANT;
case Policy.CONVERSATION_SENDERS_NONE:
return ZenPolicy.CONVERSATION_SENDERS_NONE;
- case Policy.CONVERSATION_SENDERS_UNSET:
- default:
+ default: // including Policy.CONVERSATION_SENDERS_UNSET
return ZenPolicy.CONVERSATION_SENDERS_UNSET;
}
}
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index d9ca935b35b3..1d6dd1ebd54a 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -24,6 +24,9 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCRE
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF;
+import static android.service.notification.ZenAdapters.notificationPolicySendersToZenPolicyPeopleType;
+import static android.service.notification.ZenAdapters.zenPolicyConversationSendersToNotificationPolicy;
+import static android.service.notification.ZenAdapters.zenPolicyPeopleTypeToNotificationPolicySenders;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
@@ -1269,11 +1272,11 @@ public class ZenModeConfig implements Parcelable {
public ZenPolicy toZenPolicy() {
ZenPolicy.Builder builder = new ZenPolicy.Builder()
.allowCalls(allowCalls
- ? ZenModeConfig.getZenPolicySenders(allowCallsFrom)
+ ? notificationPolicySendersToZenPolicyPeopleType(allowCallsFrom)
: ZenPolicy.PEOPLE_TYPE_NONE)
.allowRepeatCallers(allowRepeatCallers)
.allowMessages(allowMessages
- ? ZenModeConfig.getZenPolicySenders(allowMessagesFrom)
+ ? notificationPolicySendersToZenPolicyPeopleType(allowMessagesFrom)
: ZenPolicy.PEOPLE_TYPE_NONE)
.allowReminders(allowReminders)
.allowEvents(allowEvents)
@@ -1333,14 +1336,14 @@ public class ZenModeConfig implements Parcelable {
if (zenPolicy.isCategoryAllowed(ZenPolicy.PRIORITY_CATEGORY_MESSAGES,
isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_MESSAGES, defaultPolicy))) {
priorityCategories |= Policy.PRIORITY_CATEGORY_MESSAGES;
- messageSenders = getNotificationPolicySenders(zenPolicy.getPriorityMessageSenders(),
- messageSenders);
+ messageSenders = zenPolicyPeopleTypeToNotificationPolicySenders(
+ zenPolicy.getPriorityMessageSenders(), messageSenders);
}
if (zenPolicy.isCategoryAllowed(ZenPolicy.PRIORITY_CATEGORY_CONVERSATIONS,
isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_CONVERSATIONS, defaultPolicy))) {
priorityCategories |= Policy.PRIORITY_CATEGORY_CONVERSATIONS;
- conversationSenders = getConversationSendersWithDefault(
+ conversationSenders = zenPolicyConversationSendersToNotificationPolicy(
zenPolicy.getPriorityConversationSenders(), conversationSenders);
} else {
conversationSenders = CONVERSATION_SENDERS_NONE;
@@ -1349,8 +1352,8 @@ public class ZenModeConfig implements Parcelable {
if (zenPolicy.isCategoryAllowed(ZenPolicy.PRIORITY_CATEGORY_CALLS,
isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_CALLS, defaultPolicy))) {
priorityCategories |= Policy.PRIORITY_CATEGORY_CALLS;
- callSenders = getNotificationPolicySenders(zenPolicy.getPriorityCallSenders(),
- callSenders);
+ callSenders = zenPolicyPeopleTypeToNotificationPolicySenders(
+ zenPolicy.getPriorityCallSenders(), callSenders);
}
if (zenPolicy.isCategoryAllowed(ZenPolicy.PRIORITY_CATEGORY_REPEAT_CALLERS,
@@ -1449,47 +1452,6 @@ public class ZenModeConfig implements Parcelable {
return (policy.suppressedVisualEffects & visualEffect) == 0;
}
- private static int getNotificationPolicySenders(@ZenPolicy.PeopleType int senders,
- int defaultPolicySender) {
- switch (senders) {
- case ZenPolicy.PEOPLE_TYPE_ANYONE:
- return Policy.PRIORITY_SENDERS_ANY;
- case ZenPolicy.PEOPLE_TYPE_CONTACTS:
- return Policy.PRIORITY_SENDERS_CONTACTS;
- case ZenPolicy.PEOPLE_TYPE_STARRED:
- return Policy.PRIORITY_SENDERS_STARRED;
- default:
- return defaultPolicySender;
- }
- }
-
- private static int getConversationSendersWithDefault(@ZenPolicy.ConversationSenders int senders,
- int defaultPolicySender) {
- switch (senders) {
- case ZenPolicy.CONVERSATION_SENDERS_ANYONE:
- case ZenPolicy.CONVERSATION_SENDERS_IMPORTANT:
- case ZenPolicy.CONVERSATION_SENDERS_NONE:
- return senders;
- default:
- return defaultPolicySender;
- }
- }
-
- /**
- * Maps NotificationManager.Policy senders type to ZenPolicy.PeopleType
- */
- public static @ZenPolicy.PeopleType int getZenPolicySenders(int senders) {
- switch (senders) {
- case Policy.PRIORITY_SENDERS_ANY:
- return ZenPolicy.PEOPLE_TYPE_ANYONE;
- case Policy.PRIORITY_SENDERS_CONTACTS:
- return ZenPolicy.PEOPLE_TYPE_CONTACTS;
- case Policy.PRIORITY_SENDERS_STARRED:
- default:
- return ZenPolicy.PEOPLE_TYPE_STARRED;
- }
- }
-
public Policy toNotificationPolicy() {
int priorityCategories = 0;
int priorityCallSenders = Policy.PRIORITY_SENDERS_CONTACTS;
@@ -1524,7 +1486,7 @@ public class ZenModeConfig implements Parcelable {
}
priorityCallSenders = sourceToPrioritySenders(allowCallsFrom, priorityCallSenders);
priorityMessageSenders = sourceToPrioritySenders(allowMessagesFrom, priorityMessageSenders);
- priorityConversationSenders = getConversationSendersWithDefault(
+ priorityConversationSenders = zenPolicyConversationSendersToNotificationPolicy(
allowConversationsFrom, priorityConversationSenders);
int state = areChannelsBypassingDnd ? Policy.STATE_CHANNELS_BYPASSING_DND : 0;
@@ -1559,15 +1521,6 @@ public class ZenModeConfig implements Parcelable {
}
}
- private static int prioritySendersToSource(int prioritySenders, int def) {
- switch (prioritySenders) {
- case Policy.PRIORITY_SENDERS_CONTACTS: return SOURCE_CONTACT;
- case Policy.PRIORITY_SENDERS_STARRED: return SOURCE_STAR;
- case Policy.PRIORITY_SENDERS_ANY: return SOURCE_ANYONE;
- default: return def;
- }
- }
-
private static int normalizePrioritySenders(int prioritySenders, int def) {
if (!(prioritySenders == Policy.PRIORITY_SENDERS_CONTACTS
|| prioritySenders == Policy.PRIORITY_SENDERS_STARRED
diff --git a/core/java/android/service/ondeviceintelligence/IOnDeviceIntelligenceService.aidl b/core/java/android/service/ondeviceintelligence/IOnDeviceIntelligenceService.aidl
index bbb4bc6c0272..e44c69c4df28 100644
--- a/core/java/android/service/ondeviceintelligence/IOnDeviceIntelligenceService.aidl
+++ b/core/java/android/service/ondeviceintelligence/IOnDeviceIntelligenceService.aidl
@@ -26,6 +26,7 @@ import android.app.ondeviceintelligence.IFeatureCallback;
import android.app.ondeviceintelligence.IListFeaturesCallback;
import android.app.ondeviceintelligence.IFeatureDetailsCallback;
import com.android.internal.infra.AndroidFuture;
+import android.service.ondeviceintelligence.IRemoteProcessingService;
/**
@@ -41,4 +42,5 @@ oneway interface IOnDeviceIntelligenceService {
void getReadOnlyFileDescriptor(in String fileName, in AndroidFuture<ParcelFileDescriptor> future);
void getReadOnlyFeatureFileDescriptorMap(in Feature feature, in RemoteCallback remoteCallback);
void requestFeatureDownload(in Feature feature, in ICancellationSignal cancellationSignal, in IDownloadCallback downloadCallback);
+ void registerRemoteServices(in IRemoteProcessingService remoteProcessingService);
} \ No newline at end of file
diff --git a/core/java/android/service/ondeviceintelligence/IOnDeviceTrustedInferenceService.aidl b/core/java/android/service/ondeviceintelligence/IOnDeviceTrustedInferenceService.aidl
index 08eb9278fcc4..e3fda04e6592 100644
--- a/core/java/android/service/ondeviceintelligence/IOnDeviceTrustedInferenceService.aidl
+++ b/core/java/android/service/ondeviceintelligence/IOnDeviceTrustedInferenceService.aidl
@@ -23,8 +23,10 @@ import android.app.ondeviceintelligence.IProcessingSignal;
import android.app.ondeviceintelligence.Content;
import android.app.ondeviceintelligence.Feature;
import android.os.ICancellationSignal;
+import android.os.PersistableBundle;
+import android.os.Bundle;
import android.service.ondeviceintelligence.IRemoteStorageService;
-
+import android.service.ondeviceintelligence.IProcessingUpdateStatusCallback;
/**
* Interface for a concrete implementation to provide on device trusted inference.
@@ -41,4 +43,6 @@ oneway interface IOnDeviceTrustedInferenceService {
void processRequestStreaming(in Feature feature, in Content request, in int requestType,
in ICancellationSignal cancellationSignal, in IProcessingSignal processingSignal,
in IStreamingResponseCallback callback);
+ void updateProcessingState(in Bundle processingState,
+ in IProcessingUpdateStatusCallback callback);
} \ No newline at end of file
diff --git a/core/java/android/service/ondeviceintelligence/IProcessingUpdateStatusCallback.aidl b/core/java/android/service/ondeviceintelligence/IProcessingUpdateStatusCallback.aidl
new file mode 100644
index 000000000000..7ead8690abb4
--- /dev/null
+++ b/core/java/android/service/ondeviceintelligence/IProcessingUpdateStatusCallback.aidl
@@ -0,0 +1,14 @@
+package android.service.ondeviceintelligence;
+
+import android.os.PersistableBundle;
+
+/**
+ * Interface for receiving status from a updateProcessingState call from on-device intelligence
+ * service.
+ *
+ * @hide
+ */
+interface IProcessingUpdateStatusCallback {
+ void onSuccess(in PersistableBundle statusParams) = 1;
+ void onFailure(int errorCode, in String errorMessage) = 2;
+}
diff --git a/core/java/android/service/ondeviceintelligence/IRemoteProcessingService.aidl b/core/java/android/service/ondeviceintelligence/IRemoteProcessingService.aidl
new file mode 100644
index 000000000000..32a8a6a70406
--- /dev/null
+++ b/core/java/android/service/ondeviceintelligence/IRemoteProcessingService.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.ondeviceintelligence;
+
+import android.os.Bundle;
+import android.service.ondeviceintelligence.IProcessingUpdateStatusCallback;
+
+
+/**
+ * Interface for a concrete implementation to provide methods to update state of a remote service.
+ *
+ * @hide
+ */
+oneway interface IRemoteProcessingService {
+ void updateProcessingState(in Bundle processingState,
+ in IProcessingUpdateStatusCallback callback);
+}
diff --git a/core/java/android/service/ondeviceintelligence/OnDeviceIntelligenceService.java b/core/java/android/service/ondeviceintelligence/OnDeviceIntelligenceService.java
index 0cba1d37721a..46ba25d40bec 100644
--- a/core/java/android/service/ondeviceintelligence/OnDeviceIntelligenceService.java
+++ b/core/java/android/service/ondeviceintelligence/OnDeviceIntelligenceService.java
@@ -18,6 +18,7 @@ package android.service.ondeviceintelligence;
import static android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE;
+import android.annotation.CallbackExecutor;
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -47,11 +48,18 @@ import android.util.Slog;
import com.android.internal.infra.AndroidFuture;
+import androidx.annotation.IntDef;
+
import java.io.File;
import java.io.FileNotFoundException;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.LongConsumer;
@@ -64,6 +72,10 @@ import java.util.function.LongConsumer;
* {@code config_defaultOnDeviceIntelligenceService}. If this config has no value, a stub is
* returned.
*
+ * <p> Similar to {@link OnDeviceIntelligenceManager} class, the contracts in this service are
+ * defined to be open-ended in general, to allow interoperability. Therefore, it is recommended
+ * that implementations of this system-service expose this API to the clients via a library which
+ * has more defined contract.</p>
* <pre>
* {@literal
* <service android:name=".SampleOnDeviceIntelligenceService"
@@ -78,6 +90,8 @@ import java.util.function.LongConsumer;
public abstract class OnDeviceIntelligenceService extends Service {
private static final String TAG = OnDeviceIntelligenceService.class.getSimpleName();
+ private volatile IRemoteProcessingService mRemoteProcessingService;
+
/**
* The {@link Intent} that must be declared as handled by the service. To be supported, the
* service must also require the
@@ -88,6 +102,7 @@ public abstract class OnDeviceIntelligenceService extends Service {
public static final String SERVICE_INTERFACE =
"android.service.ondeviceintelligence.OnDeviceIntelligenceService";
+
/**
* @hide
*/
@@ -167,12 +182,58 @@ public abstract class OnDeviceIntelligenceService extends Service {
remoteCallback.sendResult(bundle);
});
}
+
+ @Override
+ public void registerRemoteServices(
+ IRemoteProcessingService remoteProcessingService) {
+ mRemoteProcessingService = remoteProcessingService;
+ }
};
}
Slog.w(TAG, "Incorrect service interface, returning null.");
return null;
}
+ /**
+ * Invoked by the {@link OnDeviceIntelligenceService} inorder to send updates to the inference
+ * service if there is a state change to be performed.
+ *
+ * @param processingState the updated state to be applied.
+ * @param callbackExecutor executor to the run status callback on.
+ * @param statusReceiver receiver to get status of the update state operation.
+ */
+ public final void updateProcessingState(@NonNull Bundle processingState,
+ @NonNull @CallbackExecutor Executor callbackExecutor,
+ @NonNull OutcomeReceiver<PersistableBundle, OnDeviceUpdateProcessingException> statusReceiver) {
+ Objects.requireNonNull(callbackExecutor);
+ if (mRemoteProcessingService == null) {
+ throw new IllegalStateException("Remote processing service is unavailable.");
+ }
+ try {
+ mRemoteProcessingService.updateProcessingState(processingState,
+ new IProcessingUpdateStatusCallback.Stub() {
+ @Override
+ public void onSuccess(PersistableBundle result) {
+ Binder.withCleanCallingIdentity(() -> {
+ callbackExecutor.execute(
+ () -> statusReceiver.onResult(result));
+ });
+ }
+
+ @Override
+ public void onFailure(int errorCode, String errorMessage) {
+ Binder.withCleanCallingIdentity(() -> callbackExecutor.execute(
+ () -> statusReceiver.onError(
+ new OnDeviceUpdateProcessingException(
+ errorCode, errorMessage))));
+ }
+ });
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error in updateProcessingState: " + e);
+ throw new RuntimeException(e);
+ }
+ }
+
private OutcomeReceiver<Feature,
OnDeviceIntelligenceManager.OnDeviceIntelligenceManagerException> wrapFeatureCallback(
IFeatureCallback featureCallback) {
@@ -197,7 +258,6 @@ public abstract class OnDeviceIntelligenceService extends Service {
}
}
};
-
}
private OutcomeReceiver<List<Feature>,
@@ -380,4 +440,60 @@ public abstract class OnDeviceIntelligenceService extends Service {
* @param versionConsumer consumer to populate the version.
*/
public abstract void onGetVersion(@NonNull LongConsumer versionConsumer);
+
+
+ /**
+ * Exception type to be populated when calls to {@link #updateProcessingState} fail.
+ */
+ public static class OnDeviceUpdateProcessingException extends
+ OnDeviceIntelligenceServiceException {
+ /**
+ * The connection to remote service failed and the processing state could not be updated.
+ */
+ public static final int PROCESSING_UPDATE_STATUS_CONNECTION_FAILED = 1;
+
+
+ /**
+ * @hide
+ */
+ @IntDef(value = {
+ PROCESSING_UPDATE_STATUS_CONNECTION_FAILED
+ }, open = true)
+ @Target({ElementType.TYPE_USE, ElementType.METHOD, ElementType.PARAMETER,
+ ElementType.FIELD})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ErrorCode {
+ }
+
+ public OnDeviceUpdateProcessingException(@ErrorCode int errorCode) {
+ super(errorCode);
+ }
+
+ public OnDeviceUpdateProcessingException(@ErrorCode int errorCode,
+ @NonNull String errorMessage) {
+ super(errorCode, errorMessage);
+ }
+ }
+
+ /**
+ * Exception type to be used for surfacing errors to service implementation.
+ */
+ public abstract static class OnDeviceIntelligenceServiceException extends Exception {
+ private final int mErrorCode;
+
+ public OnDeviceIntelligenceServiceException(int errorCode) {
+ this.mErrorCode = errorCode;
+ }
+
+ public OnDeviceIntelligenceServiceException(int errorCode,
+ @NonNull String errorMessage) {
+ super(errorMessage);
+ this.mErrorCode = errorCode;
+ }
+
+ public int getErrorCode() {
+ return mErrorCode;
+ }
+
+ }
}
diff --git a/core/java/android/service/ondeviceintelligence/OnDeviceTrustedInferenceService.java b/core/java/android/service/ondeviceintelligence/OnDeviceTrustedInferenceService.java
index 96982e3d7829..86001975cc09 100644
--- a/core/java/android/service/ondeviceintelligence/OnDeviceTrustedInferenceService.java
+++ b/core/java/android/service/ondeviceintelligence/OnDeviceTrustedInferenceService.java
@@ -36,13 +36,16 @@ import android.app.ondeviceintelligence.ProcessingSignal;
import android.app.ondeviceintelligence.StreamingResponseReceiver;
import android.content.Context;
import android.content.Intent;
+import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.IBinder;
import android.os.ICancellationSignal;
import android.os.OutcomeReceiver;
import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
import android.os.RemoteCallback;
import android.os.RemoteException;
+import android.service.ondeviceintelligence.OnDeviceIntelligenceService.OnDeviceUpdateProcessingException;
import android.util.Log;
import android.util.Slog;
@@ -65,6 +68,11 @@ import java.util.function.Consumer;
* non-streaming fashion. Also, provides a way to register a storage service that will be used to
* read-only access files from the {@link OnDeviceIntelligenceService} counterpart. </p>
*
+ * <p> Similar to {@link OnDeviceIntelligenceManager} class, the contracts in this service are
+ * defined to be open-ended in general, to allow interoperability. Therefore, it is recommended
+ * that implementations of this system-service expose this API to the clients via a library which
+ * has more defined contract.</p>
+ *
* <pre>
* {@literal
* <service android:name=".SampleTrustedInferenceService"
@@ -152,6 +160,17 @@ public abstract class OnDeviceTrustedInferenceService extends Service {
wrapResponseCallback(callback)
);
}
+
+ @Override
+ public void updateProcessingState(Bundle processingState,
+ IProcessingUpdateStatusCallback callback) {
+ Objects.requireNonNull(processingState);
+ Objects.requireNonNull(callback);
+
+ OnDeviceTrustedInferenceService.this.onUpdateProcessingState(processingState,
+ wrapOutcomeReceiver(callback)
+ );
+ }
};
}
Slog.w(TAG, "Incorrect service interface, returning null.");
@@ -233,6 +252,21 @@ public abstract class OnDeviceTrustedInferenceService extends Service {
@NonNull OutcomeReceiver<Content,
OnDeviceIntelligenceManager.OnDeviceIntelligenceManagerProcessingException> callback);
+
+ /**
+ * Invoked when processing environment needs to be updated or refreshed with fresh
+ * configuration, files or state.
+ *
+ * @param processingState contains updated state and params that are to be applied to the
+ * processing environmment,
+ * @param callback callback to populate the update status and if there are params
+ * associated with the status.
+ */
+ public abstract void onUpdateProcessingState(@NonNull Bundle processingState,
+ @NonNull OutcomeReceiver<PersistableBundle,
+ OnDeviceUpdateProcessingException> callback);
+
+
/**
* Overrides {@link Context#openFileInput} to read files with the given file names under the
* internal app storage of the {@link OnDeviceIntelligenceService}, i.e., only files stored in
@@ -407,4 +441,31 @@ public abstract class OnDeviceTrustedInferenceService extends Service {
}
};
}
+
+ @NonNull
+ private static OutcomeReceiver<PersistableBundle, OnDeviceUpdateProcessingException> wrapOutcomeReceiver(
+ IProcessingUpdateStatusCallback callback) {
+ return new OutcomeReceiver<>() {
+ @Override
+ public void onResult(@NonNull PersistableBundle result) {
+ try {
+ callback.onSuccess(result);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error sending result: " + e);
+
+ }
+ }
+
+ @Override
+ public void onError(
+ @androidx.annotation.NonNull OnDeviceUpdateProcessingException error) {
+ try {
+ callback.onFailure(error.getErrorCode(), error.getMessage());
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error sending exception details: " + e);
+ }
+ }
+ };
+ }
+
}
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 20adc5427495..306410c9a98b 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -519,7 +519,7 @@ public class VoiceInteractionService extends Service {
@NonNull String keyphrase, @SuppressLint("UseIcu") @NonNull Locale locale,
@NonNull @CallbackExecutor Executor executor,
@NonNull AlwaysOnHotwordDetector.Callback callback) {
- // TODO(b/269080850): Resolve AndroidFrameworkRequiresPermission lint warning
+ // TODO (b/269080850): Resolve AndroidFrameworkRequiresPermission lint warning
Objects.requireNonNull(keyphrase);
Objects.requireNonNull(locale);
@@ -545,10 +545,6 @@ public class VoiceInteractionService extends Service {
@NonNull SoundTrigger.ModuleProperties moduleProperties,
@NonNull @CallbackExecutor Executor executor,
@NonNull AlwaysOnHotwordDetector.Callback callback) {
- // TODO(b/305787465): Remove the MANAGE_HOTWORD_DETECTION permission enforcement on the
- // {@link #createAlwaysOnHotwordDetectorForTest(String, Locale,
- // SoundTrigger.ModuleProperties, AlwaysOnHotwordDetector.Callback)} and replace with the
- // permission RECEIVE_SANDBOX_TRIGGER_AUDIO when it is fully launched.
Objects.requireNonNull(keyphrase);
Objects.requireNonNull(locale);
@@ -615,11 +611,6 @@ public class VoiceInteractionService extends Service {
@Nullable PersistableBundle options,
@Nullable SharedMemory sharedMemory,
@SuppressLint("MissingNullability") AlwaysOnHotwordDetector.Callback callback) {
- // TODO(b/305787465): Remove the MANAGE_HOTWORD_DETECTION permission enforcement on the
- // {@link #createAlwaysOnHotwordDetector(String, Locale, PersistableBundle, SharedMemory,
- // AlwaysOnHotwordDetector.Callback)} and replace with the permission
- // RECEIVE_SANDBOX_TRIGGER_AUDIO when it is fully launched.
-
return createAlwaysOnHotwordDetectorInternal(keyphrase, locale,
/* supportHotwordDetectionService= */ true, options, sharedMemory,
/* modulProperties */ null, /* executor= */ null, callback);
@@ -671,11 +662,7 @@ public class VoiceInteractionService extends Service {
@Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory,
@NonNull @CallbackExecutor Executor executor,
@NonNull AlwaysOnHotwordDetector.Callback callback) {
- // TODO(b/269080850): Resolve AndroidFrameworkRequiresPermission lint warning
- // TODO(b/305787465): Remove the MANAGE_HOTWORD_DETECTION permission enforcement on the
- // {@link #createAlwaysOnHotwordDetector(String, Locale, PersistableBundle, SharedMemory,
- // Executor, AlwaysOnHotwordDetector.Callback)} and replace with the permission
- // RECEIVE_SANDBOX_TRIGGER_AUDIO when it is fully launched.
+ // TODO (b/269080850): Resolve AndroidFrameworkRequiresPermission lint warning
Objects.requireNonNull(keyphrase);
Objects.requireNonNull(locale);
@@ -702,10 +689,6 @@ public class VoiceInteractionService extends Service {
@NonNull SoundTrigger.ModuleProperties moduleProperties,
@NonNull @CallbackExecutor Executor executor,
@NonNull AlwaysOnHotwordDetector.Callback callback) {
- // TODO(b/305787465): Remove the MANAGE_HOTWORD_DETECTION permission enforcement on the
- // {@link #createAlwaysOnHotwordDetectorForTest(String, Locale, PersistableBundle,
- // SharedMemory, SoundTrigger.ModuleProperties, Executor, AlwaysOnHotwordDetector.Callback)}
- // and replace with the permission RECEIVE_SANDBOX_TRIGGER_AUDIO when it is fully launched.
Objects.requireNonNull(keyphrase);
Objects.requireNonNull(locale);
diff --git a/core/java/android/view/ScrollFeedbackProvider.java b/core/java/android/view/ScrollFeedbackProvider.java
index 8a44d4fa5934..798203fadb4d 100644
--- a/core/java/android/view/ScrollFeedbackProvider.java
+++ b/core/java/android/view/ScrollFeedbackProvider.java
@@ -21,8 +21,11 @@ import android.annotation.NonNull;
import android.view.flags.Flags;
/**
- * Interface to represent an entity giving consistent feedback for different events surrounding view
- * scroll.
+ * Provides feedback to the user for scroll events on a {@link View}. The type of feedback provided
+ * to the user may depend on the {@link InputDevice} that generated the scroll events.
+ *
+ * <p>An example of the type of feedback that this interface may provide is haptic feedback (that
+ * is, tactile feedback that provide the user physical feedback for their scroll).
*
* <p>The interface provides methods for the client to report different scroll events. The client
* should report all scroll events that they want to be considered for scroll feedback using the
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 708751a25053..a7cb1696e668 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1210,6 +1210,9 @@ public final class ViewRootImpl implements ViewParent,
mSensitiveContentProtectionService =
ISensitiveContentProtectionManager.Stub.asInterface(
ServiceManager.getService(Context.SENSITIVE_CONTENT_PROTECTION_SERVICE));
+ if (mSensitiveContentProtectionService == null) {
+ Log.e(TAG, "SensitiveContentProtectionService shouldn't be null");
+ }
} else {
mSensitiveContentProtectionService = null;
}
@@ -4179,6 +4182,9 @@ public final class ViewRootImpl implements ViewParent,
*/
void notifySensitiveContentAppProtection(boolean showSensitiveContent) {
try {
+ if (mSensitiveContentProtectionService == null) {
+ return;
+ }
// The window would be blocked during screen share if it shows sensitive content.
mSensitiveContentProtectionService.setSensitiveContentProtection(
getWindowToken(), mContext.getPackageName(), showSensitiveContent);
diff --git a/core/java/android/view/inputmethod/ImeTracker.java b/core/java/android/view/inputmethod/ImeTracker.java
index 7f796611d217..d992febc375e 100644
--- a/core/java/android/view/inputmethod/ImeTracker.java
+++ b/core/java/android/view/inputmethod/ImeTracker.java
@@ -182,7 +182,6 @@ public interface ImeTracker {
PHASE_CLIENT_ANIMATION_FINISHED_SHOW,
PHASE_CLIENT_ANIMATION_FINISHED_HIDE,
PHASE_WM_ABORT_SHOW_IME_POST_LAYOUT,
- PHASE_CLIENT_ANIMATION_FINISHED_HIDE,
PHASE_IME_SHOW_WINDOW,
PHASE_IME_HIDE_WINDOW,
PHASE_IME_PRIVILEGED_OPERATIONS,
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 0e5747d0e445..fe4ac4e2f0f1 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -1105,6 +1105,7 @@ public class RemoteViews implements Parcelable, Filter {
SetRemoteCollectionItemListAdapterAction(Parcel parcel) {
mViewId = parcel.readInt();
mIntentId = parcel.readInt();
+ mIsReplacedIntoAction = parcel.readBoolean();
mServiceIntent = parcel.readTypedObject(Intent.CREATOR);
mItems = mServiceIntent != null
? null
@@ -1128,6 +1129,7 @@ public class RemoteViews implements Parcelable, Filter {
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mViewId);
dest.writeInt(mIntentId);
+ dest.writeBoolean(mIsReplacedIntoAction);
dest.writeTypedObject(mServiceIntent, flags);
if (mItems != null) {
mItems.writeToParcel(dest, flags, /* attached= */ true);
@@ -1209,6 +1211,19 @@ public class RemoteViews implements Parcelable, Filter {
}
/**
+ * The maximum size for RemoteViews with converted RemoteCollectionItemsAdapter.
+ * When converting RemoteViewsAdapter to RemoteCollectionItemsAdapter, we want to put size
+ * limits on each unique RemoteCollectionItems in order to not exceed the transaction size limit
+ * for each parcel (typically 1 MB). We leave a certain ratio of the maximum size as a buffer
+ * for missing calculations of certain parameters (e.g. writing a RemoteCollectionItems to the
+ * parcel will write its Id array as well, but that is missing when writing itschild RemoteViews
+ * directly to the parcel as we did in RemoteViewsService)
+ *
+ * @hide
+ */
+ private static final int MAX_SINGLE_PARCEL_SIZE = (int) (1_000_000 * 0.8);
+
+ /**
* @hide
*/
public CompletableFuture<Void> collectAllIntents() {
@@ -1260,17 +1275,47 @@ public class RemoteViews implements Parcelable, Filter {
return mUriToCollectionMapping.get(uri);
}
- CompletableFuture<Void> collectAllIntentsNoComplete(@NonNull RemoteViews inViews) {
- CompletableFuture<Void> collectionFuture = CompletableFuture.completedFuture(null);
+ public @NonNull CompletableFuture<Void> collectAllIntentsNoComplete(
+ @NonNull RemoteViews inViews) {
+ SparseArray<Intent> idToIntentMapping = new SparseArray<>();
+ // Collect the number of uinque Intent (which is equal to the number of new connections
+ // to make) for size allocation and exclude certain collections from being written to
+ // the parcel to better estimate the space left for reallocation.
+ collectAllIntentsInternal(inViews, idToIntentMapping);
+
+ // Calculate the individual size here
+ int numOfIntents = idToIntentMapping.size();
+ if (numOfIntents == 0) {
+ Log.e(LOG_TAG, "Possibly notifying updates for nonexistent view Id");
+ return CompletableFuture.completedFuture(null);
+ }
+
+ Parcel sizeTestParcel = Parcel.obtain();
+ // Write self RemoteViews to the parcel, which includes the actions/bitmaps/collection
+ // cache to see how much space is left for the RemoteCollectionItems that are to be
+ // updated.
+ RemoteViews.this.writeToParcel(sizeTestParcel,
+ /* flags= */ 0,
+ /* intentsToIgnore= */ idToIntentMapping);
+ int remainingSize = MAX_SINGLE_PARCEL_SIZE - sizeTestParcel.dataSize();
+ sizeTestParcel.recycle();
+
+ int individualSize = remainingSize < 0
+ ? 0
+ : remainingSize / numOfIntents;
+
+ return connectAllUniqueIntents(individualSize, idToIntentMapping);
+ }
+
+ private void collectAllIntentsInternal(@NonNull RemoteViews inViews,
+ @NonNull SparseArray<Intent> idToIntentMapping) {
if (inViews.hasSizedRemoteViews()) {
for (RemoteViews remoteViews : inViews.mSizedRemoteViews) {
- collectionFuture = CompletableFuture.allOf(collectionFuture,
- collectAllIntentsNoComplete(remoteViews));
+ collectAllIntentsInternal(remoteViews, idToIntentMapping);
}
} else if (inViews.hasLandscapeAndPortraitLayouts()) {
- collectionFuture = CompletableFuture.allOf(
- collectAllIntentsNoComplete(inViews.mLandscape),
- collectAllIntentsNoComplete(inViews.mPortrait));
+ collectAllIntentsInternal(inViews.mLandscape, idToIntentMapping);
+ collectAllIntentsInternal(inViews.mPortrait, idToIntentMapping);
} else if (inViews.mActions != null) {
for (Action action : inViews.mActions) {
if (action instanceof SetRemoteCollectionItemListAdapterAction rca) {
@@ -1280,13 +1325,16 @@ public class RemoteViews implements Parcelable, Filter {
}
if (rca.mIntentId != -1 && rca.mIsReplacedIntoAction) {
- final String uri = mIdToUriMapping.get(rca.mIntentId);
- collectionFuture = CompletableFuture.allOf(collectionFuture,
- getItemsFutureFromIntentWithTimeout(rca.mServiceIntent)
- .thenAccept(rc -> {
- rc.setHierarchyRootData(getHierarchyRootData());
- mUriToCollectionMapping.put(uri, rc);
- }));
+ rca.mIsReplacedIntoAction = false;
+
+ // Avoid redundant connections for the same intent. Also making sure
+ // that the number of connections we are making is always equal to the
+ // nmuber of unique intents that are being used for the updates.
+ if (idToIntentMapping.contains(rca.mIntentId)) {
+ continue;
+ }
+
+ idToIntentMapping.put(rca.mIntentId, rca.mServiceIntent);
rca.mItems = null;
continue;
}
@@ -1295,7 +1343,7 @@ public class RemoteViews implements Parcelable, Filter {
// intents.
if (rca.mServiceIntent != null) {
final String uri = rca.mServiceIntent.toUri(0);
- int index = mIdToUriMapping.indexOfValue(uri);
+ int index = mIdToUriMapping.indexOfValueByValue(uri);
if (index == -1) {
int newIntentId = mIdToUriMapping.size();
rca.mIntentId = newIntentId;
@@ -1305,41 +1353,50 @@ public class RemoteViews implements Parcelable, Filter {
rca.mItems = null;
continue;
}
- collectionFuture = CompletableFuture.allOf(collectionFuture,
- getItemsFutureFromIntentWithTimeout(rca.mServiceIntent)
- .thenAccept(rc -> {
- rc.setHierarchyRootData(getHierarchyRootData());
- mUriToCollectionMapping.put(uri, rc);
- }));
+
+ idToIntentMapping.put(rca.mIntentId, rca.mServiceIntent);
rca.mItems = null;
} else {
for (RemoteViews views : rca.mItems.mViews) {
- collectionFuture = CompletableFuture.allOf(collectionFuture,
- collectAllIntentsNoComplete(views));
+ collectAllIntentsInternal(views, idToIntentMapping);
}
}
} else if (action instanceof ViewGroupActionAdd vgaa
&& vgaa.mNestedViews != null) {
- collectionFuture = CompletableFuture.allOf(collectionFuture,
- collectAllIntentsNoComplete(vgaa.mNestedViews));
+ collectAllIntentsInternal(vgaa.mNestedViews, idToIntentMapping);
}
}
}
+ }
- return collectionFuture;
+ private @NonNull CompletableFuture<Void> connectAllUniqueIntents(int individualSize,
+ @NonNull SparseArray<Intent> idToIntentMapping) {
+ List<CompletableFuture<Void>> intentFutureList = new ArrayList<>();
+ for (int i = 0; i < idToIntentMapping.size(); i++) {
+ String currentIntentUri = mIdToUriMapping.get(idToIntentMapping.keyAt(i));
+ Intent currentIntent = idToIntentMapping.valueAt(i);
+ intentFutureList.add(getItemsFutureFromIntentWithTimeout(currentIntent,
+ individualSize)
+ .thenAccept(items -> {
+ items.setHierarchyRootData(getHierarchyRootData());
+ mUriToCollectionMapping.put(currentIntentUri, items);
+ }));
+ }
+
+ return CompletableFuture.allOf(intentFutureList.toArray(CompletableFuture[]::new));
}
private static CompletableFuture<RemoteCollectionItems> getItemsFutureFromIntentWithTimeout(
- Intent intent) {
+ Intent intent, int individualSize) {
if (intent == null) {
Log.e(LOG_TAG, "Null intent received when generating adapter future");
return CompletableFuture.completedFuture(new RemoteCollectionItems
- .Builder().build());
+ .Builder().build());
}
final Context context = ActivityThread.currentApplication();
- final CompletableFuture<RemoteCollectionItems> result = new CompletableFuture<>();
+ final CompletableFuture<RemoteCollectionItems> result = new CompletableFuture<>();
context.bindService(intent, Context.BindServiceFlags.of(Context.BIND_AUTO_CREATE),
result.defaultExecutor(), new ServiceConnection() {
@Override
@@ -1348,11 +1405,11 @@ public class RemoteViews implements Parcelable, Filter {
RemoteCollectionItems items;
try {
items = IRemoteViewsFactory.Stub.asInterface(iBinder)
- .getRemoteCollectionItems();
+ .getRemoteCollectionItems(individualSize);
} catch (RemoteException re) {
items = new RemoteCollectionItems.Builder().build();
- Log.e(LOG_TAG, "Error getting collection items from the factory",
- re);
+ Log.e(LOG_TAG, "Error getting collection items from the"
+ + " factory", re);
} finally {
context.unbindService(this);
}
@@ -1371,10 +1428,17 @@ public class RemoteViews implements Parcelable, Filter {
return result;
}
- public void writeToParcel(Parcel out, int flags) {
+ public void writeToParcel(Parcel out, int flags,
+ @Nullable SparseArray<Intent> intentsToIgnore) {
out.writeInt(mIdToUriMapping.size());
for (int i = 0; i < mIdToUriMapping.size(); i++) {
- out.writeInt(mIdToUriMapping.keyAt(i));
+ int currentIntentId = mIdToUriMapping.keyAt(i);
+ if (intentsToIgnore != null && intentsToIgnore.contains(currentIntentId)) {
+ // Skip writing collections that are to be updated in the following steps to
+ // better estimate the RemoteViews size.
+ continue;
+ }
+ out.writeInt(currentIntentId);
String intentUri = mIdToUriMapping.valueAt(i);
out.writeString8(intentUri);
mUriToCollectionMapping.get(intentUri).writeToParcel(out, flags, true);
@@ -6724,7 +6788,13 @@ public class RemoteViews implements Parcelable, Filter {
return 0;
}
+ @Override
public void writeToParcel(Parcel dest, int flags) {
+ writeToParcel(dest, flags, /* intentsToIgnore= */ null);
+ }
+
+ private void writeToParcel(Parcel dest, int flags,
+ @Nullable SparseArray<Intent> intentsToIgnore) {
boolean prevSquashingAllowed = dest.allowSquashing();
if (!hasMultipleLayouts()) {
@@ -6733,7 +6803,7 @@ public class RemoteViews implements Parcelable, Filter {
// is shared by all children.
if (mIsRoot) {
mBitmapCache.writeBitmapsToParcel(dest, flags);
- mCollectionCache.writeToParcel(dest, flags);
+ mCollectionCache.writeToParcel(dest, flags, intentsToIgnore);
}
mApplication.writeToParcel(dest, flags);
if (mIsRoot || mIdealSize == null) {
@@ -6750,7 +6820,7 @@ public class RemoteViews implements Parcelable, Filter {
dest.writeInt(MODE_HAS_SIZED_REMOTEVIEWS);
if (mIsRoot) {
mBitmapCache.writeBitmapsToParcel(dest, flags);
- mCollectionCache.writeToParcel(dest, flags);
+ mCollectionCache.writeToParcel(dest, flags, intentsToIgnore);
}
dest.writeInt(mSizedRemoteViews.size());
for (RemoteViews view : mSizedRemoteViews) {
@@ -6762,7 +6832,7 @@ public class RemoteViews implements Parcelable, Filter {
// is shared by all children.
if (mIsRoot) {
mBitmapCache.writeBitmapsToParcel(dest, flags);
- mCollectionCache.writeToParcel(dest, flags);
+ mCollectionCache.writeToParcel(dest, flags, intentsToIgnore);
}
mLandscape.writeToParcel(dest, flags);
// Both RemoteViews already share the same package and user
diff --git a/core/java/android/widget/RemoteViewsService.java b/core/java/android/widget/RemoteViewsService.java
index a250a867b9de..d4a5bbd79d31 100644
--- a/core/java/android/widget/RemoteViewsService.java
+++ b/core/java/android/widget/RemoteViewsService.java
@@ -19,6 +19,7 @@ package android.widget;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
+import android.os.Parcel;
import com.android.internal.widget.IRemoteViewsFactory;
@@ -43,13 +44,6 @@ public abstract class RemoteViewsService extends Service {
private static final Object sLock = new Object();
/**
- * Used for determining the maximum number of entries to retrieve from RemoteViewsFactory
- *
- * @hide
- */
- private static final int MAX_NUM_ENTRY = 10;
-
- /**
* An interface for an adapter between a remote collection view (ListView, GridView, etc) and
* the underlying data for that view. The implementor is responsible for making a RemoteView
* for each item in the data set. This interface is a thin wrapper around {@link Adapter}.
@@ -235,9 +229,10 @@ public abstract class RemoteViewsService extends Service {
}
@Override
- public RemoteViews.RemoteCollectionItems getRemoteCollectionItems() {
+ public RemoteViews.RemoteCollectionItems getRemoteCollectionItems(int capSize) {
RemoteViews.RemoteCollectionItems items = new RemoteViews.RemoteCollectionItems
.Builder().build();
+ Parcel capSizeTestParcel = Parcel.obtain();
try {
RemoteViews.RemoteCollectionItems.Builder itemsBuilder =
@@ -245,15 +240,25 @@ public abstract class RemoteViewsService extends Service {
mFactory.onDataSetChanged();
itemsBuilder.setHasStableIds(mFactory.hasStableIds());
- final int numOfEntries = Math.min(mFactory.getCount(), MAX_NUM_ENTRY);
+ final int numOfEntries = mFactory.getCount();
+
for (int i = 0; i < numOfEntries; i++) {
- itemsBuilder.addItem(mFactory.getItemId(i), mFactory.getViewAt(i));
+ final long currentItemId = mFactory.getItemId(i);
+ final RemoteViews currentView = mFactory.getViewAt(i);
+ currentView.writeToParcel(capSizeTestParcel, 0);
+ if (capSizeTestParcel.dataSize() > capSize) {
+ break;
+ }
+ itemsBuilder.addItem(currentItemId, currentView);
}
items = itemsBuilder.build();
} catch (Exception ex) {
Thread t = Thread.currentThread();
Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, ex);
+ } finally {
+ // Recycle the parcel
+ capSizeTestParcel.recycle();
}
return items;
}
diff --git a/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl b/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl
index 918d9c029ef5..1d0e97295571 100644
--- a/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl
+++ b/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl
@@ -39,6 +39,6 @@ interface IRemoteViewsFactory {
boolean hasStableIds();
@UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
boolean isCreated();
- RemoteViews.RemoteCollectionItems getRemoteCollectionItems();
+ RemoteViews.RemoteCollectionItems getRemoteCollectionItems(int capSize);
}
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 240028c191bc..76e71380017c 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -400,6 +400,7 @@ cc_library_shared_for_libandroid_runtime {
"libbinary_parse",
"libdng_sdk",
"libft2",
+ "libhostgraphics",
"libhwui",
"libimage_type_recognition",
"libjpeg",
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 487b5be9ef5c..ba9751fe1d12 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -8621,6 +8621,10 @@
android:permission="android.permission.BIND_JOB_SERVICE">
</service>
+ <service android:name="com.android.system.virtualmachine.SecretkeeperJobService"
+ android:permission="android.permission.BIND_JOB_SERVICE">
+ </service>
+
<service android:name="com.android.server.PruneInstantAppsJobService"
android:permission="android.permission.BIND_JOB_SERVICE" >
</service>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index d419cee4eef5..7155bf4241e6 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -633,8 +633,8 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"به برنامه اجازه می‌دهد مجموعه عکستان را تغییر دهد."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"خواندن مکان‌ها از مجموعه رسانه شما"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"به برنامه اجازه می‌دهد مکان‌ها را از مجموعه رسانه‌تان بخواند."</string>
- <string name="biometric_app_setting_name" msgid="3339209978734534457">"استفاده از زیست‌سنجشی"</string>
- <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"استفاده از زیست‌سنجشی یا قفل صفحه"</string>
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"استفاده از داده‌های زیست‌سنجشی"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"استفاده از داده‌های زیست‌سنجشی یا قفل صفحه"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"تأیید کنید این شمایید"</string>
<string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"برای ادامه، از زیست‌سنجشی استفاده کنید"</string>
<string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"برای ادامه، از زیست‌سنجشی یا قفل صفحه استفاده کنید"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 8edf42afa730..90f27311d7c3 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3348,26 +3348,23 @@
<string name="config_carrierAppInstallDialogComponent" translatable="false"
>com.android.simappdialog/com.android.simappdialog.InstallCarrierAppActivity</string>
- <!-- Name of the default framework dialog that is used to get or save an app credential.
+ <!-- Name of the fallback CredentialManager dialog that is used to get or save an app
+ credential.
- This UI should be always launch-able and is used as a fallback when an oem replacement activity
- (defined at config_oemCredentialManagerDialogComponent) is undefined / not found. -->
- <string name="config_credentialManagerDialogComponent" translatable="false"
- >com.android.credentialmanager/com.android.credentialmanager.CredentialSelectorActivity</string>
- <!-- Whether to allow the credential selector activity to be replaced by an activity at
- run-time (restricted to the privileged activity specified by
- config_credentialSelectorActivityName).
+ If empty, no fallback will be used. IMPORTANT: In that case the OEM dialog value specified in
+ config_oemCredentialManagerDialogComponent must always launch-able. Otherwise, the
+ CredentialManager API contract is broken.
- When disabled, the fallback activity defined at
- config_credentialManagerDialogComponent will be used instead. -->
- <bool name="config_enableOemCredentialManagerDialogComponent" translatable="false">true</bool>
+ If specified, this UI should be always launch-able. It will be used as a fallback when the OEM
+ dialog value specified in config_oemCredentialManagerDialogComponent) is undefined / not
+ found. -->
+ <string name="config_fallbackCredentialManagerDialogComponent" translatable="false"
+ >com.android.credentialmanager/com.android.credentialmanager.CredentialSelectorActivity</string>
<!-- Fully qualified activity name providing the credential selector UI, that serves the
- CredentialManager APIs.
-
- Used only when config_enableOemCredentialManagerDialogComponent is true.
+ CredentialManager APIs. Must be a system app component.
- If the activity specified cannot be found or launched, then the fallback activity defined at
- config_credentialManagerDialogComponent will be used instead. -->
+ If empty, or if this activity specified cannot be found or launched, then the fallback activity
+ defined at config_fallbackCredentialManagerDialogComponent will be used instead. -->
<string name="config_oemCredentialManagerDialogComponent" translatable="false"></string>
<!-- Name of the broadcast receiver that is used to receive provider change events -->
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index 5e3e1b0bbb43..6e56fe2abfdd 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -334,4 +334,9 @@
<bool name="config_enable_cellular_on_boot_default">true</bool>
<java-symbol type="bool" name="config_enable_cellular_on_boot_default" />
+ <!-- Defines metrics pull cooldown period. The default cooldown period is 23 hours,
+ some Telephony metrics need to be pulled more frequently -->
+ <integer name="config_metrics_pull_cooldown_millis">82800000</integer>
+ <java-symbol type="integer" name="config_metrics_pull_cooldown_millis" />
+
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index a1804672da73..a025c8db547f 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2297,8 +2297,7 @@
<java-symbol type="string" name="config_customVpnAlwaysOnDisconnectedDialogComponent" />
<java-symbol type="string" name="config_platformVpnConfirmDialogComponent" />
<java-symbol type="string" name="config_carrierAppInstallDialogComponent" />
- <java-symbol type="string" name="config_credentialManagerDialogComponent" />
- <java-symbol type="bool" name="config_enableOemCredentialManagerDialogComponent" />
+ <java-symbol type="string" name="config_fallbackCredentialManagerDialogComponent" />
<java-symbol type="string" name="config_oemCredentialManagerDialogComponent" />
<java-symbol type="string" name="config_credentialManagerReceiverComponent" />
<java-symbol type="string" name="config_defaultNetworkScorerPackageName" />
diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
index d115bf306b45..927c67cb1d36 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
@@ -21,16 +21,22 @@ import static android.content.Intent.ACTION_EDIT;
import static android.content.Intent.ACTION_VIEW;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
+import static com.android.window.flags.Flags.FLAG_ACTIVITY_WINDOW_INFO_FLAG;
+
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import android.annotation.NonNull;
@@ -46,6 +52,7 @@ import android.app.servertransaction.ActivityConfigurationChangeItem;
import android.app.servertransaction.ActivityRelaunchItem;
import android.app.servertransaction.ClientTransaction;
import android.app.servertransaction.ClientTransactionItem;
+import android.app.servertransaction.ClientTransactionListenerController;
import android.app.servertransaction.ConfigurationChangeItem;
import android.app.servertransaction.NewIntentItem;
import android.app.servertransaction.ResumeActivityItem;
@@ -60,7 +67,9 @@ import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.os.Bundle;
import android.os.IBinder;
+import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.util.DisplayMetrics;
import android.util.MergedConfiguration;
import android.view.Display;
@@ -81,11 +90,14 @@ 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 java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import java.util.function.BiConsumer;
import java.util.function.Consumer;
/**
@@ -103,11 +115,17 @@ public class ActivityThreadTest {
// few sequence numbers the framework used to launch the test activity.
private static final int BASE_SEQ = 10000000;
- @Rule
+ @Rule(order = 0)
public final ActivityTestRule<TestActivity> mActivityTestRule =
new ActivityTestRule<>(TestActivity.class, true /* initialTouchMode */,
false /* launchActivity */);
+ @Rule(order = 1)
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
+
+ @Mock
+ private BiConsumer<IBinder, ActivityWindowInfo> mActivityWindowInfoListener;
+
private WindowTokenClientController mOriginalWindowTokenClientController;
private Configuration mOriginalAppConfig;
@@ -115,6 +133,8 @@ public class ActivityThreadTest {
@Before
public void setup() {
+ MockitoAnnotations.initMocks(this);
+
// Keep track of the original controller, so that it can be used to restore in tearDown()
// when there is override in some test cases.
mOriginalWindowTokenClientController = WindowTokenClientController.getInstance();
@@ -129,6 +149,8 @@ public class ActivityThreadTest {
mCreatedVirtualDisplays = null;
}
WindowTokenClientController.overrideForTesting(mOriginalWindowTokenClientController);
+ ClientTransactionListenerController.getInstance()
+ .unregisterActivityWindowInfoChangedListener(mActivityWindowInfoListener);
InstrumentationRegistry.getInstrumentation().runOnMainSync(
() -> restoreConfig(ActivityThread.currentActivityThread(), mOriginalAppConfig));
}
@@ -783,6 +805,101 @@ public class ActivityThreadTest {
verify(windowTokenClientController).onWindowContextWindowRemoved(clientToken);
}
+ @Test
+ public void testActivityWindowInfoChanged_activityLaunch() {
+ mSetFlagsRule.enableFlags(FLAG_ACTIVITY_WINDOW_INFO_FLAG);
+
+ ClientTransactionListenerController.getInstance().registerActivityWindowInfoChangedListener(
+ mActivityWindowInfoListener);
+
+ final Activity activity = mActivityTestRule.launchActivity(new Intent());
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ final ActivityClientRecord activityClientRecord = getActivityClientRecord(activity);
+
+ verify(mActivityWindowInfoListener).accept(activityClientRecord.token,
+ activityClientRecord.getActivityWindowInfo());
+ }
+
+ @Test
+ public void testActivityWindowInfoChanged_activityRelaunch() throws RemoteException {
+ mSetFlagsRule.enableFlags(FLAG_ACTIVITY_WINDOW_INFO_FLAG);
+
+ ClientTransactionListenerController.getInstance().registerActivityWindowInfoChangedListener(
+ mActivityWindowInfoListener);
+
+ final Activity activity = mActivityTestRule.launchActivity(new Intent());
+ final IApplicationThread appThread = activity.getActivityThread().getApplicationThread();
+ appThread.scheduleTransaction(newRelaunchResumeTransaction(activity));
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ final ActivityClientRecord activityClientRecord = getActivityClientRecord(activity);
+
+ // The same ActivityWindowInfo won't trigger duplicated callback.
+ verify(mActivityWindowInfoListener).accept(activityClientRecord.token,
+ activityClientRecord.getActivityWindowInfo());
+
+ final Configuration currentConfig = activity.getResources().getConfiguration();
+ final ActivityWindowInfo activityWindowInfo = new ActivityWindowInfo();
+ activityWindowInfo.set(true /* isEmbedded */, new Rect(0, 0, 1000, 2000),
+ new Rect(0, 0, 1000, 1000));
+ final ActivityRelaunchItem relaunchItem = ActivityRelaunchItem.obtain(
+ activity.getActivityToken(), null, null, 0,
+ new MergedConfiguration(currentConfig, currentConfig),
+ false /* preserveWindow */, activityWindowInfo);
+ final ClientTransaction transaction = newTransaction(activity);
+ transaction.addTransactionItem(relaunchItem);
+ appThread.scheduleTransaction(transaction);
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+ verify(mActivityWindowInfoListener).accept(activityClientRecord.token,
+ activityWindowInfo);
+ }
+
+ @Test
+ public void testActivityWindowInfoChanged_activityConfigurationChanged()
+ throws RemoteException {
+ mSetFlagsRule.enableFlags(FLAG_ACTIVITY_WINDOW_INFO_FLAG);
+
+ ClientTransactionListenerController.getInstance().registerActivityWindowInfoChangedListener(
+ mActivityWindowInfoListener);
+
+ final Activity activity = mActivityTestRule.launchActivity(new Intent());
+ final IApplicationThread appThread = activity.getActivityThread().getApplicationThread();
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+ clearInvocations(mActivityWindowInfoListener);
+ final Configuration config = new Configuration(activity.getResources().getConfiguration());
+ config.seq++;
+ final Rect taskBounds = new Rect(0, 0, 1000, 2000);
+ final Rect taskFragmentBounds = new Rect(0, 0, 1000, 1000);
+ final ActivityWindowInfo activityWindowInfo = new ActivityWindowInfo();
+ activityWindowInfo.set(true /* isEmbedded */, taskBounds, taskFragmentBounds);
+ final ActivityConfigurationChangeItem activityConfigurationChangeItem =
+ ActivityConfigurationChangeItem.obtain(
+ activity.getActivityToken(), config, activityWindowInfo);
+ final ClientTransaction transaction = newTransaction(activity);
+ transaction.addTransactionItem(activityConfigurationChangeItem);
+ appThread.scheduleTransaction(transaction);
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+ verify(mActivityWindowInfoListener).accept(activity.getActivityToken(),
+ activityWindowInfo);
+
+ clearInvocations(mActivityWindowInfoListener);
+ final ActivityWindowInfo activityWindowInfo2 = new ActivityWindowInfo();
+ activityWindowInfo2.set(true /* isEmbedded */, taskBounds, taskFragmentBounds);
+ config.seq++;
+ final ActivityConfigurationChangeItem activityConfigurationChangeItem2 =
+ ActivityConfigurationChangeItem.obtain(
+ activity.getActivityToken(), config, activityWindowInfo2);
+ final ClientTransaction transaction2 = newTransaction(activity);
+ transaction2.addTransactionItem(activityConfigurationChangeItem2);
+ appThread.scheduleTransaction(transaction);
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+ // The same ActivityWindowInfo won't trigger duplicated callback.
+ verify(mActivityWindowInfoListener, never()).accept(any(), any());
+ }
+
/**
* Calls {@link ActivityThread#handleActivityConfigurationChanged(ActivityClientRecord,
* Configuration, int, ActivityWindowInfo)} to try to push activity configuration to the
@@ -871,7 +988,7 @@ public class ActivityThreadTest {
@NonNull
private static ClientTransaction newStopTransaction(@NonNull Activity activity) {
final StopActivityItem stopStateRequest = StopActivityItem.obtain(
- activity.getActivityToken(), 0 /* configChanges */);
+ activity.getActivityToken());
final ClientTransaction transaction = newTransaction(activity);
transaction.addTransactionItem(stopStateRequest);
diff --git a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionItemTest.java b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionItemTest.java
index 4db5d1bf4f67..990739745f24 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionItemTest.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionItemTest.java
@@ -136,7 +136,7 @@ public class ClientTransactionItemTest {
@Test
public void testDestroyActivityItem_preExecute() {
final DestroyActivityItem item = DestroyActivityItem
- .obtain(mActivityToken, false /* finished */, 123 /* configChanges */);
+ .obtain(mActivityToken, false /* finished */);
item.preExecute(mHandler);
assertEquals(1, mActivitiesToBeDestroyed.size());
@@ -146,7 +146,7 @@ public class ClientTransactionItemTest {
@Test
public void testDestroyActivityItem_postExecute() {
final DestroyActivityItem item = DestroyActivityItem
- .obtain(mActivityToken, false /* finished */, 123 /* configChanges */);
+ .obtain(mActivityToken, false /* finished */);
item.preExecute(mHandler);
item.postExecute(mHandler, mPendingActions);
@@ -156,11 +156,11 @@ public class ClientTransactionItemTest {
@Test
public void testDestroyActivityItem_execute() {
final DestroyActivityItem item = DestroyActivityItem
- .obtain(mActivityToken, false /* finished */, 123 /* configChanges */);
+ .obtain(mActivityToken, false /* finished */);
item.execute(mHandler, mActivityClientRecord, mPendingActions);
verify(mHandler).handleDestroyActivity(eq(mActivityClientRecord), eq(false) /* finishing */,
- eq(123) /* configChanges */, eq(false) /* getNonConfigInstance */, any());
+ eq(false) /* getNonConfigInstance */, any());
}
@Test
diff --git a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionListenerControllerTest.java b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionListenerControllerTest.java
index 213fd7bd494d..77d31a5f27e7 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionListenerControllerTest.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionListenerControllerTest.java
@@ -22,21 +22,29 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat
import static com.android.window.flags.Flags.FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManagerGlobal;
import android.hardware.display.IDisplayManager;
import android.os.Handler;
+import android.os.IBinder;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.platform.test.flag.junit.SetFlagsRule;
import android.view.DisplayInfo;
+import android.window.ActivityWindowInfo;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.window.flags.Flags;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -44,6 +52,8 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.function.BiConsumer;
+
/**
* Tests for {@link ClientTransactionListenerController}.
*
@@ -62,6 +72,10 @@ public class ClientTransactionListenerControllerTest {
private IDisplayManager mIDisplayManager;
@Mock
private DisplayManager.DisplayListener mListener;
+ @Mock
+ private BiConsumer<IBinder, ActivityWindowInfo> mActivityWindowInfoListener;
+ @Mock
+ private IBinder mActivityToken;
private DisplayManagerGlobal mDisplayManager;
private Handler mHandler;
@@ -91,4 +105,24 @@ public class ClientTransactionListenerControllerTest {
verify(mListener).onDisplayChanged(123);
}
+
+ @Test
+ public void testActivityWindowInfoChangedListener() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_ACTIVITY_WINDOW_INFO_FLAG);
+
+ mController.registerActivityWindowInfoChangedListener(mActivityWindowInfoListener);
+ final ActivityWindowInfo activityWindowInfo = new ActivityWindowInfo();
+ activityWindowInfo.set(true /* isEmbedded */, new Rect(0, 0, 1000, 2000),
+ new Rect(0, 0, 1000, 1000));
+ mController.onActivityWindowInfoChanged(mActivityToken, activityWindowInfo);
+
+ verify(mActivityWindowInfoListener).accept(mActivityToken, activityWindowInfo);
+
+ clearInvocations(mActivityWindowInfoListener);
+ mController.unregisterActivityWindowInfoChangedListener(mActivityWindowInfoListener);
+
+ mController.onActivityWindowInfoChanged(mActivityToken, activityWindowInfo);
+
+ verify(mActivityWindowInfoListener, never()).accept(any(), any());
+ }
}
diff --git a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
index 31ea6759c710..584fe16d00ac 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
@@ -98,7 +98,7 @@ public class ObjectPoolTests {
@Test
public void testRecycleDestroyActivityItem() {
- testRecycle(() -> DestroyActivityItem.obtain(mActivityToken, true, 117));
+ testRecycle(() -> DestroyActivityItem.obtain(mActivityToken, true));
}
@Test
@@ -169,7 +169,7 @@ public class ObjectPoolTests {
@Test
public void testRecyclePauseActivityItemItem() {
- testRecycle(() -> PauseActivityItem.obtain(mActivityToken, true, true, 5, true, true));
+ testRecycle(() -> PauseActivityItem.obtain(mActivityToken, true, true, true, true));
}
@Test
@@ -185,7 +185,7 @@ public class ObjectPoolTests {
@Test
public void testRecycleStopItem() {
- testRecycle(() -> StopActivityItem.obtain(mActivityToken, 4));
+ testRecycle(() -> StopActivityItem.obtain(mActivityToken));
}
@Test
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
index adb6f2a23847..935bc7565986 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
@@ -306,7 +306,7 @@ public class TransactionExecutorTests {
final IBinder token = mock(IBinder.class);
final ClientTransaction destroyTransaction = ClientTransaction.obtain(null /* client */);
destroyTransaction.addTransactionItem(
- DestroyActivityItem.obtain(token, false /* finished */, 0 /* configChanges */));
+ DestroyActivityItem.obtain(token, false /* finished */));
destroyTransaction.preExecute(mTransactionHandler);
// The activity should be added to to-be-destroyed container.
assertEquals(1, activitiesToBeDestroyed.size());
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
index 75347bf2c8de..d451fe58e8e4 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
@@ -155,8 +155,7 @@ public class TransactionParcelTests {
@Test
public void testDestroy() {
- DestroyActivityItem item = DestroyActivityItem.obtain(mActivityToken, true /* finished */,
- 135 /* configChanges */);
+ DestroyActivityItem item = DestroyActivityItem.obtain(mActivityToken, true /* finished */);
writeAndPrepareForReading(item);
// Read from parcel and assert
@@ -244,8 +243,7 @@ public class TransactionParcelTests {
public void testPause() {
// Write to parcel
PauseActivityItem item = PauseActivityItem.obtain(mActivityToken, true /* finished */,
- true /* userLeaving */, 135 /* configChanges */, true /* dontReport */,
- true /* autoEnteringPip */);
+ true /* userLeaving */, true /* dontReport */, true /* autoEnteringPip */);
writeAndPrepareForReading(item);
// Read from parcel and assert
@@ -272,7 +270,7 @@ public class TransactionParcelTests {
@Test
public void testStop() {
// Write to parcel
- StopActivityItem item = StopActivityItem.obtain(mActivityToken, 14 /* configChanges */);
+ StopActivityItem item = StopActivityItem.obtain(mActivityToken);
writeAndPrepareForReading(item);
// Read from parcel and assert
@@ -305,8 +303,7 @@ public class TransactionParcelTests {
ActivityConfigurationChangeItem callback2 = ActivityConfigurationChangeItem.obtain(
mActivityToken, config(), new ActivityWindowInfo());
- StopActivityItem lifecycleRequest = StopActivityItem.obtain(mActivityToken,
- 78 /* configChanges */);
+ StopActivityItem lifecycleRequest = StopActivityItem.obtain(mActivityToken);
ClientTransaction transaction = ClientTransaction.obtain(null /* client */);
transaction.addTransactionItem(callback1);
@@ -351,8 +348,7 @@ public class TransactionParcelTests {
mSetFlagsRule.disableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
// Write to parcel
- StopActivityItem lifecycleRequest = StopActivityItem.obtain(mActivityToken,
- 78 /* configChanges */);
+ StopActivityItem lifecycleRequest = StopActivityItem.obtain(mActivityToken);
ClientTransaction transaction = ClientTransaction.obtain(null /* client */);
transaction.addTransactionItem(lifecycleRequest);
diff --git a/core/tests/coretests/src/android/widget/RemoteViewsAdapterTest.java b/core/tests/coretests/src/android/widget/RemoteViewsAdapterTest.java
index 4f722cefcf9f..6ab77dc9d535 100644
--- a/core/tests/coretests/src/android/widget/RemoteViewsAdapterTest.java
+++ b/core/tests/coretests/src/android/widget/RemoteViewsAdapterTest.java
@@ -355,7 +355,7 @@ public class RemoteViewsAdapterTest {
}
@Override
- public RemoteViews.RemoteCollectionItems getRemoteCollectionItems() {
+ public RemoteViews.RemoteCollectionItems getRemoteCollectionItems(int capSize) {
RemoteViews.RemoteCollectionItems.Builder itemsBuilder =
new RemoteViews.RemoteCollectionItems.Builder();
itemsBuilder.setHasStableIds(hasStableIds())
diff --git a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
index 66be05ff233c..ed641e048a81 100644
--- a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
+++ b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
@@ -309,17 +309,17 @@ public class ActivityThreadClientTest {
private void pauseActivity(ActivityClientRecord r) {
mThread.handlePauseActivity(r, false /* finished */,
- false /* userLeaving */, 0 /* configChanges */, false /* autoEnteringPip */,
+ false /* userLeaving */, false /* autoEnteringPip */,
null /* pendingActions */, "test");
}
private void stopActivity(ActivityClientRecord r) {
- mThread.handleStopActivity(r, 0 /* configChanges */,
+ mThread.handleStopActivity(r,
new PendingTransactionActions(), false /* finalStateRequest */, "test");
}
private void destroyActivity(ActivityClientRecord r) {
- mThread.handleDestroyActivity(r, true /* finishing */, 0 /* configChanges */,
+ mThread.handleDestroyActivity(r, true /* finishing */,
false /* getNonConfigInstance */, "test");
}
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index 238a3e10f058..1410950966e9 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -72,6 +72,12 @@ prebuilt_etc {
src: "enhanced-confirmation.xml",
}
+prebuilt_etc {
+ name: "package-shareduid-allowlist.xml",
+ sub_dir: "sysconfig",
+ src: "package-shareduid-allowlist.xml",
+}
+
// Privapp permission whitelist files
prebuilt_etc {
diff --git a/data/etc/CleanSpec.mk b/data/etc/CleanSpec.mk
index 783a7edadeb7..fd38d2782cb2 100644
--- a/data/etc/CleanSpec.mk
+++ b/data/etc/CleanSpec.mk
@@ -43,6 +43,8 @@
#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product/etc/sysconfig/package-shareduid-allowlist.xml)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product/etc/sysconfig/package-shareduid-allowlist.xml)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product/etc/permissions/com.android.carrierconfig.xml)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product/etc/permissions/com.android.carrierconfig.xml)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product/etc/permissions/com.android.emergency.xml)
diff --git a/data/etc/package-shareduid-allowlist.xml b/data/etc/package-shareduid-allowlist.xml
new file mode 100644
index 000000000000..2401d4a26e68
--- /dev/null
+++ b/data/etc/package-shareduid-allowlist.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<!--
+This XML defines an allowlist for packages that want to join a particular shared-uid.
+If a non-system package that is signed with platform signature, is trying to join a particular
+shared-uid, and not in this list, the installation will fail.
+
+- The "package" XML attribute refers to the app's package name.
+- The "shareduid" XML attribute refers to the shared uid name.
+
+Example usage
+ 1. <allow-package-shareduid package="com.example.app" shareduid="android.uid.system"/>
+ Indicates that a package - com.example.app, will be able to join android.uid.system.
+ 2. <allow-package-shareduid package="oem.example.app" shareduid="oem.uid.custom"/>
+ Indicates that a package - oem.example.app, will be able to join oem.uid.custom.
+-->
+
+<config>
+ <allow-package-shareduid package="android.test.settings" shareduid="android.uid.system" />
+</config>
diff --git a/data/fonts/font_fallback.xml b/data/fonts/font_fallback.xml
index 15ea15a9b4c1..53024ab858c4 100644
--- a/data/fonts/font_fallback.xml
+++ b/data/fonts/font_fallback.xml
@@ -792,14 +792,10 @@
</font>
</family>
<family lang="ja">
- <font weight="400" style="normal">
- NotoSerifHentaigana-EL.ttf
+ <font postScriptName="NotoSerifHentaigana-ExtraLight" supportedAxes="wght">
+ NotoSerifHentaigana.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="700" style="normal">
- NotoSerifHentaigana-EL.ttf
- <axis tag="wght" stylevalue="700"/>
- </font>
</family>
<family lang="ko">
<font weight="400" style="normal" index="1" postScriptName="NotoSansCJKjp-Regular">
diff --git a/data/fonts/font_fallback_cjkvf.xml b/data/fonts/font_fallback_cjkvf.xml
index c1ca67ef456a..ac1b06495832 100644
--- a/data/fonts/font_fallback_cjkvf.xml
+++ b/data/fonts/font_fallback_cjkvf.xml
@@ -804,14 +804,10 @@
</font>
</family>
<family lang="ja">
- <font weight="400" style="normal">
- NotoSerifHentaigana-EL.ttf
+ <font postScriptName="NotoSerifHentaigana-ExtraLight" supportedAxes="wght">
+ NotoSerifHentaigana.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="700" style="normal">
- NotoSerifHentaigana-EL.ttf
- <axis tag="wght" stylevalue="700"/>
- </font>
</family>
<family lang="ko">
<font weight="400" style="normal" index="1" postScriptName="NotoSansCJKjp-Thin"
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index b23f00554bdb..d1aa8e9734c2 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -1433,12 +1433,12 @@
</font>
</family>
<family lang="ja">
- <font weight="400" style="normal">
- NotoSerifHentaigana-EL.ttf
+ <font weight="400" style="normal" postScriptName="NotoSerifHentaigana-ExtraLight">
+ NotoSerifHentaigana.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="700" style="normal">
- NotoSerifHentaigana-EL.ttf
+ <font weight="700" style="normal" postScriptName="NotoSerifHentaigana-ExtraLight">
+ NotoSerifHentaigana.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
diff --git a/data/fonts/fonts_cjkvf.xml b/data/fonts/fonts_cjkvf.xml
index 1ab71ae270eb..9545ae718574 100644
--- a/data/fonts/fonts_cjkvf.xml
+++ b/data/fonts/fonts_cjkvf.xml
@@ -1532,12 +1532,12 @@
</font>
</family>
<family lang="ja">
- <font weight="400" style="normal">
- NotoSerifHentaigana-EL.ttf
+ <font weight="400" style="normal" postScriptName="NotoSerifHentaigana-ExtraLight">
+ NotoSerifHentaigana.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="700" style="normal">
- NotoSerifHentaigana-EL.ttf
+ <font weight="700" style="normal" postScriptName="NotoSerifHentaigana-ExtraLight">
+ NotoSerifHentaigana.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
diff --git a/graphics/java/android/graphics/text/MeasuredText.java b/graphics/java/android/graphics/text/MeasuredText.java
index 6da07198c3ad..884268a4b85c 100644
--- a/graphics/java/android/graphics/text/MeasuredText.java
+++ b/graphics/java/android/graphics/text/MeasuredText.java
@@ -29,11 +29,13 @@ import android.util.Log;
import com.android.internal.util.Preconditions;
import dalvik.annotation.optimization.CriticalNative;
+import dalvik.annotation.optimization.NeverInline;
import libcore.util.NativeAllocationRegistry;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Locale;
import java.util.Objects;
/**
@@ -85,6 +87,30 @@ public class MeasuredText {
return mChars;
}
+ private void rangeCheck(int start, int end) {
+ if (start < 0 || start > end || end > mChars.length) {
+ throwRangeError(start, end);
+ }
+ }
+
+ @NeverInline
+ private void throwRangeError(int start, int end) {
+ throw new IllegalArgumentException(String.format(Locale.US,
+ "start(%d) end(%d) length(%d) out of bounds", start, end, mChars.length));
+ }
+
+ private void offsetCheck(int offset) {
+ if (offset < 0 || offset >= mChars.length) {
+ throwOffsetError(offset);
+ }
+ }
+
+ @NeverInline
+ private void throwOffsetError(int offset) {
+ throw new IllegalArgumentException(String.format(Locale.US,
+ "offset (%d) length(%d) out of bounds", offset, mChars.length));
+ }
+
/**
* Returns the width of a given range.
*
@@ -93,12 +119,7 @@ public class MeasuredText {
*/
public @FloatRange(from = 0.0) @Px float getWidth(
@IntRange(from = 0) int start, @IntRange(from = 0) int end) {
- Preconditions.checkArgument(0 <= start && start <= mChars.length,
- "start(%d) must be 0 <= start <= %d", start, mChars.length);
- Preconditions.checkArgument(0 <= end && end <= mChars.length,
- "end(%d) must be 0 <= end <= %d", end, mChars.length);
- Preconditions.checkArgument(start <= end,
- "start(%d) is larger than end(%d)", start, end);
+ rangeCheck(start, end);
return nGetWidth(mNativePtr, start, end);
}
@@ -120,12 +141,7 @@ public class MeasuredText {
*/
public void getBounds(@IntRange(from = 0) int start, @IntRange(from = 0) int end,
@NonNull Rect rect) {
- Preconditions.checkArgument(0 <= start && start <= mChars.length,
- "start(%d) must be 0 <= start <= %d", start, mChars.length);
- Preconditions.checkArgument(0 <= end && end <= mChars.length,
- "end(%d) must be 0 <= end <= %d", end, mChars.length);
- Preconditions.checkArgument(start <= end,
- "start(%d) is larger than end(%d)", start, end);
+ rangeCheck(start, end);
Preconditions.checkNotNull(rect);
nGetBounds(mNativePtr, mChars, start, end, rect);
}
@@ -139,12 +155,7 @@ public class MeasuredText {
*/
public void getFontMetricsInt(@IntRange(from = 0) int start, @IntRange(from = 0) int end,
@NonNull Paint.FontMetricsInt outMetrics) {
- Preconditions.checkArgument(0 <= start && start <= mChars.length,
- "start(%d) must be 0 <= start <= %d", start, mChars.length);
- Preconditions.checkArgument(0 <= end && end <= mChars.length,
- "end(%d) must be 0 <= end <= %d", end, mChars.length);
- Preconditions.checkArgument(start <= end,
- "start(%d) is larger than end(%d)", start, end);
+ rangeCheck(start, end);
Objects.requireNonNull(outMetrics);
long packed = nGetExtent(mNativePtr, mChars, start, end);
@@ -160,8 +171,7 @@ public class MeasuredText {
* @param offset an offset of the character.
*/
public @FloatRange(from = 0.0f) @Px float getCharWidthAt(@IntRange(from = 0) int offset) {
- Preconditions.checkArgument(0 <= offset && offset < mChars.length,
- "offset(%d) is larger than text length %d" + offset, mChars.length);
+ offsetCheck(offset);
return nGetCharWidthAt(mNativePtr, offset);
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index 038d0081ead8..1abda4287800 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -56,6 +56,7 @@ import android.app.ActivityOptions;
import android.app.ActivityThread;
import android.app.Application;
import android.app.Instrumentation;
+import android.app.servertransaction.ClientTransactionListenerController;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -103,6 +104,7 @@ import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Executor;
+import java.util.function.BiConsumer;
/**
* Main controller class that manages split states and presentation.
@@ -178,6 +180,20 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
private final List<ActivityStack> mLastReportedActivityStacks = new ArrayList<>();
+ /** WM Jetpack set callback for {@link EmbeddedActivityWindowInfo}. */
+ @GuardedBy("mLock")
+ @Nullable
+ private Pair<Executor, Consumer<EmbeddedActivityWindowInfo>>
+ mEmbeddedActivityWindowInfoCallback;
+
+ /** Listener registered to {@link ClientTransactionListenerController}. */
+ @GuardedBy("mLock")
+ @Nullable
+ private final BiConsumer<IBinder, ActivityWindowInfo> mActivityWindowInfoListener =
+ Flags.activityWindowInfoFlag()
+ ? this::onActivityWindowInfoChanged
+ : null;
+
private final Handler mHandler;
final Object mLock = new Object();
private final ActivityStartMonitor mActivityStartMonitor;
@@ -2456,6 +2472,13 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
}
@VisibleForTesting
+ @Nullable
+ ActivityThread.ActivityClientRecord getActivityClientRecord(@NonNull Activity activity) {
+ return ActivityThread.currentActivityThread()
+ .getActivityClient(activity.getActivityToken());
+ }
+
+ @VisibleForTesting
ActivityStartMonitor getActivityStartMonitor() {
return mActivityStartMonitor;
}
@@ -2468,8 +2491,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
@VisibleForTesting
@Nullable
IBinder getTaskFragmentTokenFromActivityClientRecord(@NonNull Activity activity) {
- final ActivityThread.ActivityClientRecord record = ActivityThread.currentActivityThread()
- .getActivityClient(activity.getActivityToken());
+ final ActivityThread.ActivityClientRecord record = getActivityClientRecord(activity);
return record != null ? record.mTaskFragmentToken : null;
}
@@ -2876,17 +2898,102 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
}
}
+ @Override
+ public void setEmbeddedActivityWindowInfoCallback(@NonNull Executor executor,
+ @NonNull Consumer<EmbeddedActivityWindowInfo> callback) {
+ if (!Flags.activityWindowInfoFlag()) {
+ return;
+ }
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+ synchronized (mLock) {
+ if (mEmbeddedActivityWindowInfoCallback == null) {
+ ClientTransactionListenerController.getInstance()
+ .registerActivityWindowInfoChangedListener(getActivityWindowInfoListener());
+ }
+ mEmbeddedActivityWindowInfoCallback = new Pair<>(executor, callback);
+ }
+ }
+
+ @Override
+ public void clearEmbeddedActivityWindowInfoCallback() {
+ if (!Flags.activityWindowInfoFlag()) {
+ return;
+ }
+ synchronized (mLock) {
+ if (mEmbeddedActivityWindowInfoCallback == null) {
+ return;
+ }
+ mEmbeddedActivityWindowInfoCallback = null;
+ ClientTransactionListenerController.getInstance()
+ .unregisterActivityWindowInfoChangedListener(getActivityWindowInfoListener());
+ }
+ }
+
+ @VisibleForTesting
+ @GuardedBy("mLock")
+ @Nullable
+ BiConsumer<IBinder, ActivityWindowInfo> getActivityWindowInfoListener() {
+ return mActivityWindowInfoListener;
+ }
+
+ @Nullable
+ @Override
+ public EmbeddedActivityWindowInfo getEmbeddedActivityWindowInfo(@NonNull Activity activity) {
+ if (!Flags.activityWindowInfoFlag()) {
+ return null;
+ }
+ synchronized (mLock) {
+ final ActivityWindowInfo activityWindowInfo = getActivityWindowInfo(activity);
+ return activityWindowInfo != null
+ ? translateActivityWindowInfo(activity, activityWindowInfo)
+ : null;
+ }
+ }
+
+ @VisibleForTesting
+ void onActivityWindowInfoChanged(@NonNull IBinder activityToken,
+ @NonNull ActivityWindowInfo activityWindowInfo) {
+ synchronized (mLock) {
+ if (mEmbeddedActivityWindowInfoCallback == null) {
+ return;
+ }
+ final Executor executor = mEmbeddedActivityWindowInfoCallback.first;
+ final Consumer<EmbeddedActivityWindowInfo> callback =
+ mEmbeddedActivityWindowInfoCallback.second;
+
+ final Activity activity = getActivity(activityToken);
+ if (activity == null) {
+ return;
+ }
+ final EmbeddedActivityWindowInfo info = translateActivityWindowInfo(
+ activity, activityWindowInfo);
+
+ executor.execute(() -> callback.accept(info));
+ }
+ }
+
@Nullable
- private static ActivityWindowInfo getActivityWindowInfo(@NonNull Activity activity) {
+ private ActivityWindowInfo getActivityWindowInfo(@NonNull Activity activity) {
if (activity.isFinishing()) {
return null;
}
- final ActivityThread.ActivityClientRecord record =
- ActivityThread.currentActivityThread()
- .getActivityClient(activity.getActivityToken());
+ final ActivityThread.ActivityClientRecord record = getActivityClientRecord(activity);
return record != null ? record.getActivityWindowInfo() : null;
}
+ @NonNull
+ private static EmbeddedActivityWindowInfo translateActivityWindowInfo(
+ @NonNull Activity activity, @NonNull ActivityWindowInfo activityWindowInfo) {
+ final boolean isEmbedded = activityWindowInfo.isEmbedded();
+ final Rect activityBounds = new Rect(activity.getResources().getConfiguration()
+ .windowConfiguration.getBounds());
+ final Rect taskBounds = new Rect(activityWindowInfo.getTaskBounds());
+ final Rect activityStackBounds = new Rect(activityWindowInfo.getTaskFragmentBounds());
+ return new EmbeddedActivityWindowInfo(activity, isEmbedded, activityBounds, taskBounds,
+ activityStackBounds);
+ }
+
/**
* If the two rules have the same presentation, and the calculated {@link SplitAttributes}
* matches the {@link SplitAttributes} of {@link SplitContainer}, we can reuse the same
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 00f8b5925d66..bdeeb7304b12 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
@@ -72,6 +72,8 @@ import static org.mockito.Mockito.times;
import android.annotation.NonNull;
import android.app.Activity;
import android.app.ActivityOptions;
+import android.app.ActivityThread;
+import android.app.servertransaction.ClientTransactionListenerController;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -83,9 +85,11 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.util.ArraySet;
import android.view.WindowInsets;
import android.view.WindowMetrics;
+import android.window.ActivityWindowInfo;
import android.window.TaskFragmentInfo;
import android.window.TaskFragmentOrganizer;
import android.window.TaskFragmentParentInfo;
@@ -99,7 +103,10 @@ import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
import androidx.window.extensions.layout.WindowLayoutComponentImpl;
import androidx.window.extensions.layout.WindowLayoutInfo;
+import com.android.window.flags.Flags;
+
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -110,6 +117,8 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.function.BiConsumer;
import java.util.function.Consumer;
/**
@@ -127,6 +136,9 @@ public class SplitControllerTest {
private static final Intent PLACEHOLDER_INTENT = new Intent().setComponent(
new ComponentName("test", "placeholder"));
+ @Rule
+ public final SetFlagsRule mSetFlagRule = new SetFlagsRule();
+
private Activity mActivity;
@Mock
private Resources mActivityResources;
@@ -138,6 +150,13 @@ public class SplitControllerTest {
private Handler mHandler;
@Mock
private WindowLayoutComponentImpl mWindowLayoutComponent;
+ @Mock
+ private ActivityWindowInfo mActivityWindowInfo;
+ @Mock
+ private BiConsumer<IBinder, ActivityWindowInfo> mActivityWindowInfoListener;
+ @Mock
+ private androidx.window.extensions.core.util.function.Consumer<EmbeddedActivityWindowInfo>
+ mEmbeddedActivityWindowInfoCallback;
private SplitController mSplitController;
private SplitPresenter mSplitPresenter;
@@ -1529,6 +1548,73 @@ public class SplitControllerTest {
.getTopNonFinishingActivity(), secondaryActivity);
}
+ @Test
+ public void testIsActivityEmbedded() {
+ mSetFlagRule.enableFlags(Flags.FLAG_ACTIVITY_WINDOW_INFO_FLAG);
+
+ assertFalse(mSplitController.isActivityEmbedded(mActivity));
+
+ doReturn(true).when(mActivityWindowInfo).isEmbedded();
+
+ assertTrue(mSplitController.isActivityEmbedded(mActivity));
+ }
+
+ @Test
+ public void testGetEmbeddedActivityWindowInfo() {
+ mSetFlagRule.enableFlags(Flags.FLAG_ACTIVITY_WINDOW_INFO_FLAG);
+
+ final boolean isEmbedded = true;
+ final Rect activityBounds = mActivity.getResources().getConfiguration().windowConfiguration
+ .getBounds();
+ final Rect taskBounds = new Rect(0, 0, 1000, 2000);
+ final Rect activityStackBounds = new Rect(0, 0, 500, 2000);
+ doReturn(isEmbedded).when(mActivityWindowInfo).isEmbedded();
+ doReturn(taskBounds).when(mActivityWindowInfo).getTaskBounds();
+ doReturn(activityStackBounds).when(mActivityWindowInfo).getTaskFragmentBounds();
+
+ final EmbeddedActivityWindowInfo expected = new EmbeddedActivityWindowInfo(mActivity,
+ isEmbedded, activityBounds, taskBounds, activityStackBounds);
+ assertEquals(expected, mSplitController.getEmbeddedActivityWindowInfo(mActivity));
+ }
+
+ @Test
+ public void testSetEmbeddedActivityWindowInfoCallback() {
+ mSetFlagRule.enableFlags(Flags.FLAG_ACTIVITY_WINDOW_INFO_FLAG);
+
+ final ClientTransactionListenerController controller = ClientTransactionListenerController
+ .getInstance();
+ spyOn(controller);
+ doNothing().when(controller).registerActivityWindowInfoChangedListener(any());
+ doReturn(mActivityWindowInfoListener).when(mSplitController)
+ .getActivityWindowInfoListener();
+ final Executor executor = Runnable::run;
+
+ // Register to ClientTransactionListenerController
+ mSplitController.setEmbeddedActivityWindowInfoCallback(executor,
+ mEmbeddedActivityWindowInfoCallback);
+
+ verify(controller).registerActivityWindowInfoChangedListener(mActivityWindowInfoListener);
+ verify(mEmbeddedActivityWindowInfoCallback, never()).accept(any());
+
+ // Test onActivityWindowInfoChanged triggered.
+ mSplitController.onActivityWindowInfoChanged(mActivity.getActivityToken(),
+ mActivityWindowInfo);
+
+ verify(mEmbeddedActivityWindowInfoCallback).accept(any());
+
+ // Unregister to ClientTransactionListenerController
+ mSplitController.clearEmbeddedActivityWindowInfoCallback();
+
+ verify(controller).unregisterActivityWindowInfoChangedListener(mActivityWindowInfoListener);
+
+ // Test onActivityWindowInfoChanged triggered as no-op after clear callback.
+ clearInvocations(mEmbeddedActivityWindowInfoCallback);
+ mSplitController.onActivityWindowInfoChanged(mActivity.getActivityToken(),
+ mActivityWindowInfo);
+
+ verify(mEmbeddedActivityWindowInfoCallback, never()).accept(any());
+ }
+
/** Creates a mock activity in the organizer process. */
private Activity createMockActivity() {
return createMockActivity(TASK_ID);
@@ -1537,13 +1623,17 @@ public class SplitControllerTest {
/** Creates a mock activity in the organizer process. */
private Activity createMockActivity(int taskId) {
final Activity activity = mock(Activity.class);
+ final ActivityThread.ActivityClientRecord activityClientRecord =
+ mock(ActivityThread.ActivityClientRecord.class);
doReturn(mActivityResources).when(activity).getResources();
final IBinder activityToken = new Binder();
doReturn(activityToken).when(activity).getActivityToken();
doReturn(activity).when(mSplitController).getActivity(activityToken);
+ doReturn(activityClientRecord).when(mSplitController).getActivityClientRecord(activity);
doReturn(taskId).when(activity).getTaskId();
doReturn(new ActivityInfo()).when(activity).getActivityInfo();
doReturn(DEFAULT_DISPLAY).when(activity).getDisplayId();
+ doReturn(mActivityWindowInfo).when(activityClientRecord).getActivityWindowInfo();
return activity;
}
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_header_ic_close.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_header_ic_close.xml
new file mode 100644
index 000000000000..ff49edb7a699
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_header_ic_close.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
+</vector>
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml
index 490f0883fbfb..a5605a7ff50a 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml
@@ -33,14 +33,15 @@
android:orientation="horizontal"
android:clickable="true"
android:focusable="true"
- android:paddingStart="6dp"
- android:paddingEnd="8dp">
+ android:paddingStart="12dp">
<ImageView
android:id="@+id/application_icon"
android:layout_width="@dimen/desktop_mode_caption_icon_radius"
android:layout_height="@dimen/desktop_mode_caption_icon_radius"
android:layout_gravity="center_vertical"
- android:contentDescription="@string/app_icon_text" />
+ android:contentDescription="@string/app_icon_text"
+ android:layout_marginStart="6dp"
+ android:scaleType="centerCrop"/>
<TextView
android:id="@+id/application_name"
@@ -53,8 +54,7 @@
android:lineHeight="20dp"
android:layout_gravity="center_vertical"
android:layout_weight="1"
- android:paddingStart="8dp"
- android:paddingEnd="8dp"
+ android:layout_marginStart="8dp"
tools:text="Gmail"/>
<ImageButton
@@ -67,6 +67,7 @@
android:scaleType="fitCenter"
android:clickable="false"
android:focusable="false"
+ android:layout_marginHorizontal="8dp"
android:layout_gravity="center_vertical"/>
</LinearLayout>
@@ -87,14 +88,15 @@
<ImageButton
android:id="@+id/close_window"
- android:layout_width="40dp"
+ android:layout_width="44dp"
android:layout_height="40dp"
- android:padding="4dp"
+ android:paddingHorizontal="10dp"
+ android:paddingVertical="8dp"
android:layout_marginEnd="8dp"
android:tint="?androidprv:attr/materialColorOnSurface"
android:background="?android:selectableItemBackgroundBorderless"
android:contentDescription="@string/close_button_text"
- android:src="@drawable/decor_close_button_dark"
- android:scaleType="fitCenter"
+ android:src="@drawable/desktop_mode_header_ic_close"
+ android:scaleType="centerCrop"
android:gravity="end"/>
</com.android.wm.shell.windowdecor.WindowDecorLinearLayout> \ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/values/config.xml b/libs/WindowManager/Shell/res/values/config.xml
index 8baaf2f155af..a541c590575f 100644
--- a/libs/WindowManager/Shell/res/values/config.xml
+++ b/libs/WindowManager/Shell/res/values/config.xml
@@ -145,4 +145,7 @@
<!-- Whether CompatUIController is enabled -->
<bool name="config_enableCompatUIController">true</bool>
+
+ <!-- Whether pointer pilfer is required to start back animation. -->
+ <bool name="config_backAnimationRequiresPointerPilfer">true</bool>
</resources>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 48e6428524ae..7dd39613b438 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -434,15 +434,22 @@
<!-- (32 dp buttons + 10dp margins) * 3 buttons-->
<dimen name="caption_right_buttons_width">126dp</dimen>
- <!-- 2 buttons * 48dp button size. -->
- <dimen name="desktop_mode_right_edge_buttons_width">96dp</dimen>
+ <!-- 2 buttons * 44dp button size + 16dp total margins. -->
+ <dimen name="desktop_mode_right_edge_buttons_width">104dp</dimen>
<!-- 22dp padding + 24dp app icon + 16dp expand button.
Text varies in size, we will calculate that width separately. -->
<dimen name="desktop_mode_app_details_width_minus_text">62dp</dimen>
- <!-- 22dp padding + 24dp app icon + 16dp expand button + 86dp text (max) -->
- <dimen name="desktop_mode_app_details_max_width">148dp</dimen>
+ <!-- When custom headers are requested, this is the width of the left-aligned region that is
+ taken up by caption elements and extra margins. The customizable region starts at the
+ end of this area. -->
+ <dimen name="desktop_mode_customizable_caption_margin_start">84dp</dimen>
+
+ <!-- When custom headers are requested, this is the width of the right-aligned region that is
+ taken up by caption elements and extra margins. The customizable region ends at the
+ start of this area. -->
+ <dimen name="desktop_mode_customizable_caption_margin_end">152dp</dimen>
<!-- The width of the maximize menu in desktop mode. -->
<dimen name="desktop_mode_maximize_menu_width">287dp</dimen>
@@ -490,7 +497,7 @@
<dimen name="desktop_mode_handle_menu_corner_radius">26dp</dimen>
<!-- The radius of the caption menu icon. -->
- <dimen name="desktop_mode_caption_icon_radius">28dp</dimen>
+ <dimen name="desktop_mode_caption_icon_radius">24dp</dimen>
<!-- The radius of the caption menu shadow. -->
<dimen name="desktop_mode_handle_menu_shadow_radius">2dp</dimen>
@@ -503,10 +510,6 @@
split select if dragged until the touch input is within the range. -->
<dimen name="desktop_mode_transition_area_width">32dp</dimen>
- <!-- The height of the area at the top of the screen where a freeform task will transition to
- fullscreen if dragged until the top bound of the task is within the area. -->
- <dimen name="desktop_mode_transition_area_height">16dp</dimen>
-
<!-- The width of the area where a desktop task will transition to fullscreen. -->
<dimen name="desktop_mode_fullscreen_from_desktop_width">80dp</dimen>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index 2606fb661e80..9bd8531d33dc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -64,6 +64,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.LatencyTracker;
import com.android.internal.view.AppearanceRegion;
+import com.android.wm.shell.R;
import com.android.wm.shell.animation.FlingAnimationUtils;
import com.android.wm.shell.common.ExternalInterfaceBinder;
import com.android.wm.shell.common.RemoteCallable;
@@ -115,6 +116,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
private boolean mShouldStartOnNextMoveEvent = false;
private boolean mOnBackStartDispatched = false;
private boolean mPointerPilfered = false;
+ private final boolean mRequirePointerPilfer;
private final FlingAnimationUtils mFlingAnimationUtils;
@@ -220,6 +222,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
mActivityTaskManager = activityTaskManager;
mContext = context;
mContentResolver = contentResolver;
+ mRequirePointerPilfer =
+ context.getResources().getBoolean(R.bool.config_backAnimationRequiresPointerPilfer);
mBgHandler = bgHandler;
shellInit.addInitCallback(this::onInit, this);
mAnimationBackground = backAnimationBackground;
@@ -560,7 +564,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
private void tryDispatchOnBackStarted(
IOnBackInvokedCallback callback,
BackMotionEvent backEvent) {
- if (mOnBackStartDispatched || callback == null || !mPointerPilfered) {
+ if (mOnBackStartDispatched
+ || callback == null
+ || (!mPointerPilfered && mRequirePointerPilfer)) {
return;
}
dispatchOnBackStarted(callback, backEvent);
@@ -1006,6 +1012,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
pw.println(prefix + " mBackGestureStarted=" + mBackGestureStarted);
pw.println(prefix + " mPostCommitAnimationInProgress=" + mPostCommitAnimationInProgress);
pw.println(prefix + " mShouldStartOnNextMoveEvent=" + mShouldStartOnNextMoveEvent);
+ pw.println(prefix + " mPointerPilfered=" + mPointerPilfered);
+ pw.println(prefix + " mRequirePointerPilfer=" + mRequirePointerPilfer);
pw.println(prefix + " mCurrentTracker state:");
mCurrentTracker.dump(pw, prefix + " ");
pw.println(prefix + " mQueuedTracker state:");
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/OWNERS
index 7237d2bde39f..37ccd15587e1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/OWNERS
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/OWNERS
@@ -1,2 +1,4 @@
# WM shell sub-modules splitscreen owner
chenghsiuchang@google.com
+jeremysim@google.com
+peanutbutter@google.com
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
index 7091c4b7210a..fb0ed1587055 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
@@ -98,6 +98,7 @@ public class DesktopModeVisualIndicator {
* Based on the coordinates of the current drag event, determine which indicator type we should
* display, including no visible indicator.
*/
+ @NonNull
IndicatorType updateIndicatorType(PointF inputCoordinates, int windowingMode) {
final DisplayLayout layout = mDisplayController.getDisplayLayout(mTaskInfo.displayId);
// If we are in freeform, we don't want a visible indicator in the "freeform" drag zone.
@@ -136,18 +137,18 @@ public class DesktopModeVisualIndicator {
Region calculateFullscreenRegion(DisplayLayout layout,
@WindowConfiguration.WindowingMode int windowingMode, int captionHeight) {
final Region region = new Region();
- int edgeTransitionHeight = mContext.getResources().getDimensionPixelSize(
- com.android.wm.shell.R.dimen.desktop_mode_transition_area_height);
+ int transitionHeight = windowingMode == WINDOWING_MODE_FREEFORM
+ ? 2 * layout.stableInsets().top
+ : mContext.getResources().getDimensionPixelSize(
+ com.android.wm.shell.R.dimen.desktop_mode_fullscreen_from_desktop_height);
// A thin, short Rect at the top of the screen.
if (windowingMode == WINDOWING_MODE_FREEFORM) {
int fromFreeformWidth = mContext.getResources().getDimensionPixelSize(
com.android.wm.shell.R.dimen.desktop_mode_fullscreen_from_desktop_width);
- int fromFreeformHeight = mContext.getResources().getDimensionPixelSize(
- com.android.wm.shell.R.dimen.desktop_mode_fullscreen_from_desktop_height);
region.union(new Rect((layout.width() / 2) - (fromFreeformWidth / 2),
-captionHeight,
(layout.width() / 2) + (fromFreeformWidth / 2),
- fromFreeformHeight));
+ transitionHeight));
}
// A screen-wide, shorter Rect if the task is in fullscreen or split.
if (windowingMode == WINDOWING_MODE_FULLSCREEN
@@ -155,7 +156,7 @@ public class DesktopModeVisualIndicator {
region.union(new Rect(0,
-captionHeight,
layout.width(),
- edgeTransitionHeight));
+ transitionHeight));
}
return region;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index b9d0342137c5..654409f4a637 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -62,7 +62,6 @@ import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.common.annotations.ExternalThread
import com.android.wm.shell.common.annotations.ShellMainThread
import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
-import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository.VisibleTasksListener
import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler.DragToDesktopStateListener
import com.android.wm.shell.draganddrop.DragAndDropController
@@ -141,7 +140,7 @@ class DesktopTasksController(
private val transitionAreaHeight
get() = context.resources.getDimensionPixelSize(
- com.android.wm.shell.R.dimen.desktop_mode_transition_area_height
+ com.android.wm.shell.R.dimen.desktop_mode_fullscreen_from_desktop_height
)
private val transitionAreaWidth
@@ -417,23 +416,9 @@ class DesktopTasksController(
splitScreenController.getStageOfTask(taskInfo.taskId),
EXIT_REASON_DESKTOP_MODE
)
- getOtherSplitTask(taskInfo.taskId)?.let { otherTaskInfo ->
- wct.removeTask(otherTaskInfo.token)
- }
}
}
- private fun getOtherSplitTask(taskId: Int): RunningTaskInfo? {
- val remainingTaskPosition: Int =
- if (splitScreenController.getSplitPosition(taskId)
- == SPLIT_POSITION_BOTTOM_OR_RIGHT) {
- SPLIT_POSITION_TOP_OR_LEFT
- } else {
- SPLIT_POSITION_BOTTOM_OR_RIGHT
- }
- return splitScreenController.getTaskInfo(remainingTaskPosition)
- }
-
/**
* The second part of the animated drag to desktop transition, called after
* [startDragToDesktop].
@@ -580,30 +565,7 @@ class DesktopTasksController(
* @param position the portion of the screen (RIGHT or LEFT) we want to snap the task to.
*/
fun snapToHalfScreen(taskInfo: RunningTaskInfo, position: SnapPosition) {
- val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return
-
- val stableBounds = Rect()
- displayLayout.getStableBounds(stableBounds)
-
- val destinationWidth = stableBounds.width() / 2
- val destinationBounds = when (position) {
- SnapPosition.LEFT -> {
- Rect(
- stableBounds.left,
- stableBounds.top,
- stableBounds.left + destinationWidth,
- stableBounds.bottom
- )
- }
- SnapPosition.RIGHT -> {
- Rect(
- stableBounds.right - destinationWidth,
- stableBounds.top,
- stableBounds.right,
- stableBounds.bottom
- )
- }
- }
+ val destinationBounds = getSnapBounds(taskInfo, position)
if (destinationBounds == taskInfo.configuration.windowConfiguration.bounds) return
@@ -624,8 +586,35 @@ class DesktopTasksController(
outBounds.set(0, 0, desiredWidth, desiredHeight)
// Center the task in screen bounds
outBounds.offset(
- screenBounds.centerX() - outBounds.centerX(),
- screenBounds.centerY() - outBounds.centerY())
+ screenBounds.centerX() - outBounds.centerX(),
+ screenBounds.centerY() - outBounds.centerY())
+ }
+
+ private fun getSnapBounds(taskInfo: RunningTaskInfo, position: SnapPosition): Rect {
+ val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return Rect()
+
+ val stableBounds = Rect()
+ displayLayout.getStableBounds(stableBounds)
+
+ val destinationWidth = stableBounds.width() / 2
+ return when (position) {
+ SnapPosition.LEFT -> {
+ Rect(
+ stableBounds.left,
+ stableBounds.top,
+ stableBounds.left + destinationWidth,
+ stableBounds.bottom
+ )
+ }
+ SnapPosition.RIGHT -> {
+ Rect(
+ stableBounds.right - destinationWidth,
+ stableBounds.top,
+ stableBounds.right,
+ stableBounds.bottom
+ )
+ }
+ }
}
/**
@@ -661,7 +650,7 @@ class DesktopTasksController(
?.let { homeTask -> wct.reorder(homeTask.getToken(), true /* onTop */) }
}
- private fun releaseVisualIndicator() {
+ fun releaseVisualIndicator() {
val t = SurfaceControl.Transaction()
visualIndicator?.releaseVisualIndicator(t)
visualIndicator = null
@@ -942,16 +931,13 @@ class DesktopTasksController(
taskSurface: SurfaceControl,
inputX: Float,
taskTop: Float
- ) {
+ ): DesktopModeVisualIndicator.IndicatorType {
// If the visual indicator does not exist, create it.
- if (visualIndicator == null) {
- visualIndicator = DesktopModeVisualIndicator(
- syncQueue, taskInfo, displayController, context, taskSurface,
- rootTaskDisplayAreaOrganizer)
- }
- // Then, update the indicator type.
- val indicator = visualIndicator ?: return
- indicator.updateIndicatorType(PointF(inputX, taskTop), taskInfo.windowingMode)
+ val indicator = visualIndicator ?: DesktopModeVisualIndicator(
+ syncQueue, taskInfo, displayController, context, taskSurface,
+ rootTaskDisplayAreaOrganizer)
+ if (visualIndicator == null) visualIndicator = indicator
+ return indicator.updateIndicatorType(PointF(inputX, taskTop), taskInfo.windowingMode)
}
/**
@@ -971,20 +957,28 @@ class DesktopTasksController(
if (taskInfo.configuration.windowConfiguration.windowingMode != WINDOWING_MODE_FREEFORM) {
return
}
- if (taskBounds.top <= transitionAreaHeight) {
- moveToFullscreenWithAnimation(taskInfo, position)
- return
- }
- if (inputCoordinate.x <= transitionAreaWidth) {
- releaseVisualIndicator()
- snapToHalfScreen(taskInfo, SnapPosition.LEFT)
- return
- }
- if (inputCoordinate.x >= (displayController.getDisplayLayout(taskInfo.displayId)?.width()
- ?.minus(transitionAreaWidth) ?: return)) {
- releaseVisualIndicator()
- snapToHalfScreen(taskInfo, SnapPosition.RIGHT)
- return
+
+ val indicator = visualIndicator ?: return
+ val indicatorType = indicator.updateIndicatorType(
+ PointF(inputCoordinate.x, taskBounds.top.toFloat()),
+ taskInfo.windowingMode
+ )
+ when (indicatorType) {
+ DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR -> {
+ moveToFullscreenWithAnimation(taskInfo, position)
+ }
+ DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR -> {
+ releaseVisualIndicator()
+ snapToHalfScreen(taskInfo, SnapPosition.LEFT)
+ }
+ DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR -> {
+ releaseVisualIndicator()
+ snapToHalfScreen(taskInfo, SnapPosition.RIGHT)
+ }
+ DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR,
+ DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR -> {
+ releaseVisualIndicator()
+ }
}
// A freeform drag-move ended, remove the indicator immediately.
releaseVisualIndicator()
@@ -997,14 +991,28 @@ class DesktopTasksController(
* @param y height of drag, to be checked against status bar height.
*/
fun onDragPositioningEndThroughStatusBar(
+ inputCoordinates: PointF,
taskInfo: RunningTaskInfo,
freeformBounds: Rect
) {
- finalizeDragToDesktop(taskInfo, freeformBounds)
- }
-
- private fun getStatusBarHeight(taskInfo: RunningTaskInfo): Int {
- return displayController.getDisplayLayout(taskInfo.displayId)?.stableInsets()?.top ?: 0
+ val indicator = visualIndicator ?: return
+ val indicatorType = indicator
+ .updateIndicatorType(inputCoordinates, taskInfo.windowingMode)
+ when (indicatorType) {
+ DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR -> {
+ finalizeDragToDesktop(taskInfo, freeformBounds)
+ }
+ DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR,
+ DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR -> {
+ cancelDragToDesktop(taskInfo)
+ }
+ DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR -> {
+ finalizeDragToDesktop(taskInfo, getSnapBounds(taskInfo, SnapPosition.LEFT))
+ }
+ DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR -> {
+ finalizeDragToDesktop(taskInfo, getSnapBounds(taskInfo, SnapPosition.RIGHT))
+ }
+ }
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index 2cdec81d77ac..4d47ca998d8b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -122,6 +122,8 @@ public class PipController implements PipTransitionController.PipTransitionCallb
private static final long PIP_KEEP_CLEAR_AREAS_DELAY =
SystemProperties.getLong("persist.wm.debug.pip_keep_clear_areas_delay", 200);
+ private static final long ENABLE_TOUCH_DELAY_MS = 200L;
+
private Context mContext;
protected ShellExecutor mMainExecutor;
private DisplayController mDisplayController;
@@ -152,6 +154,8 @@ public class PipController implements PipTransitionController.PipTransitionCallb
private final Runnable mMovePipInResponseToKeepClearAreasChangeCallback =
this::onKeepClearAreasChangedCallback;
+ private final Runnable mEnableTouchCallback = () -> mTouchHandler.setTouchEnabled(true);
+
private void onKeepClearAreasChangedCallback() {
if (mIsKeyguardShowingOrAnimating) {
// early bail out if the change was caused by keyguard showing up
@@ -1037,6 +1041,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb
saveReentryState(pipBounds);
}
// Disable touches while the animation is running
+ mMainExecutor.removeCallbacks(mEnableTouchCallback);
mTouchHandler.setTouchEnabled(false);
if (mPinnedStackAnimationRecentsCallback != null) {
mPinnedStackAnimationRecentsCallback.onPipAnimationStarted();
@@ -1067,7 +1072,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb
InteractionJankMonitor.getInstance().end(CUJ_PIP_TRANSITION);
// Re-enable touches after the animation completes
- mTouchHandler.setTouchEnabled(true);
+ mMainExecutor.executeDelayed(mEnableTouchCallback, ENABLE_TOUCH_DELAY_MS);
mTouchHandler.onPinnedStackAnimationEnded(direction);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/OWNERS
index 7237d2bde39f..37ccd15587e1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/OWNERS
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/OWNERS
@@ -1,2 +1,4 @@
# WM shell sub-modules splitscreen owner
chenghsiuchang@google.com
+jeremysim@google.com
+peanutbutter@google.com
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 2321869d2f4a..76504447339f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -55,6 +55,7 @@ import static com.android.wm.shell.splitscreen.SplitScreenController.ENTER_REASO
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_FINISHED;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_CHILD_TASK_ENTER_PIP;
+import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DESKTOP_MODE;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DEVICE_FOLDED;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_FULLSCREEN_SHORTCUT;
@@ -1607,6 +1608,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// The device is folded
case EXIT_REASON_FULLSCREEN_SHORTCUT:
// User has used a keyboard shortcut to go back to fullscreen from split
+ case EXIT_REASON_DESKTOP_MODE:
+ // One of the children enters desktop mode
return true;
default:
return false;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index 8d798a3035f6..f4ccd689f938 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -30,6 +30,10 @@ import static android.view.WindowInsets.Type.statusBars;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
+import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR;
+import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR;
+import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR;
+import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR;
import static com.android.wm.shell.desktopmode.EnterDesktopTaskTransitionHandler.FREEFORM_ANIMATION_DURATION;
import static com.android.wm.shell.windowdecor.MoveToDesktopAnimator.DRAG_FREEFORM_SCALE;
@@ -81,6 +85,7 @@ import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
import com.android.wm.shell.desktopmode.DesktopModeStatus;
+import com.android.wm.shell.desktopmode.DesktopModeVisualIndicator;
import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition;
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
@@ -119,9 +124,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
private final Choreographer mMainChoreographer;
private final DisplayController mDisplayController;
private final SyncTransactionQueue mSyncQueue;
- private final Optional<DesktopTasksController> mDesktopTasksController;
+ private final DesktopTasksController mDesktopTasksController;
private final InputManager mInputManager;
-
private boolean mTransitionDragActive;
private SparseArray<EventReceiver> mEventReceiversByDisplay = new SparseArray<>();
@@ -129,8 +133,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
private final ExclusionRegionListener mExclusionRegionListener =
new ExclusionRegionListenerImpl();
- private final SparseArray<DesktopModeWindowDecoration> mWindowDecorByTaskId =
- new SparseArray<>();
+ private final SparseArray<DesktopModeWindowDecoration> mWindowDecorByTaskId;
private final DragStartListenerImpl mDragStartListener = new DragStartListenerImpl();
private final InputMonitorFactory mInputMonitorFactory;
private TaskOperations mTaskOperations;
@@ -197,7 +200,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
new DesktopModeWindowDecoration.Factory(),
new InputMonitorFactory(),
SurfaceControl.Transaction::new,
- rootTaskDisplayAreaOrganizer);
+ rootTaskDisplayAreaOrganizer,
+ new SparseArray<>());
}
@VisibleForTesting
@@ -219,7 +223,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
DesktopModeWindowDecoration.Factory desktopModeWindowDecorFactory,
InputMonitorFactory inputMonitorFactory,
Supplier<SurfaceControl.Transaction> transactionFactory,
- RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) {
+ RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
+ SparseArray<DesktopModeWindowDecoration> windowDecorByTaskId) {
mContext = context;
mMainExecutor = shellExecutor;
mMainHandler = mainHandler;
@@ -231,7 +236,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
mDisplayInsetsController = displayInsetsController;
mSyncQueue = syncQueue;
mTransitions = transitions;
- mDesktopTasksController = desktopTasksController;
+ mDesktopTasksController = desktopTasksController.get();
mShellCommandHandler = shellCommandHandler;
mWindowManager = windowManager;
mDesktopModeWindowDecorFactory = desktopModeWindowDecorFactory;
@@ -239,6 +244,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
mTransactionFactory = transactionFactory;
mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
mInputManager = mContext.getSystemService(InputManager.class);
+ mWindowDecorByTaskId = windowDecorByTaskId;
shellInit.addInitCallback(this::onInit, this);
}
@@ -248,8 +254,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
mShellCommandHandler.addDumpCallback(this::dump, this);
mDisplayInsetsController.addInsetsChangedListener(mContext.getDisplayId(),
new DesktopModeOnInsetsChangedListener());
- mDesktopTasksController.ifPresent(c -> c.setOnTaskResizeAnimationListener(
- new DeskopModeOnTaskResizeAnimationListener()));
+ mDesktopTasksController.setOnTaskResizeAnimationListener(
+ new DeskopModeOnTaskResizeAnimationListener());
try {
mWindowManager.registerSystemGestureExclusionListener(mGestureExclusionListener,
mContext.getDisplayId());
@@ -273,7 +279,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
DesktopModeWindowDecoration decor = mWindowDecorByTaskId.get(taskId);
if (decor != null && DesktopModeStatus.isEnabled()
&& decor.mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
- mDesktopTasksController.ifPresent(c -> c.moveToSplit(decor.mTaskInfo));
+ mDesktopTasksController.moveToSplit(decor.mTaskInfo);
}
}
}
@@ -340,8 +346,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
@Override
public void destroyWindowDecoration(RunningTaskInfo taskInfo) {
- final DesktopModeWindowDecoration decoration =
- mWindowDecorByTaskId.removeReturnOld(taskInfo.taskId);
+ final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId);
if (decoration == null) return;
decoration.close();
@@ -349,6 +354,10 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
if (mEventReceiversByDisplay.contains(displayId)) {
removeTaskFromEventReceiver(displayId);
}
+ // Remove the decoration from the cache last because WindowDecoration#close could still
+ // issue CANCEL MotionEvents to touch listeners before its view host is released.
+ // See b/327664694.
+ mWindowDecorByTaskId.remove(taskInfo.taskId);
}
private class DesktopModeTouchEventListener extends GestureDetector.SimpleOnGestureListener
@@ -414,14 +423,11 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
decoration.closeHandleMenu();
}
} else if (id == R.id.desktop_button) {
- if (mDesktopTasksController.isPresent()) {
- final WindowContainerTransaction wct = new WindowContainerTransaction();
- // App sometimes draws before the insets from WindowDecoration#relayout have
- // been added, so they must be added here
- mWindowDecorByTaskId.get(mTaskId).addCaptionInset(wct);
- mDesktopTasksController.get().moveToDesktop(mTaskId, wct);
- closeOtherSplitTask(mTaskId);
- }
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ // App sometimes draws before the insets from WindowDecoration#relayout have
+ // been added, so they must be added here
+ mWindowDecorByTaskId.get(mTaskId).addCaptionInset(wct);
+ mDesktopTasksController.moveToDesktop(mTaskId, wct);
decoration.closeHandleMenu();
} else if (id == R.id.fullscreen_button) {
decoration.closeHandleMenu();
@@ -429,42 +435,37 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
mSplitScreenController.moveTaskToFullscreen(mTaskId,
SplitScreenController.EXIT_REASON_DESKTOP_MODE);
} else {
- mDesktopTasksController.ifPresent(c ->
- c.moveToFullscreen(mTaskId));
+ mDesktopTasksController.moveToFullscreen(mTaskId);
}
} else if (id == R.id.split_screen_button) {
decoration.closeHandleMenu();
- mDesktopTasksController.ifPresent(c -> {
- c.requestSplit(decoration.mTaskInfo);
- });
+ mDesktopTasksController.requestSplit(decoration.mTaskInfo);
} else if (id == R.id.collapse_menu_button) {
decoration.closeHandleMenu();
} else if (id == R.id.select_button) {
if (DesktopModeStatus.IS_DISPLAY_CHANGE_ENABLED) {
// TODO(b/278084491): dev option to enable display switching
// remove when select is implemented
- mDesktopTasksController.ifPresent(c -> c.moveToNextDisplay(mTaskId));
+ mDesktopTasksController.moveToNextDisplay(mTaskId);
}
} else if (id == R.id.maximize_window) {
final RunningTaskInfo taskInfo = decoration.mTaskInfo;
decoration.closeHandleMenu();
decoration.closeMaximizeMenu();
- mDesktopTasksController.ifPresent(c -> c.toggleDesktopTaskSize(taskInfo));
+ mDesktopTasksController.toggleDesktopTaskSize(taskInfo);
} else if (id == R.id.maximize_menu_maximize_button) {
final RunningTaskInfo taskInfo = decoration.mTaskInfo;
- mDesktopTasksController.ifPresent(c -> c.toggleDesktopTaskSize(taskInfo));
+ mDesktopTasksController.toggleDesktopTaskSize(taskInfo);
decoration.closeHandleMenu();
decoration.closeMaximizeMenu();
} else if (id == R.id.maximize_menu_snap_left_button) {
final RunningTaskInfo taskInfo = decoration.mTaskInfo;
- mDesktopTasksController.ifPresent(c -> c.snapToHalfScreen(
- taskInfo, SnapPosition.LEFT));
+ mDesktopTasksController.snapToHalfScreen(taskInfo, SnapPosition.LEFT);
decoration.closeHandleMenu();
decoration.closeMaximizeMenu();
} else if (id == R.id.maximize_menu_snap_right_button) {
final RunningTaskInfo taskInfo = decoration.mTaskInfo;
- mDesktopTasksController.ifPresent(c -> c.snapToHalfScreen(
- taskInfo, SnapPosition.RIGHT));
+ mDesktopTasksController.snapToHalfScreen(taskInfo, SnapPosition.RIGHT);
decoration.closeHandleMenu();
decoration.closeMaximizeMenu();
}
@@ -559,8 +560,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
} else if (ev.getAction() == ACTION_HOVER_EXIT) {
if (!decoration.isMaximizeMenuActive() && id == R.id.maximize_window) {
decoration.onMaximizeWindowHoverExit();
- } else if (id == R.id.maximize_window
- || MaximizeMenu.Companion.isMaximizeMenuView(id)) {
+ } else if (id == R.id.maximize_window || id == R.id.maximize_menu) {
// Close menu if not hovering over maximize menu or maximize button after a
// delay to give user a chance to re-enter view or to move from one maximize
// menu view to another.
@@ -574,7 +574,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
private void moveTaskToFront(RunningTaskInfo taskInfo) {
if (!taskInfo.isFocused) {
- mDesktopTasksController.ifPresent(c -> c.moveTaskToFront(taskInfo));
+ mDesktopTasksController.moveTaskToFront(taskInfo);
}
}
@@ -618,10 +618,10 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
final int dragPointerIdx = e.findPointerIndex(mDragPointerId);
final Rect newTaskBounds = mDragPositioningCallback.onDragPositioningMove(
e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
- mDesktopTasksController.ifPresent(c -> c.onDragPositioningMove(taskInfo,
+ mDesktopTasksController.onDragPositioningMove(taskInfo,
decoration.mTaskSurface,
e.getRawX(dragPointerIdx),
- newTaskBounds));
+ newTaskBounds);
mIsDragging = true;
return true;
}
@@ -643,10 +643,9 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
(int) (e.getRawY(dragPointerIdx) - e.getY(dragPointerIdx)));
final Rect newTaskBounds = mDragPositioningCallback.onDragPositioningEnd(
e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
- mDesktopTasksController.ifPresent(c -> c.onDragPositioningEnd(taskInfo,
- position,
+ mDesktopTasksController.onDragPositioningEnd(taskInfo, position,
new PointF(e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx)),
- newTaskBounds));
+ newTaskBounds);
if (touchingButton && !mHasLongClicked) {
// We need the input event to not be consumed here to end the ripple
// effect on the touched button. We will reset drag state in the ensuing
@@ -674,10 +673,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
&& action != MotionEvent.ACTION_CANCEL)) {
return false;
}
- mDesktopTasksController.ifPresent(c -> {
- final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
- c.toggleDesktopTaskSize(decoration.mTaskInfo);
- });
+ final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
+ mDesktopTasksController.toggleDesktopTaskSize(decoration.mTaskInfo);
return true;
}
}
@@ -841,20 +838,29 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
return;
}
if (mTransitionDragActive) {
+ final DesktopModeVisualIndicator.IndicatorType indicatorType =
+ mDesktopTasksController.updateVisualIndicator(relevantDecor.mTaskInfo,
+ relevantDecor.mTaskSurface, ev.getRawX(), ev.getRawY());
mTransitionDragActive = false;
- final int statusBarHeight = getStatusBarHeight(
- relevantDecor.mTaskInfo.displayId);
- if (ev.getRawY() > 2 * statusBarHeight) {
+ if (indicatorType == TO_DESKTOP_INDICATOR
+ || indicatorType == TO_SPLIT_LEFT_INDICATOR
+ || indicatorType == TO_SPLIT_RIGHT_INDICATOR) {
if (DesktopModeStatus.isEnabled()) {
animateToDesktop(relevantDecor, ev);
}
mMoveToDesktopAnimator = null;
return;
} else if (mMoveToDesktopAnimator != null) {
- mDesktopTasksController.ifPresent(
- c -> c.cancelDragToDesktop(relevantDecor.mTaskInfo));
+ mDesktopTasksController.onDragPositioningEndThroughStatusBar(
+ new PointF(ev.getRawX(), ev.getRawY()),
+ relevantDecor.mTaskInfo,
+ calculateFreeformBounds(ev.getDisplayId(), DRAG_FREEFORM_SCALE));
mMoveToDesktopAnimator = null;
return;
+ } else {
+ // In cases where we create an indicator but do not start the
+ // move-to-desktop animation, we need to dismiss it.
+ mDesktopTasksController.releaseVisualIndicator();
}
}
relevantDecor.checkClickEvent(ev);
@@ -866,20 +872,17 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
return;
}
if (mTransitionDragActive) {
- mDesktopTasksController.ifPresent(
- c -> c.updateVisualIndicator(
+ final DesktopModeVisualIndicator.IndicatorType indicatorType =
+ mDesktopTasksController.updateVisualIndicator(
relevantDecor.mTaskInfo,
- relevantDecor.mTaskSurface, ev.getRawX(), ev.getRawY()));
- final int statusBarHeight = getStatusBarHeight(
- relevantDecor.mTaskInfo.displayId);
- if (ev.getRawY() > statusBarHeight) {
+ relevantDecor.mTaskSurface, ev.getRawX(), ev.getRawY());
+ if (indicatorType != TO_FULLSCREEN_INDICATOR) {
if (mMoveToDesktopAnimator == null) {
mMoveToDesktopAnimator = new MoveToDesktopAnimator(
mContext, mDragToDesktopAnimationStartBounds,
relevantDecor.mTaskInfo, relevantDecor.mTaskSurface);
- mDesktopTasksController.ifPresent(
- c -> c.startDragToDesktop(relevantDecor.mTaskInfo,
- mMoveToDesktopAnimator));
+ mDesktopTasksController.startDragToDesktop(relevantDecor.mTaskInfo,
+ mMoveToDesktopAnimator);
}
}
if (mMoveToDesktopAnimator != null) {
@@ -925,6 +928,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
* Animates a window to the center, grows to freeform size, and transitions to Desktop Mode.
* @param relevantDecor the window decor of the task to be animated
* @param ev the motion event that triggers the animation
+ * TODO(b/315527000): This animation needs to be adjusted to allow snap left/right cases.
+ * Currently fullscreen -> split snap still animates to center screen before readjusting.
*/
private void centerAndMoveToDesktopWithAnimation(DesktopModeWindowDecoration relevantDecor,
MotionEvent ev) {
@@ -948,13 +953,12 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- mDesktopTasksController.ifPresent(
- c -> {
- c.onDragPositioningEndThroughStatusBar(relevantDecor.mTaskInfo,
- calculateFreeformBounds(ev.getDisplayId(),
- DesktopTasksController
- .DESKTOP_MODE_INITIAL_BOUNDS_SCALE));
- });
+ mDesktopTasksController.onDragPositioningEndThroughStatusBar(
+ new PointF(ev.getRawX(), ev.getRawY()),
+ relevantDecor.mTaskInfo,
+ calculateFreeformBounds(ev.getDisplayId(),
+ DesktopTasksController
+ .DESKTOP_MODE_INITIAL_BOUNDS_SCALE));
}
});
animator.start();
@@ -1084,7 +1088,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
final DragPositioningCallback dragPositioningCallback;
final int transitionAreaHeight = mContext.getResources().getDimensionPixelSize(
- R.dimen.desktop_mode_transition_area_height);
+ R.dimen.desktop_mode_fullscreen_from_desktop_height);
if (!DesktopModeStatus.isVeiledResizeEnabled()) {
dragPositioningCallback = new FluidResizeTaskPositioner(
mTaskOrganizer, mTransitions, windowDecoration, mDisplayController,
@@ -1119,12 +1123,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
return mSplitScreenController.getTaskInfo(remainingTaskPosition);
}
- private void closeOtherSplitTask(int taskId) {
- if (isTaskInSplitScreen(taskId)) {
- mTaskOperations.closeTask(getOtherSplitTask(taskId).token);
- }
- }
-
private boolean isTaskInSplitScreen(int taskId) {
return mSplitScreenController != null
&& mSplitScreenController.isTaskInSplitScreen(taskId);
@@ -1189,12 +1187,12 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
@Override
public void onExclusionRegionChanged(int taskId, Region region) {
- mDesktopTasksController.ifPresent(d -> d.onExclusionRegionChanged(taskId, region));
+ mDesktopTasksController.onExclusionRegionChanged(taskId, region);
}
@Override
public void onExclusionRegionDismissed(int taskId) {
- mDesktopTasksController.ifPresent(d -> d.removeExclusionRegionForTask(taskId));
+ mDesktopTasksController.removeExclusionRegionForTask(taskId);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index 9e999ae52835..39803e2afd34 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -318,28 +318,25 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
relayoutParams.mCaptionHeightId = getCaptionHeightIdStatic(taskInfo.getWindowingMode());
relayoutParams.mCaptionWidthId = getCaptionWidthId(relayoutParams.mLayoutResId);
- // The "app controls" type caption bar should report the occluding elements as bounding
- // rects to the insets system so that apps can draw in the empty space left in the center.
- if (captionLayoutId == R.layout.desktop_mode_app_controls_window_decor) {
- // The "app chip" section of the caption bar, it's aligned to the left and its width
- // varies depending on the length of the app name, but we'll report its max width for
- // now.
- // TODO(b/316387515): consider reporting the true width after it's been laid out.
+ if (captionLayoutId == R.layout.desktop_mode_app_controls_window_decor
+ && TaskInfoKt.isTransparentCaptionBarAppearance(taskInfo)) {
+ // App is requesting to customize the caption bar. Allow input to fall through to the
+ // windows below so that the app can respond to input events on their custom content.
+ relayoutParams.mAllowCaptionInputFallthrough = true;
+ // Report occluding elements as bounding rects to the insets system so that apps can
+ // draw in the empty space in the center:
+ // First, the "app chip" section of the caption bar (+ some extra margins).
final RelayoutParams.OccludingCaptionElement appChipElement =
new RelayoutParams.OccludingCaptionElement();
- appChipElement.mWidthResId = R.dimen.desktop_mode_app_details_max_width;
+ appChipElement.mWidthResId = R.dimen.desktop_mode_customizable_caption_margin_start;
appChipElement.mAlignment = RelayoutParams.OccludingCaptionElement.Alignment.START;
relayoutParams.mOccludingCaptionElements.add(appChipElement);
- // The "controls" section of the caption bar (maximize, close btns). These are aligned
- // to the right of the caption bar and have a fixed width.
- // TODO(b/316387515): add additional padding for an exclusive drag-move region.
+ // Then, the right-aligned section (drag space, maximize and close buttons).
final RelayoutParams.OccludingCaptionElement controlsElement =
new RelayoutParams.OccludingCaptionElement();
- controlsElement.mWidthResId = R.dimen.desktop_mode_right_edge_buttons_width;
+ controlsElement.mWidthResId = R.dimen.desktop_mode_customizable_caption_margin_end;
controlsElement.mAlignment = RelayoutParams.OccludingCaptionElement.Alignment.END;
relayoutParams.mOccludingCaptionElements.add(controlsElement);
- relayoutParams.mAllowCaptionInputFallthrough =
- TaskInfoKt.isTransparentCaptionBarAppearance(taskInfo);
}
if (DesktopModeStatus.useWindowShadow(/* isFocusedWindow= */ taskInfo.isFocused)) {
relayoutParams.mShadowRadiusId = taskInfo.isFocused
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt
index b7dd01faa543..58bbb030da01 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt
@@ -12,6 +12,7 @@ import android.widget.ImageButton
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.withStyledAttributes
+import androidx.core.view.isVisible
import com.android.internal.R.attr.materialColorOnSecondaryContainer
import com.android.internal.R.attr.materialColorOnSurface
import com.android.internal.R.attr.materialColorSecondaryContainer
@@ -76,6 +77,7 @@ internal class DesktopModeAppControlsWindowDecorationViewHolder(
closeWindowButton.imageTintList = ColorStateList.valueOf(color)
maximizeWindowButton.imageTintList = ColorStateList.valueOf(color)
expandMenuButton.imageTintList = ColorStateList.valueOf(color)
+ appNameTextView.isVisible = !taskInfo.isTransparentCaptionBarAppearance
appNameTextView.setTextColor(color)
appIconImageView.imageAlpha = alpha
maximizeWindowButton.imageAlpha = alpha
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
index f8ce4ee8e1ce..9703dce8bf53 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
@@ -56,18 +56,16 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() {
context, taskSurface, taskDisplayAreaOrganizer)
whenever(displayLayout.width()).thenReturn(DISPLAY_BOUNDS.width())
whenever(displayLayout.height()).thenReturn(DISPLAY_BOUNDS.height())
+ whenever(displayLayout.stableInsets()).thenReturn(STABLE_INSETS)
}
@Test
fun testFullscreenRegionCalculation() {
val transitionHeight = context.resources.getDimensionPixelSize(
- R.dimen.desktop_mode_transition_area_height)
+ R.dimen.desktop_mode_fullscreen_from_desktop_height)
val fromFreeformWidth = mContext.resources.getDimensionPixelSize(
R.dimen.desktop_mode_fullscreen_from_desktop_width
)
- val fromFreeformHeight = mContext.resources.getDimensionPixelSize(
- R.dimen.desktop_mode_fullscreen_from_desktop_height
- )
var testRegion = visualIndicator.calculateFullscreenRegion(displayLayout,
WINDOWING_MODE_FULLSCREEN, CAPTION_HEIGHT)
assertThat(testRegion.bounds).isEqualTo(Rect(0, -50, 2400, transitionHeight))
@@ -77,7 +75,7 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() {
DISPLAY_BOUNDS.width() / 2 - fromFreeformWidth / 2,
-50,
DISPLAY_BOUNDS.width() / 2 + fromFreeformWidth / 2,
- fromFreeformHeight))
+ 2 * STABLE_INSETS.top))
testRegion = visualIndicator.calculateFullscreenRegion(displayLayout,
WINDOWING_MODE_MULTI_WINDOW, CAPTION_HEIGHT)
assertThat(testRegion.bounds).isEqualTo(Rect(0, -50, 2400, transitionHeight))
@@ -135,5 +133,12 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() {
private const val TRANSITION_AREA_WIDTH = 32
private const val CAPTION_HEIGHT = 50
private val DISPLAY_BOUNDS = Rect(0, 0, 2400, 1600)
+ private const val NAVBAR_HEIGHT = 50
+ private val STABLE_INSETS = Rect(
+ DISPLAY_BOUNDS.left,
+ DISPLAY_BOUNDS.top + CAPTION_HEIGHT,
+ DISPLAY_BOUNDS.right,
+ DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT
+ )
}
} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
index 917fd715f71f..9bb5482de715 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
@@ -29,6 +29,7 @@ import android.hardware.display.VirtualDisplay
import android.os.Handler
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
+import android.util.SparseArray
import android.view.Choreographer
import android.view.Display.DEFAULT_DISPLAY
import android.view.IWindowManager
@@ -72,6 +73,8 @@ import org.mockito.kotlin.eq
import org.mockito.kotlin.whenever
import java.util.Optional
import java.util.function.Supplier
+import org.mockito.Mockito
+import org.mockito.kotlin.spy
/** Tests of [DesktopModeWindowDecorViewModel] */
@@ -102,6 +105,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
private val transactionFactory = Supplier<SurfaceControl.Transaction> {
SurfaceControl.Transaction()
}
+ private val windowDecorByTaskIdSpy = spy(SparseArray<DesktopModeWindowDecoration>())
private lateinit var shellInit: ShellInit
private lateinit var desktopModeOnInsetsChangedListener: DesktopModeOnInsetsChangedListener
@@ -110,6 +114,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
@Before
fun setUp() {
shellInit = ShellInit(mockShellExecutor)
+ windowDecorByTaskIdSpy.clear()
desktopModeWindowDecorViewModel = DesktopModeWindowDecorViewModel(
mContext,
mockShellExecutor,
@@ -128,7 +133,8 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
mockDesktopModeWindowDecorFactory,
mockInputMonitorFactory,
transactionFactory,
- mockRootTaskDisplayAreaOrganizer
+ mockRootTaskDisplayAreaOrganizer,
+ windowDecorByTaskIdSpy
)
whenever(mockDisplayController.getDisplayLayout(any())).thenReturn(mockDisplayLayout)
@@ -332,6 +338,19 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
verify(decoration, times(1)).relayout(task)
}
+ @Test
+ fun testDestroyWindowDecoration_closesBeforeCleanup() {
+ val task = createTask(windowingMode = WINDOWING_MODE_FREEFORM)
+ val decoration = setUpMockDecorationForTask(task)
+ val inOrder = Mockito.inOrder(decoration, windowDecorByTaskIdSpy)
+
+ onTaskOpening(task)
+ desktopModeWindowDecorViewModel.destroyWindowDecoration(task)
+
+ inOrder.verify(decoration).close()
+ inOrder.verify(windowDecorByTaskIdSpy).remove(task.taskId)
+ }
+
private fun onTaskOpening(task: RunningTaskInfo, leash: SurfaceControl = SurfaceControl()) {
desktopModeWindowDecorViewModel.onTaskOpening(
task,
diff --git a/libs/hostgraphics/ADisplay.cpp b/libs/hostgraphics/ADisplay.cpp
new file mode 100644
index 000000000000..9cc1f40184e3
--- /dev/null
+++ b/libs/hostgraphics/ADisplay.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <apex/display.h>
+#include <utils/Errors.h>
+
+namespace android::display::impl {
+
+/**
+ * Implementation of ADisplayConfig
+ */
+struct DisplayConfigImpl {
+ /**
+ * The width in pixels of the display configuration.
+ */
+ int32_t width{1080};
+
+ /**
+ * The height in pixels of the display configuration.
+ */
+
+ int32_t height{1920};
+
+ /**
+ * The refresh rate of the display configuration, in frames per second.
+ */
+ float fps{60.0};
+
+ /**
+ * The vsync offset at which surfaceflinger runs, in nanoseconds.
+ */
+ int64_t sfOffset{0};
+
+ /**
+ * The vsync offset at which applications run, in nanoseconds.
+ */
+ int64_t appOffset{0};
+};
+
+// DisplayConfigImpl allocation is not managed through C++ memory apis, so
+// preventing calling the destructor here.
+static_assert(std::is_trivially_destructible<DisplayConfigImpl>::value);
+
+/**
+ * Implementation of ADisplay
+ */
+struct DisplayImpl {
+ /**
+ * The type of the display, i.e. whether it is an internal or external
+ * display.
+ */
+ ADisplayType type;
+
+ /**
+ * The preferred WCG dataspace
+ */
+ ADataSpace wcgDataspace;
+
+ /**
+ * The preferred WCG pixel format
+ */
+ AHardwareBuffer_Format wcgPixelFormat;
+
+ /**
+ * The config for this display.
+ */
+ DisplayConfigImpl config;
+};
+
+// DisplayImpl allocation is not managed through C++ memory apis, so
+// preventing calling the destructor here.
+static_assert(std::is_trivially_destructible<DisplayImpl>::value);
+
+} // namespace android::display::impl
+
+using namespace android;
+using namespace android::display::impl;
+
+namespace android {
+
+int ADisplay_acquirePhysicalDisplays(ADisplay*** outDisplays) {
+ // This is running on host, so there are no physical displays available.
+ // Create 1 fake display instead.
+ DisplayImpl** const impls = reinterpret_cast<DisplayImpl**>(
+ malloc(sizeof(DisplayImpl*) + sizeof(DisplayImpl)));
+ DisplayImpl* const displayData = reinterpret_cast<DisplayImpl*>(impls + 1);
+
+ displayData[0] = DisplayImpl{ADisplayType::DISPLAY_TYPE_INTERNAL,
+ ADataSpace::ADATASPACE_UNKNOWN,
+ AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
+ DisplayConfigImpl()};
+ impls[0] = displayData;
+ *outDisplays = reinterpret_cast<ADisplay**>(impls);
+ return 1;
+}
+
+void ADisplay_release(ADisplay** displays) {
+ if (displays == nullptr) {
+ return;
+ }
+ free(displays);
+}
+
+float ADisplay_getMaxSupportedFps(ADisplay* display) {
+ DisplayImpl* impl = reinterpret_cast<DisplayImpl*>(display);
+ return impl->config.fps;
+}
+
+ADisplayType ADisplay_getDisplayType(ADisplay* display) {
+ return reinterpret_cast<DisplayImpl*>(display)->type;
+}
+
+void ADisplay_getPreferredWideColorFormat(ADisplay* display, ADataSpace* outDataspace,
+ AHardwareBuffer_Format* outPixelFormat) {
+ DisplayImpl* impl = reinterpret_cast<DisplayImpl*>(display);
+ *outDataspace = impl->wcgDataspace;
+ *outPixelFormat = impl->wcgPixelFormat;
+}
+
+int ADisplay_getCurrentConfig(ADisplay* display, ADisplayConfig** outConfig) {
+ DisplayImpl* impl = reinterpret_cast<DisplayImpl*>(display);
+ *outConfig = reinterpret_cast<ADisplayConfig*>(&impl->config);
+ return OK;
+}
+
+int32_t ADisplayConfig_getWidth(ADisplayConfig* config) {
+ return reinterpret_cast<DisplayConfigImpl*>(config)->width;
+}
+
+int32_t ADisplayConfig_getHeight(ADisplayConfig* config) {
+ return reinterpret_cast<DisplayConfigImpl*>(config)->height;
+}
+
+float ADisplayConfig_getFps(ADisplayConfig* config) {
+ return reinterpret_cast<DisplayConfigImpl*>(config)->fps;
+}
+
+int64_t ADisplayConfig_getCompositorOffsetNanos(ADisplayConfig* config) {
+ return reinterpret_cast<DisplayConfigImpl*>(config)->sfOffset;
+}
+
+int64_t ADisplayConfig_getAppVsyncOffsetNanos(ADisplayConfig* config) {
+ return reinterpret_cast<DisplayConfigImpl*>(config)->appOffset;
+}
+
+} // namespace android
diff --git a/libs/hostgraphics/Android.bp b/libs/hostgraphics/Android.bp
index f166fdeafa41..4407af68de99 100644
--- a/libs/hostgraphics/Android.bp
+++ b/libs/hostgraphics/Android.bp
@@ -22,6 +22,7 @@ cc_library_host_static {
srcs: [
":libui_host_common",
+ "ADisplay.cpp",
"Fence.cpp",
"HostBufferQueue.cpp",
"PublicFormat.cpp",
@@ -32,16 +33,21 @@ cc_library_host_static {
// When frameworks/native/include will be removed from the list of automatic includes.
// We will have to copy necessary headers with a pre-build step (generated headers).
".",
- "frameworks/native/libs/nativebase/include",
- "frameworks/native/libs/nativewindow/include",
"frameworks/native/libs/arect/include",
"frameworks/native/libs/ui/include_private",
],
+
+ header_libs: [
+ "libnativebase_headers",
+ "libnativedisplay_headers",
+ "libnativewindow_headers",
+ ],
+
export_include_dirs: ["."],
target: {
windows: {
enabled: true,
- }
+ },
},
}
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 40239b8c2719..54f94f5c4b14 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -346,6 +346,7 @@ cc_defaults {
"jni/android_util_PathParser.cpp",
"jni/Bitmap.cpp",
+ "jni/BitmapRegionDecoder.cpp",
"jni/BufferUtils.cpp",
"jni/HardwareBufferHelpers.cpp",
"jni/BitmapFactory.cpp",
@@ -421,7 +422,6 @@ cc_defaults {
"jni/android_graphics_TextureLayer.cpp",
"jni/android_graphics_HardwareRenderer.cpp",
"jni/android_graphics_HardwareBufferRenderer.cpp",
- "jni/BitmapRegionDecoder.cpp",
"jni/GIFMovie.cpp",
"jni/GraphicsStatsService.cpp",
"jni/Movie.cpp",
@@ -559,8 +559,13 @@ cc_defaults {
"AnimatorManager.cpp",
"CanvasTransform.cpp",
"DamageAccumulator.cpp",
+ "DeviceInfo.cpp",
+ "FrameInfo.cpp",
+ "FrameInfoVisualizer.cpp",
+ "FrameMetricsReporter.cpp",
"Gainmap.cpp",
"Interpolator.cpp",
+ "JankTracker.cpp",
"LightingInfo.cpp",
"Matrix.cpp",
"Mesh.cpp",
@@ -623,13 +628,8 @@ cc_defaults {
"utils/NdkUtils.cpp",
"AutoBackendTextureRelease.cpp",
"DeferredLayerUpdater.cpp",
- "DeviceInfo.cpp",
- "FrameInfo.cpp",
- "FrameInfoVisualizer.cpp",
"HardwareBitmapUploader.cpp",
"HWUIProperties.sysprop",
- "JankTracker.cpp",
- "FrameMetricsReporter.cpp",
"Layer.cpp",
"LayerUpdateQueue.cpp",
"ProfileDataContainer.cpp",
@@ -643,7 +643,10 @@ cc_defaults {
cflags: ["-Wno-implicit-fallthrough"],
},
host: {
- header_libs: ["libnativebase_headers"],
+ header_libs: [
+ "libnativebase_headers",
+ "libnativedisplay_headers",
+ ],
local_include_dirs: ["platform/host"],
@@ -655,7 +658,11 @@ cc_defaults {
"platform/host/WebViewFunctorManager.cpp",
],
- cflags: ["-Wno-unused-private-field"],
+ cflags: [
+ "-DHWUI_NULL_GPU",
+ "-DNULL_GPU_MAX_TEXTURE_SIZE=4096",
+ "-Wno-unused-private-field",
+ ],
},
},
}
diff --git a/libs/hwui/FrameInfoVisualizer.cpp b/libs/hwui/FrameInfoVisualizer.cpp
index 59f21694fb77..1e53fc2164c7 100644
--- a/libs/hwui/FrameInfoVisualizer.cpp
+++ b/libs/hwui/FrameInfoVisualizer.cpp
@@ -249,6 +249,7 @@ bool FrameInfoVisualizer::consumeProperties() {
}
void FrameInfoVisualizer::dumpData(int fd) {
+#ifdef __ANDROID__
RETURN_IF_PROFILING_DISABLED();
// This method logs the last N frames (where N is <= mDataSize) since the
@@ -268,6 +269,7 @@ void FrameInfoVisualizer::dumpData(int fd) {
durationMS(i, FrameInfoIndex::IssueDrawCommandsStart, FrameInfoIndex::SwapBuffers),
durationMS(i, FrameInfoIndex::SwapBuffers, FrameInfoIndex::FrameCompleted));
}
+#endif
}
} /* namespace uirenderer */
diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp
index 4b0ddd2fa2ef..638a060bdb1c 100644
--- a/libs/hwui/JankTracker.cpp
+++ b/libs/hwui/JankTracker.cpp
@@ -17,10 +17,10 @@
#include "JankTracker.h"
#include <cutils/ashmem.h>
+#include <cutils/trace.h>
#include <errno.h>
#include <inttypes.h>
#include <log/log.h>
-#include <sys/mman.h>
#include <algorithm>
#include <cmath>
@@ -278,7 +278,7 @@ void JankTracker::recomputeThresholds(int64_t frameBudget) REQUIRES(mDataMutex)
void JankTracker::dumpData(int fd, const ProfileDataDescription* description,
const ProfileData* data) {
-
+#ifdef __ANDROID__
if (description) {
switch (description->type) {
case JankTrackerType::Generic:
@@ -296,9 +296,11 @@ void JankTracker::dumpData(int fd, const ProfileDataDescription* description,
}
data->dump(fd);
dprintf(fd, "\n");
+#endif
}
void JankTracker::dumpFrames(int fd) {
+#ifdef __ANDROID__
dprintf(fd, "\n\n---PROFILEDATA---\n");
for (size_t i = 0; i < static_cast<size_t>(FrameInfoIndex::NumIndexes); i++) {
dprintf(fd, "%s", FrameInfoNames[i]);
@@ -315,6 +317,7 @@ void JankTracker::dumpFrames(int fd) {
}
}
dprintf(fd, "\n---PROFILEDATA---\n\n");
+#endif
}
void JankTracker::reset() REQUIRES(mDataMutex) {
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index e358b57f6fe1..b1ad8b2eb1b9 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -16,32 +16,29 @@
#pragma once
-#ifdef __ANDROID__ // Layoutlib does not support device info
-#include "DeviceInfo.h"
-#endif // __ANDROID__
-
-#include "Outline.h"
-#include "Rect.h"
-#include "RevealClip.h"
-#include "effects/StretchEffect.h"
-#include "utils/MathUtils.h"
-#include "utils/PaintUtils.h"
-
#include <SkBlendMode.h>
-#include <SkImageFilter.h>
#include <SkCamera.h>
#include <SkColor.h>
+#include <SkImageFilter.h>
#include <SkMatrix.h>
#include <SkRegion.h>
-
#include <androidfw/ResourceTypes.h>
#include <cutils/compiler.h>
#include <stddef.h>
#include <utils/Log.h>
+
#include <algorithm>
#include <ostream>
#include <vector>
+#include "DeviceInfo.h"
+#include "Outline.h"
+#include "Rect.h"
+#include "RevealClip.h"
+#include "effects/StretchEffect.h"
+#include "utils/MathUtils.h"
+#include "utils/PaintUtils.h"
+
class SkBitmap;
class SkColorFilter;
class SkPaint;
@@ -546,13 +543,9 @@ public:
}
bool fitsOnLayer() const {
-#ifdef __ANDROID__ // Layoutlib does not support device info
const DeviceInfo* deviceInfo = DeviceInfo::get();
return mPrimitiveFields.mWidth <= deviceInfo->maxTextureSize() &&
mPrimitiveFields.mHeight <= deviceInfo->maxTextureSize();
-#else
- return mPrimitiveFields.mWidth <= 4096 && mPrimitiveFields.mHeight <= 4096;
-#endif
}
bool promotedToLayer() const {
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index 536ff781badc..2ea4e3f21163 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -16,6 +16,7 @@
#include "VectorDrawable.h"
+#include <gui/TraceUtils.h>
#include <math.h>
#include <string.h>
#include <utils/Log.h>
@@ -26,12 +27,7 @@
#include "SkSamplingOptions.h"
#include "SkScalar.h"
#include "hwui/Paint.h"
-
-#ifdef __ANDROID__
#include "renderthread/RenderThread.h"
-#endif
-
-#include <gui/TraceUtils.h>
#include "utils/Macros.h"
#include "utils/VectorDrawableUtils.h"
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/CredentialKtx.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/CredentialKtx.kt
index 83490b899eb0..892eabf14191 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/CredentialKtx.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/CredentialKtx.kt
@@ -30,6 +30,7 @@ import android.graphics.drawable.Drawable
import android.text.TextUtils
import android.util.Log
import androidx.activity.result.IntentSenderRequest
+import androidx.credentials.PasswordCredential
import androidx.credentials.PublicKeyCredential
import androidx.credentials.provider.Action
import androidx.credentials.provider.AuthenticationAction
@@ -125,6 +126,7 @@ private fun getCredentialOptionInfoList(
pendingIntent = credentialEntry.pendingIntent,
fillInIntent = it.frameworkExtrasIntent,
credentialType = CredentialType.PASSWORD,
+ rawCredentialType = PasswordCredential.TYPE_PASSWORD_CREDENTIAL,
credentialTypeDisplayName = credentialEntry.typeDisplayName.toString(),
userName = credentialEntry.username.toString(),
displayName = credentialEntry.displayName?.toString(),
@@ -136,6 +138,7 @@ private fun getCredentialOptionInfoList(
entryGroupId = credentialEntry.entryGroupId.toString(),
isDefaultIconPreferredAsSingleProvider =
credentialEntry.isDefaultIconPreferredAsSingleProvider,
+ affiliatedDomain = credentialEntry.affiliatedDomain?.toString(),
)
)
}
@@ -149,6 +152,7 @@ private fun getCredentialOptionInfoList(
pendingIntent = credentialEntry.pendingIntent,
fillInIntent = it.frameworkExtrasIntent,
credentialType = CredentialType.PASSKEY,
+ rawCredentialType = PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
credentialTypeDisplayName = credentialEntry.typeDisplayName.toString(),
userName = credentialEntry.username.toString(),
displayName = credentialEntry.displayName?.toString(),
@@ -162,6 +166,7 @@ private fun getCredentialOptionInfoList(
entryGroupId = credentialEntry.entryGroupId.toString(),
isDefaultIconPreferredAsSingleProvider =
credentialEntry.isDefaultIconPreferredAsSingleProvider,
+ affiliatedDomain = credentialEntry.affiliatedDomain?.toString(),
)
)
}
@@ -175,6 +180,7 @@ private fun getCredentialOptionInfoList(
pendingIntent = credentialEntry.pendingIntent,
fillInIntent = it.frameworkExtrasIntent,
credentialType = CredentialType.UNKNOWN,
+ rawCredentialType = credentialEntry.type,
credentialTypeDisplayName =
credentialEntry.typeDisplayName?.toString().orEmpty(),
userName = credentialEntry.title.toString(),
@@ -187,6 +193,7 @@ private fun getCredentialOptionInfoList(
entryGroupId = credentialEntry.entryGroupId.toString(),
isDefaultIconPreferredAsSingleProvider =
credentialEntry.isDefaultIconPreferredAsSingleProvider,
+ affiliatedDomain = credentialEntry.affiliatedDomain?.toString(),
)
)
}
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
index 9f360965fcf9..a657e97de3cc 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/CredentialEntryInfo.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/CredentialEntryInfo.kt
@@ -31,6 +31,11 @@ class CredentialEntryInfo(
fillInIntent: Intent?,
/** Type of this credential used for sorting. Not localized so must not be directly displayed. */
val credentialType: CredentialType,
+ /**
+ * String type value of this credential used for sorting. Not localized so must not be directly
+ * displayed.
+ */
+ val rawCredentialType: String,
/** Localized type value of this credential used for display purpose. */
val credentialTypeDisplayName: String,
val providerDisplayName: String,
@@ -43,6 +48,7 @@ class CredentialEntryInfo(
val entryGroupId: String, // Used for deduplication, and displayed as the grouping title
// "For <value-of-entryGroupId>" on the more-option screen.
val isDefaultIconPreferredAsSingleProvider: Boolean,
+ val affiliatedDomain: String?,
) : EntryInfo(
providerId,
entryKey,
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
index ccf401da5a4c..6a1998a5e24e 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
@@ -20,6 +20,7 @@ import android.content.ComponentName
import android.content.Context
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
+import android.credentials.GetCredentialRequest
import android.credentials.selection.CreateCredentialProviderData
import android.credentials.selection.DisabledProviderData
import android.credentials.selection.Entry
@@ -44,6 +45,9 @@ import androidx.credentials.CreateCredentialRequest
import androidx.credentials.CreateCustomCredentialRequest
import androidx.credentials.CreatePasswordRequest
import androidx.credentials.CreatePublicKeyCredentialRequest
+import androidx.credentials.PasswordCredential
+import androidx.credentials.PriorityHints
+import androidx.credentials.PublicKeyCredential
import androidx.credentials.provider.CreateEntry
import androidx.credentials.provider.RemoteEntry
import org.json.JSONObject
@@ -162,6 +166,25 @@ private fun getPackageInfo(
/** Utility functions for converting CredentialManager data structures to or from UI formats. */
class GetFlowUtils {
companion object {
+ fun extractTypePriorityMap(request: GetCredentialRequest): Map<String, Int> {
+ val typePriorityMap = mutableMapOf<String, Int>()
+ request.credentialOptions.forEach {option ->
+ // TODO(b/280085288) - use jetpack conversion method when exposed, rather than
+ // parsing from the raw Bundle
+ val priority = option.candidateQueryData.getInt(
+ "androidx.credentials.BUNDLE_KEY_TYPE_PRIORITY_VALUE",
+ when (option.type) {
+ PasswordCredential.TYPE_PASSWORD_CREDENTIAL ->
+ PriorityHints.PRIORITY_PASSWORD_OR_SIMILAR
+ PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL -> 100
+ else -> PriorityHints.PRIORITY_DEFAULT
+ }
+ )
+ typePriorityMap[option.type] = priority
+ }
+ return typePriorityMap
+ }
+
// Returns the list (potentially empty) of enabled provider.
fun toProviderList(
providerDataList: List<GetCredentialProviderData>,
@@ -193,6 +216,9 @@ class GetFlowUtils {
null
}
}
+
+ val typePriorityMap = extractTypePriorityMap(getCredentialRequest)
+
return com.android.credentialmanager.getflow.RequestDisplayInfo(
appName = originName?.ifEmpty { null }
?: getAppLabel(context.packageManager, requestInfo.packageName)
@@ -203,6 +229,7 @@ class GetFlowUtils {
// exposed.
"androidx.credentials.BUNDLE_KEY_PREFER_IDENTITY_DOC_UI"),
preferTopBrandingContent = preferTopBrandingContent,
+ typePriorityMap = typePriorityMap,
)
}
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
index 293e1112636e..4e1f4ee2e565 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
@@ -33,7 +33,6 @@ import android.graphics.drawable.Icon
import android.os.Bundle
import android.os.CancellationSignal
import android.os.OutcomeReceiver
-import android.provider.Settings
import android.service.autofill.AutofillService
import android.service.autofill.Dataset
import android.service.autofill.Field
@@ -140,7 +139,7 @@ class CredentialAutofillService : AutofillService() {
override fun onResult(result: GetCandidateCredentialsResponse) {
Log.i(TAG, "getCandidateCredentials onResult")
val fillResponse = convertToFillResponse(result, request,
- responseClientState)
+ responseClientState, GetFlowUtils.extractTypePriorityMap(getCredRequest))
if (fillResponse != null) {
callback.onSuccess(fillResponse)
} else {
@@ -197,7 +196,8 @@ class CredentialAutofillService : AutofillService() {
private fun convertToFillResponse(
getCredResponse: GetCandidateCredentialsResponse,
filLRequest: FillRequest,
- responseClientState: Bundle
+ responseClientState: Bundle,
+ typePriorityMap: Map<String, Int>,
): FillResponse? {
val candidateProviders = getCredResponse.candidateProviderDataList
if (candidateProviders.isEmpty()) {
@@ -213,7 +213,7 @@ class CredentialAutofillService : AutofillService() {
autofillIdToProvidersMap.forEach { (autofillId, providers) ->
validFillResponse = processProvidersForAutofillId(
filLRequest, autofillId, providers, entryIconMap, fillResponseBuilder,
- getCredResponse.intent)
+ getCredResponse.intent, typePriorityMap)
.or(validFillResponse)
}
if (!validFillResponse) {
@@ -229,7 +229,8 @@ class CredentialAutofillService : AutofillService() {
providerDataList: ArrayList<GetCredentialProviderData>,
entryIconMap: Map<String, Icon>,
fillResponseBuilder: FillResponse.Builder,
- bottomSheetIntent: Intent
+ bottomSheetIntent: Intent,
+ typePriorityMap: Map<String, Int>,
): Boolean {
val providerList = GetFlowUtils.toProviderList(
providerDataList,
@@ -237,7 +238,8 @@ class CredentialAutofillService : AutofillService() {
if (providerList.isEmpty()) {
return false
}
- val providerDisplayInfo: ProviderDisplayInfo = toProviderDisplayInfo(providerList)
+ val providerDisplayInfo: ProviderDisplayInfo =
+ toProviderDisplayInfo(providerList, typePriorityMap)
var totalEntryCount = providerDisplayInfo.sortedUserNameToCredentialEntryList.size
val inlineSuggestionsRequest = filLRequest.inlineSuggestionsRequest
val inlinePresentationSpecs = inlineSuggestionsRequest?.inlinePresentationSpecs
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Entry.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Entry.kt
index 8ff17e0d333a..56bd06618684 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Entry.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Entry.kt
@@ -78,6 +78,8 @@ fun Entry(
isLockedAuthEntry: Boolean = false,
enforceOneLine: Boolean = false,
onTextLayout: (TextLayoutResult) -> Unit = {},
+ /** Get flow only, if present, where be drawn as a line above the headline. */
+ affiliatedDomainText: String? = null,
) {
val iconPadding = Modifier.wrapContentSize().padding(
// Horizontal padding should be 16dp, but the suggestion chip itself
@@ -102,6 +104,13 @@ fun Entry(
) {
// Apply weight so that the trailing icon can always show.
Column(modifier = Modifier.wrapContentHeight().fillMaxWidth().weight(1f)) {
+ if (!affiliatedDomainText.isNullOrBlank()) {
+ BodySmallText(
+ text = affiliatedDomainText,
+ enforceOneLine = enforceOneLine,
+ onTextLayout = onTextLayout,
+ )
+ }
SmallTitleText(
text = entryHeadlineText,
enforceOneLine = enforceOneLine,
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
index 1fef5226188f..748c79891a40 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
@@ -376,6 +376,7 @@ fun PrimarySelectionCard(
}
internal const val MAX_ENTRY_FOR_PRIMARY_PAGE = 4
+
/** Draws the primary credential selection page, used starting from android V. */
@Composable
fun PrimarySelectionCardVImpl(
@@ -805,6 +806,7 @@ fun CredentialEntryRow(
},
enforceOneLine = enforceOneLine,
onTextLayout = onTextLayout,
+ affiliatedDomainText = credentialEntryInfo.affiliatedDomain,
)
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
index e7f11a15a06c..ef4018833721 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
@@ -18,9 +18,9 @@ package com.android.credentialmanager.getflow
import android.credentials.flags.Flags.selectorUiImprovementsEnabled
import android.graphics.drawable.Drawable
+import androidx.credentials.PriorityHints
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
@@ -30,7 +30,8 @@ data class GetCredentialUiState(
val isRequestForAllOptions: Boolean,
val providerInfoList: List<ProviderInfo>,
val requestDisplayInfo: RequestDisplayInfo,
- val providerDisplayInfo: ProviderDisplayInfo = toProviderDisplayInfo(providerInfoList),
+ val providerDisplayInfo: ProviderDisplayInfo =
+ toProviderDisplayInfo(providerInfoList, requestDisplayInfo.typePriorityMap),
val currentScreenState: GetScreenState = toGetScreenState(
providerDisplayInfo, isRequestForAllOptions),
val activeEntry: EntryInfo? = toActiveEntry(providerDisplayInfo),
@@ -79,6 +80,8 @@ data class RequestDisplayInfo(
val preferIdentityDocUi: Boolean,
// A top level branding icon + display name preferred by the app.
val preferTopBrandingContent: TopBrandingContent?,
+ // Map of credential type -> priority.
+ val typePriorityMap: Map<String, Int>,
)
data class TopBrandingContent(
@@ -119,7 +122,8 @@ enum class GetScreenState {
* @hide
*/
fun toProviderDisplayInfo(
- providerInfoList: List<ProviderInfo>
+ providerInfoList: List<ProviderInfo>,
+ typePriorityMap: Map<String, Int>,
): ProviderDisplayInfo {
val userNameToCredentialEntryMap = mutableMapOf<String, MutableList<CredentialEntryInfo>>()
val authenticationEntryList = mutableListOf<AuthenticationEntryInfo>()
@@ -147,7 +151,7 @@ fun toProviderDisplayInfo(
}
// Compose sortedUserNameToCredentialEntryList
- val comparator = CredentialEntryInfoComparatorByTypeThenTimestamp()
+ val comparator = CredentialEntryInfoComparatorByTypeThenTimestamp(typePriorityMap)
// Sort per username
userNameToCredentialEntryMap.values.forEach {
it.sortWith(comparator)
@@ -203,13 +207,21 @@ private fun toGetScreenState(
else GetScreenState.PRIMARY_SELECTION
}
-internal class CredentialEntryInfoComparatorByTypeThenTimestamp : Comparator<CredentialEntryInfo> {
+internal class CredentialEntryInfoComparatorByTypeThenTimestamp(
+ val typePriorityMap: Map<String, Int>,
+) : Comparator<CredentialEntryInfo> {
override fun compare(p0: CredentialEntryInfo, p1: CredentialEntryInfo): Int {
// First prefer passkey type for its security benefits
- if (p0.credentialType != p1.credentialType) {
- if (CredentialType.PASSKEY == p0.credentialType) {
+ if (p0.rawCredentialType != p1.rawCredentialType) {
+ val p0Priority = typePriorityMap.getOrDefault(
+ p0.rawCredentialType, PriorityHints.PRIORITY_DEFAULT
+ )
+ val p1Priority = typePriorityMap.getOrDefault(
+ p1.rawCredentialType, PriorityHints.PRIORITY_DEFAULT
+ )
+ if (p0Priority < p1Priority) {
return -1
- } else if (CredentialType.PASSKEY == p1.credentialType) {
+ } else if (p1Priority < p0Priority) {
return 1
}
}
diff --git a/packages/CredentialManager/tests/robotests/screenshot/src/com/android/credentialmanager/GetCredScreenshotTest.kt b/packages/CredentialManager/tests/robotests/screenshot/src/com/android/credentialmanager/GetCredScreenshotTest.kt
index 94217d0c00c3..28d83ee157b6 100644
--- a/packages/CredentialManager/tests/robotests/screenshot/src/com/android/credentialmanager/GetCredScreenshotTest.kt
+++ b/packages/CredentialManager/tests/robotests/screenshot/src/com/android/credentialmanager/GetCredScreenshotTest.kt
@@ -53,6 +53,7 @@ class GetCredScreenshotTest(emulationSpec: DeviceEmulationSpec) {
preferImmediatelyAvailableCredentials = false,
preferIdentityDocUi = false,
preferTopBrandingContent = null,
+ typePriorityMap = emptyMap(),
)
}
@@ -68,7 +69,7 @@ class GetCredScreenshotTest(emulationSpec: DeviceEmulationSpec) {
fun singleCredentialScreen_M3BottomSheetDisabled() {
setFlagsRule.disableFlags(Flags.FLAG_SELECTOR_UI_IMPROVEMENTS_ENABLED)
val providerInfoList = buildProviderInfoList()
- val providerDisplayInfo = toProviderDisplayInfo(providerInfoList)
+ val providerDisplayInfo = toProviderDisplayInfo(providerInfoList, emptyMap())
val activeEntry = toActiveEntry(providerDisplayInfo)
screenshotRule.screenshotTest("singleCredentialScreen") {
ModalBottomSheet(
@@ -96,7 +97,7 @@ class GetCredScreenshotTest(emulationSpec: DeviceEmulationSpec) {
fun singleCredentialScreen_M3BottomSheetEnabled() {
setFlagsRule.enableFlags(Flags.FLAG_SELECTOR_UI_IMPROVEMENTS_ENABLED)
val providerInfoList = buildProviderInfoList()
- val providerDisplayInfo = toProviderDisplayInfo(providerInfoList)
+ val providerDisplayInfo = toProviderDisplayInfo(providerInfoList, emptyMap())
val activeEntry = toActiveEntry(providerDisplayInfo)
screenshotRule.screenshotTest(
"singleCredentialScreen_newM3BottomSheet",
@@ -149,6 +150,8 @@ class GetCredScreenshotTest(emulationSpec: DeviceEmulationSpec) {
isAutoSelectable = false,
entryGroupId = "username",
isDefaultIconPreferredAsSingleProvider = false,
+ rawCredentialType = "unknown-type",
+ affiliatedDomain = null,
)
),
authenticationEntryList = emptyList(),
diff --git a/packages/PackageInstaller/res/values-el/strings.xml b/packages/PackageInstaller/res/values-el/strings.xml
index 61aa4e65128a..3c37df68456c 100644
--- a/packages/PackageInstaller/res/values-el/strings.xml
+++ b/packages/PackageInstaller/res/values-el/strings.xml
@@ -117,7 +117,7 @@
<string name="unarchive_error_generic_title" msgid="7123457671482449992">"Κάτι πήγε στραβά"</string>
<string name="unarchive_error_generic_body" msgid="4486803312463813079">"Παρουσιάστηκε κάποιο πρόβλημα κατά την επαναφορά αυτής της εφαρμογής"</string>
<string name="unarchive_error_storage_title" msgid="5080723357273852630">"Δεν επαρκεί ο αποθηκευτικός χώρος"</string>
- <string name="unarchive_error_storage_body" msgid="6879544407568780524">"Για να επαναφέρετε αυτή την εφαρμογή, μπορείτε να ελευθερώσετε χώρο στη συσκευή. Απαιτούμενος αποθηκευτικός χώρος: <xliff:g id="BYTES">%1$s</xliff:g>"</string>
+ <string name="unarchive_error_storage_body" msgid="6879544407568780524">"Για να επαναφέρετε αυτή την εφαρμογή, μπορείτε να αποδεσμεύσετε χώρο στη συσκευή. Απαιτούμενος αποθηκευτικός χώρος: <xliff:g id="BYTES">%1$s</xliff:g>"</string>
<string name="unarchive_action_required_title" msgid="4971245740162604619">"Απαιτούμενη ενέργεια"</string>
<string name="unarchive_action_required_body" msgid="1679431572983989231">"Ακολουθήστε τα επόμενα βήματα για να επαναφέρετε αυτή την εφαρμογή"</string>
<string name="unarchive_error_installer_disabled_title" msgid="4815715617014985605">"Το <xliff:g id="INSTALLERNAME">%1$s</xliff:g> είναι απενεργοποιημένο"</string>
diff --git a/packages/SettingsLib/DataStore/tests/Android.bp b/packages/SettingsLib/DataStore/tests/Android.bp
new file mode 100644
index 000000000000..8770dfa013d0
--- /dev/null
+++ b/packages/SettingsLib/DataStore/tests/Android.bp
@@ -0,0 +1,24 @@
+package {
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_app {
+ name: "SettingsLibDataStoreShell",
+ platform_apis: true,
+}
+
+android_robolectric_test {
+ name: "SettingsLibDataStoreTest",
+ srcs: ["src/**/*"],
+ static_libs: [
+ "SettingsLibDataStore",
+ "androidx.test.ext.junit",
+ "guava",
+ "mockito-robolectric-prebuilt", // mockito deps order matters!
+ "mockito-kotlin2",
+ ],
+ java_resource_dirs: ["config"],
+ instrumentation_for: "SettingsLibDataStoreShell",
+ coverage_libs: ["SettingsLibDataStore"],
+ upstream: true,
+}
diff --git a/packages/SettingsLib/DataStore/tests/AndroidManifest.xml b/packages/SettingsLib/DataStore/tests/AndroidManifest.xml
new file mode 100644
index 000000000000..ffc24e4330d1
--- /dev/null
+++ b/packages/SettingsLib/DataStore/tests/AndroidManifest.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.settingslib.datastore.test">
+
+ <application android:debuggable="true" />
+</manifest>
diff --git a/packages/SettingsLib/DataStore/tests/config/robolectric.properties b/packages/SettingsLib/DataStore/tests/config/robolectric.properties
new file mode 100644
index 000000000000..fab7251d020b
--- /dev/null
+++ b/packages/SettingsLib/DataStore/tests/config/robolectric.properties
@@ -0,0 +1 @@
+sdk=NEWEST_SDK
diff --git a/packages/SettingsLib/DataStore/tests/src/com/android/settingslib/datastore/ObserverTest.kt b/packages/SettingsLib/DataStore/tests/src/com/android/settingslib/datastore/ObserverTest.kt
new file mode 100644
index 000000000000..bb791dc9a23c
--- /dev/null
+++ b/packages/SettingsLib/DataStore/tests/src/com/android/settingslib/datastore/ObserverTest.kt
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.datastore
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import com.google.common.util.concurrent.MoreExecutors
+import java.util.concurrent.Executor
+import java.util.concurrent.atomic.AtomicInteger
+import org.junit.Assert.assertThrows
+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 org.mockito.kotlin.any
+import org.mockito.kotlin.never
+import org.mockito.kotlin.reset
+import org.mockito.kotlin.verify
+
+@RunWith(AndroidJUnit4::class)
+class ObserverTest {
+ @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
+
+ @Mock private lateinit var observer1: Observer
+
+ @Mock private lateinit var observer2: Observer
+
+ @Mock private lateinit var executor: Executor
+
+ private val observable = DataObservable()
+
+ @Test
+ fun addObserver_sameExecutor() {
+ observable.addObserver(observer1, executor)
+ observable.addObserver(observer1, executor)
+ }
+
+ @Test
+ fun addObserver_differentExecutor() {
+ observable.addObserver(observer1, executor)
+ assertThrows(IllegalStateException::class.java) {
+ observable.addObserver(observer1, MoreExecutors.directExecutor())
+ }
+ }
+
+ @Test
+ fun addObserver_weaklyReferenced() {
+ val counter = AtomicInteger()
+ var observer: Observer? = Observer { counter.incrementAndGet() }
+ observable.addObserver(observer!!, MoreExecutors.directExecutor())
+
+ observable.notifyChange(ChangeReason.UPDATE)
+ assertThat(counter.get()).isEqualTo(1)
+
+ // trigger GC, the observer callback should not be invoked
+ @Suppress("unused")
+ observer = null
+ System.gc()
+ System.runFinalization()
+
+ observable.notifyChange(ChangeReason.UPDATE)
+ assertThat(counter.get()).isEqualTo(1)
+ }
+
+ @Test
+ fun addObserver_notifyObservers_removeObserver() {
+ observable.addObserver(observer1, MoreExecutors.directExecutor())
+ observable.addObserver(observer2, executor)
+
+ observable.notifyChange(ChangeReason.DELETE)
+
+ verify(observer1).onChanged(ChangeReason.DELETE)
+ verify(observer2, never()).onChanged(any())
+ verify(executor).execute(any())
+
+ reset(observer1, executor)
+ observable.removeObserver(observer2)
+
+ observable.notifyChange(ChangeReason.UPDATE)
+ verify(observer1).onChanged(ChangeReason.UPDATE)
+ verify(executor, never()).execute(any())
+ }
+
+ @Test
+ fun notifyChange_addObserverWithinCallback() {
+ // ConcurrentModificationException is raised if it is not implemented correctly
+ observable.addObserver(
+ { observable.addObserver(observer1, executor) },
+ MoreExecutors.directExecutor()
+ )
+ observable.notifyChange(ChangeReason.UPDATE)
+ }
+}
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 7245099c4ff2..cc23f6eedf9a 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Geneutraliseer deur <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Laaiproses is onderbreek om battery te beskerm"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - Gaan die laaibykomstigheid na"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Ongeveer <xliff:g id="TIME_REMAINING">%1$s</xliff:g> oor"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Ongeveer <xliff:g id="TIME_REMAINING">%1$s</xliff:g> oor (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Ongeveer <xliff:g id="TIME_REMAINING">%1$s</xliff:g> oor gegrond op jou gebruik"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index dc91df021347..0ecd376626c4 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"በ<xliff:g id="TITLE">%1$s</xliff:g> ተሽሯል"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - ባትሪን ለመጠበቅ ኃይል መሙላት በይቆይ ላይ"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - የኃይል መሙላት መለዋወጫን ይፈትሹ"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ገደማ ቀርቷል"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>) ገደማ ቀርቷል"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"በአጠቃቀምዎ መሠረት <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ገደማ ቀርቷል"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 87c4d7fb99a7..1f313aef239c 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"تم الاستبدال بـ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"‫<xliff:g id="LEVEL">%1$s</xliff:g> - الشحن معلَّق لحماية البطارية"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - فحص ملحق الشحن"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"يتبقى <xliff:g id="TIME_REMAINING">%1$s</xliff:g> تقريبًا."</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"يتبقى <xliff:g id="TIME_REMAINING">%1$s</xliff:g> تقريبًا (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"يتبقى <xliff:g id="TIME_REMAINING">%1$s</xliff:g> تقريبًا، بناءً على استخدامك"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index bcf9f5d25980..a4be8e997311 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g>ৰ দ্বাৰা অগ্ৰাহ্য কৰা হৈছে"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - বেটাৰী সুৰক্ষিত কৰিবলৈ চাৰ্জিং স্থগিত ৰখা হৈছে"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - চাৰ্জিঙৰ সৈতে জড়িত আনুষংগিক সামগ্ৰী পৰীক্ষা কৰক"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"প্রায় <xliff:g id="TIME_REMAINING">%1$s</xliff:g> বাকী আছে"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"প্রায় <xliff:g id="TIME_REMAINING">%1$s</xliff:g> বাকী আছে (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"আপোনাৰ ব্যৱহাৰৰ ওপৰত ভিত্তি কৰি প্ৰায় <xliff:g id="TIME_REMAINING">%1$s</xliff:g> বাকী আছে"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 22dbff2036bb..df6dad208bd8 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> tərəfindən qəbul edilmir"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Batareyanı qorumaq üçün şarj gözlədilir"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - Şarj aksesuarını yoxlayın"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Təxminən <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qalıb"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Təxminən <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qalıb (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"İstifadəyə əsasən təxminən <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qalıb"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index ee58e8ef5e04..8bb8c838ed39 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Zamenjuje ga <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g>–<xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – punjenje je na čekanju da bi se zaštitila baterija"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – Proverite dodatnu opremu za punjenje"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Preostalo je oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Preostalo je oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Preostalo je oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g> na osnovu korišćenja"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 079a8f3aaa11..433c2430a40d 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Перавызначаны <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – зарадка прыпынена, каб абараніць акумулятар"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g>, праверце зарадную прыладу"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Зараду хопіць прыблізна на <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Зараду (<xliff:g id="LEVEL">%2$s</xliff:g>) хопіць прыблізна на <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Зараду пры такім выкарыстанні хопіць прыблізна на <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 5a0c0b779f55..27e27bef4f3a 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Заменено от „<xliff:g id="TITLE">%1$s</xliff:g>“"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Зареждането е поставено на пауза с цел запазване на батерията"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – Проверете аксесоара за зареждане"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Още около <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Още около <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Още около <xliff:g id="TIME_REMAINING">%1$s</xliff:g> въз основа на използването"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 6fb6fb3dc6cd..2cf055654f3b 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> এর দ্বারা ওভাররাইড করা হয়েছে"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - ব্যাটারিকে সুরক্ষিত রাখতে চার্জিং হোল্ড করা হয়েছে"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - চার্জিং অ্যাক্সেসরি চেক করুন"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"আর আনুমানিক <xliff:g id="TIME_REMAINING">%1$s</xliff:g> চলবে"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"আর আনুমানিক <xliff:g id="TIME_REMAINING">%1$s</xliff:g> চলবে (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"ব্যবহারের উপর ভিত্তি করে আর আনুমানিক <xliff:g id="TIME_REMAINING">%1$s</xliff:g> চলবে"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index a430848e79f3..64ccf98c3aa8 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Zamjenjuje <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – punjenje je na čekanju radi zaštite baterije"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – provjerite opremu za punjenje"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Preostalo je još oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Preostalo je još oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Preostalo je još oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g> na osnovu vaše potrošnje"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 0bbb97960a76..81f9e97a2203 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"S\'ha substituït per <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g>: <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g>: la càrrega s\'ha posat en espera per protegir la bateria"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g>: revisa l\'accessori de càrrega"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Temps restant aproximat: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Temps restant aproximat: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Temps restant aproximat segons l\'ús que en fas: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 97d0d15bfedf..cb8c36b55580 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Přepsáno nastavením <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Nabíjení je pozastaveno za účelem ochrany baterie"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – Zkontrolujte nabíjecí příslušenství"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Zbývá asi <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Zbývá asi <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Při vašem obvyklém využití zbývá asi <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 096042246e01..625f05b57ac8 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Tilsidesat af <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Opladningen er sat på pause for at beskytte batteriet"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – Tjek opladningstilbehøret"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Ca. <xliff:g id="TIME_REMAINING">%1$s</xliff:g> tilbage"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Ca. <xliff:g id="TIME_REMAINING">%1$s</xliff:g> tilbage (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Ca. <xliff:g id="TIME_REMAINING">%1$s</xliff:g> tilbage, alt efter hvordan du bruger enheden"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index cb36cca64ff4..f622f61505f5 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Außer Kraft gesetzt von \"<xliff:g id="TITLE">%1$s</xliff:g>\""</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Ladevorgang zum Schutz des Akkus angehalten"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – Ladezubehör prüfen"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Noch etwa <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Noch etwa <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Bei deinem Nutzungsmuster hast du noch ca. <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 4953884b0d74..861f4722edfb 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Αντικαταστάθηκε από <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Η φόρτιση τέθηκε σε αναμονή για προστασία της μπαταρίας"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – Έλεγχος αξεσουάρ φόρτισης"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Απομένει/ουν περίπου <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Απομένει/ουν περίπου <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Απομένει/ουν περίπου <xliff:g id="TIME_REMAINING">%1$s</xliff:g>, βάσει της χρήσης σας"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index d730fb7951e1..e6923de1af8c 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Charging on hold to protect battery"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – check charging accessory"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left based on your usage"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index d730fb7951e1..e6923de1af8c 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Charging on hold to protect battery"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – check charging accessory"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left based on your usage"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index d730fb7951e1..e6923de1af8c 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Charging on hold to protect battery"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – check charging accessory"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left based on your usage"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 775f23c14eac..a6fdf569954c 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Reemplazado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Se detuvo la carga para proteger la batería"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - Verifica el accesorio de carga"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Tiempo restante: aproximadamente <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Tiempo restante: aproximadamente <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Tiempo restante: aproximadamente <xliff:g id="TIME_REMAINING">%1$s</xliff:g> en función de tu uso"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 70b85029a2b0..d57a33a305c6 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g>: <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carga pausada para proteger la batería"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - Comprueba el accesorio de carga"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Tiempo restante aproximado: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Tiempo restante aproximado: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Tiempo restante aproximado según tu uso: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index daae2147ce7b..dfe78d8f3557 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Alistas <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – laadimine on aku kaitsmiseks ootele pandud"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – kontrollige laadimistarvikut"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Ligikaudu <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäänud"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Ligikaudu <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäänud (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Teie kasutuse põhjal on jäänud ligikaudu <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 2fd01f3ab848..3c6309dad77f 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> hobespena gainjarri zaio"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g>: kargatze-prozesua zain dago bateria babesteko"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - Eman begiratu bat kargatzeko osagarriari"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> inguru gelditzen dira"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> inguru gelditzen dira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Erabilera kontuan izanda, <xliff:g id="TIME_REMAINING">%1$s</xliff:g> inguru gelditzen dira"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 9a1e1076eae9..2cb1873e5fbe 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"توسط <xliff:g id="TITLE">%1$s</xliff:g> لغو شد"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - برای محافظت از باتری، شارژ موقتاً متوقف شده است"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - لوازم شارژ را بررسی کنید"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"تقریباً <xliff:g id="TIME_REMAINING">%1$s</xliff:g> شارژ باقی مانده است"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"تقریباً <xliff:g id="TIME_REMAINING">%1$s</xliff:g> شارژ باقی مانده است (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"براساس مصرفتان، تقریباً <xliff:g id="TIME_REMAINING">%1$s</xliff:g> شارژ باقی مانده است"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 0faa32c54442..29459ca5ee1f 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Tämän ohittaa <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Lataus on keskeytetty akun suojaamiseksi"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – Tarkista latauslisävaruste"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Noin <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäljellä"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Noin <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäljellä (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Noin <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäljellä käyttösi perusteella"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 24de4cd07a80..f97b36ea895d 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -257,7 +257,7 @@
<string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Association de l\'appareil en cours…"</string>
<string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Échec de l\'association de l\'appareil Soit le code QR est incorrect, soit l\'appareil n\'est pas connecté au même réseau."</string>
<string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Adresse IP et port"</string>
- <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Numériser le code QR"</string>
+ <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Balayer le code QR"</string>
<string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Associer l\'appareil par Wi-Fi en numérisant un code QR"</string>
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Veuillez vous connecter à un réseau Wi-Fi"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, débogage, développeur"</string>
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> : <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – La recharge a été mise en pause pour protéger la pile"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – Vérifier l\'accessoire de recharge"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Il reste environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Il reste environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Il reste environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> en fonction de votre usage"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 8f61c8d604fa..7f7ba637b47d 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Recharge en pause pour protéger la batterie"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> : vérifiez l\'accessoire de recharge"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Temps restant : environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Temps restant : environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Temps restant en fonction de votre utilisation : environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 4cd9e2ca86b7..179d946c23da 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g>. A carga púxose en pausa para protexer a batería"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g>. Comproba o accesorio de carga"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Tempo restante aproximado: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Tempo restante aproximado (<xliff:g id="LEVEL">%2$s</xliff:g>): <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Tempo restante aproximado en función do uso: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 15f92875e22d..cafe86c26b77 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> દ્વારા ઓવરરાઇડ થયું"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - બૅટરીને સુરક્ષિત રાખવા માટે, ચાર્જિંગ હોલ્ડ પર રાખવામાં આવ્યું છે"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - ચાર્જિંગ ઍક્સેસરી ચેક કરો"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"લગભગ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> બાકી છે"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"લગભગ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> બાકી છે (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"તમારા વપરાશના આધારે લગભગ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> બાકી છે"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 5c94489f8f77..53cf7247b996 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> के द्वारा ओवरराइड किया गया"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - बैटरी को सुरक्षित रखने के लिए, फ़ोन को चार्ज होने से रोक दिया गया है"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - चार्जिंग ऐक्सेसरी की जांच करें"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"बैटरी करीब <xliff:g id="TIME_REMAINING">%1$s</xliff:g> में खत्म हो जाएगी"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"बैटरी करीब <xliff:g id="TIME_REMAINING">%1$s</xliff:g> में खत्म हो जाएगी (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"आपके इस्तेमाल के हिसाब से बैटरी करीब <xliff:g id="TIME_REMAINING">%1$s</xliff:g> में खत्म हो जाएगी"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index cc7b327e9d4f..f06baad6ea6c 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Premošćeno postavkom <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – punjenje je pauzirano radi zaštite baterije"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – provjerite dodatak za punjenje"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Još oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Još otprilike <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Još otprilike <xliff:g id="TIME_REMAINING">%1$s</xliff:g> na temelju vaše upotrebe"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index e9fd9dbd54e9..39d905f0bf46 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Felülírva erre: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Az akkumulátor védelme érdekében a töltés szünetel"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – Ellenőrizze a töltőtartozékot"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Körülbelül <xliff:g id="TIME_REMAINING">%1$s</xliff:g> maradt hátra"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Körülbelül <xliff:g id="TIME_REMAINING">%1$s</xliff:g> maradt hátra (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Körülbelül <xliff:g id="TIME_REMAINING">%1$s</xliff:g> maradt hátra az eszköz használata alapján"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index d6b356005ac6..55f09e297f2a 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Գերազանցված է <xliff:g id="TITLE">%1$s</xliff:g>-ից"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Լիցքավորումը դադարեցվել է՝ մարտկոցը պաշտպանելու համար"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – Ստուգեք լիցքավորիչը"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Լիցքը կբավարարի մոտ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Լիցքը (<xliff:g id="LEVEL">%2$s</xliff:g>) կբավարարի մոտ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Լիցքը կբավարարի մոտ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>՝ կախված օգտագործման եղանակից"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 398853aa5b02..885729da1b66 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Digantikan oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Pengisian daya dihentikan sementara untuk melindungi baterai"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - Periksa aksesori pengisian daya"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Sekitar <xliff:g id="TIME_REMAINING">%1$s</xliff:g> lagi"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Sekitar <xliff:g id="TIME_REMAINING">%1$s</xliff:g> lagi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Sekitar <xliff:g id="TIME_REMAINING">%1$s</xliff:g> lagi berdasarkan penggunaan Anda"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 2be92e5dff33..020191b55e7c 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Hnekkt af <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Hleðsla í bið til að vernda rafhlöðuna"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – Athugaðu hleðslubúnaðinn"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Um það bil <xliff:g id="TIME_REMAINING">%1$s</xliff:g> eftir"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Um það bil <xliff:g id="TIME_REMAINING">%1$s</xliff:g> eftir (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Um það bil <xliff:g id="TIME_REMAINING">%1$s</xliff:g> eftir miðað við notkun þína"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 3dc69e8ace46..37a20675abe7 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Valore sostituito da <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Ricarica in sospeso per proteggere la batteria"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - Controlla l\'accessorio di ricarica"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Tempo rimanente: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> circa"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Tempo rimanente: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> circa (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Tempo rimanente in base al tuo utilizzo: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> circa"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 9ef9cf1bc043..d87d0f8dafbc 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g>によって上書き済み"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - バッテリーを保護するため、充電を一時停止しています"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - 充電用アクセサリを確認してください"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"残り時間: 約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"残り時間: 約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"残り時間: 約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>(使用状況に基づく)"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 4ddb0054c329..7812f0b21601 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"უკუგებულია <xliff:g id="TITLE">%1$s</xliff:g>-ის მიერ"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – დატენვა შეჩერებულია ბატარეის დასაცავად"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g>: მიმდინარეობს დამტენი აქსესუარის შემოწმება"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"დარჩა დაახლოებით <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"დარჩა დაახლოებით <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"დარჩა დაახლოებით <xliff:g id="TIME_REMAINING">%1$s</xliff:g>, ბატარეის მოხმარების გათვალისწინებით"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index fa46e8e93db6..300d4e517013 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> үстінен басқан"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g>: батареяны қорғау үшін зарядтау кідіртіледі."</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – зарядтау құрылғысын тексеріңіз"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Шамамен <xliff:g id="TIME_REMAINING">%1$s</xliff:g> қалды"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Шамамен <xliff:g id="TIME_REMAINING">%1$s</xliff:g> қалды (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Пайдалану деректеріңізге сәйкес енді шамамен <xliff:g id="TIME_REMAINING">%1$s</xliff:g> қалды"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index cd2a6c41ef5a..373cfc656789 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"បដិសេធ​ដោយ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - កំពុងផ្អាកការសាកថ្ម ដើម្បីការពារថ្ម"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - ពិនិត្យមើលគ្រឿងសាកថ្ម"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"នៅសល់​ប្រហែល <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ទៀត"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"នៅសល់​ប្រហែល <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ទៀត (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"នៅសល់​ប្រហែល <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ទៀត ផ្អែក​លើការ​ប្រើប្រាស់​របស់អ្នក"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index a01a4bd1c37d..bf84cc48aa39 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> ಮೂಲಕ ಅತಿಕ್ರಮಿಸುತ್ತದೆ"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - ಬ್ಯಾಟರಿಯನ್ನು ರಕ್ಷಿಸಲು ಚಾರ್ಜಿಂಗ್ ಅನ್ನು ಹೋಲ್ಡ್‌ ಮಾಡಲಾಗಿದೆ"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - ಚಾರ್ಜಿಂಗ್ ಆ್ಯಕ್ಸೆಸರಿಯನ್ನು ಪರಿಶೀಲಿಸಿ"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ಸಮಯ ಬಾಕಿ ಉಳಿದಿದೆ"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"(<xliff:g id="LEVEL">%2$s</xliff:g>) ತಲುಪಲು <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ಸಮಯ ಬಾಕಿ ಉಳಿದಿದೆ"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"ನಿಮ್ಮ ಬಳಕೆಯ ಆಧಾರದ ಮೇಲೆ ಸುಮಾರು <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ಸಮಯ ಬಾಕಿ ಉಳಿದಿದೆ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index c9c92e5894f7..b184ef43e5b7 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> 우선 적용됨"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g>, <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - 배터리 보호를 위해 충전 일시중지"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - 충전 액세서리 확인"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"남은 시간: 약 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"남은 시간 약 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"내 사용량을 기준으로 약 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> 남음"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 44b01472b232..e565e444536c 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> менен алмаштырылган"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Батареяны коргоо үчүн кубаттоо тындырылды"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - Кубаттоо шайманын текшериңиз"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Болжол менен <xliff:g id="TIME_REMAINING">%1$s</xliff:g> калды"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Болжол менен <xliff:g id="TIME_REMAINING">%1$s</xliff:g> калды (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Колдонгонуңузга караганда болжол менен <xliff:g id="TIME_REMAINING">%1$s</xliff:g> калды"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 70e9b68551c3..6caaf952b364 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"ຖືກແທນໂດຍ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - ຢຸດການສາກຊົ່ວຄາວເພື່ອປົກປ້ອງແບັດເຕີຣີ"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - ກວດສອບອຸປະກອນເສີມສຳລັບການສາກ"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"ເຫຼືອອີກປະມານ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"ເຫຼືອອີກປະມານ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"ເຫຼືອອີກປະມານ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ອ້າງອີງຈາກການນຳໃຊ້ຂອງທ່ານ"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index d50634c1ead1..70bcc2100ddd 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Прескокнато според <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - полнењето е паузирано за да се заштити батеријата"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - Проверете го додатокот за полнење"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Уште околу <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Уште околу <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Уште околу <xliff:g id="TIME_REMAINING">%1$s</xliff:g> според вашето користење"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 085b7c16180c..9a297e5fb4d8 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> ഉപയോഗിച്ച് അസാധുവാക്കി"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - ബാറ്ററി പരിരക്ഷിക്കാൻ ചാർജിംഗ് ഹോൾഡിലാണ്"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - ചാർജിംഗ് ആക്‌സസറി പരിശോധിക്കുക"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"ഏതാണ്ട് <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"ഏതാണ്ട് <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ശേഷിക്കുന്നു (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"നിങ്ങളുടെ ഉപയോഗത്തെ അടിസ്ഥാനമാക്കി ഏതാണ്ട് <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 60a31e8e3c3b..000e306afef3 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Давхарласан <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Батарейг хамгаалахын тулд цэнэглэхийг хүлээлгэсэн"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - Цэнэглэх нэмэлт хэрэгслийг шалгах"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Ойролцоогоор <xliff:g id="TIME_REMAINING">%1$s</xliff:g> үлдсэн"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Ойролцоогоор <xliff:g id="TIME_REMAINING">%1$s</xliff:g> үлдсэн (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Таны хэрэглээнд үндэслэн ойролцоогоор <xliff:g id="TIME_REMAINING">%1$s</xliff:g> үлдсэн"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 32de0e5f5daa..6af0fbdc0ac8 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारे अधिलिखित"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - बॅटरीचे संरक्षण करण्यासाठी चार्जिंग थांबवले आहे"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - चार्जिंगसंबंधित ॲक्सेसरी तपासा"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"अंदाजे <xliff:g id="TIME_REMAINING">%1$s</xliff:g> बाकी आहे"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"अंदाजे <xliff:g id="TIME_REMAINING">%1$s</xliff:g> बाकी आहे (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"तुमच्‍या वापरावर आधारित अंदाजे <xliff:g id="TIME_REMAINING">%1$s</xliff:g> बाकी आहे"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index f0abd94dd9d1..621b4694026b 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Diatasi oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Pengecasan ditunda untuk melindungi bateri"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - Periksa aksesori pengecasan"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Kira-kira <xliff:g id="TIME_REMAINING">%1$s</xliff:g> lagi"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Kira-kira <xliff:g id="TIME_REMAINING">%1$s</xliff:g> lagi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Kira-kira <xliff:g id="TIME_REMAINING">%1$s</xliff:g> lagi berdasarkan penggunaan anda"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 3d942855e00e..60161c344ebb 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> မှ ကျော်၍ လုပ်ထားသည်။"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - ဘက်ထရီကာကွယ်ရန် အားသွင်းခြင်းကို ခဏရပ်ထားသည်"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - အားသွင်းပစ္စည်း စစ်ရန်"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ခန့် ကျန်သည်"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ခန့် ကျန်သည် (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"သင်၏ အသုံးပြုမှု အပေါ် မူတည်၍ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ခန့် ကျန်သည်"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index d286da13d8f1..256a71bb57c4 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Overstyres av <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Ladingen er satt på vent for å beskytte batteriet"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – Sjekk ladetilbehøret"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Omtrent <xliff:g id="TIME_REMAINING">%1$s</xliff:g> igjen"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Omtrent <xliff:g id="TIME_REMAINING">%1$s</xliff:g> igjen (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Omtrent <xliff:g id="TIME_REMAINING">%1$s</xliff:g> igjen basert på bruken din"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 146418c83e69..fdd965a6e52a 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारा अधिरोहित"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - ब्याट्री जोगाउन चार्जिङ होल्ड गरिएको छ"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - चार्जिङ एक्सेसरी जाँच्नुहोस्"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"लगभग <xliff:g id="TIME_REMAINING">%1$s</xliff:g> बाँकी छ"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"लगभग <xliff:g id="TIME_REMAINING">%1$s</xliff:g> बाँकी छ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"तपाईंको प्रयोगको आधारमा लगभग <xliff:g id="TIME_REMAINING">%1$s</xliff:g> बाँकी छ"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index f5ae2540d7ae..72e57af602e8 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Overschreven door <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g>: opladen is in de wacht gezet om de batterij te beschermen"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - Oplaadaccessoire checken"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Nog ongeveer <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Nog ongeveer <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Nog ongeveer <xliff:g id="TIME_REMAINING">%1$s</xliff:g> op basis van je gebruik"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index b71cf0ebd125..723af105f8ea 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> ଦ୍ୱାରା ଓଭର୍‌ରାଇଡ୍‌ କରାଯାଇଛି"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - ବେଟେରୀକୁ ସୁରକ୍ଷିତ ରଖିବା ପାଇଁ ଚାର୍ଜିଂ ହୋଲ୍ଡରେ ଅଛି"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - ଚାର୍ଜିଂ ଆକସେସୋରୀକୁ ଯାଞ୍ଚ କରନ୍ତୁ"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"ପାଖାପାଖି <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ବଳକା ଅଛି"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"ପାଖାପାଖି <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ପାଇଁ (<xliff:g id="LEVEL">%2$s</xliff:g>) ବଳକା ଅଛି"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"ଆପଣଙ୍କ ବ୍ୟବହାରକୁ ଆଧାର କରି ପାଖାପାଖି <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ବଳକା ଅଛି"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 76d49214761d..8a77c12f6c0c 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> ਦੁਆਰਾ ਓਵਰਰਾਈਡ ਕੀਤਾ"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਬੈਟਰੀ ਦੀ ਸੁਰੱਖਿਆ ਲਈ ਚਾਰਜਿੰਗ ਨੂੰ ਰੋਕਿਆ ਗਿਆ ਹੈ"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਚਾਰਜਿੰਗ ਐਕਸੈਸਰੀ ਦੀ ਜਾਂਚ ਕਰੋ"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"ਲਗਭਗ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ਬਾਕੀ"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"ਲਗਭਗ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ਬਾਕੀ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"ਤੁਹਾਡੀ ਵਰਤੋਂ ਦੇ ਆਧਾਰ \'ਤੇ ਲਗਭਗ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ਬਾਕੀ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 1b76b6f0fd03..375a35f6edef 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Nadpisana przez <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – wstrzymano ładowanie, aby chronić baterię"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – sprawdź akcesoria do ładowania"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Jeszcze około <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Jeszcze około <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Jeszcze około <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (na podstawie Twojego sposobu korzystania)"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index bdfff4aa93c7..55b9db509200 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carregamento suspenso para proteger a bateria"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g>: verifique o acessório de carregamento"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Tempo restante aproximado: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Tempo restante aproximado: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Tempo restante aproximado, com base no seu uso: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 6fb851b7a32e..ca704e7bbb87 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carregamento em espera para proteger a bateria"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - Verificar acessório de carregamento"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Resta(m) cerca de <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Resta(m) cerca de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Resta(m) cerca de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> com base na sua utilização"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index bdfff4aa93c7..55b9db509200 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carregamento suspenso para proteger a bateria"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g>: verifique o acessório de carregamento"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Tempo restante aproximado: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Tempo restante aproximado: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Tempo restante aproximado, com base no seu uso: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index e8d68520b5c4..fa89c1a4c3d8 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Valoare înlocuită de <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Încărcarea s-a întrerupt pentru a proteja bateria"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – Verifică accesoriul de încărcare"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Timp aproximativ rămas: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Timp aproximativ rămas: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"În baza utilizării, timpul rămas este de aproximativ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index ef1e817614d7..d85307098a35 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Новая настройка: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"Уровень заряда – <xliff:g id="PERCENTAGE">%1$s</xliff:g>. <xliff:g id="TIME_STRING">%2$s</xliff:g>."</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g>, зарядка приостановлена для защиты батареи"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g>, проверьте зарядное устройство"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Заряда хватит примерно на <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Заряда (<xliff:g id="LEVEL">%2$s</xliff:g>) хватит примерно на <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Заряда хватит примерно на <xliff:g id="TIME_REMAINING">%1$s</xliff:g> при текущем уровне расхода"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index cf83ee8cc27f..093f216afccc 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> මගින් ඉක්මවන ලදී"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - බැටරිය ආරක්ෂා කිරීම සඳහා ආරෝපණය රඳවා තබා ඇත"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - ආරෝපණ ආයිත්තම පරීක්ෂා කරන්න"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ක් පමණ ඉතිරියි"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ක් පමණ ඉතිරියි (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"ඔබේ භාවිතය මත පදනම්ව <xliff:g id="TIME_REMAINING">%1$s</xliff:g> පමණ ඉතිරිව ඇත"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 577a6c1ff15c..1c8293312871 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Prekonané predvoľbou <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – nabíjanie je pozastavené, aby sa chránila batéria"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – skontrolujte nabíjacie príslušenstvo"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Ešte približne <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Zostáva približne <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Zostáva približne <xliff:g id="TIME_REMAINING">%1$s</xliff:g> – závisí to od intenzity využitia"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 7acd64d1ab4e..f97dd78f8179 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Preglasila nastavitev: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Zaradi zaščite baterije je polnjenje na čakanju"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – Preverite pripomoček za polnjenje"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Še približno <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Še približno <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Glede na način uporabe še približno <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index a2b2042db952..a802f115da4a 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Mbivendosur nga <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Karikimi është vendosur në pritje për të mbrojtur baterinë"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - Kontrollo aksesorin e karikimit"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Rreth <xliff:g id="TIME_REMAINING">%1$s</xliff:g> të mbetura"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Rreth <xliff:g id="TIME_REMAINING">%1$s</xliff:g> të mbetura (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Rreth <xliff:g id="TIME_REMAINING">%1$s</xliff:g> të mbetura bazuar në përdorimin tënd"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 14dd7720ce79..df2215911673 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Замењује га <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g>–<xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – пуњење је на чекању да би се заштитила батерија"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – Проверите додатну опрему за пуњење"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Преостало је око <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Преостало је око <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Преостало је око <xliff:g id="TIME_REMAINING">%1$s</xliff:g> на основу коришћења"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index c9262e9d2494..79b8399527a0 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Har åsidosatts av <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Laddningen har pausats för att skydda batteriet"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – Kontrollera laddningstillbehöret"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Cirka <xliff:g id="TIME_REMAINING">%1$s</xliff:g> kvar"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Cirka <xliff:g id="TIME_REMAINING">%1$s</xliff:g> kvar (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Cirka <xliff:g id="TIME_REMAINING">%1$s</xliff:g> kvar utifrån din användning"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 92c9c7c573cd..c0ace5805e63 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Imetanguliwa na <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Imesitisha kuchaji ili kulinda betri yako"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - Kagua kifaa cha kuchaji"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Zimesalia takribani <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Zimesalia takribani <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Zimesalia takribani <xliff:g id="TIME_REMAINING">%1$s</xliff:g> kulingana na jinsi unavyoitumia"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index ec73fbed7264..ebca26dc3063 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> மூலம் மேலெழுதப்பட்டது"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - பேட்டரியைப் பாதுகாப்பதற்காகச் சார்ஜிங் இடைநிறுத்தப்பட்டுள்ளது"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - சார்ஜிங் துணைக்கருவியைச் சரிபாருங்கள்"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"கிட்டத்தட்ட <xliff:g id="TIME_REMAINING">%1$s</xliff:g> மீதமுள்ளது"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"கிட்டத்தட்ட <xliff:g id="TIME_REMAINING">%1$s</xliff:g> மீதமுள்ளது (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"உபயோகத்தின் அடிப்படையில் கிட்டத்தட்ட <xliff:g id="TIME_REMAINING">%1$s</xliff:g> மீதமுள்ளது"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 0ffdf6a680ae..cf3c08acc54c 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> ద్వారా భర్తీ చేయబడింది"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - బ్యాటరీని రక్షించడానికి ఛార్జింగ్ హోల్డ్‌లో ఉంచబడింది"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - ఛార్జింగ్ యాక్సెసరీని ఎంచుకోండి"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> సమయం మిగిలి ఉంది"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"దాదాపు <xliff:g id="TIME_REMAINING">%1$s</xliff:g> సమయం మిగిలి ఉంది (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"మీ వినియోగం ఆధారంగా దాదాపు <xliff:g id="TIME_REMAINING">%1$s</xliff:g> సమయం మిగిలి ఉంది"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 7bccc25c65dd..a74265ee3e9a 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"แทนที่โดย <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - หยุดการชาร์จชั่วคราวเพื่อถนอมแบตเตอรี่"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - ตรวจสอบอุปกรณ์เสริมสำหรับการชาร์จ"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"เหลืออีกประมาณ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"เหลืออีกประมาณ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"เหลืออีกประมาณ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ขึ้นอยู่กับการใช้งานของคุณ"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 19ba24fcbda4..18d3d3b626fa 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Na-override ng <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Naka-hold ang pag-charge para protektahan ang baterya"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - Suriin ang accessory sa pag-charge"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Humigit-kumulang <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ang natitira"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Humigit-kumulang <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ang natitira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Humigit-kumulang <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ang natitira batay sa iyong paggamit"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 80d2fe294ea3..c4241150ad12 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> tarafından geçersiz kılındı"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Pili korumak için şarj beklemede"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - Şarj aksesuarını kontrol edin"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Yaklaşık <xliff:g id="TIME_REMAINING">%1$s</xliff:g> kaldı"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Yaklaşık <xliff:g id="TIME_REMAINING">%1$s</xliff:g> kaldı (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Kullanımınıza dayalı olarak yaklaşık <xliff:g id="TIME_REMAINING">%1$s</xliff:g> kaldı"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index b1c64f8222b3..97592f970b67 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Замінено на <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – заряджання призупинено, щоб захистити акумулятор"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – перевірте зарядний пристрій"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Залишилося приблизно <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Залишилося приблизно <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Згідно з даними про використання залишилося приблизно <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index f71f4a2174b1..9d3405234e5b 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> کے ذریعہ منسوخ کردیا گیا"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - بیٹری کی حفاظت کرنے کے لیے چارجنگ ہولڈ پر ہے"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - چارجنگ ایکسیسری چیک کریں"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"تقریباً <xliff:g id="TIME_REMAINING">%1$s</xliff:g> باقی ہے"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"تقریباً <xliff:g id="TIME_REMAINING">%1$s</xliff:g> باقی ہے (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"آپ کے استعمال کی بنیاد پر تقریباً <xliff:g id="TIME_REMAINING">%1$s</xliff:g> باقی ہے"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index a3ef6b64d9f9..bd38bb44df6e 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> bilan almashtirildi"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Batareyani himoyalash uchun quvvatlash toʻxtatildi"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – Quvvatlash aksessuarini tekshiring"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Taxminan <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qoldi"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Taxminan <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qoldi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Quvvati tugashiga taxminan <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qoldi"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 3ac91fac6cc0..5b91df3e44a2 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Bị ghi đè bởi <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Đang tạm ngưng sạc để bảo vệ pin"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – Hãy kiểm tra phụ kiện sạc"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Còn khoảng <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Còn khoảng <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Còn khoảng <xliff:g id="TIME_REMAINING">%1$s</xliff:g> dựa trên mức sử dụng của bạn"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 7ff6ceec5fa1..594922a4050d 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"已被“<xliff:g id="TITLE">%1$s</xliff:g>”覆盖"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - 为保护电池,已暂停充电"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - 请检查充电配件"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"大约还可使用<xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"大约还可使用<xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"根据您的使用情况,大约还可使用<xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 53b55bba0bd0..b3aafae4a3c6 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"已由「<xliff:g id="TITLE">%1$s</xliff:g>」覆寫"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - 為保護電池,目前暫停充電"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - 檢查充電配件"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"還有大約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"還有大約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"根據你的使用情況,還有大約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index f9ee07d07fd0..c3be21a93d8c 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"已改為<xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - 為保護電池,目前暫停充電"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> · 請檢查充電配件"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"還能使用約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"目前電量為 <xliff:g id="LEVEL">%2$s</xliff:g>,還能使用約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"根據你的使用情形,還能使用約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 8ff64d141b94..f6aaf813af84 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -457,8 +457,7 @@
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Igitshezwe ngaphezulu yi-<xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Ukushaja kumisiwe ukuze kuvikelwe ibhethri"</string>
- <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) -->
- <skip />
+ <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - Hlola insiza yokushaja"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Cishe u-<xliff:g id="TIME_REMAINING">%1$s</xliff:g> osele"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Cishe u-<xliff:g id="TIME_REMAINING">%1$s</xliff:g> osele (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Cishe u-<xliff:g id="TIME_REMAINING">%1$s</xliff:g> osele ngokususelwe ekusebenziseni wakho"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
index bdb58719b1a8..5f026c451152 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
@@ -74,6 +74,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -84,6 +85,7 @@ public abstract class InfoMediaManager extends MediaManager {
private static final String TAG = "InfoMediaManager";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ protected final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>();
/** Checked exception that signals the specified package is not present in the system. */
public static class PackageNotAvailableException extends Exception {
@@ -227,6 +229,16 @@ public abstract class InfoMediaManager extends MediaManager {
Api34Impl.onRouteListingPreferenceUpdated(routeListingPreference, mPreferenceItemMap);
}
+ protected final MediaDevice findMediaDevice(@NonNull String id) {
+ for (MediaDevice mediaDevice : mMediaDevices) {
+ if (mediaDevice.getId().equals(id)) {
+ return mediaDevice;
+ }
+ }
+ Log.e(TAG, "findMediaDevice() can't find device with id: " + id);
+ return null;
+ }
+
/**
* Get current device that played media.
* @return MediaDevice
@@ -433,7 +445,7 @@ public abstract class InfoMediaManager extends MediaManager {
protected final synchronized void refreshDevices() {
rebuildDeviceList();
- dispatchDeviceListAdded();
+ dispatchDeviceListAdded(mMediaDevices);
}
// MediaRoute2Info.getType was made public on API 34, but exists since API 30.
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaManager.java
index 8bebd6ee3448..d562c8a82f2d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/MediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaManager.java
@@ -15,9 +15,9 @@
*/
package com.android.settingslib.media;
+import android.annotation.NonNull;
import android.app.Notification;
import android.content.Context;
-import android.util.Log;
import java.util.ArrayList;
import java.util.Collection;
@@ -29,10 +29,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
*/
public abstract class MediaManager {
- private static final String TAG = "MediaManager";
-
protected final Collection<MediaDeviceCallback> mCallbacks = new CopyOnWriteArrayList<>();
- protected final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>();
protected Context mContext;
protected Notification mNotification;
@@ -54,19 +51,9 @@ public abstract class MediaManager {
}
}
- protected MediaDevice findMediaDevice(String id) {
- for (MediaDevice mediaDevice : mMediaDevices) {
- if (mediaDevice.getId().equals(id)) {
- return mediaDevice;
- }
- }
- Log.e(TAG, "findMediaDevice() can't found device");
- return null;
- }
-
- protected void dispatchDeviceListAdded() {
+ protected void dispatchDeviceListAdded(@NonNull List<MediaDevice> devices) {
for (MediaDeviceCallback callback : getCallbacks()) {
- callback.onDeviceListAdded(new ArrayList<>(mMediaDevices));
+ callback.onDeviceListAdded(new ArrayList<>(devices));
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt
index 65b73caeada7..0117ece888c0 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt
@@ -46,7 +46,7 @@ open class WifiUtils {
/**
* Wrapper the [.getInternetIconResource] for testing compatibility.
*/
- class InternetIconInjector(protected val context: Context) {
+ open class InternetIconInjector(protected val context: Context) {
/**
* Returns the Internet icon for a given RSSI level.
*
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaManagerTest.java
index 46e724d245f5..c3237f0e72eb 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaManagerTest.java
@@ -16,7 +16,6 @@
package com.android.settingslib.media;
-import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
@@ -32,6 +31,8 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
+import java.util.Collections;
+
@RunWith(RobolectricTestRunner.class)
public class MediaManagerTest {
@@ -59,7 +60,7 @@ public class MediaManagerTest {
public void dispatchDeviceListAdded_registerCallback_shouldDispatchCallback() {
mMediaManager.registerCallback(mCallback);
- mMediaManager.dispatchDeviceListAdded();
+ mMediaManager.dispatchDeviceListAdded(Collections.emptyList());
verify(mCallback).onDeviceListAdded(any());
}
@@ -68,9 +69,9 @@ public class MediaManagerTest {
public void dispatchDeviceListRemoved_registerCallback_shouldDispatchCallback() {
mMediaManager.registerCallback(mCallback);
- mMediaManager.dispatchDeviceListRemoved(mMediaManager.mMediaDevices);
+ mMediaManager.dispatchDeviceListRemoved(Collections.emptyList());
- verify(mCallback).onDeviceListRemoved(mMediaManager.mMediaDevices);
+ verify(mCallback).onDeviceListRemoved(Collections.emptyList());
}
@Test
@@ -83,24 +84,6 @@ public class MediaManagerTest {
}
@Test
- public void findMediaDevice_idExist_shouldReturnMediaDevice() {
- mMediaManager.mMediaDevices.add(mDevice);
-
- final MediaDevice device = mMediaManager.findMediaDevice(TEST_ID);
-
- assertThat(device.getId()).isEqualTo(mDevice.getId());
- }
-
- @Test
- public void findMediaDevice_idNotExist_shouldReturnNull() {
- mMediaManager.mMediaDevices.add(mDevice);
-
- final MediaDevice device = mMediaManager.findMediaDevice("123");
-
- assertThat(device).isNull();
- }
-
- @Test
public void dispatchOnRequestFailed_registerCallback_shouldDispatchCallback() {
mMediaManager.registerCallback(mCallback);
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 2fa1c6eda458..a490b6f096ef 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -154,6 +154,7 @@ public class SecureSettings {
Settings.Secure.MANUAL_RINGER_TOGGLE_COUNT,
Settings.Secure.LOW_POWER_WARNING_ACKNOWLEDGED,
Settings.Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED,
+ Settings.Secure.EMERGENCY_THERMAL_ALERT_DISABLED,
Settings.Secure.HUSH_GESTURE_USED,
Settings.Secure.IN_CALL_NOTIFICATION_ENABLED,
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 2535fdb6e4d0..4cdf98cbe14e 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -235,6 +235,7 @@ public class SecureSettingsValidators {
VALIDATORS.put(Secure.MANUAL_RINGER_TOGGLE_COUNT, NON_NEGATIVE_INTEGER_VALIDATOR);
VALIDATORS.put(Secure.LOW_POWER_WARNING_ACKNOWLEDGED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.EMERGENCY_THERMAL_ALERT_DISABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.IN_CALL_NOTIFICATION_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, BOOLEAN_VALIDATOR);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
index 6ff36d43f91f..ad3eb92b0519 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
@@ -20,8 +20,6 @@ import static android.provider.Settings.Config.SYNC_DISABLED_MODE_NONE;
import static android.provider.Settings.Config.SYNC_DISABLED_MODE_PERSISTENT;
import static android.provider.Settings.Config.SYNC_DISABLED_MODE_UNTIL_REBOOT;
-import static com.android.providers.settings.Flags.supportOverrides;
-
import android.aconfig.Aconfig.parsed_flag;
import android.aconfig.Aconfig.parsed_flags;
import android.annotation.SuppressLint;
@@ -269,9 +267,9 @@ public final class DeviceConfigService extends Binder {
verb = CommandVerb.GET;
} else if ("put".equalsIgnoreCase(cmd)) {
verb = CommandVerb.PUT;
- } else if (supportOverrides() && "override".equalsIgnoreCase(cmd)) {
+ } else if ("override".equalsIgnoreCase(cmd)) {
verb = CommandVerb.OVERRIDE;
- } else if (supportOverrides() && "clear_override".equalsIgnoreCase(cmd)) {
+ } else if ("clear_override".equalsIgnoreCase(cmd)) {
verb = CommandVerb.CLEAR_OVERRIDE;
} else if ("delete".equalsIgnoreCase(cmd)) {
verb = CommandVerb.DELETE;
@@ -285,7 +283,7 @@ public final class DeviceConfigService extends Binder {
if (peekNextArg() == null) {
isValid = true;
}
- } else if (supportOverrides() && "list_local_overrides".equalsIgnoreCase(cmd)) {
+ } else if ("list_local_overrides".equalsIgnoreCase(cmd)) {
verb = CommandVerb.LIST_LOCAL_OVERRIDES;
if (peekNextArg() == null) {
isValid = true;
@@ -427,14 +425,10 @@ public final class DeviceConfigService extends Binder {
DeviceConfig.setProperty(namespace, key, value, makeDefault);
break;
case OVERRIDE:
- if (supportOverrides()) {
- DeviceConfig.setLocalOverride(namespace, key, value);
- }
+ DeviceConfig.setLocalOverride(namespace, key, value);
break;
case CLEAR_OVERRIDE:
- if (supportOverrides()) {
- DeviceConfig.clearLocalOverride(namespace, key);
- }
+ DeviceConfig.clearLocalOverride(namespace, key);
break;
case DELETE:
pout.println(delete(iprovider, namespace, key)
@@ -452,19 +446,15 @@ public final class DeviceConfigService extends Binder {
}
} else {
for (String line : listAll(iprovider)) {
- if (supportOverrides()) {
- boolean isPrivate = false;
- for (String privateNamespace : PRIVATE_NAMESPACES) {
- if (line.startsWith(privateNamespace)) {
- isPrivate = true;
- break;
- }
+ boolean isPrivate = false;
+ for (String privateNamespace : PRIVATE_NAMESPACES) {
+ if (line.startsWith(privateNamespace)) {
+ isPrivate = true;
+ break;
}
+ }
- if (!isPrivate) {
- pout.println(line);
- }
- } else {
+ if (!isPrivate) {
pout.println(line);
}
}
@@ -495,18 +485,16 @@ public final class DeviceConfigService extends Binder {
}
break;
case LIST_LOCAL_OVERRIDES:
- if (supportOverrides()) {
- Map<String, Map<String, String>> underlyingValues =
- DeviceConfig.getUnderlyingValuesForOverriddenFlags();
- for (String overrideNamespace : underlyingValues.keySet()) {
- Map<String, String> flagToValue =
- underlyingValues.get(overrideNamespace);
- for (String flag : flagToValue.keySet()) {
- String flagText = overrideNamespace + "/" + flag;
- String valueText =
- DeviceConfig.getProperty(overrideNamespace, flag);
- pout.println(flagText + "=" + valueText);
- }
+ Map<String, Map<String, String>> underlyingValues =
+ DeviceConfig.getUnderlyingValuesForOverriddenFlags();
+ for (String overrideNamespace : underlyingValues.keySet()) {
+ Map<String, String> flagToValue =
+ underlyingValues.get(overrideNamespace);
+ for (String flag : flagToValue.keySet()) {
+ String flagText = overrideNamespace + "/" + flag;
+ String valueText =
+ DeviceConfig.getProperty(overrideNamespace, flag);
+ pout.println(flagText + "=" + valueText);
}
}
break;
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index febce97031bb..1ead14ab6f4c 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -3812,7 +3812,7 @@ public class SettingsProvider extends ContentProvider {
}
private final class UpgradeController {
- private static final int SETTINGS_VERSION = 225;
+ private static final int SETTINGS_VERSION = 226;
private final int mUserId;
@@ -6011,6 +6011,28 @@ public class SettingsProvider extends ContentProvider {
currentVersion = 225;
}
+ // Version 225: Set the System#KEYBOARD_VIBRATION_ENABLED based on touch
+ // feedback enabled state.
+ if (currentVersion == 225) {
+ final SettingsState systemSettings = getSystemSettingsLocked(userId);
+ final Setting touchFeedbackSettings = systemSettings
+ .getSettingLocked(Settings.System.HAPTIC_FEEDBACK_ENABLED);
+ final Setting keyboardVibrationSettings = systemSettings
+ .getSettingLocked(Settings.System.KEYBOARD_VIBRATION_ENABLED);
+ if (keyboardVibrationSettings.isNull()) {
+ if (!touchFeedbackSettings.isNull()) {
+ // Use touch feedback settings.
+ systemSettings.insertSettingOverrideableByRestoreLocked(
+ Settings.System.KEYBOARD_VIBRATION_ENABLED,
+ touchFeedbackSettings.getValue(),
+ touchFeedbackSettings.getTag(),
+ touchFeedbackSettings.isDefaultFromSystem(),
+ SettingsState.SYSTEM_PACKAGE_NAME);
+ }
+ }
+ currentVersion = 226;
+ }
+
// vXXX: Add new settings above this point.
if (currentVersion != newVersion) {
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java
index 085fc2959442..88181e7e2a52 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java
@@ -56,10 +56,12 @@ public class AccessibilityMenuService extends AccessibilityService
implements View.OnTouchListener {
public static final String PACKAGE_NAME = AccessibilityMenuService.class.getPackageName();
+ public static final String PACKAGE_TESTS = ".tests";
public static final String INTENT_TOGGLE_MENU = ".toggle_menu";
public static final String INTENT_HIDE_MENU = ".hide_menu";
public static final String INTENT_GLOBAL_ACTION = ".global_action";
public static final String INTENT_GLOBAL_ACTION_EXTRA = "GLOBAL_ACTION";
+ public static final String INTENT_OPEN_BLOCKED = "OPEN_BLOCKED";
private static final String TAG = "A11yMenuService";
private static final long BUFFER_MILLISECONDS_TO_PREVENT_UPDATE_FAILURE = 100L;
@@ -192,7 +194,7 @@ public class AccessibilityMenuService extends AccessibilityService
IntentFilter hideMenuFilter = new IntentFilter();
hideMenuFilter.addAction(Intent.ACTION_SCREEN_OFF);
- hideMenuFilter.addAction(PACKAGE_NAME + INTENT_HIDE_MENU);
+ hideMenuFilter.addAction(INTENT_HIDE_MENU);
// Including WRITE_SECURE_SETTINGS enforces that we only listen to apps
// with the restricted WRITE_SECURE_SETTINGS permission who broadcast this intent.
@@ -200,7 +202,7 @@ public class AccessibilityMenuService extends AccessibilityService
Manifest.permission.WRITE_SECURE_SETTINGS, null,
Context.RECEIVER_EXPORTED);
registerReceiver(mToggleMenuReceiver,
- new IntentFilter(PACKAGE_NAME + INTENT_TOGGLE_MENU),
+ new IntentFilter(INTENT_TOGGLE_MENU),
Manifest.permission.WRITE_SECURE_SETTINGS, null,
Context.RECEIVER_EXPORTED);
@@ -245,8 +247,9 @@ public class AccessibilityMenuService extends AccessibilityService
* @return {@code true} if successful, {@code false} otherwise.
*/
private boolean performGlobalActionInternal(int globalAction) {
- Intent intent = new Intent(PACKAGE_NAME + INTENT_GLOBAL_ACTION);
+ Intent intent = new Intent(INTENT_GLOBAL_ACTION);
intent.putExtra(INTENT_GLOBAL_ACTION_EXTRA, globalAction);
+ intent.setPackage(PACKAGE_NAME + PACKAGE_TESTS);
sendBroadcast(intent);
Log.i("A11yMenuService", "Broadcasting global action " + globalAction);
return performGlobalAction(globalAction);
@@ -410,9 +413,16 @@ public class AccessibilityMenuService extends AccessibilityService
private void toggleVisibility() {
boolean locked = mKeyguardManager != null && mKeyguardManager.isKeyguardLocked();
- if (!locked && SystemClock.uptimeMillis() - mLastTimeTouchedOutside
- > BUTTON_CLICK_TIMEOUT) {
- mA11yMenuLayout.toggleVisibility();
+ if (!locked) {
+ if (SystemClock.uptimeMillis() - mLastTimeTouchedOutside
+ > BUTTON_CLICK_TIMEOUT) {
+ mA11yMenuLayout.toggleVisibility();
+ }
+ } else {
+ // Broadcast for testing.
+ Intent intent = new Intent(INTENT_OPEN_BLOCKED);
+ intent.setPackage(PACKAGE_NAME + PACKAGE_TESTS);
+ sendBroadcast(intent);
}
}
}
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java b/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java
index 72c1092b92d6..6546b87c8802 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java
@@ -23,6 +23,7 @@ import static android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_QU
import static android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_RECENTS;
import static android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT;
+import static com.android.systemui.accessibility.accessibilitymenu.AccessibilityMenuService.INTENT_OPEN_BLOCKED;
import static com.android.systemui.accessibility.accessibilitymenu.AccessibilityMenuService.INTENT_GLOBAL_ACTION;
import static com.android.systemui.accessibility.accessibilitymenu.AccessibilityMenuService.INTENT_GLOBAL_ACTION_EXTRA;
import static com.android.systemui.accessibility.accessibilitymenu.AccessibilityMenuService.INTENT_HIDE_MENU;
@@ -65,6 +66,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@RunWith(AndroidJUnit4.class)
@@ -75,12 +77,11 @@ public class AccessibilityMenuServiceTest {
private static final int TIMEOUT_SERVICE_STATUS_CHANGE_S = 5;
private static final int TIMEOUT_UI_CHANGE_S = 5;
private static final int NO_GLOBAL_ACTION = -1;
- private static final String INPUT_KEYEVENT_KEYCODE_BACK = "input keyevent KEYCODE_BACK";
- private static final String TEST_PIN = "1234";
private static Instrumentation sInstrumentation;
private static UiAutomation sUiAutomation;
- private static AtomicInteger sLastGlobalAction;
+ private static final AtomicInteger sLastGlobalAction = new AtomicInteger(NO_GLOBAL_ACTION);
+ private static final AtomicBoolean sOpenBlocked = new AtomicBoolean(false);
private static AccessibilityManager sAccessibilityManager;
private static PowerManager sPowerManager;
@@ -122,8 +123,6 @@ public class AccessibilityMenuServiceTest {
() -> sAccessibilityManager.getEnabledAccessibilityServiceList(
AccessibilityServiceInfo.FEEDBACK_ALL_MASK).stream().filter(
info -> info.getId().contains(serviceName)).count() == 1);
-
- sLastGlobalAction = new AtomicInteger(NO_GLOBAL_ACTION);
context.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -131,20 +130,28 @@ public class AccessibilityMenuServiceTest {
sLastGlobalAction.set(
intent.getIntExtra(INTENT_GLOBAL_ACTION_EXTRA, NO_GLOBAL_ACTION));
}},
- new IntentFilter(PACKAGE_NAME + INTENT_GLOBAL_ACTION),
+ new IntentFilter(INTENT_GLOBAL_ACTION),
+ null, null, Context.RECEIVER_EXPORTED);
+
+ context.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.i(TAG, "Received notification that menu cannot be opened.");
+ sOpenBlocked.set(true);
+ }},
+ new IntentFilter(INTENT_OPEN_BLOCKED),
null, null, Context.RECEIVER_EXPORTED);
}
@AfterClass
- public static void classTeardown() throws Throwable {
- clearPin();
+ public static void classTeardown() {
Settings.Secure.putString(sInstrumentation.getTargetContext().getContentResolver(),
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, "");
}
@Before
public void setup() throws Throwable {
- clearPin();
+ sOpenBlocked.set(false);
wakeUpScreen();
sUiAutomation.executeShellCommand("input keyevent KEYCODE_MENU");
openMenu();
@@ -154,20 +161,8 @@ public class AccessibilityMenuServiceTest {
public void tearDown() throws Throwable {
closeMenu();
sLastGlobalAction.set(NO_GLOBAL_ACTION);
- }
-
- private static void clearPin() throws Throwable {
- sUiAutomation.executeShellCommand("locksettings clear --old " + TEST_PIN);
- TestUtils.waitUntil("Device did not register as unlocked & insecure.",
- TIMEOUT_SERVICE_STATUS_CHANGE_S,
- () -> !sKeyguardManager.isDeviceSecure());
- }
-
- private static void setPin() throws Throwable {
- sUiAutomation.executeShellCommand("locksettings set-pin " + TEST_PIN);
- TestUtils.waitUntil("Device did not recognize as locked & secure.",
- TIMEOUT_SERVICE_STATUS_CHANGE_S,
- () -> sKeyguardManager.isDeviceSecure());
+ // dismisses screenshot popup if present.
+ sUiAutomation.executeShellCommand("input keyevent KEYCODE_BACK");
}
private static boolean isMenuVisible() {
@@ -184,7 +179,6 @@ public class AccessibilityMenuServiceTest {
private static void closeScreen() throws Throwable {
Display display = sDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
- setPin();
sUiAutomation.performGlobalAction(GLOBAL_ACTION_LOCK_SCREEN);
TestUtils.waitUntil("Screen did not close.",
TIMEOUT_UI_CHANGE_S,
@@ -194,12 +188,20 @@ public class AccessibilityMenuServiceTest {
}
private static void openMenu() throws Throwable {
- Intent intent = new Intent(PACKAGE_NAME + INTENT_TOGGLE_MENU);
+ openMenu(false);
+ }
+
+ private static void openMenu(boolean abandonOnBlock) throws Throwable {
+ Intent intent = new Intent(INTENT_TOGGLE_MENU);
+ intent.setPackage(PACKAGE_NAME);
sInstrumentation.getContext().sendBroadcast(intent);
TestUtils.waitUntil("Timed out before menu could appear.",
TIMEOUT_UI_CHANGE_S,
() -> {
+ if (sOpenBlocked.get() && abandonOnBlock) {
+ throw new IllegalStateException();
+ }
if (isMenuVisible()) {
return true;
} else {
@@ -213,7 +215,8 @@ public class AccessibilityMenuServiceTest {
if (!isMenuVisible()) {
return;
}
- Intent intent = new Intent(PACKAGE_NAME + INTENT_HIDE_MENU);
+ Intent intent = new Intent(INTENT_HIDE_MENU);
+ intent.setPackage(PACKAGE_NAME);
sInstrumentation.getContext().sendBroadcast(intent);
TestUtils.waitUntil("Timed out before menu could close.",
TIMEOUT_UI_CHANGE_S, () -> !isMenuVisible());
@@ -444,13 +447,13 @@ public class AccessibilityMenuServiceTest {
closeScreen();
wakeUpScreen();
- boolean timedOut = false;
+ boolean blocked = false;
try {
- openMenu();
- } catch (AssertionError e) {
+ openMenu(true);
+ } catch (IllegalStateException e) {
// Expected
- timedOut = true;
+ blocked = true;
}
- assertThat(timedOut).isTrue();
+ assertThat(blocked).isTrue();
}
}
diff --git a/packages/SystemUI/aconfig/predictive_back.aconfig b/packages/SystemUI/aconfig/predictive_back.aconfig
index d0e6b2865891..7bbe82c212e7 100644
--- a/packages/SystemUI/aconfig/predictive_back.aconfig
+++ b/packages/SystemUI/aconfig/predictive_back.aconfig
@@ -4,26 +4,26 @@ flag {
name: "predictive_back_sysui"
namespace: "systemui"
description: "Predictive Back Dispatching for SysUI"
- bug: "309545085"
+ bug: "327737297"
}
flag {
name: "predictive_back_animate_shade"
namespace: "systemui"
description: "Enable Shade Animations"
- bug: "309545085"
+ bug: "327732946"
}
flag {
name: "predictive_back_animate_bouncer"
namespace: "systemui"
description: "Enable Predictive Back Animation in Bouncer"
- bug: "309545085"
+ bug: "327733487"
}
flag {
name: "predictive_back_animate_dialogs"
namespace: "systemui"
description: "Enable Predictive Back Animation for SysUI dialogs"
- bug: "309545085"
+ bug: "327721544"
} \ No newline at end of file
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
index 078da1c863ce..515c8169f1c4 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
@@ -31,8 +31,8 @@ import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
@@ -93,6 +93,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId
@@ -118,6 +119,7 @@ import com.android.systemui.communal.ui.compose.extensions.firstItemAtOffset
import com.android.systemui.communal.ui.compose.extensions.observeTapsWithoutConsuming
import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel
import com.android.systemui.communal.ui.viewmodel.CommunalEditModeViewModel
+import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
import com.android.systemui.communal.widgets.WidgetConfigurator
import com.android.systemui.res.R
import kotlinx.coroutines.launch
@@ -197,26 +199,37 @@ fun CommunalHub(
}
},
) {
- CommunalHubLazyGrid(
- communalContent = communalContent,
- viewModel = viewModel,
- contentPadding = contentPadding,
- contentOffset = contentOffset,
- setGridCoordinates = { gridCoordinates = it },
- updateDragPositionForRemove = { offset ->
- isDraggingToRemove =
- isPointerWithinCoordinates(
- offset = gridCoordinates?.let { it.positionInWindow() + offset },
- containerToCheck = removeButtonCoordinates
- )
- isDraggingToRemove
- },
- onOpenWidgetPicker = onOpenWidgetPicker,
- gridState = gridState,
- contentListState = contentListState,
- selectedKey = selectedKey,
- widgetConfigurator = widgetConfigurator,
- )
+ Column(Modifier.align(Alignment.TopStart)) {
+ CommunalHubLazyGrid(
+ communalContent = communalContent,
+ viewModel = viewModel,
+ contentPadding = contentPadding,
+ contentOffset = contentOffset,
+ setGridCoordinates = { gridCoordinates = it },
+ updateDragPositionForRemove = { offset ->
+ isDraggingToRemove =
+ isPointerWithinCoordinates(
+ offset = gridCoordinates?.let { it.positionInWindow() + offset },
+ containerToCheck = removeButtonCoordinates
+ )
+ isDraggingToRemove
+ },
+ onOpenWidgetPicker = onOpenWidgetPicker,
+ gridState = gridState,
+ contentListState = contentListState,
+ selectedKey = selectedKey,
+ widgetConfigurator = widgetConfigurator,
+ )
+ // TODO(b/326060686): Remove this once keyguard indication area can persist over hub
+ if (viewModel is CommunalViewModel) {
+ val isUnlocked by viewModel.deviceUnlocked.collectAsState(initial = false)
+ Spacer(Modifier.height(24.dp))
+ LockStateIcon(
+ isUnlocked = isUnlocked,
+ modifier = Modifier.align(Alignment.CenterHorizontally),
+ )
+ }
+ }
if (viewModel.isEditMode && onOpenWidgetPicker != null && onEditDone != null) {
Toolbar(
@@ -268,7 +281,7 @@ fun CommunalHub(
@OptIn(ExperimentalFoundationApi::class)
@Composable
-private fun BoxScope.CommunalHubLazyGrid(
+private fun ColumnScope.CommunalHubLazyGrid(
communalContent: List<CommunalContentModel>,
viewModel: BaseCommunalViewModel,
contentPadding: PaddingValues,
@@ -282,7 +295,7 @@ private fun BoxScope.CommunalHubLazyGrid(
widgetConfigurator: WidgetConfigurator?,
) {
var gridModifier =
- Modifier.align(Alignment.TopStart).onGloballyPositioned { setGridCoordinates(it) }
+ Modifier.align(Alignment.Start).onGloballyPositioned { setGridCoordinates(it) }
var list = communalContent
var dragDropState: GridDragDropState? = null
if (viewModel.isEditMode && viewModel is CommunalEditModeViewModel) {
@@ -364,6 +377,26 @@ private fun BoxScope.CommunalHubLazyGrid(
}
}
+@Composable
+private fun LockStateIcon(
+ isUnlocked: Boolean,
+ modifier: Modifier = Modifier,
+) {
+ val colors = LocalAndroidColorScheme.current
+ val resource =
+ if (isUnlocked) {
+ R.drawable.ic_unlocked
+ } else {
+ R.drawable.ic_lock
+ }
+ Icon(
+ painter = painterResource(id = resource),
+ contentDescription = null,
+ tint = colors.onPrimaryContainer,
+ modifier = modifier.size(52.dp)
+ )
+}
+
/**
* Toolbar that contains action buttons to
* 1) open the widget picker
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyboard/stickykeys/ui/view/StickyKeysIndicator.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyboard/stickykeys/ui/view/StickyKeysIndicator.kt
index dd8664696973..a8d801abdcd0 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyboard/stickykeys/ui/view/StickyKeysIndicator.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyboard/stickykeys/ui/view/StickyKeysIndicator.kt
@@ -18,8 +18,11 @@ package com.android.systemui.keyboard.stickykeys.ui.view
import android.content.Context
import android.view.View
+import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
@@ -61,22 +64,32 @@ fun StickyKeysIndicator(viewModel: StickyKeysIndicatorViewModel) {
@Composable
fun StickyKeysIndicator(stickyKeys: Map<ModifierKey, Locked>, modifier: Modifier = Modifier) {
Surface(
- color = MaterialTheme.colorScheme.surface,
+ color = MaterialTheme.colorScheme.inverseSurface,
shape = MaterialTheme.shapes.medium,
- modifier = modifier
+ modifier = modifier.heightIn(min = 84.dp).width(96.dp)
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.Center,
modifier = Modifier.padding(16.dp)
) {
- stickyKeys.forEach { (key, isLocked) ->
- key(key) {
- Text(
- text = key.displayedText,
- fontWeight = if (isLocked.locked) FontWeight.Bold else FontWeight.Normal
- )
- }
- }
+ stickyKeys.forEach { (key, isLocked) -> key(key) { StickyKeyText(key, isLocked) } }
}
}
}
+
+@Composable
+private fun StickyKeyText(key: ModifierKey, isLocked: Locked, modifier: Modifier = Modifier) {
+ Text(
+ text = key.displayedText,
+ fontWeight = if (isLocked.locked) FontWeight.Bold else FontWeight.Normal,
+ style = MaterialTheme.typography.bodyMedium,
+ color =
+ if (isLocked.locked) {
+ MaterialTheme.colorScheme.inverseOnSurface
+ } else {
+ MaterialTheme.colorScheme.outlineVariant
+ },
+ modifier = modifier
+ )
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/mediaoutput/ui/composable/MediaOutputComponent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/mediaoutput/ui/composable/MediaOutputComponent.kt
index b3fcc305e6b5..53de5bc3a36d 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/mediaoutput/ui/composable/MediaOutputComponent.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/mediaoutput/ui/composable/MediaOutputComponent.kt
@@ -27,12 +27,14 @@ import androidx.compose.animation.scaleOut
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.animation.togetherWith
+import androidx.compose.foundation.background
import androidx.compose.foundation.basicMarquee
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
+import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
@@ -137,12 +139,14 @@ constructor(
}
}
) { targetViewModel ->
- Expandable(
- modifier = Modifier.fillMaxSize(),
- color = targetViewModel.backgroundColor.toColor(),
- shape = RoundedCornerShape(12.dp),
- onClick = { viewModel.onDeviceClick(it) },
- ) {}
+ Spacer(
+ modifier =
+ Modifier.fillMaxSize()
+ .background(
+ color = targetViewModel.backgroundColor.toColor(),
+ shape = RoundedCornerShape(12.dp),
+ ),
+ )
}
transition.AnimatedContent(
contentKey = { it.icon },
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraAutoRotateRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraAutoRotateRepositoryImplTest.kt
new file mode 100644
index 000000000000..9cfa57257053
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraAutoRotateRepositoryImplTest.kt
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.camera.data.repository
+
+import android.os.UserHandle
+import android.provider.Settings
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectValues
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.util.settings.fakeSettings
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@android.platform.test.annotations.EnabledOnRavenwood
+class CameraAutoRotateRepositoryImplTest : SysuiTestCase() {
+ private val kosmos = Kosmos()
+ private val testScope = kosmos.testScope
+ private val settings = kosmos.fakeSettings
+ private val testUser = UserHandle.of(1)
+
+ private val underTest =
+ CameraAutoRotateRepositoryImpl(settings, testScope.testScheduler, testScope.backgroundScope)
+
+ /** 3 changes => 3 change signals + 1 signal emitted at start => 4 signals */
+ @Test
+ fun isCameraAutoRotateSettingEnabled_3times() =
+ testScope.runTest {
+ settings.putIntForUser(SETTING_NAME, DISABLE, testUser.identifier)
+ val isCameraAutoRotateSettingEnabled by
+ collectValues(underTest.isCameraAutoRotateSettingEnabled(testUser))
+ runCurrent()
+ assertThat(isCameraAutoRotateSettingEnabled.last()).isFalse()
+
+ settings.putIntForUser(SETTING_NAME, ENABLE, testUser.identifier)
+ runCurrent()
+ assertThat(isCameraAutoRotateSettingEnabled.last()).isTrue()
+
+ settings.putIntForUser(SETTING_NAME, DISABLE, testUser.identifier)
+ runCurrent()
+ assertThat(isCameraAutoRotateSettingEnabled.last()).isFalse()
+
+ settings.putIntForUser(SETTING_NAME, ENABLE, testUser.identifier)
+ runCurrent()
+ assertThat(isCameraAutoRotateSettingEnabled.last()).isTrue()
+
+ assertThat(isCameraAutoRotateSettingEnabled).hasSize(4)
+ }
+
+ @Test
+ fun isCameraAutoRotateSettingEnabled_emitsOnStart() =
+ testScope.runTest {
+ val isCameraAutoRotateSettingEnabled: List<Boolean> by
+ collectValues(underTest.isCameraAutoRotateSettingEnabled(testUser))
+
+ runCurrent()
+
+ assertThat(isCameraAutoRotateSettingEnabled).hasSize(1)
+ }
+
+ /** 0 for 0 changes + 1 signal emitted on start => 1 signal */
+ @Test
+ fun isCameraAutoRotateSettingEnabled_0Times() =
+ testScope.runTest {
+ settings.putIntForUser(SETTING_NAME, DISABLE, testUser.identifier)
+ val isCameraAutoRotateSettingEnabled: List<Boolean> by
+ collectValues(underTest.isCameraAutoRotateSettingEnabled(testUser))
+ runCurrent()
+
+ settings.putIntForUser(SETTING_NAME, DISABLE, testUser.identifier)
+ runCurrent()
+
+ assertThat(isCameraAutoRotateSettingEnabled).hasSize(1)
+ assertThat(isCameraAutoRotateSettingEnabled[0]).isFalse()
+ }
+
+ /** Maintain that flows are cached by user */
+ @Test
+ fun sameUserCallsIsCameraAutoRotateSettingEnabledTwice_getsSameFlow() =
+ testScope.runTest {
+ val flow1 = underTest.isCameraAutoRotateSettingEnabled(testUser)
+ val flow2 = underTest.isCameraAutoRotateSettingEnabled(testUser)
+
+ assertThat(flow1).isEqualTo(flow2)
+ }
+
+ @Test
+ fun differentUsersCallIsCameraAutoRotateSettingEnabled_getDifferentFlow() =
+ testScope.runTest {
+ val user2 = UserHandle.of(2)
+ val flow1 = underTest.isCameraAutoRotateSettingEnabled(testUser)
+ val flow2 = underTest.isCameraAutoRotateSettingEnabled(user2)
+
+ assertThat(flow1).isNotEqualTo(flow2)
+ }
+
+ private companion object {
+ private const val SETTING_NAME = Settings.Secure.CAMERA_AUTOROTATE
+ private const val DISABLE = 0
+ private const val ENABLE = 1
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraSensorPrivacyRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraSensorPrivacyRepositoryImplTest.kt
new file mode 100644
index 000000000000..29de58e2b28f
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraSensorPrivacyRepositoryImplTest.kt
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.camera.data.repository
+
+import android.hardware.SensorPrivacyManager
+import android.os.UserHandle
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.util.mockito.mock
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers
+import org.mockito.Mockito
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@android.platform.test.annotations.EnabledOnRavenwood
+class CameraSensorPrivacyRepositoryImplTest : SysuiTestCase() {
+ private val kosmos = Kosmos()
+ private val testScope = kosmos.testScope
+ private val testUser = UserHandle.of(1)
+ private val privacyManager = mock<SensorPrivacyManager>()
+ private val underTest =
+ CameraSensorPrivacyRepositoryImpl(
+ testScope.testScheduler,
+ testScope.backgroundScope,
+ privacyManager
+ )
+
+ @Test
+ fun isEnabled_2TimesForSameUserReturnsCachedFlow() =
+ testScope.runTest {
+ val flow1 = underTest.isEnabled(testUser)
+ val flow2 = underTest.isEnabled(testUser)
+ runCurrent()
+
+ assertThat(flow1).isEqualTo(flow2)
+ }
+
+ @Test
+ fun isEnabled_2TimesForDifferentUsersReturnsTwoDifferentFlows() =
+ testScope.runTest {
+ val user2 = UserHandle.of(2)
+
+ val flow1 = underTest.isEnabled(testUser)
+ val flow2 = underTest.isEnabled(user2)
+ runCurrent()
+
+ assertThat(flow1).isNotEqualTo(flow2)
+ }
+
+ @Test
+ fun isEnabled_dataMatchesSensorPrivacyManager() =
+ testScope.runTest {
+ val isEnabled = collectLastValue(underTest.isEnabled(testUser))
+
+ val captor =
+ ArgumentCaptor.forClass(
+ SensorPrivacyManager.OnSensorPrivacyChangedListener::class.java
+ )
+ runCurrent()
+ assertThat(isEnabled()).isEqualTo(false)
+
+ Mockito.verify(privacyManager)
+ .addSensorPrivacyListener(
+ ArgumentMatchers.eq(SensorPrivacyManager.Sensors.CAMERA),
+ ArgumentMatchers.eq(testUser.identifier),
+ captor.capture()
+ )
+ val sensorPrivacyCallback = captor.value!!
+
+ sensorPrivacyCallback.onSensorPrivacyChanged(SensorPrivacyManager.Sensors.CAMERA, true)
+ runCurrent()
+ assertThat(isEnabled()).isEqualTo(true)
+
+ sensorPrivacyCallback.onSensorPrivacyChanged(SensorPrivacyManager.Sensors.CAMERA, false)
+ runCurrent()
+ assertThat(isEnabled()).isEqualTo(false)
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepositoryTest.kt
new file mode 100644
index 000000000000..f75e036d78d4
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepositoryTest.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.camera.data.repository
+
+import android.os.UserHandle
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectValues
+import com.android.systemui.kosmos.Kosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@android.platform.test.annotations.EnabledOnRavenwood
+class FakeCameraAutoRotateRepositoryTest : SysuiTestCase() {
+ private val kosmos = Kosmos()
+ private val underTest = kosmos.fakeCameraAutoRotateRepository
+ private val testUser = UserHandle.of(1)
+
+ @Test
+ fun isCameraAutoRotateSettingEnabled_emitsFalseOnStart() = runTest {
+ val isCameraAutoRotateSettingEnabled by
+ collectValues(underTest.isCameraAutoRotateSettingEnabled(testUser))
+
+ assertThat(isCameraAutoRotateSettingEnabled).hasSize(1)
+ assertThat(isCameraAutoRotateSettingEnabled.first()).isFalse()
+ }
+
+ /**
+ * The value explicitly set in this test is not distinct, therefore only 1 value is collected.
+ */
+ @Test
+ fun isCameraAutoRotateSettingEnabled_emitsDistinctValueOnly() = runTest {
+ val isCameraAutoRotateSettingEnabled by
+ collectValues(underTest.isCameraAutoRotateSettingEnabled(testUser))
+ underTest.setEnabled(testUser, false)
+ runCurrent()
+
+ assertThat(isCameraAutoRotateSettingEnabled).hasSize(1)
+ assertThat(isCameraAutoRotateSettingEnabled.first()).isFalse()
+ }
+
+ @Test
+ fun isCameraAutoRotateSettingEnabled_canSetValue3Times() = runTest {
+ val isCameraAutoRotateSettingEnabled by
+ collectValues(underTest.isCameraAutoRotateSettingEnabled(testUser))
+ runCurrent()
+ underTest.setEnabled(testUser, true)
+ runCurrent()
+ underTest.setEnabled(testUser, false)
+ runCurrent()
+ underTest.setEnabled(testUser, true)
+ runCurrent()
+ assertThat(isCameraAutoRotateSettingEnabled).hasSize(4)
+ assertThat(isCameraAutoRotateSettingEnabled.last()).isTrue()
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepositoryTest.kt
new file mode 100644
index 000000000000..7fa1be3d20ff
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepositoryTest.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.camera.data.repository
+
+import android.os.UserHandle
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectValues
+import com.android.systemui.kosmos.Kosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@android.platform.test.annotations.EnabledOnRavenwood
+class FakeCameraSensorPrivacyRepositoryTest : SysuiTestCase() {
+ private val kosmos = Kosmos()
+ private val underTest = kosmos.fakeCameraSensorPrivacyRepository
+ private val testUser = UserHandle.of(1)
+
+ @Test
+ fun isCameraSensorPrivacyEnabled_emitsFalseOnStart() = runTest {
+ val isCameraSensorPrivacySettingEnabled by collectValues(underTest.isEnabled(testUser))
+
+ assertThat(isCameraSensorPrivacySettingEnabled).hasSize(1)
+ assertThat(isCameraSensorPrivacySettingEnabled.first()).isFalse()
+ }
+
+ /**
+ * The value explicitly set in this test is not distinct, therefore only 1 value is collected.
+ */
+ @Test
+ fun isCameraSensorPrivacyEnabled_emitsDistinctValueOnly() = runTest {
+ val isCameraSensorPrivacySettingEnabled by collectValues(underTest.isEnabled(testUser))
+ underTest.setEnabled(testUser, false)
+ runCurrent()
+
+ assertThat(isCameraSensorPrivacySettingEnabled).hasSize(1)
+ assertThat(isCameraSensorPrivacySettingEnabled.first()).isFalse()
+ }
+
+ @Test
+ fun isCameraSensorPrivacyEnabled_canSetValue3Times() = runTest {
+ val isCameraSensorPrivacySettingEnabled by collectValues(underTest.isEnabled(testUser))
+ runCurrent()
+ underTest.setEnabled(testUser, true)
+ runCurrent()
+ underTest.setEnabled(testUser, false)
+ runCurrent()
+ underTest.setEnabled(testUser, true)
+ runCurrent()
+ assertThat(isCameraSensorPrivacySettingEnabled).hasSize(4)
+ assertThat(isCameraSensorPrivacySettingEnabled.last()).isTrue()
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
index 37b135eaf3e9..ce6445b75fb9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
@@ -23,7 +23,6 @@ import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.communal.domain.interactor.setCommunalAvailable
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.dock.DockManager
import com.android.systemui.dock.dockManager
import com.android.systemui.dock.fakeDockManager
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
@@ -40,6 +39,7 @@ import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
+import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
@@ -92,6 +92,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
}
+ @Ignore("Ignored until custom animations are implemented in b/322787129")
@Test
fun deviceDocked_forceCommunalScene() =
with(kosmos) {
@@ -110,6 +111,23 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
@Test
+ fun exitingDream_forceCommunalScene() =
+ with(kosmos) {
+ testScope.runTest {
+ val scene by collectLastValue(communalInteractor.desiredScene)
+ assertThat(scene).isEqualTo(CommunalScenes.Blank)
+
+ updateDocked(true)
+ fakeKeyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.DREAMING,
+ to = KeyguardState.LOCKSCREEN,
+ testScope = this
+ )
+ assertThat(scene).isEqualTo(CommunalScenes.Communal)
+ }
+ }
+
+ @Test
fun deviceDocked_doesNotForceCommunalIfTransitioningFromCommunal() =
with(kosmos) {
testScope.runTest {
@@ -175,6 +193,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
}
+ @Ignore("Ignored until custom animations are implemented in b/322787129")
@Test
fun dockingOnLockscreen_forcesCommunal() =
with(kosmos) {
@@ -196,6 +215,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
}
+ @Ignore("Ignored until custom animations are implemented in b/322787129")
@Test
fun dockingOnLockscreen_doesNotForceCommunalIfDreamStarts() =
with(kosmos) {
@@ -230,7 +250,8 @@ class CommunalSceneStartableTest : SysuiTestCase() {
with(kosmos) {
runCurrent()
fakeDockManager.setIsDocked(docked)
- fakeDockManager.setDockEvent(DockManager.STATE_DOCKED)
+ // TODO(b/322787129): uncomment once custom animations are in place
+ // fakeDockManager.setDockEvent(DockManager.STATE_DOCKED)
runCurrent()
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
index 563aad1920f7..8f802b80781f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
@@ -39,6 +39,7 @@ import com.android.systemui.communal.shared.model.CommunalWidgetContentModel
import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
import com.android.systemui.communal.ui.viewmodel.CommunalViewModel.Companion.POPUP_AUTO_HIDE_TIMEOUT_MS
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
@@ -113,6 +114,7 @@ class CommunalViewModelTest : SysuiTestCase() {
kosmos.communalInteractor,
kosmos.communalTutorialInteractor,
kosmos.shadeInteractor,
+ kosmos.deviceEntryInteractor,
mediaHost,
logcatLogBuffer("CommunalViewModelTest"),
)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
index 19b80da62dc7..128b46533a8b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
@@ -25,6 +25,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.AuthController
import com.android.systemui.biometrics.data.repository.FakeFacePropertyRepository
+import com.android.systemui.common.shared.model.Position
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.doze.DozeMachine
import com.android.systemui.doze.DozeTransitionCallback
@@ -151,6 +152,24 @@ class KeyguardRepositoryImplTest : SysuiTestCase() {
}
@Test
+ fun clockPosition() =
+ testScope.runTest {
+ assertThat(underTest.clockPosition.value).isEqualTo(Position(0, 0))
+
+ underTest.setClockPosition(0, 1)
+ assertThat(underTest.clockPosition.value).isEqualTo(Position(0, 1))
+
+ underTest.setClockPosition(1, 9)
+ assertThat(underTest.clockPosition.value).isEqualTo(Position(1, 9))
+
+ underTest.setClockPosition(1, 0)
+ assertThat(underTest.clockPosition.value).isEqualTo(Position(1, 0))
+
+ underTest.setClockPosition(3, 1)
+ assertThat(underTest.clockPosition.value).isEqualTo(Position(3, 1))
+ }
+
+ @Test
fun dozeTimeTick() =
testScope.runTest {
val lastDozeTimeTick by collectLastValue(underTest.dozeTimeTick)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt
index 225b5b1408e3..b0f59fe68f11 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt
@@ -71,7 +71,7 @@ class AodBurnInViewModelTest : SysuiTestCase() {
mSetFlagsRule.disableFlags(AConfigFlags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT)
MockitoAnnotations.initMocks(this)
- whenever(burnInInteractor.burnIn(anyInt(), anyInt())).thenReturn(burnInFlow)
+ whenever(burnInInteractor.keyguardBurnIn).thenReturn(burnInFlow)
kosmos.burnInInteractor = burnInInteractor
whenever(goneToAodTransitionViewModel.enterFromTopTranslationY(anyInt()))
.thenReturn(emptyFlow())
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractorTest.kt
new file mode 100644
index 000000000000..266875e9e12a
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractorTest.kt
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.impl.rotation.domain.interactor
+
+import android.Manifest
+import android.content.packageManager
+import android.content.pm.PackageManager
+import android.os.UserHandle
+import android.platform.test.annotations.EnabledOnRavenwood
+import android.testing.LeakCheck
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.camera.data.repository.fakeCameraAutoRotateRepository
+import com.android.systemui.camera.data.repository.fakeCameraSensorPrivacyRepository
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.utils.leaks.FakeBatteryController
+import com.android.systemui.utils.leaks.FakeRotationLockController
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.toCollection
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@EnabledOnRavenwood
+@RunWith(AndroidJUnit4::class)
+class RotationLockTileDataInteractorTest : SysuiTestCase() {
+ private val kosmos = Kosmos()
+ private val testScope = kosmos.testScope
+ private val batteryController = FakeBatteryController(LeakCheck())
+ private val rotationController = FakeRotationLockController(LeakCheck())
+ private val fakeCameraAutoRotateRepository = kosmos.fakeCameraAutoRotateRepository
+ private val fakeCameraSensorPrivacyRepository = kosmos.fakeCameraSensorPrivacyRepository
+ private val packageManager = kosmos.packageManager
+
+ private val testUser = UserHandle.of(1)
+ private lateinit var underTest: RotationLockTileDataInteractor
+
+ @Before
+ fun setup() {
+ whenever(packageManager.rotationResolverPackageName).thenReturn(TEST_PACKAGE_NAME)
+ whenever(
+ packageManager.checkPermission(
+ eq(Manifest.permission.CAMERA),
+ eq(TEST_PACKAGE_NAME)
+ )
+ )
+ .thenReturn(PackageManager.PERMISSION_GRANTED)
+
+ underTest =
+ RotationLockTileDataInteractor(
+ rotationController,
+ batteryController,
+ fakeCameraAutoRotateRepository,
+ fakeCameraSensorPrivacyRepository,
+ packageManager,
+ context.orCreateTestableResources
+ .apply {
+ addOverride(com.android.internal.R.bool.config_allowRotationResolver, true)
+ }
+ .resources
+ )
+ }
+
+ @Test
+ fun availability_isTrue() =
+ testScope.runTest {
+ val availability = underTest.availability(testUser).toCollection(mutableListOf())
+
+ assertThat(availability).hasSize(1)
+ assertThat(availability.last()).isTrue()
+ }
+
+ @Test
+ fun tileData_isRotationLockedMatchesRotationController() =
+ testScope.runTest {
+ val data by
+ collectLastValue(
+ underTest.tileData(testUser, flowOf(DataUpdateTrigger.InitialRequest))
+ )
+
+ runCurrent()
+ assertThat(data!!.isRotationLocked).isEqualTo(false)
+
+ rotationController.setRotationLocked(true, CALLER)
+ runCurrent()
+ assertThat(data!!.isRotationLocked).isEqualTo(true)
+
+ rotationController.setRotationLocked(false, CALLER)
+ runCurrent()
+ assertThat(data!!.isRotationLocked).isEqualTo(false)
+ }
+
+ @Test
+ fun tileData_cameraRotationMatchesBatteryController() =
+ testScope.runTest {
+ setupControllersToEnableCameraRotation()
+ val data by
+ collectLastValue(
+ underTest.tileData(testUser, flowOf(DataUpdateTrigger.InitialRequest))
+ )
+
+ runCurrent()
+ assertThat(data!!.isCameraRotationEnabled).isTrue()
+
+ batteryController.setPowerSaveMode(true)
+ runCurrent()
+ assertThat(data!!.isCameraRotationEnabled).isFalse()
+
+ batteryController.setPowerSaveMode(false)
+ runCurrent()
+ assertThat(data!!.isCameraRotationEnabled).isTrue()
+ }
+
+ @Test
+ fun tileData_cameraRotationMatchesSensorPrivacyRepository() =
+ testScope.runTest {
+ setupControllersToEnableCameraRotation()
+ val lastValue by
+ this.collectLastValue(
+ underTest.tileData(testUser, flowOf(DataUpdateTrigger.InitialRequest))
+ )
+ runCurrent()
+ assertThat(lastValue!!.isCameraRotationEnabled).isTrue()
+
+ fakeCameraSensorPrivacyRepository.setEnabled(testUser, true)
+ runCurrent()
+ assertThat(lastValue!!.isCameraRotationEnabled).isFalse()
+
+ fakeCameraSensorPrivacyRepository.setEnabled(testUser, false)
+ runCurrent()
+ assertThat(lastValue!!.isCameraRotationEnabled).isTrue()
+ }
+
+ @Test
+ fun tileData_cameraRotationMatchesAutoRotateRepository() =
+ testScope.runTest {
+ setupControllersToEnableCameraRotation()
+
+ val lastValue by
+ collectLastValue(
+ underTest.tileData(testUser, flowOf(DataUpdateTrigger.InitialRequest))
+ )
+ runCurrent()
+ assertThat(lastValue!!.isCameraRotationEnabled).isTrue()
+
+ fakeCameraAutoRotateRepository.setEnabled(testUser, false)
+ runCurrent()
+ assertThat(lastValue!!.isCameraRotationEnabled).isFalse()
+
+ fakeCameraAutoRotateRepository.setEnabled(testUser, true)
+ runCurrent()
+ assertThat(lastValue!!.isCameraRotationEnabled).isTrue()
+ }
+
+ @Test
+ fun tileData_matchesPackageManagerPermissionDenied() =
+ testScope.runTest {
+ whenever(
+ packageManager.checkPermission(
+ eq(Manifest.permission.CAMERA),
+ eq(TEST_PACKAGE_NAME)
+ )
+ )
+ .thenReturn(PackageManager.PERMISSION_DENIED)
+
+ val lastValue by
+ collectLastValue(
+ underTest.tileData(testUser, flowOf(DataUpdateTrigger.InitialRequest))
+ )
+ runCurrent()
+ assertThat(lastValue!!.isCameraRotationEnabled).isEqualTo(false)
+ }
+
+ @Test
+ fun tileData_setConfigAllowRotationResolverToFalse_cameraRotationIsNotEnabled() =
+ testScope.runTest {
+ underTest.apply {
+ overrideResource(com.android.internal.R.bool.config_allowRotationResolver, false)
+ }
+ setupControllersToEnableCameraRotation()
+ val lastValue by
+ collectLastValue(
+ underTest.tileData(testUser, flowOf(DataUpdateTrigger.InitialRequest))
+ )
+ runCurrent()
+
+ assertThat(lastValue!!.isCameraRotationEnabled).isEqualTo(false)
+ }
+
+ private fun setupControllersToEnableCameraRotation() {
+ rotationController.setRotationLocked(true, CALLER)
+ batteryController.setPowerSaveMode(false)
+ fakeCameraSensorPrivacyRepository.setEnabled(testUser, false)
+ fakeCameraAutoRotateRepository.setEnabled(testUser, true)
+ }
+
+ private companion object {
+ private const val CALLER = "RotationLockTileDataInteractorTest"
+ private const val TEST_PACKAGE_NAME = "com.test"
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractorTest.kt
new file mode 100644
index 000000000000..1653ce369ea1
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractorTest.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.impl.rotation.domain.interactor
+
+import android.platform.test.annotations.EnabledOnRavenwood
+import android.provider.Settings
+import android.testing.LeakCheck
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
+import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
+import com.android.systemui.qs.tiles.impl.rotation.domain.model.RotationLockTileModel
+import com.android.systemui.utils.leaks.FakeRotationLockController
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@EnabledOnRavenwood
+@RunWith(AndroidJUnit4::class)
+class RotationLockTileUserActionInteractorTest : SysuiTestCase() {
+ private val controller = FakeRotationLockController(LeakCheck())
+ private val inputHandler = FakeQSTileIntentUserInputHandler()
+
+ private val underTest =
+ RotationLockTileUserActionInteractor(
+ controller,
+ inputHandler,
+ )
+
+ @Test
+ fun handleClickWhenEnabled() = runTest {
+ val wasEnabled = true
+ controller.setRotationLocked(wasEnabled, null)
+
+ underTest.handleInput(QSTileInputTestKtx.click(RotationLockTileModel(wasEnabled, false)))
+
+ assertThat(controller.isRotationLocked).isEqualTo(!wasEnabled)
+ }
+
+ @Test
+ fun handleClickWhenDisabled() = runTest {
+ val wasEnabled = false
+ controller.setRotationLocked(wasEnabled, null)
+
+ underTest.handleInput(QSTileInputTestKtx.click(RotationLockTileModel(wasEnabled, false)))
+
+ assertThat(controller.isRotationLocked).isEqualTo(!wasEnabled)
+ }
+
+ @Test
+ fun handleLongClickWhenDisabled() = runTest {
+ val enabled = false
+
+ underTest.handleInput(
+ QSTileInputTestKtx.longClick(
+ RotationLockTileModel(
+ enabled,
+ false,
+ )
+ )
+ )
+
+ QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput {
+ assertThat(it.intent.action).isEqualTo(Settings.ACTION_AUTO_ROTATE_SETTINGS)
+ }
+ }
+
+ @Test
+ fun handleLongClickWhenEnabled() = runTest {
+ val enabled = true
+
+ underTest.handleInput(QSTileInputTestKtx.longClick(RotationLockTileModel(enabled, false)))
+
+ QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput {
+ assertThat(it.intent.action).isEqualTo(Settings.ACTION_AUTO_ROTATE_SETTINGS)
+ }
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapperTest.kt
new file mode 100644
index 000000000000..60c69f427ef3
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapperTest.kt
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.impl.rotation.ui.mapper
+
+import android.graphics.drawable.TestStubDrawable
+import android.widget.Switch
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
+import com.android.systemui.qs.tiles.impl.rotation.domain.model.RotationLockTileModel
+import com.android.systemui.qs.tiles.impl.rotation.qsRotationLockTileConfig
+import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.policy.DevicePostureController
+import com.android.systemui.statusbar.policy.devicePostureController
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class RotationLockTileMapperTest : SysuiTestCase() {
+ private val kosmos = Kosmos()
+ private val rotationLockTileConfig = kosmos.qsRotationLockTileConfig
+ private val devicePostureController = kosmos.devicePostureController
+
+ private lateinit var mapper: RotationLockTileMapper
+
+ @Before
+ fun setup() {
+ whenever(devicePostureController.devicePosture)
+ .thenReturn(DevicePostureController.DEVICE_POSTURE_CLOSED)
+
+ mapper =
+ RotationLockTileMapper(
+ context.orCreateTestableResources
+ .apply {
+ addOverride(R.drawable.qs_auto_rotate_icon_off, TestStubDrawable())
+ addOverride(R.drawable.qs_auto_rotate_icon_on, TestStubDrawable())
+ addOverride(com.android.internal.R.bool.config_allowRotationResolver, true)
+ addOverride(
+ com.android.internal.R.array.config_foldedDeviceStates,
+ intArrayOf() // empty array <=> device is not foldable
+ )
+ }
+ .resources,
+ context.theme,
+ devicePostureController
+ )
+ }
+
+ @Test
+ fun rotationNotLocked_cameraRotationDisabled() {
+ val inputModel = RotationLockTileModel(false, false)
+
+ val outputState = mapper.map(rotationLockTileConfig, inputModel)
+
+ val expectedState =
+ createRotationLockTileState(
+ QSTileState.ActivationState.ACTIVE,
+ EMPTY_SECONDARY_STRING,
+ R.drawable.qs_auto_rotate_icon_on
+ )
+ QSTileStateSubject.assertThat(outputState).isEqualTo(expectedState)
+ }
+
+ @Test
+ fun rotationNotLocked_cameraRotationEnabled() {
+ val inputModel = RotationLockTileModel(false, true)
+
+ val outputState = mapper.map(rotationLockTileConfig, inputModel)
+
+ val expectedState =
+ createRotationLockTileState(
+ QSTileState.ActivationState.ACTIVE,
+ context.getString(R.string.rotation_lock_camera_rotation_on),
+ R.drawable.qs_auto_rotate_icon_on
+ )
+ QSTileStateSubject.assertThat(outputState).isEqualTo(expectedState)
+ }
+
+ @Test
+ fun rotationLocked_cameraRotationNotEnabled() {
+ val inputModel = RotationLockTileModel(true, false)
+
+ val outputState = mapper.map(rotationLockTileConfig, inputModel)
+
+ val expectedState =
+ createRotationLockTileState(
+ QSTileState.ActivationState.INACTIVE,
+ EMPTY_SECONDARY_STRING,
+ R.drawable.qs_auto_rotate_icon_off
+ )
+ QSTileStateSubject.assertThat(outputState).isEqualTo(expectedState)
+ }
+
+ @Test
+ fun deviceFoldableAndClosed_secondaryLabelIsFoldableSpecific() {
+ setDeviceFoldable()
+ val inputModel = RotationLockTileModel(false, false)
+
+ val outputState = mapper.map(rotationLockTileConfig, inputModel)
+
+ val expectedSecondaryLabelEnding =
+ context.getString(R.string.quick_settings_rotation_posture_folded)
+ assertThat(
+ context.resources.getIntArray(
+ com.android.internal.R.array.config_foldedDeviceStates
+ )
+ )
+ .isNotEmpty()
+ val actualSecondaryLabel = outputState.secondaryLabel
+ assertThat(actualSecondaryLabel).isNotNull()
+ assertThat(actualSecondaryLabel!!.endsWith(expectedSecondaryLabelEnding)).isTrue()
+ }
+
+ @Test
+ fun deviceFoldableAndNotClosed_secondaryLabelIsFoldableSpecific() {
+ setDeviceFoldable()
+ whenever(devicePostureController.devicePosture)
+ .thenReturn(DevicePostureController.DEVICE_POSTURE_OPENED)
+ val inputModel = RotationLockTileModel(false, false)
+
+ val outputState = mapper.map(rotationLockTileConfig, inputModel)
+
+ val expectedSecondaryLabelEnding =
+ context.getString(R.string.quick_settings_rotation_posture_unfolded)
+ assertThat(
+ context.orCreateTestableResources.resources.getIntArray(
+ com.android.internal.R.array.config_foldedDeviceStates
+ )
+ )
+ .isNotEmpty()
+ val actualSecondaryLabel = outputState.secondaryLabel
+ assertThat(actualSecondaryLabel).isNotNull()
+ assertThat(actualSecondaryLabel!!.endsWith(expectedSecondaryLabelEnding)).isTrue()
+ }
+
+ private fun setDeviceFoldable() {
+ mapper.apply {
+ overrideResource(
+ com.android.internal.R.array.config_foldedDeviceStates,
+ intArrayOf(1, 2, 3)
+ )
+ }
+ }
+
+ private fun createRotationLockTileState(
+ activationState: QSTileState.ActivationState,
+ secondaryLabel: String,
+ iconRes: Int
+ ): QSTileState {
+ val label = context.getString(R.string.quick_settings_rotation_unlocked_label)
+ return QSTileState(
+ { Icon.Loaded(context.getDrawable(iconRes)!!, null) },
+ label,
+ activationState,
+ secondaryLabel,
+ setOf(QSTileState.UserAction.CLICK, QSTileState.UserAction.LONG_CLICK),
+ context.getString(R.string.accessibility_quick_settings_rotation),
+ secondaryLabel,
+ QSTileState.SideViewIcon.None,
+ QSTileState.EnabledState.ENABLED,
+ Switch::class.qualifiedName
+ )
+ }
+
+ private companion object {
+ private const val EMPTY_SECONDARY_STRING = ""
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModelTest.kt
index 243aab24b07d..dcf635e622f4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModelTest.kt
@@ -32,8 +32,8 @@ import com.android.systemui.util.mockito.whenever
import com.android.systemui.volume.localMediaRepository
import com.android.systemui.volume.mediaController
import com.android.systemui.volume.mediaControllerRepository
+import com.android.systemui.volume.mediaOutputActionsInteractor
import com.android.systemui.volume.mediaOutputInteractor
-import com.android.systemui.volume.panel.mediaOutputActionsInteractor
import com.android.systemui.volume.panel.volumePanelViewModel
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
diff --git a/packages/SystemUI/res/layout/notif_half_shelf.xml b/packages/SystemUI/res/layout/notif_half_shelf.xml
index 68c8dd96d188..d8d298573d04 100644
--- a/packages/SystemUI/res/layout/notif_half_shelf.xml
+++ b/packages/SystemUI/res/layout/notif_half_shelf.xml
@@ -19,11 +19,11 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:id="@+id/half_shelf_dialog"
android:orientation="vertical"
- android:layout_width="wrap_content"
+ android:layout_width="@dimen/large_dialog_width"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
- android:paddingStart="4dp"
- android:paddingEnd="4dp">
+ android:paddingLeft="@dimen/dialog_side_padding"
+ android:paddingRight="@dimen/dialog_side_padding">
<LinearLayout
android:id="@+id/half_shelf"
diff --git a/packages/SystemUI/res/layout/scene_window_root.xml b/packages/SystemUI/res/layout/scene_window_root.xml
index bb8de4c32e76..0dcd15b429c1 100644
--- a/packages/SystemUI/res/layout/scene_window_root.xml
+++ b/packages/SystemUI/res/layout/scene_window_root.xml
@@ -24,7 +24,7 @@
android:id="@+id/scene_window_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:fitsSystemWindows="false">
+ android:fitsSystemWindows="true">
<include layout="@layout/super_notification_shade"
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index c4d7f8bbb349..515ef619141b 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Lui"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibreer"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Demp"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Saai uit"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Onbeskikbaar omdat luitoon gedemp is"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Tik om te ontdemp."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tik om op vibreer te stel. Toeganklikheidsdienste kan dalk gedemp wees."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tik om te demp. Toeganklikheidsdienste kan dalk gedemp wees."</string>
diff --git a/packages/SystemUI/res/values-af/tiles_states_strings.xml b/packages/SystemUI/res/values-af/tiles_states_strings.xml
index 662aa717ffc1..1c9a79414ff1 100644
--- a/packages/SystemUI/res/values-af/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-af/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Af"</item>
<item msgid="578444932039713369">"Aan"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Onbeskikbaar"</item>
<item msgid="8707481475312432575">"Af"</item>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 37ba3c182422..9763ff2ae468 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"ጥሪ"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"ንዘር"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"ድምጸ-ከል አድርግ"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Cast"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"የጥሪ ድምጽ ስለተዘጋ አይገኝም"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s። ድምጸ-ከል ለማድረግ መታ ያድርጉ"</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s። ወደ ንዝረት ለማቀናበር መታ ያድርጉ። የተደራሽነት አገልግሎቶች ድምጸ-ከል ሊደረግባቸው ይችላል።"</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s። ድምጸ-ከል ለማድረግ መታ ያድርጉ። የተደራሽነት አገልግሎቶች ድምጸ-ከል ሊደረግባቸው ይችላል።"</string>
diff --git a/packages/SystemUI/res/values-am/tiles_states_strings.xml b/packages/SystemUI/res/values-am/tiles_states_strings.xml
index e5d68d985792..3fb24b983162 100644
--- a/packages/SystemUI/res/values-am/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-am/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"ጠፍቷል"</item>
<item msgid="578444932039713369">"በርቷል"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"አይገኝም"</item>
<item msgid="8707481475312432575">"ጠፍቷል"</item>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 1de96aea2210..1b7e3037103f 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"استصدار رنين"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"اهتزاز"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"كتم الصوت"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"البثّ"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"يتعذّر التغيير بسبب كتم صوت الرنين."</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"‏%1$s. انقر لإلغاء التجاهل."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"‏%1$s. انقر للتعيين على الاهتزاز. قد يتم تجاهل خدمات \"سهولة الاستخدام\"."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"‏%1$s. انقر للتجاهل. قد يتم تجاهل خدمات \"سهولة الاستخدام\"."</string>
diff --git a/packages/SystemUI/res/values-ar/tiles_states_strings.xml b/packages/SystemUI/res/values-ar/tiles_states_strings.xml
index 856ae1db8fa1..cf050ac26473 100644
--- a/packages/SystemUI/res/values-ar/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ar/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"الميزة غير مفعّلة"</item>
<item msgid="578444932039713369">"الميزة مفعّلة"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"الميزة غير متاحة"</item>
<item msgid="8707481475312432575">"الميزة غير مفعّلة"</item>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index da69f77836a1..429f03ed3a63 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"ৰিং"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"কম্পন"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"মিউট"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"কাষ্ট কৰক"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"ৰিং মিউট কৰি থোৱাৰ বাবে উপলব্ধ নহয়"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s। আনমিউট কৰিবৰ বাবে টিপক।"</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s। কম্পনৰ বাবে টিপক। দিব্য়াংগসকলৰ বাবে থকা সেৱা মিউট হৈ থাকিব পাৰে।"</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s। মিউট কৰিবলৈ টিপক। দিব্য়াংগসকলৰ বাবে থকা সেৱা মিউট হৈ থাকিব পাৰে।"</string>
diff --git a/packages/SystemUI/res/values-as/tiles_states_strings.xml b/packages/SystemUI/res/values-as/tiles_states_strings.xml
index a9c3e3b997b7..f4268ed17ff5 100644
--- a/packages/SystemUI/res/values-as/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-as/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"অফ আছে"</item>
<item msgid="578444932039713369">"অন কৰা আছে"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"উপলব্ধ নহয়"</item>
<item msgid="8707481475312432575">"অফ আছে"</item>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 8857ddb72b47..639cbbc4cef1 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Zəng"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrasiya"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Susdurun"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Yayım"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Zəng səssiz edildiyi üçün əlçatan deyil"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Səsli etmək üçün tıklayın."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Vibrasiyanı ayarlamaq üçün tıklayın. Əlçatımlılıq xidmətləri səssiz edilmiş ola bilər."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Səssiz etmək üçün tıklayın. Əlçatımlılıq xidmətləri səssiz edilmiş ola bilər."</string>
diff --git a/packages/SystemUI/res/values-az/tiles_states_strings.xml b/packages/SystemUI/res/values-az/tiles_states_strings.xml
index d973e4ead3c2..eeb81ccf42e1 100644
--- a/packages/SystemUI/res/values-az/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-az/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Deaktiv"</item>
<item msgid="578444932039713369">"Aktiv"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Əlçatan deyil"</item>
<item msgid="8707481475312432575">"Deaktiv"</item>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 677f169f8bc4..e97dbec9a690 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Aktiviraj zvono"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibriraj"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Isključi zvuk"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Prebacivanje"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Nedostupno jer je zvuk isključen"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Dodirnite da biste uključili zvuk."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Dodirnite da biste podesili na vibraciju. Zvuk usluga pristupačnosti će možda biti isključen."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Dodirnite da biste isključili zvuk. Zvuk usluga pristupačnosti će možda biti isključen."</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
index 32051ef19743..217d99975d3f 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Isključeno"</item>
<item msgid="578444932039713369">"Uključeno"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Nedostupno"</item>
<item msgid="8707481475312432575">"Isključeno"</item>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 7feb1607be22..3b06d05e76f5 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Званок"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Вібрацыя"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Гук выключаны"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Трансляцыя"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Недаступна, бо выключаны гук выклікаў"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Дакраніцеся, каб уключыць гук."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Дакраніцеся, каб уключыць вібрацыю. Можа быць адключаны гук службаў спецыяльных магчымасцей."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Дакраніцеся, каб адключыць гук. Можа быць адключаны гук службаў спецыяльных магчымасцей."</string>
diff --git a/packages/SystemUI/res/values-be/tiles_states_strings.xml b/packages/SystemUI/res/values-be/tiles_states_strings.xml
index e71c29bd15de..717e4c9a9c39 100644
--- a/packages/SystemUI/res/values-be/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-be/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Выключана"</item>
<item msgid="578444932039713369">"Уключана"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Недаступна"</item>
<item msgid="8707481475312432575">"Выключана"</item>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index d684d650af94..643ef9cecbf1 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Позвъняване"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Вибриране"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Без звук"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Предаване"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Не е налице, защото звъненето е спряно"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Докоснете, за да включите отново звука."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Докоснете, за да зададете вибриране. Възможно е звукът на услугите за достъпност да бъде заглушен."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Докоснете, за да заглушите звука. Възможно е звукът на услугите за достъпност да бъде заглушен."</string>
diff --git a/packages/SystemUI/res/values-bg/tiles_states_strings.xml b/packages/SystemUI/res/values-bg/tiles_states_strings.xml
index 24b41d23e900..58fa82bbc77a 100644
--- a/packages/SystemUI/res/values-bg/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bg/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Изкл."</item>
<item msgid="578444932039713369">"Вкл."</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Не е налице"</item>
<item msgid="8707481475312432575">"Изкл."</item>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index db52b2ea1621..9a2f040c7e7e 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"রিং"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"ভাইব্রেট"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"মিউট"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"কাস্ট করুন"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"রিং মিউট করা হয়েছে বলে উপলভ্য নেই"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s। সশব্দ করতে আলতো চাপুন।"</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s। কম্পন এ সেট করতে আলতো চাপুন। অ্যাক্সেসযোগ্যতার পরিষেবাগুলিকে মিউট করা হতে পারে।"</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s। মিউট করতে আলতো চাপুন। অ্যাক্সেসযোগ্যতার পরিষেবাগুলিকে মিউট করা হতে পারে।"</string>
diff --git a/packages/SystemUI/res/values-bn/tiles_states_strings.xml b/packages/SystemUI/res/values-bn/tiles_states_strings.xml
index 59061c223580..5c3c66c29461 100644
--- a/packages/SystemUI/res/values-bn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bn/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"বন্ধ আছে"</item>
<item msgid="578444932039713369">"চালু আছে"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"উপলভ্য নেই"</item>
<item msgid="8707481475312432575">"বন্ধ আছে"</item>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 3d54f6cfb747..db102a0ed68b 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Zvono"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibriranje"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Isključi zvuk"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Emitiraj"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Nedostupno zbog isključenog zvona"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Dodirnite da uključite zvukove."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Dodirnite za postavljanje vibracije. Zvukovi usluga pristupačnosti mogu biti isključeni."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Dodirnite da isključite zvuk. Zvukovi usluga pristupačnosti mogu biti isključeni."</string>
diff --git a/packages/SystemUI/res/values-bs/tiles_states_strings.xml b/packages/SystemUI/res/values-bs/tiles_states_strings.xml
index 32051ef19743..217d99975d3f 100644
--- a/packages/SystemUI/res/values-bs/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bs/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Isključeno"</item>
<item msgid="578444932039713369">"Uključeno"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Nedostupno"</item>
<item msgid="8707481475312432575">"Isključeno"</item>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index bcc451b60e16..c5287344c7c0 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Fes sonar"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibra"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Silencia"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Emet"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"No disponible perquè el so està silenciat"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Toca per activar el so."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Toca per activar la vibració. Pot ser que els serveis d\'accessibilitat se silenciïn."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Toca per silenciar el so. Pot ser que els serveis d\'accessibilitat se silenciïn."</string>
diff --git a/packages/SystemUI/res/values-ca/tiles_states_strings.xml b/packages/SystemUI/res/values-ca/tiles_states_strings.xml
index e99926c57324..c1ac5a356f05 100644
--- a/packages/SystemUI/res/values-ca/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ca/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Desactivat"</item>
<item msgid="578444932039713369">"Activat"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"No disponible"</item>
<item msgid="8707481475312432575">"Desactivat"</item>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index bf7566a803ee..f29dabb388d8 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Vyzvánění"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrace"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Ztlumení"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Odesílání"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Nedostupné, protože vyzvánění je ztlumené"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Klepnutím zapnete zvuk."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Klepnutím aktivujete režim vibrací. Služby přístupnosti mohou být ztlumeny."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Klepnutím vypnete zvuk. Služby přístupnosti mohou být ztlumeny."</string>
diff --git a/packages/SystemUI/res/values-cs/tiles_states_strings.xml b/packages/SystemUI/res/values-cs/tiles_states_strings.xml
index 6359f94112bb..0a4d4d0cfeef 100644
--- a/packages/SystemUI/res/values-cs/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-cs/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Vypnuto"</item>
<item msgid="578444932039713369">"Zapnuto"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Nedostupné"</item>
<item msgid="8707481475312432575">"Vypnuto"</item>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 60cf76a2d5e7..ec899f2f2c20 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Ring"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibration"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Slå lyden fra"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Cast"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Ikke muligt, da ringetonen er slået fra"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Tryk for at slå lyden til."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tryk for at konfigurere til at vibrere. Tilgængelighedstjenester kan blive deaktiveret."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tryk for at slå lyden fra. Lyden i tilgængelighedstjenester kan blive slået fra."</string>
diff --git a/packages/SystemUI/res/values-da/tiles_states_strings.xml b/packages/SystemUI/res/values-da/tiles_states_strings.xml
index 1daed4cd6864..2391753f8c0b 100644
--- a/packages/SystemUI/res/values-da/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-da/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Fra"</item>
<item msgid="578444932039713369">"Til"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Ikke tilgængelig"</item>
<item msgid="8707481475312432575">"Fra"</item>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 60165d24a260..f7e74c906960 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Klingeln lassen"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrieren"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Stummschalten"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Stream"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Nicht verfügbar, da Klingelton stumm"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Zum Aufheben der Stummschaltung tippen."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tippen, um Vibrieren festzulegen. Bedienungshilfen werden unter Umständen stummgeschaltet."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Zum Stummschalten tippen. Bedienungshilfen werden unter Umständen stummgeschaltet."</string>
diff --git a/packages/SystemUI/res/values-de/tiles_states_strings.xml b/packages/SystemUI/res/values-de/tiles_states_strings.xml
index 9a087472bd03..3aae04bbc931 100644
--- a/packages/SystemUI/res/values-de/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-de/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Aus"</item>
<item msgid="578444932039713369">"An"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Nicht verfügbar"</item>
<item msgid="8707481475312432575">"Aus"</item>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 6c45adfbda4b..6b341fdf1d93 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Κουδούνισμα"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Δόνηση"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Σίγαση"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Μετάδοση"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Μη διαθέσιμο λόγω σίγασης ήχου κλήσης"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Πατήστε για κατάργηση σίγασης."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Πατήστε για ενεργοποιήσετε τη δόνηση. Οι υπηρεσίες προσβασιμότητας ενδέχεται να τεθούν σε σίγαση."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Πατήστε για σίγαση. Οι υπηρεσίες προσβασιμότητας ενδέχεται να τεθούν σε σίγαση."</string>
diff --git a/packages/SystemUI/res/values-el/tiles_states_strings.xml b/packages/SystemUI/res/values-el/tiles_states_strings.xml
index 4d94515ac130..035f1171d3b4 100644
--- a/packages/SystemUI/res/values-el/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-el/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Ανενεργό"</item>
<item msgid="578444932039713369">"Ενεργό"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Μη διαθέσιμο"</item>
<item msgid="8707481475312432575">"Ανενεργό"</item>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 3dbe2dc013f5..021f7db6c2b6 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -429,8 +429,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Add more widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customise widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customise widgets"</string>
- <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) -->
- <skip />
+ <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string>
<string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string>
<string name="button_to_remove_widget" msgid="3948204829181214098">"Remove"</string>
<string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Add widget"</string>
@@ -575,10 +574,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Ring"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrate"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Mute"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Cast"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Unavailable because ring is muted"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Tap to unmute."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tap to set to vibrate. Accessibility services may be muted."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tap to mute. Accessibility services may be muted."</string>
@@ -839,10 +836,8 @@
<string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string>
<string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string>
<string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string>
- <!-- no translation found for finder_active (7907846989716941952) -->
- <skip />
- <!-- no translation found for shutdown_progress (5464239146561542178) -->
- <skip />
+ <string name="finder_active" msgid="7907846989716941952">"You can locate this phone with Find My Device even when powered off"</string>
+ <string name="shutdown_progress" msgid="5464239146561542178">"Shutting down…"</string>
<string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"See care steps"</string>
<string name="high_temp_dialog_help_text" msgid="7380171287943345858">"See care steps"</string>
<string name="high_temp_alarm_title" msgid="8654754369605452169">"Unplug your device"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
index 0cf28684aa48..2576b6080638 100644
--- a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Off"</item>
<item msgid="578444932039713369">"On"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Unavailable"</item>
<item msgid="8707481475312432575">"Off"</item>
diff --git a/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
index 0cf28684aa48..2576b6080638 100644
--- a/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Off"</item>
<item msgid="578444932039713369">"On"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Unavailable"</item>
<item msgid="8707481475312432575">"Off"</item>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 3dbe2dc013f5..021f7db6c2b6 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -429,8 +429,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Add more widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customise widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customise widgets"</string>
- <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) -->
- <skip />
+ <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string>
<string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string>
<string name="button_to_remove_widget" msgid="3948204829181214098">"Remove"</string>
<string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Add widget"</string>
@@ -575,10 +574,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Ring"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrate"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Mute"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Cast"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Unavailable because ring is muted"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Tap to unmute."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tap to set to vibrate. Accessibility services may be muted."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tap to mute. Accessibility services may be muted."</string>
@@ -839,10 +836,8 @@
<string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string>
<string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string>
<string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string>
- <!-- no translation found for finder_active (7907846989716941952) -->
- <skip />
- <!-- no translation found for shutdown_progress (5464239146561542178) -->
- <skip />
+ <string name="finder_active" msgid="7907846989716941952">"You can locate this phone with Find My Device even when powered off"</string>
+ <string name="shutdown_progress" msgid="5464239146561542178">"Shutting down…"</string>
<string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"See care steps"</string>
<string name="high_temp_dialog_help_text" msgid="7380171287943345858">"See care steps"</string>
<string name="high_temp_alarm_title" msgid="8654754369605452169">"Unplug your device"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
index 0cf28684aa48..2576b6080638 100644
--- a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Off"</item>
<item msgid="578444932039713369">"On"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Unavailable"</item>
<item msgid="8707481475312432575">"Off"</item>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 3dbe2dc013f5..021f7db6c2b6 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -429,8 +429,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Add more widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customise widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customise widgets"</string>
- <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) -->
- <skip />
+ <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string>
<string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string>
<string name="button_to_remove_widget" msgid="3948204829181214098">"Remove"</string>
<string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Add widget"</string>
@@ -575,10 +574,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Ring"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrate"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Mute"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Cast"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Unavailable because ring is muted"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Tap to unmute."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tap to set to vibrate. Accessibility services may be muted."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tap to mute. Accessibility services may be muted."</string>
@@ -839,10 +836,8 @@
<string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string>
<string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string>
<string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string>
- <!-- no translation found for finder_active (7907846989716941952) -->
- <skip />
- <!-- no translation found for shutdown_progress (5464239146561542178) -->
- <skip />
+ <string name="finder_active" msgid="7907846989716941952">"You can locate this phone with Find My Device even when powered off"</string>
+ <string name="shutdown_progress" msgid="5464239146561542178">"Shutting down…"</string>
<string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"See care steps"</string>
<string name="high_temp_dialog_help_text" msgid="7380171287943345858">"See care steps"</string>
<string name="high_temp_alarm_title" msgid="8654754369605452169">"Unplug your device"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
index 0cf28684aa48..2576b6080638 100644
--- a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Off"</item>
<item msgid="578444932039713369">"On"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Unavailable"</item>
<item msgid="8707481475312432575">"Off"</item>
diff --git a/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml
index b9c8e5fcdd6a..42daf8a6b23d 100644
--- a/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‏‏‏‏‎‏‎‏‎‎‏‏‎‎‎‏‏‎‎‎‏‎‏‏‏‎‎‏‎‎‏‏‎‏‎‎‏‎‎‏‎‎‏‏‏‏‏‏‎‎‎‏‎Off‎‏‎‎‏‎"</item>
<item msgid="578444932039713369">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‎‏‏‏‎‎‎‎‏‏‎‎‏‎‎‏‏‎‎‏‏‏‎‏‏‎‎‎‎‏‎‏‏‎‏‎‎‎‏‎‎‎‏‎‎‏‎‏‏‎‎‏‎On‎‏‎‎‏‎"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‎‎‏‎‎‏‎‎‎‏‎‏‏‎‎‎‏‎‏‎‏‎‎‎‎‏‎‎‏‎‎‏‎‏‎‏‎‎‎‎‎‎‏‏‎Unavailable‎‏‎‎‏‎"</item>
<item msgid="8707481475312432575">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‏‏‎‎‏‏‎‎‎‎‎‏‎‎‎‏‎‎‏‎‎‎‎‎‎‎‎‏‎‎‏‎‏‎‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‏‎Off‎‏‎‎‏‎"</item>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 15de0d5bacaf..1798e9aa4b2d 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -429,8 +429,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Agregar más widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantén presionado para personalizar los widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string>
- <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) -->
- <skip />
+ <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ícono de la app de widget inhabilitado"</string>
<string name="edit_widget" msgid="9030848101135393954">"Modificar widget"</string>
<string name="button_to_remove_widget" msgid="3948204829181214098">"Quitar"</string>
<string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Agregar widget"</string>
@@ -575,10 +574,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Timbre"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrar"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Silenciar"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Transmisión"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"No disponible por timbre silenciado"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Presiona para dejar de silenciar."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Presiona para establecer el modo vibración. Es posible que los servicios de accesibilidad estén silenciados."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Presiona para silenciar. Es posible que los servicios de accesibilidad estén silenciados."</string>
@@ -839,10 +836,8 @@
<string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menú de encendido"</string>
<string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
<string name="tuner_lock_screen" msgid="2267383813241144544">"Pantalla de bloqueo"</string>
- <!-- no translation found for finder_active (7907846989716941952) -->
- <skip />
- <!-- no translation found for shutdown_progress (5464239146561542178) -->
- <skip />
+ <string name="finder_active" msgid="7907846989716941952">"Puedes ubicar este teléfono con Encontrar mi dispositivo, incluso si está apagado"</string>
+ <string name="shutdown_progress" msgid="5464239146561542178">"Apagando…"</string>
<string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Ver pasos de mantenimiento"</string>
<string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Ver pasos de mantenimiento"</string>
<string name="high_temp_alarm_title" msgid="8654754369605452169">"Desenchufa el dispositivo"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
index bb3983b0bb09..09abc543dbcf 100644
--- a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Desactivado"</item>
<item msgid="578444932039713369">"Activado"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"No disponible"</item>
<item msgid="8707481475312432575">"Desactivado"</item>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 3edc603034f1..73c913fe9a6d 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Hacer sonar"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrar"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Silenciar"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Enviar"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"No disponible (el tono está silenciado)"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Toca para activar el sonido."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Toca para poner el dispositivo en vibración. Los servicios de accesibilidad pueden silenciarse."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Toca para silenciar. Los servicios de accesibilidad pueden silenciarse."</string>
diff --git a/packages/SystemUI/res/values-es/tiles_states_strings.xml b/packages/SystemUI/res/values-es/tiles_states_strings.xml
index 66c7ee5efe6c..83b4627897da 100644
--- a/packages/SystemUI/res/values-es/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-es/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Desactivado"</item>
<item msgid="578444932039713369">"Activado"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"No disponible"</item>
<item msgid="8707481475312432575">"Desactivado"</item>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 7ae5219795a9..6fa704490367 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Helisemine"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibreerimine"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Vaigistatud"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Ülekandmine"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Pole saadaval, kuna helin on vaigistatud"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Puudutage vaigistuse tühistamiseks."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Puudutage värinarežiimi määramiseks. Juurdepääsetavuse teenused võidakse vaigistada."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Puudutage vaigistamiseks. Juurdepääsetavuse teenused võidakse vaigistada."</string>
diff --git a/packages/SystemUI/res/values-et/tiles_states_strings.xml b/packages/SystemUI/res/values-et/tiles_states_strings.xml
index 6a9edbbe812a..4f0551d7af74 100644
--- a/packages/SystemUI/res/values-et/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-et/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Väljas"</item>
<item msgid="578444932039713369">"Sees"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Pole saadaval"</item>
<item msgid="8707481475312432575">"Väljas"</item>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index d0b10a0db21d..564fbb395aeb 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Jo tonua"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Dardara"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Ez jo tonua"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Igorri"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Ez dago erabilgarri, tonua desaktibatuta dagoelako"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Sakatu audioa aktibatzeko."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Sakatu dardara ezartzeko. Baliteke erabilerraztasun-eginbideen audioa desaktibatzea."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Sakatu audioa desaktibatzeko. Baliteke erabilerraztasun-eginbideen audioa desaktibatzea."</string>
@@ -732,7 +730,7 @@
<string name="group_system_full_screenshot" msgid="5742204844232667785">"Atera pantaila-argazki bat"</string>
<string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Erakutsi lasterbideak"</string>
<string name="group_system_go_back" msgid="2730322046244918816">"Egin atzera"</string>
- <string name="group_system_access_home_screen" msgid="4130366993484706483">"Joan hasierako pantailara"</string>
+ <string name="group_system_access_home_screen" msgid="4130366993484706483">"Joan orri nagusira"</string>
<string name="group_system_overview_open_apps" msgid="5659958952937994104">"Ikusi azkenaldiko aplikazioak"</string>
<string name="group_system_cycle_forward" msgid="5478663965957647805">"Ikusi azken aplikazioak banan-banan (aurrerantz)"</string>
<string name="group_system_cycle_back" msgid="8194102916946802902">"Ikusi azken aplikazioak banan-banan (atzerantz)"</string>
@@ -1096,7 +1094,7 @@
<string name="build_number_copy_toast" msgid="877720921605503046">"Kopiatu da konpilazio-zenbakia arbelean."</string>
<string name="basic_status" msgid="2315371112182658176">"Elkarrizketa irekia"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Elkarrizketa-widgetak"</string>
- <string name="select_conversation_text" msgid="3376048251434956013">"Sakatu elkarrizketa bat hasierako pantailan gehitzeko"</string>
+ <string name="select_conversation_text" msgid="3376048251434956013">"Sakatu elkarrizketa bat orri nagusian gehitzeko"</string>
<string name="no_conversations_text" msgid="5354115541282395015">"Azken elkarrizketak agertuko dira hemen"</string>
<string name="priority_conversations" msgid="3967482288896653039">"Lehentasunezko elkarrizketak"</string>
<string name="recent_conversations" msgid="8531874684782574622">"Azken elkarrizketak"</string>
diff --git a/packages/SystemUI/res/values-eu/tiles_states_strings.xml b/packages/SystemUI/res/values-eu/tiles_states_strings.xml
index d023076ca2bf..accecacbe8dd 100644
--- a/packages/SystemUI/res/values-eu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-eu/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Desaktibatuta"</item>
<item msgid="578444932039713369">"Aktibatuta"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Ez dago erabilgarri"</item>
<item msgid="8707481475312432575">"Desaktibatuta"</item>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 0f937814e55d..95f17b0d1e56 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"زنگ زدن"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"لرزش"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"صامت"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"ارسال محتوا"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"دردسترس نیست، چون زنگ بی‌صدا شده است"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"‏%1$s. برای باصدا کردن ضربه بزنید."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"‏%1$s. برای تنظیم روی لرزش ضربه بزنید. ممکن است سرویس‌های دسترس‌پذیری بی‌صدا شوند."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"‏%1$s. برای صامت کردن ضربه بزنید. ممکن است سرویس‌های دسترس‌پذیری صامت شود."</string>
diff --git a/packages/SystemUI/res/values-fa/tiles_states_strings.xml b/packages/SystemUI/res/values-fa/tiles_states_strings.xml
index b341e9e64c7b..01a549ed70b3 100644
--- a/packages/SystemUI/res/values-fa/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fa/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"خاموش"</item>
<item msgid="578444932039713369">"روشن"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"دردسترس نیست"</item>
<item msgid="8707481475312432575">"خاموش"</item>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 5d3959d92b68..ab022dd80277 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Soittoääni"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Värinä"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Äänetön"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Striimaa"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Ei käytettävissä, soittoääni mykistetty"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Poista mykistys koskettamalla."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Siirry värinätilaan koskettamalla. Myös esteettömyyspalvelut saattavat mykistyä."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Mykistä koskettamalla. Myös esteettömyyspalvelut saattavat mykistyä."</string>
diff --git a/packages/SystemUI/res/values-fi/tiles_states_strings.xml b/packages/SystemUI/res/values-fi/tiles_states_strings.xml
index bbd64fdb87da..f7a8ec94f1bd 100644
--- a/packages/SystemUI/res/values-fi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fi/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Poissa päältä"</item>
<item msgid="578444932039713369">"Päällä"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Ei saatavilla"</item>
<item msgid="8707481475312432575">"Poissa päältä"</item>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index e02c75ceae3b..1186c81c1a10 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Sonnerie"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibration"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Sonnerie désactivée"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Diffuser"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Inaccessible : sonnerie en sourdine"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Touchez pour réactiver le son."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Touchez pour activer les vibrations. Il est possible de couper le son des services d\'accessibilité."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Touchez pour couper le son. Il est possible de couper le son des services d\'accessibilité."</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
index b96984173d37..7b9708ef03f4 100644
--- a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Désactivé"</item>
<item msgid="578444932039713369">"Activé"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Non disponible"</item>
<item msgid="8707481475312432575">"Désactivé"</item>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 2621a904fa33..a02c9f7f9e6f 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Sonnerie"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibreur"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Couper le son"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Caster"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Indisponible, car la sonnerie est coupée"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Appuyez pour ne plus ignorer."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Appuyez pour mettre en mode vibreur. Vous pouvez ignorer les services d\'accessibilité."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Appuyez pour ignorer. Vous pouvez ignorer les services d\'accessibilité."</string>
diff --git a/packages/SystemUI/res/values-fr/tiles_states_strings.xml b/packages/SystemUI/res/values-fr/tiles_states_strings.xml
index 34440a0d299b..af1d09d3db3d 100644
--- a/packages/SystemUI/res/values-fr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Désactivé"</item>
<item msgid="578444932039713369">"Activé"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Indisponible"</item>
<item msgid="8707481475312432575">"Désactivée"</item>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 1955c040990f..e758af880582 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Facer soar"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrar"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Silenciar"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Emitir"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Non dispoñible (o son está silenciado)"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Toca para activar o son."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Toca para establecer a vibración. Pódense silenciar os servizos de accesibilidade."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Toca para silenciar. Pódense silenciar os servizos de accesibilidade."</string>
diff --git a/packages/SystemUI/res/values-gl/tiles_states_strings.xml b/packages/SystemUI/res/values-gl/tiles_states_strings.xml
index b03f31171e5c..a963decd28e9 100644
--- a/packages/SystemUI/res/values-gl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-gl/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Non"</item>
<item msgid="578444932039713369">"Si"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Non dispoñible"</item>
<item msgid="8707481475312432575">"Non"</item>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 5a1cf421da54..6d1d8df1bc27 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"રિંગ કરો"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"વાઇબ્રેટ"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"મ્યૂટ કરો"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"કાસ્ટ કરો"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"રિંગ મ્યૂટ કરી હોવાના કારણે અનુપલબ્ધ છે"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. અનમ્યૂટ કરવા માટે ટૅપ કરો."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. વાઇબ્રેટ પર સેટ કરવા માટે ટૅપ કરો. ઍક્સેસિબિલિટી સેવાઓ મ્યૂટ કરવામાં આવી શકે છે."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. મ્યૂટ કરવા માટે ટૅપ કરો. ઍક્સેસિબિલિટી સેવાઓ મ્યૂટ કરવામાં આવી શકે છે."</string>
diff --git a/packages/SystemUI/res/values-gu/tiles_states_strings.xml b/packages/SystemUI/res/values-gu/tiles_states_strings.xml
index 5d1ad6ff0514..580ec104dfb4 100644
--- a/packages/SystemUI/res/values-gu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-gu/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"બંધ છે"</item>
<item msgid="578444932039713369">"ચાલુ છે"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"ઉપલબ્ધ નથી"</item>
<item msgid="8707481475312432575">"બંધ છે"</item>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 4b8c959064af..2035429a00b9 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"आवाज़ चालू है"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"वाइब्रेशन"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"आवाज़ बंद है"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"कास्ट करें"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"रिंग म्यूट होने से आवाज़ नहीं सुनाई दी"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. अनम्यूट करने के लिए टैप करें."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. कंपन पर सेट करने के लिए टैप करें. सुलभता सेवाएं म्यूट हो सकती हैं."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. म्यूट करने के लिए टैप करें. सुलभता सेवाएं म्यूट हो सकती हैं."</string>
diff --git a/packages/SystemUI/res/values-hi/tiles_states_strings.xml b/packages/SystemUI/res/values-hi/tiles_states_strings.xml
index cd29fb92063f..3fd0b30ea4a0 100644
--- a/packages/SystemUI/res/values-hi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hi/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"बंद है"</item>
<item msgid="578444932039713369">"चालू है"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"उपलब्ध नहीं है"</item>
<item msgid="8707481475312432575">"बंद है"</item>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 45666c07aa21..d50a95121148 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Zvonjenje"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibriranje"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Zvuk je isključen"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Emitiraj"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Nedostupno jer je zvono utišano"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Dodirnite da biste uključili zvuk."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Dodirnite da biste postavili na vibraciju. Usluge pristupačnosti možda neće imati zvuk."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Dodirnite da biste isključili zvuk. Usluge pristupačnosti možda neće imati zvuk."</string>
diff --git a/packages/SystemUI/res/values-hr/tiles_states_strings.xml b/packages/SystemUI/res/values-hr/tiles_states_strings.xml
index 32051ef19743..217d99975d3f 100644
--- a/packages/SystemUI/res/values-hr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hr/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Isključeno"</item>
<item msgid="578444932039713369">"Uključeno"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Nedostupno"</item>
<item msgid="8707481475312432575">"Isključeno"</item>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 3606d7486737..b09419bd396d 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Csörgés"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Rezgés"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Néma"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Átküldés"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Nem lehetséges, a csörgés le van némítva"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Koppintson a némítás megszüntetéséhez."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Koppintson a rezgés beállításához. Előfordulhat, hogy a kisegítő lehetőségek szolgáltatásai le vannak némítva."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Koppintson a némításhoz. Előfordulhat, hogy a kisegítő lehetőségek szolgáltatásai le vannak némítva."</string>
diff --git a/packages/SystemUI/res/values-hu/tiles_states_strings.xml b/packages/SystemUI/res/values-hu/tiles_states_strings.xml
index 157c552b31a6..fad2cd4e6d4b 100644
--- a/packages/SystemUI/res/values-hu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hu/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Ki"</item>
<item msgid="578444932039713369">"Be"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Nem áll rendelkezésre"</item>
<item msgid="8707481475312432575">"Ki"</item>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 1510291e00f2..4ea86d0571bb 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Սովորական"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Թրթռոց"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Անձայն"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Հեռարձակում"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Հասանելի չէ, երբ զանգի ձայնն անջատված է"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s: Հպեք՝ ձայնը միացնելու համար:"</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s: Հպեք՝ թրթռումը միացնելու համար: Մատչելիության ծառայությունների ձայնը կարող է անջատվել:"</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s: Հպեք՝ ձայնն անջատելու համար: Մատչելիության ծառայությունների ձայնը կարող է անջատվել:"</string>
diff --git a/packages/SystemUI/res/values-hy/tiles_states_strings.xml b/packages/SystemUI/res/values-hy/tiles_states_strings.xml
index 089716fa51d6..380d9d2d9a95 100644
--- a/packages/SystemUI/res/values-hy/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hy/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Անջատված է"</item>
<item msgid="578444932039713369">"Միացված է"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Հասանելի չէ"</item>
<item msgid="8707481475312432575">"Անջատված է"</item>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 09a9938b5abb..188f3fbcd14d 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Dering"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Getar"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Nonaktifkan"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Transmisi"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Tidak tersedia karena volume dering dibisukan"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Ketuk untuk menyuarakan."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Ketuk untuk menyetel agar bergetar. Layanan aksesibilitas mungkin dibisukan."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Ketuk untuk membisukan. Layanan aksesibilitas mungkin dibisukan."</string>
diff --git a/packages/SystemUI/res/values-in/tiles_states_strings.xml b/packages/SystemUI/res/values-in/tiles_states_strings.xml
index 71460a71b414..9be5d0276a24 100644
--- a/packages/SystemUI/res/values-in/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-in/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Nonaktif"</item>
<item msgid="578444932039713369">"Aktif"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Tidak tersedia"</item>
<item msgid="8707481475312432575">"Nonaktif"</item>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index bbc8eab4f9da..47756c213877 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Hringing"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Titringur"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Hljóð af"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Senda út"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Ekki í boði þar sem hringing er þögguð"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Ýttu til að hætta að þagga."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Ýttu til að stilla á titring. Hugsanlega verður slökkt á hljóði aðgengisþjónustu."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Ýttu til að þagga. Hugsanlega verður slökkt á hljóði aðgengisþjónustu."</string>
diff --git a/packages/SystemUI/res/values-is/tiles_states_strings.xml b/packages/SystemUI/res/values-is/tiles_states_strings.xml
index 17aaf6c2a877..1ee6e471fad3 100644
--- a/packages/SystemUI/res/values-is/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-is/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Slökkt"</item>
<item msgid="578444932039713369">"Kveikt"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Ekki í boði"</item>
<item msgid="8707481475312432575">"Slökkt"</item>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 7c09c597f2a5..5bad44c836a7 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Attiva suoneria"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Attiva vibrazione"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Silenzia"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Trasmissione"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Non disponibile con l\'audio disattivato"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Tocca per riattivare l\'audio."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tocca per attivare la vibrazione. L\'audio dei servizi di accessibilità può essere disattivato."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tocca per disattivare l\'audio. L\'audio dei servizi di accessibilità può essere disattivato."</string>
diff --git a/packages/SystemUI/res/values-it/tiles_states_strings.xml b/packages/SystemUI/res/values-it/tiles_states_strings.xml
index 7aa09d420f87..28e28aed82b8 100644
--- a/packages/SystemUI/res/values-it/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-it/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Off"</item>
<item msgid="578444932039713369">"On"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Non disponibile"</item>
<item msgid="8707481475312432575">"Off"</item>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 644b599268ec..154de1523bbb 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"צלצול"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"רטט"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"השתקה"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"‏הפעלת Cast"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"לא זמין כי הצלצול מושתק"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"‏%1$s. יש להקיש כדי לבטל את ההשתקה."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"‏%1$s. צריך להקיש כדי להגדיר רטט. ייתכן ששירותי הנגישות מושתקים."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"‏%1$s. יש להקיש כדי להשתיק. ייתכן ששירותי הנגישות יושתקו."</string>
diff --git a/packages/SystemUI/res/values-iw/tiles_states_strings.xml b/packages/SystemUI/res/values-iw/tiles_states_strings.xml
index bd2a6f7d0d2b..bb3eb10fd719 100644
--- a/packages/SystemUI/res/values-iw/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-iw/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"כבוי"</item>
<item msgid="578444932039713369">"פועל"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"לא זמין"</item>
<item msgid="8707481475312432575">"כבוי"</item>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 3e0d24586686..227edd3570d0 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -429,8 +429,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ウィジェットの追加"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"長押ししてウィジェットをカスタマイズ"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ウィジェットのカスタマイズ"</string>
- <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) -->
- <skip />
+ <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"無効なウィジェットのアプリアイコン"</string>
<string name="edit_widget" msgid="9030848101135393954">"ウィジェットを編集"</string>
<string name="button_to_remove_widget" msgid="3948204829181214098">"削除"</string>
<string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ウィジェットを追加"</string>
@@ -575,10 +574,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"着信音"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"バイブレーション"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"ミュート"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"キャスト"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"着信音がミュートされているため利用できません"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s。タップしてミュートを解除します。"</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s。タップしてバイブレーションに設定します。ユーザー補助機能サービスがミュートされる場合があります。"</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s。タップしてミュートします。ユーザー補助機能サービスがミュートされる場合があります。"</string>
@@ -839,10 +836,8 @@
<string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"電源ボタン メニュー"</string>
<string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ページ <xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g>"</string>
<string name="tuner_lock_screen" msgid="2267383813241144544">"ロック画面"</string>
- <!-- no translation found for finder_active (7907846989716941952) -->
- <skip />
- <!-- no translation found for shutdown_progress (5464239146561542178) -->
- <skip />
+ <string name="finder_active" msgid="7907846989716941952">"「デバイスを探す」を使うと、電源が OFF の状態でもこのスマートフォンの現在地を確認できます"</string>
+ <string name="shutdown_progress" msgid="5464239146561542178">"シャットダウン中…"</string>
<string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"取り扱いに関する手順をご覧ください"</string>
<string name="high_temp_dialog_help_text" msgid="7380171287943345858">"取り扱いに関する手順をご覧ください"</string>
<string name="high_temp_alarm_title" msgid="8654754369605452169">"デバイスを電源から外します"</string>
diff --git a/packages/SystemUI/res/values-ja/tiles_states_strings.xml b/packages/SystemUI/res/values-ja/tiles_states_strings.xml
index 31158ca59882..ebadf3b385ce 100644
--- a/packages/SystemUI/res/values-ja/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ja/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"OFF"</item>
<item msgid="578444932039713369">"ON"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"使用不可"</item>
<item msgid="8707481475312432575">"OFF"</item>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 973af6fa5361..70eeb334556d 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"დარეკვა"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"ვიბრაცია"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"დადუმება"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"ტრანსლირება"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"ზარის დადუმების გამო ხელმისაწვდომი არაა"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. შეეხეთ დადუმების გასაუქმებლად."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. შეეხეთ ვიბრაციაზე დასაყენებლად. შეიძლება დადუმდეს მარტივი წვდომის სერვისებიც."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. შეეხეთ დასადუმებლად. შეიძლება დადუმდეს მარტივი წვდომის სერვისებიც."</string>
diff --git a/packages/SystemUI/res/values-ka/tiles_states_strings.xml b/packages/SystemUI/res/values-ka/tiles_states_strings.xml
index 366030a2231f..07a8a76b8c97 100644
--- a/packages/SystemUI/res/values-ka/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ka/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"გამორთულია"</item>
<item msgid="578444932039713369">"ჩართულია"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"მიუწვდომელია"</item>
<item msgid="8707481475312432575">"გამორთულია"</item>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index d5ae0ac6419f..c2525d9aec8f 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Шылдырлау"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Діріл"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Дыбысын өшіру"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Трансляциялау"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Қолжетімді емес, шылдырлату өшірулі."</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Дыбысын қосу үшін түртіңіз."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Діріл режимін орнату үшін түртіңіз. Арнайы мүмкіндік қызметтерінің дыбысы өшуі мүмкін."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Дыбысын өшіру үшін түртіңіз. Арнайы мүмкіндік қызметтерінің дыбысы өшуі мүмкін."</string>
diff --git a/packages/SystemUI/res/values-kk/tiles_states_strings.xml b/packages/SystemUI/res/values-kk/tiles_states_strings.xml
index b8089e44a5ce..f5b094855618 100644
--- a/packages/SystemUI/res/values-kk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-kk/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Өшірулі"</item>
<item msgid="578444932039713369">"Қосулы"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Қолжетімсіз"</item>
<item msgid="8707481475312432575">"Өшірулі"</item>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 11a284d2d9f4..0d2503359790 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"រោទ៍"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"ញ័រ"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"បិទសំឡេង"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"បញ្ជូន"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"មិន​អាច​ប្រើ​បាន​ទេ​ ព្រោះ​សំឡេង​រោទ៍​ត្រូវ​បាន​បិទ"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s។ ប៉ះដើម្បីបើកសំឡេង។"</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s។ ប៉ះដើម្បីកំណត់ឲ្យញ័រ។ សេវាកម្មលទ្ធភាពប្រើប្រាស់អាចនឹងត្រូវបានបិទសំឡេង។"</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s។ ប៉ះដើម្បីបិទសំឡេង។ សេវាកម្មលទ្ធភាពប្រើប្រាស់អាចនឹងត្រូវបានបិទសំឡេង។"</string>
diff --git a/packages/SystemUI/res/values-km/tiles_states_strings.xml b/packages/SystemUI/res/values-km/tiles_states_strings.xml
index 8c5c8d1ce088..a2031b070a0c 100644
--- a/packages/SystemUI/res/values-km/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-km/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"បិទ"</item>
<item msgid="578444932039713369">"បើក"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"មិនមានទេ"</item>
<item msgid="8707481475312432575">"បិទ"</item>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index a311a8621af3..66b8e72ee2cf 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"ರಿಂಗ್"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"ವೈಬ್ರೇಟ್‌"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"ಮ್ಯೂಟ್"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"ಬಿತ್ತರಿಸಿ"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"ರಿಂಗ್ ಮ್ಯೂಟ್ ಆಗಿರುವ ಕಾರಣ ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. ಅನ್‌ಮ್ಯೂಟ್‌ ಮಾಡುವುದಕ್ಕಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. ಕಂಪನಕ್ಕೆ ಹೊಂದಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ. ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಸೇವೆಗಳನ್ನು ಮ್ಯೂಟ್‌ ಮಾಡಬಹುದು."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. ಮ್ಯೂಟ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ. ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಸೇವೆಗಳನ್ನು ಮ್ಯೂಟ್‌ ಮಾಡಬಹುದು."</string>
diff --git a/packages/SystemUI/res/values-kn/tiles_states_strings.xml b/packages/SystemUI/res/values-kn/tiles_states_strings.xml
index 250eb5adc8de..de0fcae601cd 100644
--- a/packages/SystemUI/res/values-kn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-kn/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"ಆಫ್"</item>
<item msgid="578444932039713369">"ಆನ್"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"ಲಭ್ಯವಿಲ್ಲ"</item>
<item msgid="8707481475312432575">"ಆಫ್"</item>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 1fe5f90fd78f..028c8cf06eb9 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"벨소리"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"진동"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"음소거"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"전송"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"벨소리가 음소거되어 있으므로 사용할 수 없음"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. 탭하여 음소거를 해제하세요."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. 탭하여 진동으로 설정하세요. 접근성 서비스가 음소거될 수 있습니다."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. 탭하여 음소거로 설정하세요. 접근성 서비스가 음소거될 수 있습니다."</string>
diff --git a/packages/SystemUI/res/values-ko/tiles_states_strings.xml b/packages/SystemUI/res/values-ko/tiles_states_strings.xml
index 7981d285946c..c9b2846ad9e1 100644
--- a/packages/SystemUI/res/values-ko/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ko/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"꺼짐"</item>
<item msgid="578444932039713369">"켜짐"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"이용 불가"</item>
<item msgid="8707481475312432575">"꺼짐"</item>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 789f7d806548..0f0055561759 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Шыңгыратуу"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Дирилдөө"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Үнсүз"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Тышкы экранга чыгруу"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Үнсүз режимде жеткиликсиз"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Үнүн чыгаруу үчүн таптап коюңуз."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Дирилдөөгө коюу үчүн таптап коюңуз. Атайын мүмкүнчүлүктөр кызматынын үнүн өчүрүп койсо болот."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Үнүн өчүрүү үчүн таптап коюңуз. Атайын мүмкүнчүлүктөр кызматынын үнүн өчүрүп койсо болот."</string>
diff --git a/packages/SystemUI/res/values-ky/tiles_states_strings.xml b/packages/SystemUI/res/values-ky/tiles_states_strings.xml
index 0f277f9de292..bc47e5aea38f 100644
--- a/packages/SystemUI/res/values-ky/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ky/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Өчүк"</item>
<item msgid="578444932039713369">"Күйүк"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Жеткиликсиз"</item>
<item msgid="8707481475312432575">"Өчүк"</item>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 1ca3b2fee9bc..db976555009d 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -429,8 +429,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ເພີ່ມວິດເຈັດເພີ່ມເຕີມ"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ກົດຄ້າງໄວ້ເພື່ອປັບແຕ່ງວິດເຈັດ"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ປັບແຕ່ງວິດເຈັດ"</string>
- <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) -->
- <skip />
+ <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ໄອຄອນແອັບສຳລັບວິດເຈັດທີ່ຖືກປິດການນຳໃຊ້"</string>
<string name="edit_widget" msgid="9030848101135393954">"ແກ້ໄຂວິດເຈັດ"</string>
<string name="button_to_remove_widget" msgid="3948204829181214098">"ລຶບອອກ"</string>
<string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ເພີ່ມວິດເຈັດ"</string>
@@ -837,10 +836,8 @@
<string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ເມນູເປີດປິດ"</string>
<string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g> ຈາກທັງໝົດ <xliff:g id="ID_2">%2$d</xliff:g>"</string>
<string name="tuner_lock_screen" msgid="2267383813241144544">"ໜ້າຈໍລັອກ"</string>
- <!-- no translation found for finder_active (7907846989716941952) -->
- <skip />
- <!-- no translation found for shutdown_progress (5464239146561542178) -->
- <skip />
+ <string name="finder_active" msgid="7907846989716941952">"ທ່ານສາມາດຊອກຫາສະຖານທີ່ຂອງໂທລະສັບເຄື່ອງນີ້ໄດ້ດ້ວຍແອັບຊອກຫາອຸປະກອນຂອງຂ້ອຍເຖິງແມ່ນວ່າຈະປິດເຄື່ອງຢູ່ກໍຕາມ"</string>
+ <string name="shutdown_progress" msgid="5464239146561542178">"ກຳລັງປິດເຄື່ອງ…"</string>
<string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"ເບິ່ງຂັ້ນຕອນການເບິ່ງແຍງ"</string>
<string name="high_temp_dialog_help_text" msgid="7380171287943345858">"ເບິ່ງຂັ້ນຕອນການເບິ່ງແຍງ"</string>
<string name="high_temp_alarm_title" msgid="8654754369605452169">"ຖອດອຸປະກອນຂອງທ່ານອອກ"</string>
diff --git a/packages/SystemUI/res/values-lo/tiles_states_strings.xml b/packages/SystemUI/res/values-lo/tiles_states_strings.xml
index d54cf4d24181..75958972cdce 100644
--- a/packages/SystemUI/res/values-lo/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lo/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"ປິດ"</item>
<item msgid="578444932039713369">"ເປີດ"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
<item msgid="8707481475312432575">"ປິດ"</item>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index eac5ee48ead1..9eaab8f6a6f0 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Skambinti"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibruoti"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Nutildyti"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Perdavimas"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Nepasiekiama, nes skambutis nutildytas"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Palieskite, kad įjungtumėte garsą."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Palieskite, kad nustatytumėte vibravimą. Gali būti nutildytos pritaikymo neįgaliesiems paslaugos."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Palieskite, kad nutildytumėte. Gali būti nutildytos pritaikymo neįgaliesiems paslaugos."</string>
diff --git a/packages/SystemUI/res/values-lt/tiles_states_strings.xml b/packages/SystemUI/res/values-lt/tiles_states_strings.xml
index e66f590364dd..94343bac9ff8 100644
--- a/packages/SystemUI/res/values-lt/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lt/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Išjungta"</item>
<item msgid="578444932039713369">"Įjungta"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Nepasiekiama"</item>
<item msgid="8707481475312432575">"Išjungta"</item>
diff --git a/packages/SystemUI/res/values-lv/tiles_states_strings.xml b/packages/SystemUI/res/values-lv/tiles_states_strings.xml
index d32efec81a99..d8b24676ea27 100644
--- a/packages/SystemUI/res/values-lv/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lv/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Izslēgta"</item>
<item msgid="578444932039713369">"Ieslēgta"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Nav pieejama"</item>
<item msgid="8707481475312432575">"Izslēgta"</item>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index b244fe9343bb..6ea4d1f1d9ab 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Ѕвони"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Вибрации"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Исклучи звук"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Емитување"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Недостапно бидејќи ѕвонењето е исклучено"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Допрете за да вклучите звук."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Допрете за да поставите на вибрации. Можеби ќе се исклучи звукот на услугите за достапност."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Допрете за да исклучите звук. Можеби ќе се исклучи звукот на услугите за достапност."</string>
diff --git a/packages/SystemUI/res/values-mk/tiles_states_strings.xml b/packages/SystemUI/res/values-mk/tiles_states_strings.xml
index 0a42d7cbe2df..8b0faf7d966e 100644
--- a/packages/SystemUI/res/values-mk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mk/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Исклучено"</item>
<item msgid="578444932039713369">"Вклучено"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Недостапно"</item>
<item msgid="8707481475312432575">"Исклучено"</item>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 8678b663a089..82d257a473b2 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -429,8 +429,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"കൂടുതൽ വിജറ്റുകൾ ചേർക്കുക"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"വിജറ്റുകൾ ഇഷ്ടാനുസൃതമാക്കാൻ ദീർഘനേരം അമർത്തുക"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"വിജറ്റുകൾ ഇഷ്ടാനുസൃതമാക്കുക"</string>
- <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) -->
- <skip />
+ <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"പ്രവർത്തനരഹിതമാക്കിയ വിജറ്റിനുള്ള ആപ്പ് ഐക്കൺ"</string>
<string name="edit_widget" msgid="9030848101135393954">"വിജറ്റ് എഡിറ്റ് ചെയ്യുക"</string>
<string name="button_to_remove_widget" msgid="3948204829181214098">"നീക്കം ചെയ്യുക"</string>
<string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"വിജറ്റ് ചേർക്കുക"</string>
@@ -837,10 +836,8 @@
<string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"പവർ മെനു"</string>
<string name="accessibility_quick_settings_page" msgid="7506322631645550961">"പേജ് <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
<string name="tuner_lock_screen" msgid="2267383813241144544">"ലോക്ക് സ്‌ക്രീൻ"</string>
- <!-- no translation found for finder_active (7907846989716941952) -->
- <skip />
- <!-- no translation found for shutdown_progress (5464239146561542178) -->
- <skip />
+ <string name="finder_active" msgid="7907846989716941952">"ഓഫായിരിക്കുമ്പോഴും Find My Device ഉപയോഗിച്ച് നിങ്ങൾക്ക് ഈ ഫോൺ കണ്ടെത്താനാകും"</string>
+ <string name="shutdown_progress" msgid="5464239146561542178">"ഷട്ട്‌ഡൗൺ ചെയ്യുന്നു…"</string>
<string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"പരിപാലന നിർദ്ദേശങ്ങൾ കാണുക"</string>
<string name="high_temp_dialog_help_text" msgid="7380171287943345858">"പരിപാലന നിർദ്ദേശങ്ങൾ കാണുക"</string>
<string name="high_temp_alarm_title" msgid="8654754369605452169">"ഉപകരണം അൺപ്ലഗ് ചെയ്യുക"</string>
diff --git a/packages/SystemUI/res/values-ml/tiles_states_strings.xml b/packages/SystemUI/res/values-ml/tiles_states_strings.xml
index 62bac5cd1212..529d0def3e27 100644
--- a/packages/SystemUI/res/values-ml/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ml/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"ഓഫാണ്"</item>
<item msgid="578444932039713369">"ഓണാണ്"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"ലഭ്യമല്ല"</item>
<item msgid="8707481475312432575">"ഓഫാണ്"</item>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 8aafee3341de..aad6a13c43d7 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Хонх дуугаргах"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Чичиргэх"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Хаах"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Дамжуулах"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Хонхны дууг хаасан тул боломжгүй"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Дууг нь нээхийн тулд товшино уу."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Чичиргээнд тохируулахын тулд товшино уу. Хүртээмжийн үйлчилгээний дууг хаасан."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Дууг нь хаахын тулд товшино уу. Хүртээмжийн үйлчилгээний дууг хаасан."</string>
diff --git a/packages/SystemUI/res/values-mn/tiles_states_strings.xml b/packages/SystemUI/res/values-mn/tiles_states_strings.xml
index 33f359672477..0db122904755 100644
--- a/packages/SystemUI/res/values-mn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mn/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Унтраалттай"</item>
<item msgid="578444932039713369">"Асаалттай"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Боломжгүй"</item>
<item msgid="8707481475312432575">"Унтраалттай"</item>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index e781b45803ef..d7acf5f5fea2 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"रिंग करा"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"व्हायब्रेट"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"म्यूट करा"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"कास्ट करा"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"रिंग म्यूट केल्यामुळे उपलब्ध नाही"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. अनम्यूट करण्यासाठी टॅप करा."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. व्हायब्रेट सेट करण्यासाठी टॅप करा. प्रवेशयोग्यता सेवा म्यूट केल्या जाऊ शकतात."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. म्यूट करण्यासाठी टॅप करा. प्रवेशक्षमता सेवा म्यूट केल्या जाऊ शकतात."</string>
diff --git a/packages/SystemUI/res/values-mr/tiles_states_strings.xml b/packages/SystemUI/res/values-mr/tiles_states_strings.xml
index 24d3b47af961..b70a5cc671a7 100644
--- a/packages/SystemUI/res/values-mr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mr/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"बंद आहे"</item>
<item msgid="578444932039713369">"सुरू आहे"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"उपलब्ध नाही"</item>
<item msgid="8707481475312432575">"बंद आहे"</item>
diff --git a/packages/SystemUI/res/values-ms/tiles_states_strings.xml b/packages/SystemUI/res/values-ms/tiles_states_strings.xml
index 07a8426feeb2..b72a3756ccaa 100644
--- a/packages/SystemUI/res/values-ms/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ms/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Mati"</item>
<item msgid="578444932039713369">"Hidup"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Tidak tersedia"</item>
<item msgid="8707481475312432575">"Mati"</item>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index c408118e48ce..c6d46bccf254 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"အသံမြည်သည်"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"တုန်ခါသည်"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"အသံတိတ်သည်"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"ကာစ်လုပ်ရန်"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"ဖုန်းမြည်သံပိတ်ထားသဖြင့် မရနိုင်ပါ"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s။ အသံပြန်ဖွင့်ရန် တို့ပါ။"</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s။ တုန်ခါမှုကို သတ်မှတ်ရန် တို့ပါ။ အများသုံးနိုင်မှု ဝန်ဆောင်မှုများကို အသံပိတ်ထားနိုင်ပါသည်။"</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s။ အသံပိတ်ရန် တို့ပါ။ အများသုံးနိုင်မှု ဝန်ဆောင်မှုများကို အသံပိတ်ထားနိုင်ပါသည်။"</string>
diff --git a/packages/SystemUI/res/values-my/tiles_states_strings.xml b/packages/SystemUI/res/values-my/tiles_states_strings.xml
index fd375d4f3eb1..d223dc9d0bed 100644
--- a/packages/SystemUI/res/values-my/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-my/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"ပိတ်"</item>
<item msgid="578444932039713369">"ဖွင့်"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"မရနိုင်ပါ"</item>
<item msgid="8707481475312432575">"ပိတ်"</item>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 2ce016ac586f..a2b97eee2fbe 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Ring"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrer"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Ignorer"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Cast"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Utilgjengelig fordi ringelyden er kuttet"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Trykk for å slå på lyden."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Trykk for å angi vibrasjon. Lyden kan bli slått av for tilgjengelighetstjenestene."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Trykk for å slå av lyden. Lyden kan bli slått av for tilgjengelighetstjenestene."</string>
diff --git a/packages/SystemUI/res/values-nb/tiles_states_strings.xml b/packages/SystemUI/res/values-nb/tiles_states_strings.xml
index e4a811941b2a..2ed00960fdfd 100644
--- a/packages/SystemUI/res/values-nb/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-nb/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Av"</item>
<item msgid="578444932039713369">"På"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Utilgjengelig"</item>
<item msgid="8707481475312432575">"Av"</item>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 0096f480f67e..1388a85a6f15 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"घन्टी"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"कम्पन"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"म्युट गर्नुहोस्"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"कास्ट गर्नुहोस्"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"डिभाइस म्युट गरिएकाले यो सुविधा उपलब्ध छैन"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s। अनम्यूट गर्नाका लागि ट्याप गर्नुहोस्।"</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s। कम्पनमा सेट गर्नाका लागि ट्याप गर्नुहोस्। पहुँच सम्बन्धी सेवाहरू म्यूट हुन सक्छन्।"</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s। म्यूट गर्नाका लागि ट्याप गर्नुहोस्। पहुँच सम्बन्धी सेवाहरू म्यूट हुन सक्छन्।"</string>
diff --git a/packages/SystemUI/res/values-ne/tiles_states_strings.xml b/packages/SystemUI/res/values-ne/tiles_states_strings.xml
index 5cf91e533494..40159fb17279 100644
--- a/packages/SystemUI/res/values-ne/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ne/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"अफ छ"</item>
<item msgid="578444932039713369">"अन छ"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"उपलब्ध छैन"</item>
<item msgid="8707481475312432575">"अफ छ"</item>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 723b9096cfcf..09156cf074e6 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Bellen"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Trillen"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Geluid staat uit"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Casten"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Niet beschikbaar, belgeluid staat uit"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Tik om dempen op te heffen."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tik om in te stellen op trillen. Het geluid van toegankelijkheidsservices kan hierdoor uitgaan."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tik om te dempen. Het geluid van toegankelijkheidsservices kan hierdoor uitgaan."</string>
diff --git a/packages/SystemUI/res/values-nl/tiles_states_strings.xml b/packages/SystemUI/res/values-nl/tiles_states_strings.xml
index 592ecf5b69d6..60e35da7611b 100644
--- a/packages/SystemUI/res/values-nl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-nl/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Uit"</item>
<item msgid="578444932039713369">"Aan"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Niet beschikbaar"</item>
<item msgid="8707481475312432575">"Uit"</item>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 612e012a2546..b49c2979ac43 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -287,7 +287,7 @@
<string name="quick_settings_media_device_label" msgid="8034019242363789941">"ମିଡିଆ ଡିଭାଇସ୍‌"</string>
<string name="quick_settings_user_title" msgid="8673045967216204537">"ୟୁଜର"</string>
<string name="quick_settings_wifi_label" msgid="2879507532983487244">"ୱାଇ-ଫାଇ"</string>
- <string name="quick_settings_internet_label" msgid="6603068555872455463">"ଇଣ୍ଟରନେଟ"</string>
+ <string name="quick_settings_internet_label" msgid="6603068555872455463">"ଇଣ୍ଟର୍ନେଟ"</string>
<string name="quick_settings_networks_available" msgid="1875138606855420438">"ନେଟୱାର୍କଗୁଡ଼ିକ ଉପଲବ୍ଧ"</string>
<string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"ନେଟୱାର୍କ ଉପଲବ୍ଧ ନାହିଁ"</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"କୌଣସି ୱାଇ-ଫାଇ ନେଟ୍‌ୱର୍କ ଉପଲବ୍ଧ ନାହିଁ"</string>
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"ରିଙ୍ଗ"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"ଭାଇବ୍ରେଟ୍‌"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"ମ୍ୟୁଟ"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"କାଷ୍ଟ କରନ୍ତୁ"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"ରିଂକୁ ମ୍ୟୁଟ କରାଯାଇଥିବା ଯୋଗୁଁ ଉପଲବ୍ଧ ନାହିଁ"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s। ଅନମ୍ୟୁଟ୍‍ କରିବା ପାଇଁ ଟାପ୍‍ କରନ୍ତୁ।"</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s। ଭାଇବ୍ରେଟ୍‍ ସେଟ୍‍ କରିବାକୁ ଟାପ୍‍ କରନ୍ତୁ। ଆକ୍ସେସିବିଲିଟୀ ସର୍ଭିସ୍‌ ମ୍ୟୁଟ୍‍ କରାଯାଇପାରେ।"</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s। ମ୍ୟୁଟ୍‍ କରିବାକୁ ଟାପ୍‍ କରନ୍ତୁ। ଆକ୍ସେସିବିଲିଟୀ ସର୍ଭିସ୍‌ ମ୍ୟୁଟ୍‍ କରାଯାଇପାରେ।"</string>
diff --git a/packages/SystemUI/res/values-or/tiles_states_strings.xml b/packages/SystemUI/res/values-or/tiles_states_strings.xml
index d362c65fa971..43bddbf9f49b 100644
--- a/packages/SystemUI/res/values-or/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-or/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"ବନ୍ଦ ଅଛି"</item>
<item msgid="578444932039713369">"ଚାଲୁ ଅଛି"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"ଉପଲବ୍ଧ ନାହିଁ"</item>
<item msgid="8707481475312432575">"ବନ୍ଦ ଅଛି"</item>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index c02641329304..cd55198317e8 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"ਘੰਟੀ"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"ਥਰਥਰਾਹਟ"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"ਮਿਊਟ"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"ਕਾਸਟ ਕਰੋ"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"ਉਪਲਬਧ ਨਹੀਂ ਹੈ ਕਿਉਂਕਿ ਘੰਟੀ ਮਿਊਟ ਕੀਤੀ ਹੋਈ ਹੈ"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s। ਅਣਮਿਊਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s। ਥਰਥਰਾਹਟ ਸੈੱਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ। ਪਹੁੰਚਯੋਗਤਾ ਸੇਵਾਵਾਂ ਮਿਊਟ ਹੋ ਸਕਦੀਆਂ ਹਨ।"</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s। ਮਿਊਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ। ਪਹੁੰਚਯੋਗਤਾ ਸੇਵਾਵਾਂ ਮਿਊਟ ਹੋ ਸਕਦੀਆਂ ਹਨ।"</string>
diff --git a/packages/SystemUI/res/values-pa/tiles_states_strings.xml b/packages/SystemUI/res/values-pa/tiles_states_strings.xml
index f249afb72b6d..5f0ca172dca9 100644
--- a/packages/SystemUI/res/values-pa/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pa/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"ਬੰਦ ਹੈ"</item>
<item msgid="578444932039713369">"ਚਾਲੂ ਹੈ"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"ਅਣਉਪਲਬਧ ਹੈ"</item>
<item msgid="8707481475312432575">"ਬੰਦ ਹੈ"</item>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 44639b990e48..76547ed5266c 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Dzwonek"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Wibracje"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Wyciszenie"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Przesyłanie"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Niedostępne, bo dzwonek jest wyciszony"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Kliknij, by wyłączyć wyciszenie."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Kliknij, by włączyć wibracje. Ułatwienia dostępu mogą być wyciszone."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Kliknij, by wyciszyć. Ułatwienia dostępu mogą być wyciszone."</string>
diff --git a/packages/SystemUI/res/values-pl/tiles_states_strings.xml b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
index ea6ad58c825a..5e3a1189c940 100644
--- a/packages/SystemUI/res/values-pl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Wyłączony"</item>
<item msgid="578444932039713369">"Włączony"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Niedostępne"</item>
<item msgid="8707481475312432575">"Wyłączone"</item>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 639a488c5226..598ef78ae63b 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Tocar"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrar"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Desativar som"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Transmitir"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Indisponível com o toque foi silenciado"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Toque para ativar o som."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Toque para configurar para vibrar. É possível que os serviços de acessibilidade sejam silenciados."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Toque para silenciar. É possível que os serviços de acessibilidade sejam silenciados."</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
index 28c07f40b6b9..d4fd83803ba7 100644
--- a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Desativada"</item>
<item msgid="578444932039713369">"Ativada"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Indisponível"</item>
<item msgid="8707481475312432575">"Desativado"</item>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index f34dea1dfbf2..7e5a7368faaf 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -429,8 +429,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Adicionar mais widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantenha premido para personalizar os widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string>
- <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) -->
- <skip />
+ <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ícone da app do widget desativado"</string>
<string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string>
<string name="button_to_remove_widget" msgid="3948204829181214098">"Remover"</string>
<string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Adicionar widget"</string>
@@ -575,10 +574,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Toque"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrar"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Desativar som"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Transmitir"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Indisponível porque o toque está desat."</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Toque para reativar o som."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Toque para ativar a vibração. Os serviços de acessibilidade podem ser silenciados."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Toque para desativar o som. Os serviços de acessibilidade podem ser silenciados."</string>
@@ -839,10 +836,8 @@
<string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu ligar/desligar"</string>
<string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
<string name="tuner_lock_screen" msgid="2267383813241144544">"Ecrã de bloqueio"</string>
- <!-- no translation found for finder_active (7907846989716941952) -->
- <skip />
- <!-- no translation found for shutdown_progress (5464239146561542178) -->
- <skip />
+ <string name="finder_active" msgid="7907846989716941952">"Pode localizar este telemóvel com o serviço Localizar o meu dispositivo mesmo quando está desligado"</string>
+ <string name="shutdown_progress" msgid="5464239146561542178">"A encerrar…"</string>
<string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Veja os passos de manutenção"</string>
<string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Veja os passos de manutenção"</string>
<string name="high_temp_alarm_title" msgid="8654754369605452169">"Desligue o dispositivo"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
index b58b8488a3e4..e94b1ec6b0fd 100644
--- a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Desligado"</item>
<item msgid="578444932039713369">"Ligado"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Indisponível"</item>
<item msgid="8707481475312432575">"Desligado"</item>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 639a488c5226..598ef78ae63b 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Tocar"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrar"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Desativar som"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Transmitir"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Indisponível com o toque foi silenciado"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Toque para ativar o som."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Toque para configurar para vibrar. É possível que os serviços de acessibilidade sejam silenciados."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Toque para silenciar. É possível que os serviços de acessibilidade sejam silenciados."</string>
diff --git a/packages/SystemUI/res/values-pt/tiles_states_strings.xml b/packages/SystemUI/res/values-pt/tiles_states_strings.xml
index 28c07f40b6b9..d4fd83803ba7 100644
--- a/packages/SystemUI/res/values-pt/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Desativada"</item>
<item msgid="578444932039713369">"Ativada"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Indisponível"</item>
<item msgid="8707481475312432575">"Desativado"</item>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 7d8c2a31751c..026e22bd6328 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Sonerie"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrații"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Blochează"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Proiectează"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Indisponibil; soneria este dezactivată"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Atinge pentru a activa sunetul."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Atinge pentru a seta vibrarea. Sunetul se poate dezactiva pentru serviciile de accesibilitate."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Atinge pentru a dezactiva sunetul. Sunetul se poate dezactiva pentru serviciile de accesibilitate."</string>
diff --git a/packages/SystemUI/res/values-ro/tiles_states_strings.xml b/packages/SystemUI/res/values-ro/tiles_states_strings.xml
index 5a5eb9f6788c..75565f942ac4 100644
--- a/packages/SystemUI/res/values-ro/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ro/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Dezactivată"</item>
<item msgid="578444932039713369">"Activată"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Indisponibilă"</item>
<item msgid="8707481475312432575">"Dezactivată"</item>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 37b7ae5f7b3d..1df112ba8493 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Со звуком"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Вибрация"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Без звука"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Трансляция"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Недоступно, когда отключен звук вызовов"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Нажмите, чтобы включить звук."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Нажмите, чтобы включить вибрацию. Специальные возможности могут прекратить работу."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Нажмите, чтобы выключить звук. Специальные возможности могут прекратить работу."</string>
diff --git a/packages/SystemUI/res/values-ru/tiles_states_strings.xml b/packages/SystemUI/res/values-ru/tiles_states_strings.xml
index cd140791bbd5..3099e008c93a 100644
--- a/packages/SystemUI/res/values-ru/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ru/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Откл."</item>
<item msgid="578444932039713369">"Вкл."</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Функция недоступна"</item>
<item msgid="8707481475312432575">"Откл."</item>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index c851f8583f0d..f4b7d1eb1254 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"නාද කරන්න"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"කම්පනය කරන්න"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"නිහඬ කරන්න"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"විකාශය"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"නාදය නිහඬ කර ඇති නිසා නොලැබේ"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. නිහඬ කිරීම ඉවත් කිරීමට තට්ටු කරන්න."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. කම්පනය කිරීමට තට්ටු කරන්න. ප්‍රවේශ්‍යතා සේවා නිහඬ කළ හැකිය."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. නිහඬ කිරීමට තට්ටු කරන්න. ප්‍රවේශ්‍යතා සේවා නිහඬ කළ හැකිය."</string>
diff --git a/packages/SystemUI/res/values-si/tiles_states_strings.xml b/packages/SystemUI/res/values-si/tiles_states_strings.xml
index fcd768bfc4e3..48e8cc4af507 100644
--- a/packages/SystemUI/res/values-si/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-si/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"අක්‍රියයි"</item>
<item msgid="578444932039713369">"සක්‍රියයි"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"නොමැත"</item>
<item msgid="8707481475312432575">"අක්‍රියයි"</item>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index d25e3687b589..0f579da44ed6 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Prezvoniť"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrovať"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Vypnúť zvuk"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Prenos"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Nedostupné, pretože je vypnuté zvonenie"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Klepnutím zapnite zvuk."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Klepnutím aktivujte režim vibrovania. Služby dostupnosti je možné stlmiť."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Klepnutím vypnite zvuk. Služby dostupnosti je možné stlmiť."</string>
diff --git a/packages/SystemUI/res/values-sk/tiles_states_strings.xml b/packages/SystemUI/res/values-sk/tiles_states_strings.xml
index 660f85d365e2..fdfcd27db263 100644
--- a/packages/SystemUI/res/values-sk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sk/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Vypnuté"</item>
<item msgid="578444932039713369">"Zapnuté"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Nie je k dispozícii"</item>
<item msgid="8707481475312432575">"Vypnuté"</item>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index eb56a44aa313..7acaa54cbbad 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Zvonjenje"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibriranje"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Utišano"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Predvajanje"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Ni na voljo, ker je zvonjenje izklopljeno"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Dotaknite se, če želite vklopiti zvok."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Dotaknite se, če želite nastaviti vibriranje. V storitvah za dostopnost bo morda izklopljen zvok."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Dotaknite se, če želite izklopiti zvok. V storitvah za dostopnost bo morda izklopljen zvok."</string>
diff --git a/packages/SystemUI/res/values-sl/tiles_states_strings.xml b/packages/SystemUI/res/values-sl/tiles_states_strings.xml
index d7e62caac28d..3804d639bb52 100644
--- a/packages/SystemUI/res/values-sl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sl/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Izklopljeno"</item>
<item msgid="578444932039713369">"Vklopljeno"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Ni na voljo"</item>
<item msgid="8707481475312432575">"Izklopljeno"</item>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index eb8fa4372d2e..21a974faf29e 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Bjeri ziles"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Dridhje"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Pa zë"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Transmeto"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Nuk ofrohet; ziles i është hequr zëri"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Trokit për të aktivizuar."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Trokit për ta caktuar te dridhja. Shërbimet e qasshmërisë mund të çaktivizohen."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Trokit për të çaktivizuar. Shërbimet e qasshmërisë mund të çaktivizohen."</string>
diff --git a/packages/SystemUI/res/values-sq/tiles_states_strings.xml b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
index b8e1355dfb25..6318700bf6f2 100644
--- a/packages/SystemUI/res/values-sq/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Joaktive"</item>
<item msgid="578444932039713369">"Aktiv"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Nuk ofrohet"</item>
<item msgid="8707481475312432575">"Joaktive"</item>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 0644a8095675..2f52f90b3622 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Активирај звоно"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Вибрирај"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Искључи звук"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Пребацивање"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Недоступно јер је звук искључен"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Додирните да бисте укључили звук."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Додирните да бисте подесили на вибрацију. Звук услуга приступачности ће можда бити искључен."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Додирните да бисте искључили звук. Звук услуга приступачности ће можда бити искључен."</string>
diff --git a/packages/SystemUI/res/values-sr/tiles_states_strings.xml b/packages/SystemUI/res/values-sr/tiles_states_strings.xml
index c959bfb0eb73..e4cf0b6cd2c0 100644
--- a/packages/SystemUI/res/values-sr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sr/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Искључено"</item>
<item msgid="578444932039713369">"Укључено"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Недоступно"</item>
<item msgid="8707481475312432575">"Искључено"</item>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 208891f4fbfa..20bc7e70a0da 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Ringsignal"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibration"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Dölj"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Casta"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Otillgängligt eftersom ringljudet är av"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Tryck här om du vill slå på ljudet."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tryck här om du vill sätta på vibrationen. Tillgänglighetstjänster kanske inaktiveras."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tryck här om du vill stänga av ljudet. Tillgänglighetstjänsterna kanske inaktiveras."</string>
diff --git a/packages/SystemUI/res/values-sv/tiles_states_strings.xml b/packages/SystemUI/res/values-sv/tiles_states_strings.xml
index 28717dfa5229..8981ac775e50 100644
--- a/packages/SystemUI/res/values-sv/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sv/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Av"</item>
<item msgid="578444932039713369">"På"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Inte tillgängligt"</item>
<item msgid="8707481475312432575">"Av"</item>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 404cb487e445..fa0e7b5eba05 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Piga"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Kutetema"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Zima sauti"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Tuma"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Halipatikani kwa sababu sauti imezimwa"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Gusa ili urejeshe."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Gusa ili uweke mtetemo. Huenda ikakomesha huduma za zana za walio na matatizo ya kuona au kusikia."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Gusa ili ukomeshe. Huenda ikakomesha huduma za zana za walio na matatizo ya kuona au kusikia."</string>
diff --git a/packages/SystemUI/res/values-sw/tiles_states_strings.xml b/packages/SystemUI/res/values-sw/tiles_states_strings.xml
index 2fe40603bc7d..08a1f149264c 100644
--- a/packages/SystemUI/res/values-sw/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sw/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Kimezimwa"</item>
<item msgid="578444932039713369">"Kimewashwa"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Hakipatikani"</item>
<item msgid="8707481475312432575">"Kimezimwa"</item>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 03dd362e2b18..0f360e6bc17b 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"ஒலி"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"அதிர்வு"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"அமைதி"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"அலைபரப்பு"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"\'ரிங்\' மியூட்டில் உள்ளதால் கிடைக்கவில்லை"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. ஒலி இயக்க, தட்டவும்."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. அதிர்விற்கு அமைக்க, தட்டவும். அணுகல்தன்மை சேவைகள் ஒலியடக்கப்படக்கூடும்."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. ஒலியடக்க, தட்டவும். அணுகல்தன்மை சேவைகள் ஒலியடக்கப்படக்கூடும்."</string>
diff --git a/packages/SystemUI/res/values-ta/tiles_states_strings.xml b/packages/SystemUI/res/values-ta/tiles_states_strings.xml
index 5bcc6c761e1c..741d6dea191f 100644
--- a/packages/SystemUI/res/values-ta/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ta/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"முடக்கப்பட்டுள்ளது"</item>
<item msgid="578444932039713369">"இயக்கப்பட்டுள்ளது"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"கிடைக்கவில்லை"</item>
<item msgid="8707481475312432575">"முடக்கப்பட்டுள்ளது"</item>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 08067c93bead..4e8e2d0e4ca8 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"రింగ్"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"వైబ్రేట్"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"మ్యూట్"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"ప్రసారం చేయండి"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"వాల్యూమ్ మ్యూట్ అయినందున అందుబాటులో లేదు"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. అన్‌మ్యూట్ చేయడానికి నొక్కండి."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. వైబ్రేషన్‌కు సెట్ చేయడానికి నొక్కండి. యాక్సెస్ సామర్థ్య సేవలు మ్యూట్ చేయబడవచ్చు."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. మ్యూట్ చేయడానికి నొక్కండి. యాక్సెస్ సామర్థ్య సేవలు మ్యూట్ చేయబడవచ్చు."</string>
diff --git a/packages/SystemUI/res/values-te/tiles_states_strings.xml b/packages/SystemUI/res/values-te/tiles_states_strings.xml
index 9d2b407ccd10..6ff293479860 100644
--- a/packages/SystemUI/res/values-te/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-te/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"ఆఫ్‌లో ఉంది"</item>
<item msgid="578444932039713369">"ఆన్‌లో ఉంది"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"అందుబాటులో లేదు"</item>
<item msgid="8707481475312432575">"ఆఫ్‌లో ఉంది"</item>
diff --git a/packages/SystemUI/res/values-th/tiles_states_strings.xml b/packages/SystemUI/res/values-th/tiles_states_strings.xml
index 69449a72196e..d961385ba72e 100644
--- a/packages/SystemUI/res/values-th/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-th/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"ปิด"</item>
<item msgid="578444932039713369">"เปิด"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"ไม่พร้อมใช้งาน"</item>
<item msgid="8707481475312432575">"ปิด"</item>
diff --git a/packages/SystemUI/res/values-tl/tiles_states_strings.xml b/packages/SystemUI/res/values-tl/tiles_states_strings.xml
index 689c2a26ca61..a12c010f766a 100644
--- a/packages/SystemUI/res/values-tl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-tl/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Naka-off"</item>
<item msgid="578444932039713369">"Naka-on"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Hindi available"</item>
<item msgid="8707481475312432575">"Naka-off"</item>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 495000ba0318..2cdc6e7e1296 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Zili çaldır"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Titreşim"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Sesi kapat"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Yayınla"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Zil sesi kapatıldığı için kullanılamıyor"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Sesi açmak için dokunun."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Titreşime ayarlamak için dokunun. Erişilebilirlik hizmetlerinin sesi kapatılabilir."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Sesi kapatmak için dokunun. Erişilebilirlik hizmetlerinin sesi kapatılabilir."</string>
diff --git a/packages/SystemUI/res/values-tr/tiles_states_strings.xml b/packages/SystemUI/res/values-tr/tiles_states_strings.xml
index a8c7f784920d..c6a8aecf0da1 100644
--- a/packages/SystemUI/res/values-tr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-tr/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Kapalı"</item>
<item msgid="578444932039713369">"Açık"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Kullanılamıyor"</item>
<item msgid="8707481475312432575">"Kapalı"</item>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 67d5ffc3373a..c89ae75a5ae2 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Дзвінок"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Вібросигнал"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Без звуку"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Трансляція"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Недоступно: звук дзвінків вимкнено"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Торкніться, щоб увімкнути звук."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Торкніться, щоб налаштувати вібросигнал. Спеціальні можливості може бути вимкнено."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Торкніться, щоб вимкнути звук. Спеціальні можливості може бути вимкнено."</string>
diff --git a/packages/SystemUI/res/values-uk/tiles_states_strings.xml b/packages/SystemUI/res/values-uk/tiles_states_strings.xml
index 4062f1be4c08..a8e1ab8f3f99 100644
--- a/packages/SystemUI/res/values-uk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-uk/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Вимкнено"</item>
<item msgid="578444932039713369">"Увімкнено"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Недоступно"</item>
<item msgid="8707481475312432575">"Вимкнено"</item>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 7414ac62c4a8..3237f32f5347 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -429,8 +429,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"مزید ویجٹس شامل کریں"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ویجٹس کو حسب ضرورت بنانے کے لیے لانگ پریس کریں"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ویجیٹس کو حسب ضرورت بنائیں"</string>
- <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) -->
- <skip />
+ <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"غیر فعال ویجیٹ کے لئے ایپ آئیکن"</string>
<string name="edit_widget" msgid="9030848101135393954">"ویجیٹ میں ترمیم کریں"</string>
<string name="button_to_remove_widget" msgid="3948204829181214098">"ہٹائیں"</string>
<string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ویجیٹ شامل کریں"</string>
@@ -575,10 +574,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"رِنگ کریں"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"وائبریٹ"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"خاموش کریں"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"کاسٹ"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"دستیاب نہیں ہے کیونکہ رنگ خاموش ہے"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"‏‎%1$s۔ آواز چالو کرنے کیلئے تھپتھپائیں۔"</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"‏‎%1$s۔ ارتعاش پر سیٹ کرنے کیلئے تھپتھپائیں۔ ایکسیسبیلٹی سروسز شاید خاموش ہوں۔"</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"‏‎%1$s۔ خاموش کرنے کیلئے تھپتھپائیں۔ ایکسیسبیلٹی سروسز شاید خاموش ہوں۔"</string>
@@ -839,10 +836,8 @@
<string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"پاور مینیو"</string>
<string name="accessibility_quick_settings_page" msgid="7506322631645550961">"صفحہ <xliff:g id="ID_1">%1$d</xliff:g> از <xliff:g id="ID_2">%2$d</xliff:g>"</string>
<string name="tuner_lock_screen" msgid="2267383813241144544">"مقفل اسکرین"</string>
- <!-- no translation found for finder_active (7907846989716941952) -->
- <skip />
- <!-- no translation found for shutdown_progress (5464239146561542178) -->
- <skip />
+ <string name="finder_active" msgid="7907846989716941952">"پاور آف ہونے پر بھی آپ میرا آلہ ڈھونڈیں کے ساتھ اس فون کو تلاش کر سکتے ہیں"</string>
+ <string name="shutdown_progress" msgid="5464239146561542178">"بند ہو رہا ہے…"</string>
<string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"نگہداشت کے اقدامات ملاحظہ کریں"</string>
<string name="high_temp_dialog_help_text" msgid="7380171287943345858">"نگہداشت کے اقدامات ملاحظہ کریں"</string>
<string name="high_temp_alarm_title" msgid="8654754369605452169">"اپنے آلہ کو ان پلگ کریں"</string>
diff --git a/packages/SystemUI/res/values-ur/tiles_states_strings.xml b/packages/SystemUI/res/values-ur/tiles_states_strings.xml
index bb27b9fbe9f2..6d1e7076da40 100644
--- a/packages/SystemUI/res/values-ur/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ur/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"آف ہے"</item>
<item msgid="578444932039713369">"آن ہے"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"دستیاب نہیں ہے"</item>
<item msgid="8707481475312432575">"آف ہے"</item>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 09e5ff04d9b6..478fcdb95527 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Jiringlatish"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Tebranish"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Ovozsiz"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Translatsiya"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Jiringlash ovozsizligi uchun ishlamaydi"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Ovozini yoqish uchun ustiga bosing."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tebranishni yoqish uchun ustiga bosing. Qulayliklar ishlamasligi mumkin."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Ovozini o‘chirish uchun ustiga bosing. Qulayliklar ishlamasligi mumkin."</string>
diff --git a/packages/SystemUI/res/values-uz/tiles_states_strings.xml b/packages/SystemUI/res/values-uz/tiles_states_strings.xml
index bd5ee8951c5b..0558c4a91794 100644
--- a/packages/SystemUI/res/values-uz/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-uz/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Oʻchiq"</item>
<item msgid="578444932039713369">"Yoniq"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Ishlamaydi"</item>
<item msgid="8707481475312432575">"Oʻchiq"</item>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index f7057e948b70..7e8638b5bdeb 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Đổ chuông"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Rung"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Tắt tiếng"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Truyền"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Không hoạt động vì chuông bị tắt"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Nhấn để bật tiếng."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Nhấn để đặt chế độ rung. Bạn có thể tắt tiếng dịch vụ trợ năng."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Nhấn để tắt tiếng. Bạn có thể tắt tiếng dịch vụ trợ năng."</string>
diff --git a/packages/SystemUI/res/values-vi/tiles_states_strings.xml b/packages/SystemUI/res/values-vi/tiles_states_strings.xml
index 201a45b3d445..eee10d330258 100644
--- a/packages/SystemUI/res/values-vi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-vi/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Đang tắt"</item>
<item msgid="578444932039713369">"Đang bật"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Không hoạt động"</item>
<item msgid="8707481475312432575">"Đang tắt"</item>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 2c87e2491814..255213858f91 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"响铃"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"振动"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"静音"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"投屏"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"该功能无法使用,因为铃声被静音"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s。点按即可取消静音。"</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s。点按即可设为振动,但可能会同时将无障碍服务设为静音。"</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s。点按即可设为静音,但可能会同时将无障碍服务设为静音。"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
index 3ab2d7a3d1c7..82ab6710729d 100644
--- a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"已关闭"</item>
<item msgid="578444932039713369">"已开启"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"不可用"</item>
<item msgid="8707481475312432575">"已关闭"</item>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 78d7c7a0c9b4..5941dad6903b 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"鈴聲"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"震動"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"靜音"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"投放"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"鈴聲已設定為靜音,因此無法使用"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s。輕按即可取消靜音。"</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s。輕按即可設為震動。無障礙功能服務可能已經設為靜音。"</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s。輕按即可設為靜音。無障礙功能服務可能已經設為靜音。"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
index 89d66284ede6..6bac27502583 100644
--- a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"已關閉"</item>
<item msgid="578444932039713369">"已開啟"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"無法使用"</item>
<item msgid="8707481475312432575">"已關閉"</item>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 46d775086fc3..c46d831c741a 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"鈴聲"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"震動"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"靜音"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"投放"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"鈴聲已設為靜音,因此無法使用"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s。輕觸即可取消靜音。"</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s。輕觸即可設為震動,但系統可能會將無障礙服務一併設為靜音。"</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s。輕觸即可設為靜音,但系統可能會將無障礙服務一併設為靜音。"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
index a046e3354729..5794bf1703f9 100644
--- a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"已關閉"</item>
<item msgid="578444932039713369">"已開啟"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"無法使用"</item>
<item msgid="8707481475312432575">"已關閉"</item>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index f12c2bbdd81c..0bbac05638cc 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -575,10 +575,8 @@
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Khalisa"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Dlidlizela"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"Thulisa"</string>
- <!-- no translation found for media_device_cast (4786241789687569892) -->
- <skip />
- <!-- no translation found for stream_notification_unavailable (4313854556205836435) -->
- <skip />
+ <string name="media_device_cast" msgid="4786241789687569892">"Sakaza"</string>
+ <string name="stream_notification_unavailable" msgid="4313854556205836435">"Ayitholakali ngoba ukukhala kuthulisiwe"</string>
<string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Thepha ukuze ususe ukuthula."</string>
<string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Thepha ukuze usethe ukudlidliza. Amasevisi okufinyelela angathuliswa."</string>
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Thepha ukuze uthulise. Amasevisi okufinyelela angathuliswa."</string>
diff --git a/packages/SystemUI/res/values-zu/tiles_states_strings.xml b/packages/SystemUI/res/values-zu/tiles_states_strings.xml
index e35840b85ab4..8c7b652cdfe0 100644
--- a/packages/SystemUI/res/values-zu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zu/tiles_states_strings.xml
@@ -126,6 +126,9 @@
<item msgid="8259411607272330225">"Valiwe"</item>
<item msgid="578444932039713369">"Vuliwe"</item>
</string-array>
+ <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) -->
+ <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) -->
+ <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) -->
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Akutholakali"</item>
<item msgid="8707481475312432575">"Valiwe"</item>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 035cfdc492d0..71ae0d716429 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -223,7 +223,6 @@
<item type="id" name="lock_icon" />
<item type="id" name="lock_icon_bg" />
<item type="id" name="burn_in_layer" />
- <item type="id" name="burn_in_layer_empty_view" />
<item type="id" name="communal_tutorial_indicator" />
<item type="id" name="nssl_placeholder_barrier_bottom" />
<item type="id" name="ambient_indication_container" />
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 346bdfc8b2d8..b71341791ee6 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -3254,6 +3254,12 @@
<!-- Text for education page content description for unfolded animation. [CHAR_LIMIT=NONE] -->
<string name="rear_display_accessibility_unfolded_animation">Foldable device being flipped around</string>
+ <!-- QuickSettings: Additional label for the auto-rotation quicksettings tile indicating that the setting corresponds to the folded posture for a foldable device [CHAR LIMIT=32] -->
+ <string name="quick_settings_rotation_posture_folded">folded</string>
+ <!-- QuickSettings: Additional label for the auto-rotation quicksettings tile indicating that the setting corresponds to the unfolded posture for a foldable device [CHAR LIMIT=32] -->
+ <string name="quick_settings_rotation_posture_unfolded">unfolded</string>
+ <!-- QuickSettings: template for rotation tile foldable secondary label [CHAR LIMIT=64] !-->
+ <string name="rotation_tile_with_posture_secondary_label_template">%1$s / %2$s</string>
<!-- Title for notification of low stylus battery with percentage. "percentage" is
the value of the battery capacity remaining [CHAR LIMIT=none]-->
<string name="stylus_battery_low_percentage"><xliff:g id="percentage" example="16%">%s</xliff:g> battery remaining</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 617eadbd447c..ce08ca3e43af 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -1581,4 +1581,8 @@
<style name="Theme.PrivacyDialog" parent="@style/Theme.SystemUI.Dialog">
<item name="android:colorBackground">?androidprv:attr/materialColorSurfaceContainer</item>
</style>
+
+ <style name="Theme.SystemUI.Dialog.StickyKeys" parent="@style/Theme.SystemUI.Dialog">
+ <item name="android:colorBackground">@color/transparent</item>
+ </style>
</resources>
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
index 75cace424e8b..b9b8fbe9637f 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
@@ -209,6 +209,9 @@ public class CarrierTextManager {
// This will set/remove the listeners appropriately. Note that it will never double
// add the listeners.
handleSetListening(mCarrierTextCallback);
+ mainExecutor.execute(() -> {
+ mKeyguardUpdateMonitor.registerCallback(mCallback);
+ });
}
});
}
@@ -276,7 +279,6 @@ public class CarrierTextManager {
if (mNetworkSupported.get()) {
// Keyguard update monitor expects callbacks from main thread
mMainExecutor.execute(() -> {
- mKeyguardUpdateMonitor.registerCallback(mCallback);
mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
});
mTelephonyListenerManager.addActiveDataSubscriptionIdListener(mPhoneStateListener);
@@ -289,7 +291,6 @@ public class CarrierTextManager {
} else {
mCarrierTextCallback = null;
mMainExecutor.execute(() -> {
- mKeyguardUpdateMonitor.removeCallback(mCallback);
mWakefulnessLifecycle.removeObserver(mWakefulnessObserver);
});
mTelephonyListenerManager.removeActiveDataSubscriptionIdListener(mPhoneStateListener);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index c0ae4a1f4036..9421f150a38a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -53,6 +53,9 @@ import com.android.systemui.Dumpable;
import com.android.systemui.animation.ViewHierarchyAnimator;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
+import com.android.systemui.keyguard.shared.model.TransitionState;
+import com.android.systemui.keyguard.shared.model.TransitionStep;
import com.android.systemui.plugins.clocks.ClockController;
import com.android.systemui.power.domain.interactor.PowerInteractor;
import com.android.systemui.power.shared.model.ScreenPowerState;
@@ -101,6 +104,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
private final Rect mClipBounds = new Rect();
private final KeyguardInteractor mKeyguardInteractor;
private final PowerInteractor mPowerInteractor;
+ private final KeyguardTransitionInteractor mKeyguardTransitionInteractor;
private final DozeParameters mDozeParameters;
private View mStatusArea = null;
@@ -108,6 +112,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
private Boolean mSplitShadeEnabled = false;
private Boolean mStatusViewCentered = true;
+ private boolean mGoneToAodTransitionRunning = false;
private DumpManager mDumpManager;
private final TransitionListenerAdapter mKeyguardStatusAlignmentTransitionListener =
@@ -176,6 +181,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
KeyguardLogger logger,
InteractionJankMonitor interactionJankMonitor,
KeyguardInteractor keyguardInteractor,
+ KeyguardTransitionInteractor keyguardTransitionInteractor,
DumpManager dumpManager,
PowerInteractor powerInteractor) {
super(keyguardStatusView);
@@ -191,6 +197,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
mDumpManager = dumpManager;
mKeyguardInteractor = keyguardInteractor;
mPowerInteractor = powerInteractor;
+ mKeyguardTransitionInteractor = keyguardTransitionInteractor;
}
@Override
@@ -225,7 +232,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
mDumpManager.registerDumpable(getInstanceName(), this);
if (migrateClocksToBlueprint()) {
startCoroutines(EmptyCoroutineContext.INSTANCE);
- mView.setVisibility(View.GONE);
}
}
@@ -241,6 +247,15 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
dozeTimeTick();
}
}, context);
+
+ collectFlow(mView, mKeyguardTransitionInteractor.getGoneToAodTransition(),
+ (TransitionStep step) -> {
+ if (step.getTransitionState() == TransitionState.RUNNING) {
+ mGoneToAodTransitionRunning = true;
+ } else {
+ mGoneToAodTransitionRunning = false;
+ }
+ }, context);
}
public KeyguardStatusView getView() {
@@ -311,7 +326,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
* Set keyguard status view alpha.
*/
public void setAlpha(float alpha) {
- if (!mKeyguardVisibilityHelper.isVisibilityAnimating()) {
+ if (!mKeyguardVisibilityHelper.isVisibilityAnimating() && !mGoneToAodTransitionRunning) {
mView.setAlpha(alpha);
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index b7667a8669f4..8c51a4e0ce66 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -3313,6 +3313,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
becameAbsent |= ABSENT_SIM_STATE_LIST.contains(state);
+ // TODO(b/327476182): Preserve SIM_STATE_CARD_IO_ERROR sims in a separate data source.
SimData data = mSimDatas.get(subId);
final boolean changed;
if (data == null) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
index 77054bd29147..2000028dff41 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
@@ -88,10 +88,6 @@ public class KeyguardVisibilityHelper {
boolean keyguardFadingAway,
boolean goingToFullShade,
int oldStatusBarState) {
- if (migrateClocksToBlueprint()) {
- log("Ignoring all of KeyguardVisibilityelper");
- return;
- }
Assert.isMainThread();
PropertyAnimator.cancelAnimation(mView, AnimatableProperty.ALPHA);
boolean isOccluded = mKeyguardStateController.isOccluded();
diff --git a/packages/SystemUI/src/com/android/systemui/camera/CameraRotationModule.kt b/packages/SystemUI/src/com/android/systemui/camera/CameraRotationModule.kt
new file mode 100644
index 000000000000..f12382801887
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/camera/CameraRotationModule.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.camera
+
+import com.android.systemui.camera.data.repository.CameraAutoRotateRepository
+import com.android.systemui.camera.data.repository.CameraAutoRotateRepositoryImpl
+import com.android.systemui.camera.data.repository.CameraSensorPrivacyRepository
+import com.android.systemui.camera.data.repository.CameraSensorPrivacyRepositoryImpl
+import dagger.Binds
+import dagger.Module
+
+/** Module for repositories that provide data regarding camera rotation state. */
+@Module
+interface CameraRotationModule {
+
+ @Binds
+ fun bindsPrivacyRepoImpl(impl: CameraSensorPrivacyRepositoryImpl): CameraSensorPrivacyRepository
+ @Binds fun bindsRotateRepoImpl(impl: CameraAutoRotateRepositoryImpl): CameraAutoRotateRepository
+}
diff --git a/packages/SystemUI/src/com/android/systemui/camera/data/repository/CameraAutoRotateRepository.kt b/packages/SystemUI/src/com/android/systemui/camera/data/repository/CameraAutoRotateRepository.kt
new file mode 100644
index 000000000000..023fd285c6d8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/camera/data/repository/CameraAutoRotateRepository.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.camera.data.repository
+
+import android.os.UserHandle
+import android.provider.Settings
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.util.settings.SecureSettings
+import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
+import javax.inject.Inject
+import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onStart
+import kotlinx.coroutines.flow.stateIn
+
+interface CameraAutoRotateRepository {
+ /** @return true if camera auto rotate setting is enabled */
+ fun isCameraAutoRotateSettingEnabled(userHandle: UserHandle): StateFlow<Boolean>
+}
+
+@SysUISingleton
+class CameraAutoRotateRepositoryImpl
+@Inject
+constructor(
+ private val secureSettings: SecureSettings,
+ @Background private val bgCoroutineContext: CoroutineContext,
+ @Application private val applicationScope: CoroutineScope,
+) : CameraAutoRotateRepository {
+ private val userMap = mutableMapOf<Int, StateFlow<Boolean>>()
+
+ override fun isCameraAutoRotateSettingEnabled(userHandle: UserHandle): StateFlow<Boolean> {
+ return userMap.getOrPut(userHandle.identifier) {
+ secureSettings
+ .observerFlow(userHandle.identifier, Settings.Secure.CAMERA_AUTOROTATE)
+ .map { isAutoRotateSettingEnabled(userHandle.identifier) }
+ .onStart { emit(isAutoRotateSettingEnabled(userHandle.identifier)) }
+ .flowOn(bgCoroutineContext)
+ .stateIn(applicationScope, SharingStarted.WhileSubscribed(), false)
+ }
+ }
+
+ private fun isAutoRotateSettingEnabled(userId: Int) =
+ secureSettings.getIntForUser(SETTING_NAME, DISABLED, userId) == ENABLED
+
+ private companion object {
+ const val SETTING_NAME = Settings.Secure.CAMERA_AUTOROTATE
+ const val DISABLED = 0
+ const val ENABLED = 1
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/camera/data/repository/CameraSensorPrivacyRepository.kt b/packages/SystemUI/src/com/android/systemui/camera/data/repository/CameraSensorPrivacyRepository.kt
new file mode 100644
index 000000000000..7816a1487c01
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/camera/data/repository/CameraSensorPrivacyRepository.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.camera.data.repository
+
+import android.hardware.SensorPrivacyManager
+import android.hardware.SensorPrivacyManager.Sensors.CAMERA
+import android.os.UserHandle
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import javax.inject.Inject
+import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.onStart
+import kotlinx.coroutines.flow.stateIn
+
+interface CameraSensorPrivacyRepository {
+ /** Tracks whether camera sensor privacy is enabled. */
+ fun isEnabled(userHandle: UserHandle): StateFlow<Boolean>
+}
+
+@SysUISingleton
+class CameraSensorPrivacyRepositoryImpl
+@Inject
+constructor(
+ @Background private val bgCoroutineContext: CoroutineContext,
+ @Application private val scope: CoroutineScope,
+ private val privacyManager: SensorPrivacyManager,
+) : CameraSensorPrivacyRepository {
+ private val userMap = mutableMapOf<Int, StateFlow<Boolean>>()
+
+ /** Whether camera sensor privacy is enabled */
+ override fun isEnabled(userHandle: UserHandle): StateFlow<Boolean> =
+ userMap.getOrPut(userHandle.identifier) {
+ privacyManager
+ .isEnabled(userHandle)
+ .flowOn(bgCoroutineContext)
+ .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+ }
+}
+
+fun SensorPrivacyManager.isEnabled(userHandle: UserHandle): Flow<Boolean> {
+ return conflatedCallbackFlow {
+ val privacyCallback =
+ SensorPrivacyManager.OnSensorPrivacyChangedListener { sensor, enabled ->
+ if (sensor == CAMERA) {
+ trySend(enabled)
+ }
+ }
+ addSensorPrivacyListener(CAMERA, userHandle.identifier, privacyCallback)
+ awaitClose { removeSensorPrivacyListener(privacyCallback) }
+ }
+ .onStart { emit(isSensorPrivacyEnabled(SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE, CAMERA)) }
+ .distinctUntilChanged()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
index d5cb4d5a6b2f..c3c7411c401d 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
@@ -24,18 +24,15 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dock.DockManager
-import com.android.systemui.dock.retrieveIsDocked
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionStep
-import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapLatest
@@ -66,19 +63,21 @@ constructor(
.onEach { nextScene -> communalInteractor.onSceneChanged(nextScene) }
.launchIn(applicationScope)
+ // TODO(b/322787129): re-enable once custom animations are in place
// Handle automatically switching to communal when docked.
- dockManager
- .retrieveIsDocked()
- // Allow some time after docking to ensure the dream doesn't start. If the dream
- // starts, then we don't want to automatically transition to glanceable hub.
- .debounce(DOCK_DEBOUNCE_DELAY)
- .sample(keyguardTransitionInteractor.startedKeyguardState, ::Pair)
- .onEach { (docked, lastStartedState) ->
- if (docked && lastStartedState == KeyguardState.LOCKSCREEN) {
- communalInteractor.onSceneChanged(CommunalScenes.Communal)
- }
- }
- .launchIn(bgScope)
+ // dockManager
+ // .retrieveIsDocked()
+ // // Allow some time after docking to ensure the dream doesn't start. If the
+ // dream
+ // // starts, then we don't want to automatically transition to glanceable hub.
+ // .debounce(DOCK_DEBOUNCE_DELAY)
+ // .sample(keyguardTransitionInteractor.startedKeyguardState, ::Pair)
+ // .onEach { (docked, lastStartedState) ->
+ // if (docked && lastStartedState == KeyguardState.LOCKSCREEN) {
+ // communalInteractor.onSceneChanged(CommunalScenes.Communal)
+ // }
+ // }
+ // .launchIn(bgScope)
}
private suspend fun determineSceneAfterTransition(
@@ -89,7 +88,7 @@ constructor(
val docked = dockManager.isDocked
return when {
- docked && to == KeyguardState.LOCKSCREEN && from != KeyguardState.GLANCEABLE_HUB -> {
+ docked && to == KeyguardState.LOCKSCREEN && from == KeyguardState.DREAMING -> {
CommunalScenes.Communal
}
to == KeyguardState.GONE -> CommunalScenes.Blank
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
index fc9a7df4744d..35b27aaeb6bc 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
@@ -21,6 +21,7 @@ import com.android.systemui.communal.domain.interactor.CommunalTutorialInteracto
import com.android.systemui.communal.domain.model.CommunalContentModel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.Logger
import com.android.systemui.log.dagger.CommunalLog
@@ -46,6 +47,7 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
/** The default view model used for showing the communal hub. */
+@OptIn(ExperimentalCoroutinesApi::class)
@SysUISingleton
class CommunalViewModel
@Inject
@@ -54,6 +56,7 @@ constructor(
private val communalInteractor: CommunalInteractor,
tutorialInteractor: CommunalTutorialInteractor,
shadeInteractor: ShadeInteractor,
+ deviceEntryInteractor: DeviceEntryInteractor,
@Named(MediaModule.COMMUNAL_HUB) mediaHost: MediaHost,
@CommunalLog logBuffer: LogBuffer,
) : BaseCommunalViewModel(communalInteractor, mediaHost) {
@@ -87,6 +90,8 @@ constructor(
/** Whether touches should be disabled in communal */
val touchesAllowed: Flow<Boolean> = not(shadeInteractor.isAnyFullyExpanded)
+ val deviceUnlocked: Flow<Boolean> = deviceEntryInteractor.isUnlocked
+
init {
// Initialize our media host for the UMO. This only needs to happen once and must be done
// before the MediaHierarchyManager attempts to move the UMO to the hub.
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
index f7bc5cdc69c2..a4011fd7718c 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
@@ -43,6 +43,7 @@ import com.android.systemui.reardisplay.RearDisplayModule;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsImplementation;
import com.android.systemui.rotationlock.RotationLockModule;
+import com.android.systemui.rotationlock.RotationLockNewModule;
import com.android.systemui.scene.SceneContainerFrameworkModule;
import com.android.systemui.screenshot.ReferenceScreenshotModule;
import com.android.systemui.settings.MultiUserUtilsModule;
@@ -110,6 +111,7 @@ import javax.inject.Named;
RearDisplayModule.class,
ReferenceScreenshotModule.class,
RotationLockModule.class,
+ RotationLockNewModule.class,
ScreenDecorationsModule.class,
SystemActionsModule.class,
ShadeModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeyDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeyDialogFactory.kt
index 3501f5125ee7..89433d3e8abb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeyDialogFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeyDialogFactory.kt
@@ -46,7 +46,7 @@ constructor(
}
private fun createStickyKeyIndicator(viewModel: StickyKeysIndicatorViewModel): Dialog {
- return ComponentDialog(context, R.style.Theme_SystemUI_Dialog).apply {
+ return ComponentDialog(context, R.style.Theme_SystemUI_Dialog_StickyKeys).apply {
// because we're requesting window feature it must be called before setting content
window?.setStickyKeyWindowAttributes()
setContentView(createStickyKeyIndicatorView(context, viewModel))
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
index ad0c3fb0c53a..64e28700aa74 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
@@ -24,6 +24,7 @@ import com.android.systemui.biometrics.AuthController
import com.android.systemui.biometrics.data.repository.FacePropertyRepository
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.common.shared.model.Position
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Main
@@ -79,6 +80,12 @@ interface KeyguardRepository {
val keyguardAlpha: StateFlow<Float>
/**
+ * Observable of the relative offset of the lock-screen clock from its natural position on the
+ * screen.
+ */
+ val clockPosition: StateFlow<Position>
+
+ /**
* Observable for whether the keyguard is showing.
*
* Note: this is also `true` when the lock-screen is occluded with an `Activity` "above" it in
@@ -233,6 +240,11 @@ interface KeyguardRepository {
fun setKeyguardAlpha(alpha: Float)
/**
+ * Sets the relative offset of the lock-screen clock from its natural position on the screen.
+ */
+ fun setClockPosition(x: Int, y: Int)
+
+ /**
* Returns whether the keyguard bottom area should be constrained to the top of the lock icon
*/
fun isUdfpsSupported(): Boolean
@@ -311,6 +323,9 @@ constructor(
private val _keyguardAlpha = MutableStateFlow(1f)
override val keyguardAlpha = _keyguardAlpha.asStateFlow()
+ private val _clockPosition = MutableStateFlow(Position(0, 0))
+ override val clockPosition = _clockPosition.asStateFlow()
+
private val _clockShouldBeCentered = MutableStateFlow(true)
override val clockShouldBeCentered: Flow<Boolean> = _clockShouldBeCentered.asStateFlow()
@@ -662,6 +677,10 @@ constructor(
_keyguardAlpha.value = alpha
}
+ override fun setClockPosition(x: Int, y: Int) {
+ _clockPosition.value = Position(x, y)
+ }
+
override fun isUdfpsSupported(): Boolean = keyguardUpdateMonitor.isUdfpsSupported
override fun setQuickSettingsVisible(isVisible: Boolean) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt
index ee892a800b63..7ae70a9a3e7c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt
@@ -63,19 +63,18 @@ constructor(
burnInHelperWrapper.burnInProgressOffset()
)
- /** Given the max x,y dimens, determine the current translation shifts. */
- fun burnIn(xDimenResourceId: Int, yDimenResourceId: Int): Flow<BurnInModel> {
- return combine(
- burnInOffset(xDimenResourceId, isXAxis = true),
- burnInOffset(yDimenResourceId, isXAxis = false).map {
- it * 2 - context.resources.getDimensionPixelSize(yDimenResourceId)
+ val keyguardBurnIn: Flow<BurnInModel> =
+ combine(
+ burnInOffset(R.dimen.burn_in_prevention_offset_x, isXAxis = true),
+ burnInOffset(R.dimen.burn_in_prevention_offset_y, isXAxis = false).map {
+ it * 2 -
+ context.resources.getDimensionPixelSize(R.dimen.burn_in_prevention_offset_y)
}
) { translationX, translationY ->
BurnInModel(translationX, translationY, burnInHelperWrapper.burnInScale())
}
.distinctUntilChanged()
.stateIn(scope, SharingStarted.Lazily, BurnInModel())
- }
/**
* Use for max burn-in offsets that are NOT specified in pixels. This flow will recalculate the
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
index 617982f8532c..dbd5e26eacfc 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
@@ -93,14 +93,22 @@ constructor(
startedKeyguardTransitionStep,
keyguardInteractor.isKeyguardOccluded,
keyguardInteractor.biometricUnlockState,
+ keyguardInteractor.primaryBouncerShowing,
)
- .collect { (_, isKeyguardShowing, lastStartedStep, occluded, biometricUnlockState)
- ->
+ .collect {
+ (
+ _,
+ isKeyguardShowing,
+ lastStartedStep,
+ occluded,
+ biometricUnlockState,
+ primaryBouncerShowing) ->
if (
lastStartedStep.to == KeyguardState.AOD &&
!occluded &&
!isWakeAndUnlock(biometricUnlockState) &&
- isKeyguardShowing
+ isKeyguardShowing &&
+ !primaryBouncerShowing
) {
val modeOnCanceled =
if (lastStartedStep.from == KeyguardState.LOCKSCREEN) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
index baa865d22f70..8591fe782d3a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
@@ -31,6 +31,8 @@ import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.launch
@@ -59,6 +61,14 @@ constructor(
listenForTransitionToCamera(scope, keyguardInteractor)
}
+ private val canDismissLockScreen: Flow<Boolean> =
+ combine(
+ keyguardInteractor.isKeyguardShowing,
+ keyguardInteractor.isKeyguardDismissible,
+ ) { isKeyguardShowing, isKeyguardDismissible ->
+ isKeyguardDismissible && !isKeyguardShowing
+ }
+
private fun listenForDozingToAny() {
scope.launch {
powerInteractor.isAwake
@@ -68,8 +78,8 @@ constructor(
startedKeyguardTransitionStep,
keyguardInteractor.isKeyguardOccluded,
communalInteractor.isIdleOnCommunal,
- keyguardInteractor.isKeyguardShowing,
- keyguardInteractor.isKeyguardDismissible,
+ canDismissLockScreen,
+ keyguardInteractor.primaryBouncerShowing,
)
.collect {
(
@@ -78,16 +88,18 @@ constructor(
lastStartedTransition,
occluded,
isIdleOnCommunal,
- isKeyguardShowing,
- isKeyguardDismissible) ->
+ canDismissLockScreen,
+ primaryBouncerShowing) ->
if (!(isAwake && lastStartedTransition.to == KeyguardState.DOZING)) {
return@collect
}
startTransitionTo(
if (isWakeAndUnlock(biometricUnlockState)) {
KeyguardState.GONE
- } else if (isKeyguardDismissible && !isKeyguardShowing) {
+ } else if (canDismissLockScreen) {
KeyguardState.GONE
+ } else if (primaryBouncerShowing) {
+ KeyguardState.PRIMARY_BOUNCER
} else if (occluded) {
KeyguardState.OCCLUDED
} else if (isIdleOnCommunal) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBottomAreaInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBottomAreaInteractor.kt
index e5bb5a081b70..d2a7486eed0b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBottomAreaInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBottomAreaInteractor.kt
@@ -22,8 +22,6 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.data.repository.KeyguardRepository
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.asStateFlow
/** Encapsulates business-logic specifically related to the keyguard bottom area. */
@SysUISingleton
@@ -37,12 +35,10 @@ constructor(
/** The amount of alpha for the UI components of the bottom area. */
val alpha: Flow<Float> = repository.bottomAreaAlpha
/** The position of the keyguard clock. */
- private val _clockPosition = MutableStateFlow(Position(0, 0))
- @Deprecated("with migrateClocksToBlueprint()")
- val clockPosition: Flow<Position> = _clockPosition.asStateFlow()
+ val clockPosition: Flow<Position> = repository.clockPosition
fun setClockPosition(x: Int, y: Int) {
- _clockPosition.value = Position(x, y)
+ repository.setClockPosition(x, y)
}
fun setAlpha(alpha: Float) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
index fbf1e22ad3e1..5410b10a4b93 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
@@ -27,6 +27,7 @@ import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.common.shared.model.NotificationContainerBounds
+import com.android.systemui.common.shared.model.Position
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.data.repository.KeyguardRepository
@@ -231,6 +232,9 @@ constructor(
/** The approximate location on the screen of the face unlock sensor, if one is available. */
val faceSensorLocation: Flow<Point?> = repository.faceSensorLocation
+ /** The position of the keyguard clock. */
+ val clockPosition: Flow<Position> = repository.clockPosition
+
@Deprecated("Use the relevant TransitionViewModel")
val keyguardAlpha: Flow<Float> = repository.keyguardAlpha
@@ -338,6 +342,10 @@ constructor(
repository.setQuickSettingsVisible(isVisible)
}
+ fun setClockPosition(x: Int, y: Int) {
+ repository.setClockPosition(x, y)
+ }
+
fun setAlpha(alpha: Float) {
repository.setKeyguardAlpha(alpha)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBlueprintViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBlueprintViewBinder.kt
index 462d5e6568b0..4812e03ec3f6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBlueprintViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBlueprintViewBinder.kt
@@ -42,7 +42,7 @@ import kotlin.math.max
import kotlinx.coroutines.launch
private const val TAG = "KeyguardBlueprintViewBinder"
-private const val DEBUG = true
+private const val DEBUG = false
@SysUISingleton
class KeyguardBlueprintViewBinder
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt
index e67a3245bc85..98bebd091f1a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt
@@ -21,8 +21,6 @@ import android.content.Context
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
-import androidx.constraintlayout.widget.ConstraintSet.BOTTOM
-import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
import com.android.systemui.Flags.migrateClocksToBlueprint
import com.android.systemui.keyguard.shared.model.KeyguardSection
import com.android.systemui.keyguard.ui.view.KeyguardRootView
@@ -39,18 +37,13 @@ constructor(
private val clockViewModel: KeyguardClockViewModel,
) : KeyguardSection() {
private lateinit var burnInLayer: AodBurnInLayer
- private lateinit var emptyView: View
override fun addViews(constraintLayout: ConstraintLayout) {
if (!migrateClocksToBlueprint()) {
return
}
// The burn-in layer requires at least 1 view at all times
- emptyView =
- View(context, null).apply {
- id = R.id.burn_in_layer_empty_view
- visibility = View.GONE
- }
+ val emptyView = View(context, null).apply { id = View.generateViewId() }
constraintLayout.addView(emptyView)
burnInLayer =
AodBurnInLayer(context).apply {
@@ -77,13 +70,6 @@ constructor(
if (!migrateClocksToBlueprint()) {
return
}
-
- constraintSet.apply {
- // The empty view should not occupy any space
- constrainHeight(R.id.burn_in_layer_empty_view, 1)
- constrainWidth(R.id.burn_in_layer_empty_view, 0)
- connect(R.id.burn_in_layer_empty_view, BOTTOM, PARENT_ID, BOTTOM)
- }
}
override fun removeViews(constraintLayout: ConstraintLayout) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt
index 4ddd039edbaa..6184c82cbff7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt
@@ -199,7 +199,7 @@ class ClockSizeTransition(
private val TRANSITION_PROPERTIES =
arrayOf(PROP_VISIBILITY, PROP_ALPHA, PROP_BOUNDS, SMARTSPACE_BOUNDS)
- private val DEBUG = true
+ private val DEBUG = false
private val TAG = VisibilityBoundsTransition::class.simpleName!!
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt
index 62fc1da5a444..7be390a4526f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt
@@ -18,7 +18,6 @@
package com.android.systemui.keyguard.ui.viewmodel
-import android.util.Log
import android.util.MathUtils
import com.android.app.animation.Interpolators
import com.android.keyguard.KeyguardClockSwitch
@@ -63,8 +62,6 @@ constructor(
private val occludedToLockscreenTransitionViewModel: OccludedToLockscreenTransitionViewModel,
private val keyguardClockViewModel: KeyguardClockViewModel,
) {
- private val TAG = "AodBurnInViewModel"
-
/** Horizontal translation for elements that need to apply anti-burn-in tactics. */
fun translationX(
params: BurnInParameters,
@@ -74,17 +71,8 @@ constructor(
/** Vertical translation for elements that need to apply anti-burn-in tactics. */
fun translationY(
- burnInParams: BurnInParameters,
+ params: BurnInParameters,
): Flow<Float> {
- val params =
- if (burnInParams.minViewY < burnInParams.topInset) {
- // minViewY should never be below the inset. Correct it if needed
- Log.w(TAG, "minViewY is below topInset: $burnInParams")
- burnInParams.copy(minViewY = burnInParams.topInset)
- } else {
- burnInParams
- }
-
return configurationInteractor
.dimensionPixelSize(R.dimen.keyguard_enter_from_top_translation_y)
.flatMapLatest { enterFromTopAmount ->
@@ -137,10 +125,7 @@ constructor(
keyguardTransitionInteractor.dozeAmountTransition.map {
Interpolators.FAST_OUT_SLOW_IN.getInterpolation(it.value)
},
- burnInInteractor.burnIn(
- xDimenResourceId = R.dimen.burn_in_prevention_offset_x,
- yDimenResourceId = R.dimen.burn_in_prevention_offset_y
- )
+ burnInInteractor.keyguardBurnIn,
) { interpolated, burnIn ->
val useScaleOnly =
(clockController(params.clockControllerProvider)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
index 31e809356e02..bd19c8006e23 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
@@ -180,7 +180,7 @@ constructor(
}
private val isUnlocked: Flow<Boolean> =
- deviceEntryInteractor.isUnlocked.flatMapLatest { isUnlocked ->
+ keyguardInteractor.isKeyguardDismissible.flatMapLatest { isUnlocked ->
if (!isUnlocked) {
flowOf(false)
} else {
@@ -197,7 +197,7 @@ constructor(
val iconType: Flow<DeviceEntryIconView.IconType> =
combine(
deviceEntryUdfpsInteractor.isListeningForUdfps,
- keyguardInteractor.isKeyguardDismissible,
+ isUnlocked,
) { isListeningForUdfps, isUnlocked ->
if (isListeningForUdfps) {
DeviceEntryIconView.IconType.FINGERPRINT
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt
index e35e06533f8c..6458edaecd9e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt
@@ -17,14 +17,10 @@
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.Flags.keyguardBottomAreaRefactor
-import com.android.systemui.Flags.migrateClocksToBlueprint
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.doze.util.BurnInHelperWrapper
-import com.android.systemui.keyguard.domain.interactor.BurnInInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
-import com.android.systemui.keyguard.shared.model.BurnInModel
-import com.android.systemui.res.R
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
@@ -36,10 +32,9 @@ class KeyguardIndicationAreaViewModel
@Inject
constructor(
private val keyguardInteractor: KeyguardInteractor,
- private val bottomAreaInteractor: KeyguardBottomAreaInteractor,
+ bottomAreaInteractor: KeyguardBottomAreaInteractor,
keyguardBottomAreaViewModel: KeyguardBottomAreaViewModel,
private val burnInHelperWrapper: BurnInHelperWrapper,
- private val burnInInteractor: BurnInInteractor,
private val shortcutsCombinedViewModel: KeyguardQuickAffordancesCombinedViewModel,
configurationInteractor: ConfigurationInteractor,
) {
@@ -68,37 +63,24 @@ constructor(
}
.distinctUntilChanged()
}
-
- private val burnIn: Flow<BurnInModel> =
- burnInInteractor
- .burnIn(
- xDimenResourceId = R.dimen.burn_in_prevention_offset_x,
- yDimenResourceId = R.dimen.default_burn_in_prevention_offset,
- )
- .distinctUntilChanged()
-
/** An observable for the x-offset by which the indication area should be translated. */
val indicationAreaTranslationX: Flow<Float> =
- if (migrateClocksToBlueprint() || keyguardBottomAreaRefactor()) {
- burnIn.map { it.translationX.toFloat() }
+ if (keyguardBottomAreaRefactor()) {
+ keyguardInteractor.clockPosition.map { it.x.toFloat() }.distinctUntilChanged()
} else {
bottomAreaInteractor.clockPosition.map { it.x.toFloat() }.distinctUntilChanged()
}
/** Returns an observable for the y-offset by which the indication area should be translated. */
fun indicationAreaTranslationY(defaultBurnInOffset: Int): Flow<Float> {
- return if (migrateClocksToBlueprint()) {
- burnIn.map { it.translationY.toFloat() }
- } else {
- keyguardInteractor.dozeAmount
- .map { dozeAmount ->
- dozeAmount *
- (burnInHelperWrapper.burnInOffset(
- /* amplitude = */ defaultBurnInOffset * 2,
- /* xAxis= */ false,
- ) - defaultBurnInOffset)
- }
- .distinctUntilChanged()
- }
+ return keyguardInteractor.dozeAmount
+ .map { dozeAmount ->
+ dozeAmount *
+ (burnInHelperWrapper.burnInOffset(
+ /* amplitude = */ defaultBurnInOffset * 2,
+ /* xAxis= */ false,
+ ) - defaultBurnInOffset)
+ }
+ .distinctUntilChanged()
}
}
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 38d5e0f74b28..1760b927a6cd 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
@@ -75,6 +75,7 @@ constructor(
private val aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel,
private val dozingToGoneTransitionViewModel: DozingToGoneTransitionViewModel,
private val dozingToLockscreenTransitionViewModel: DozingToLockscreenTransitionViewModel,
+ private val dreamingToLockscreenTransitionViewModel: DreamingToLockscreenTransitionViewModel,
private val glanceableHubToLockscreenTransitionViewModel:
GlanceableHubToLockscreenTransitionViewModel,
private val goneToAodTransitionViewModel: GoneToAodTransitionViewModel,
@@ -171,6 +172,7 @@ constructor(
aodToLockscreenTransitionViewModel.lockscreenAlpha(viewState),
dozingToGoneTransitionViewModel.lockscreenAlpha(viewState),
dozingToLockscreenTransitionViewModel.lockscreenAlpha,
+ dreamingToLockscreenTransitionViewModel.lockscreenAlpha,
glanceableHubToLockscreenTransitionViewModel.keyguardAlpha,
goneToAodTransitionViewModel.enterFromTopAnimationAlpha,
goneToDozingTransitionViewModel.lockscreenAlpha,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractor.kt
new file mode 100644
index 000000000000..736e1a5cb9b6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractor.kt
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.impl.rotation.domain.interactor
+
+import android.Manifest
+import android.content.pm.PackageManager
+import android.content.res.Resources
+import android.os.UserHandle
+import com.android.systemui.camera.data.repository.CameraAutoRotateRepository
+import com.android.systemui.camera.data.repository.CameraSensorPrivacyRepository
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.impl.rotation.domain.model.RotationLockTileModel
+import com.android.systemui.statusbar.policy.BatteryController
+import com.android.systemui.statusbar.policy.RotationLockController
+import com.android.systemui.util.kotlin.isBatteryPowerSaveEnabled
+import com.android.systemui.util.kotlin.isRotationLockEnabled
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flowOf
+
+/** Observes rotation lock state changes providing the [RotationLockTileModel]. */
+class RotationLockTileDataInteractor
+@Inject
+constructor(
+ private val rotationLockController: RotationLockController,
+ private val batteryController: BatteryController,
+ private val cameraAutoRotateRepository: CameraAutoRotateRepository,
+ private val cameraSensorPrivacyRepository: CameraSensorPrivacyRepository,
+ private val packageManager: PackageManager,
+ @Main private val resources: Resources,
+) : QSTileDataInteractor<RotationLockTileModel> {
+
+ override fun tileData(
+ user: UserHandle,
+ triggers: Flow<DataUpdateTrigger>
+ ): Flow<RotationLockTileModel> =
+ combine(
+ rotationLockController.isRotationLockEnabled(),
+ cameraSensorPrivacyRepository.isEnabled(user),
+ batteryController.isBatteryPowerSaveEnabled(),
+ cameraAutoRotateRepository.isCameraAutoRotateSettingEnabled(user)
+ ) {
+ isRotationLockEnabled,
+ isCamPrivacySensorEnabled,
+ isBatteryPowerSaveEnabled,
+ isCameraAutoRotateEnabled,
+ ->
+ RotationLockTileModel(
+ isRotationLockEnabled,
+ isCameraRotationEnabled(
+ isBatteryPowerSaveEnabled,
+ isCamPrivacySensorEnabled,
+ isCameraAutoRotateEnabled
+ ),
+ )
+ }
+
+ override fun availability(user: UserHandle): Flow<Boolean> = flowOf(true)
+
+ private fun hasSufficientPermission(): Boolean {
+ val rotationPackage: String = packageManager.rotationResolverPackageName
+ return rotationPackage != null &&
+ packageManager.checkPermission(Manifest.permission.CAMERA, rotationPackage) ==
+ PackageManager.PERMISSION_GRANTED
+ }
+
+ private fun isCameraRotationEnabled(
+ isBatteryPowerSaverModeOn: Boolean,
+ isCameraSensorPrivacyEnabled: Boolean,
+ isCameraAutoRotateEnabled: Boolean
+ ): Boolean =
+ resources.getBoolean(com.android.internal.R.bool.config_allowRotationResolver) &&
+ !isBatteryPowerSaverModeOn &&
+ !isCameraSensorPrivacyEnabled &&
+ hasSufficientPermission() &&
+ isCameraAutoRotateEnabled
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractor.kt
new file mode 100644
index 000000000000..8530926e68e0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractor.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.impl.rotation.domain.interactor
+
+import android.content.Intent
+import android.provider.Settings
+import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.interactor.QSTileInput
+import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.impl.rotation.domain.model.RotationLockTileModel
+import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+import com.android.systemui.statusbar.policy.RotationLockController
+import javax.inject.Inject
+
+/** Handles rotation lock tile clicks. */
+class RotationLockTileUserActionInteractor
+@Inject
+constructor(
+ private val controller: RotationLockController,
+ private val qsTileIntentUserActionHandler: QSTileIntentUserInputHandler,
+) : QSTileUserActionInteractor<RotationLockTileModel> {
+
+ override suspend fun handleInput(input: QSTileInput<RotationLockTileModel>) {
+ with(input) {
+ when (action) {
+ is QSTileUserAction.Click -> {
+ controller.setRotationLocked(!data.isRotationLocked, CALLER)
+ }
+ is QSTileUserAction.LongClick -> {
+ qsTileIntentUserActionHandler.handle(
+ action.view,
+ Intent(Settings.ACTION_AUTO_ROTATE_SETTINGS)
+ )
+ }
+ }
+ }
+ }
+
+ companion object {
+ private const val CALLER = "QSTileUserActionInteractor#handleInput"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/model/RotationLockTileModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/model/RotationLockTileModel.kt
new file mode 100644
index 000000000000..32e6cb8cb52c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/model/RotationLockTileModel.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.impl.rotation.domain.model
+
+/** Model for rotation lock tile */
+class RotationLockTileModel(
+ val isRotationLocked: Boolean,
+ val isCameraRotationEnabled: Boolean,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapper.kt
new file mode 100644
index 000000000000..070cdef336e5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapper.kt
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.impl.rotation.ui.mapper
+
+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.rotation.domain.model.RotationLockTileModel
+import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
+import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.policy.DevicePostureController
+import javax.inject.Inject
+
+/** Maps [RotationLockTileModel] to [QSTileState]. */
+class RotationLockTileMapper
+@Inject
+constructor(
+ @Main private val resources: Resources,
+ private val theme: Resources.Theme,
+ private val devicePostureController: DevicePostureController
+) : QSTileDataToStateMapper<RotationLockTileModel> {
+ override fun map(config: QSTileConfig, data: RotationLockTileModel): QSTileState =
+ QSTileState.build(resources, theme, config.uiConfig) {
+ this.label = resources.getString(R.string.quick_settings_rotation_unlocked_label)
+ this.contentDescription =
+ resources.getString(R.string.accessibility_quick_settings_rotation)
+
+ if (data.isRotationLocked) {
+ activationState = QSTileState.ActivationState.INACTIVE
+ this.secondaryLabel = EMPTY_SECONDARY_STRING
+ this.icon = {
+ Icon.Loaded(
+ resources.getDrawable(R.drawable.qs_auto_rotate_icon_off, theme),
+ contentDescription = null
+ )
+ }
+ } else {
+ activationState = QSTileState.ActivationState.ACTIVE
+ this.secondaryLabel =
+ if (data.isCameraRotationEnabled) {
+ resources.getString(R.string.rotation_lock_camera_rotation_on)
+ } else {
+ EMPTY_SECONDARY_STRING
+ }
+ this.icon = {
+ Icon.Loaded(
+ resources.getDrawable(R.drawable.qs_auto_rotate_icon_on, theme),
+ contentDescription = null
+ )
+ }
+ }
+ if (isDeviceFoldable()) {
+ this.secondaryLabel = getSecondaryLabelWithPosture(this.activationState)
+ }
+ this.stateDescription = this.secondaryLabel
+ this.sideViewIcon = QSTileState.SideViewIcon.None
+ supportedActions =
+ setOf(QSTileState.UserAction.CLICK, QSTileState.UserAction.LONG_CLICK)
+ }
+
+ private fun isDeviceFoldable(): Boolean {
+ val intArray = resources.getIntArray(com.android.internal.R.array.config_foldedDeviceStates)
+ return intArray.isNotEmpty()
+ }
+
+ private fun getSecondaryLabelWithPosture(activationState: QSTileState.ActivationState): String {
+ val stateNames = resources.getStringArray(R.array.tile_states_rotation)
+ val stateName =
+ stateNames[
+ if (activationState == QSTileState.ActivationState.ACTIVE) ON_INDEX else OFF_INDEX]
+ val posture =
+ if (
+ devicePostureController.devicePosture ==
+ DevicePostureController.DEVICE_POSTURE_CLOSED
+ )
+ resources.getString(R.string.quick_settings_rotation_posture_folded)
+ else resources.getString(R.string.quick_settings_rotation_posture_unfolded)
+
+ return resources.getString(
+ R.string.rotation_tile_with_posture_secondary_label_template,
+ stateName,
+ posture
+ )
+ }
+
+ private companion object {
+ const val EMPTY_SECONDARY_STRING = ""
+ const val OFF_INDEX = 1
+ const val ON_INDEX = 2
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockNewModule.kt b/packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockNewModule.kt
new file mode 100644
index 000000000000..eb64dd609a72
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockNewModule.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.rotationlock
+
+import com.android.systemui.camera.CameraRotationModule
+import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory
+import com.android.systemui.qs.tiles.impl.rotation.domain.interactor.RotationLockTileDataInteractor
+import com.android.systemui.qs.tiles.impl.rotation.domain.interactor.RotationLockTileUserActionInteractor
+import com.android.systemui.qs.tiles.impl.rotation.domain.model.RotationLockTileModel
+import com.android.systemui.qs.tiles.impl.rotation.ui.mapper.RotationLockTileMapper
+import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
+import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
+import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
+import com.android.systemui.res.R
+import dagger.Module
+import dagger.Provides
+import dagger.multibindings.IntoMap
+import dagger.multibindings.StringKey
+
+@Module(includes = [CameraRotationModule::class])
+interface RotationLockNewModule {
+ companion object {
+ private const val ROTATION_TILE_SPEC = "rotation"
+
+ /** Inject rotation tile config */
+ @Provides
+ @IntoMap
+ @StringKey(ROTATION_TILE_SPEC)
+ fun provideRotationTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
+ QSTileConfig(
+ tileSpec = TileSpec.create(ROTATION_TILE_SPEC),
+ uiConfig =
+ QSTileUIConfig.Resource(
+ iconRes = R.drawable.qs_auto_rotate_icon_off,
+ labelRes = R.string.quick_settings_rotation_unlocked_label,
+ ),
+ instanceId = uiEventLogger.getNewInstanceId(),
+ )
+
+ /** Inject Rotation tile into tileViewModelMap in QSModule */
+ @Provides
+ @IntoMap
+ @StringKey(ROTATION_TILE_SPEC)
+ fun provideRotationTileViewModel(
+ factory: QSTileViewModelFactory.Static<RotationLockTileModel>,
+ mapper: RotationLockTileMapper,
+ stateInteractor: RotationLockTileDataInteractor,
+ userActionInteractor: RotationLockTileUserActionInteractor
+ ): QSTileViewModel =
+ factory.create(
+ TileSpec.create(ROTATION_TILE_SPEC),
+ userActionInteractor,
+ stateInteractor,
+ mapper,
+ )
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
index 306aad131624..75bf131afdf9 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
@@ -156,6 +156,7 @@ constructor(
* desired scene. Once enough of the transition has occurred, the [currentScene] will become
* [toScene] (unless the transition is canceled by user action or another call to this method).
*/
+ @JvmOverloads
fun changeScene(
toScene: SceneKey,
loggingReason: String,
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt
index 22645c4532f6..ea19020d84d4 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt
@@ -71,7 +71,6 @@ open class WindowRootView(
override fun onApplyWindowInsets(windowInsets: WindowInsets): WindowInsets? {
val insets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars())
- val displayCutout = rootWindowInsets.displayCutout
if (fitsSystemWindows) {
val paddingChanged = insets.top != paddingTop || insets.bottom != paddingBottom
@@ -79,23 +78,22 @@ open class WindowRootView(
if (paddingChanged) {
setPadding(0, 0, 0, 0)
}
-
- val pairInsets: Pair<Int, Int> =
- layoutInsetsController.getinsets(windowInsets, displayCutout)
- leftInset = pairInsets.first
- rightInset = pairInsets.second
- applyMargins()
} else {
val changed =
paddingLeft != 0 || paddingRight != 0 || paddingTop != 0 || paddingBottom != 0
if (changed) {
setPadding(0, 0, 0, 0)
}
-
- leftInset = 0
- rightInset = 0
}
+ leftInset = 0
+ rightInset = 0
+ val displayCutout = rootWindowInsets.displayCutout
+ val pairInsets: Pair<Int, Int> =
+ layoutInsetsController.getinsets(windowInsets, displayCutout)
+ leftInset = pairInsets.first
+ rightInset = pairInsets.second
+ applyMargins()
return windowInsets
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 8ad7217246b8..13448d258a2c 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -578,7 +578,7 @@ public class ScreenshotController {
private void releaseMediaPlayer() {
if (mScreenshotSoundController == null) return;
- mScreenshotSoundController.releaseScreenshotSound();
+ mScreenshotSoundController.releaseScreenshotSoundAsync();
}
private void respondToKeyDismissal() {
@@ -891,7 +891,7 @@ public class ScreenshotController {
private void playCameraSoundIfNeeded() {
if (mScreenshotSoundController == null) return;
// the controller is not-null only on the default display controller
- mScreenshotSoundController.playCameraSound();
+ mScreenshotSoundController.playScreenshotSoundAsync();
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSoundController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSoundController.kt
index 2c0bddecc58e..d3a7fc4a3e4a 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSoundController.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSoundController.kt
@@ -21,22 +21,34 @@ import android.util.Log
import com.android.app.tracing.coroutines.async
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
-import com.google.errorprone.annotations.CanIgnoreReturnValue
import javax.inject.Inject
import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.TimeoutCancellationException
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeout
/** Controls sound reproduction after a screenshot is taken. */
interface ScreenshotSoundController {
/** Reproduces the camera sound. */
- @CanIgnoreReturnValue fun playCameraSound(): Deferred<Unit>
+ suspend fun playScreenshotSound()
- /** Releases the sound. [playCameraSound] behaviour is undefined after this has been called. */
- @CanIgnoreReturnValue fun releaseScreenshotSound(): Deferred<Unit>
+ /**
+ * Releases the sound. [playScreenshotSound] behaviour is undefined after this has been called.
+ */
+ suspend fun releaseScreenshotSound()
+
+ /** Reproduces the camera sound. Used for compatibility with Java code. */
+ fun playScreenshotSoundAsync()
+
+ /**
+ * Releases the sound. [playScreenshotSound] behaviour is undefined after this has been called.
+ * Used for compatibility with Java code.
+ */
+ fun releaseScreenshotSoundAsync()
}
class ScreenshotSoundControllerImpl
@@ -47,8 +59,8 @@ constructor(
@Background private val bgDispatcher: CoroutineDispatcher
) : ScreenshotSoundController {
- val player: Deferred<MediaPlayer?> =
- coroutineScope.async("loadCameraSound", bgDispatcher) {
+ private val player: Deferred<MediaPlayer?> =
+ coroutineScope.async("loadScreenshotSound", bgDispatcher) {
try {
soundProvider.getScreenshotSound()
} catch (e: IllegalStateException) {
@@ -57,8 +69,8 @@ constructor(
}
}
- override fun playCameraSound(): Deferred<Unit> {
- return coroutineScope.async("playCameraSound", bgDispatcher) {
+ override suspend fun playScreenshotSound() {
+ withContext(bgDispatcher) {
try {
player.await()?.start()
} catch (e: IllegalStateException) {
@@ -68,8 +80,8 @@ constructor(
}
}
- override fun releaseScreenshotSound(): Deferred<Unit> {
- return coroutineScope.async("releaseScreenshotSound", bgDispatcher) {
+ override suspend fun releaseScreenshotSound() {
+ withContext(bgDispatcher) {
try {
withTimeout(1.seconds) { player.await()?.release() }
} catch (e: TimeoutCancellationException) {
@@ -79,6 +91,14 @@ constructor(
}
}
+ override fun playScreenshotSoundAsync() {
+ coroutineScope.launch { playScreenshotSound() }
+ }
+
+ override fun releaseScreenshotSoundAsync() {
+ coroutineScope.launch { releaseScreenshotSound() }
+ }
+
private companion object {
const val TAG = "ScreenshotSoundControllerImpl"
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index cf7c3e019818..1566de58ef3a 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -1288,9 +1288,10 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mView.getContext().getDisplay());
mKeyguardStatusViewController = statusViewComponent.getKeyguardStatusViewController();
mKeyguardStatusViewController.init();
+ }
- mKeyguardStatusViewController.setSplitShadeEnabled(mSplitShadeEnabled);
- mKeyguardStatusViewController.getView().addOnLayoutChangeListener(
+ mKeyguardStatusViewController.setSplitShadeEnabled(mSplitShadeEnabled);
+ mKeyguardStatusViewController.getView().addOnLayoutChangeListener(
(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
int oldHeight = oldBottom - oldTop;
if (v.getHeight() != oldHeight) {
@@ -1298,8 +1299,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
}
});
- updateClockAppearance();
- }
+ updateClockAppearance();
}
@Override
@@ -1326,9 +1326,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
private void onSplitShadeEnabledChanged() {
mShadeLog.logSplitShadeChanged(mSplitShadeEnabled);
- if (!migrateClocksToBlueprint()) {
- mKeyguardStatusViewController.setSplitShadeEnabled(mSplitShadeEnabled);
- }
+ mKeyguardStatusViewController.setSplitShadeEnabled(mSplitShadeEnabled);
// Reset any left over overscroll state. It is a rare corner case but can happen.
mQsController.setOverScrollAmount(0);
mScrimController.setNotificationsOverScrollAmount(0);
@@ -1443,13 +1441,11 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mStatusBarStateListener.onDozeAmountChanged(mStatusBarStateController.getDozeAmount(),
mStatusBarStateController.getInterpolatedDozeAmount());
- if (!migrateClocksToBlueprint()) {
- mKeyguardStatusViewController.setKeyguardStatusViewVisibility(
- mBarState,
- false,
- false,
- mBarState);
- }
+ mKeyguardStatusViewController.setKeyguardStatusViewVisibility(
+ mBarState,
+ false,
+ false,
+ mBarState);
if (mKeyguardQsUserSwitchController != null) {
mKeyguardQsUserSwitchController.setKeyguardQsUserSwitchVisibility(
mBarState,
@@ -1669,11 +1665,13 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mKeyguardStatusViewController.setLockscreenClockY(
mClockPositionAlgorithm.getExpandedPreferredClockY());
}
- if (!(migrateClocksToBlueprint() || keyguardBottomAreaRefactor())) {
+ if (keyguardBottomAreaRefactor()) {
+ mKeyguardInteractor.setClockPosition(
+ mClockPositionResult.clockX, mClockPositionResult.clockY);
+ } else {
mKeyguardBottomAreaInteractor.setClockPosition(
mClockPositionResult.clockX, mClockPositionResult.clockY);
}
-
boolean animate = mNotificationStackScrollLayoutController.isAddOrRemoveAnimationPending();
boolean animateClock = (animate || mAnimateNextPositionUpdate) && shouldAnimateClockChange;
@@ -1751,11 +1749,13 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
}
private void updateKeyguardStatusViewAlignment(boolean animate) {
+ boolean shouldBeCentered = shouldKeyguardStatusViewBeCentered();
+ ConstraintLayout layout;
if (migrateClocksToBlueprint()) {
- return;
+ layout = mKeyguardViewConfigurator.getKeyguardRootView();
+ } else {
+ layout = mNotificationContainerParent;
}
- boolean shouldBeCentered = shouldKeyguardStatusViewBeCentered();
- ConstraintLayout layout = mNotificationContainerParent;
mKeyguardStatusViewController.updateAlignment(
layout, mSplitShadeEnabled, shouldBeCentered, animate);
mKeyguardUnfoldTransition.ifPresent(t -> t.setStatusViewCentered(shouldBeCentered));
@@ -3316,9 +3316,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
/** Updates the views to the initial state for the fold to AOD animation. */
@Override
public void prepareFoldToAodAnimation() {
- if (migrateClocksToBlueprint()) {
- return;
- }
// Force show AOD UI even if we are not locked
showAodUi();
@@ -3340,9 +3337,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
@Override
public void startFoldToAodAnimation(Runnable startAction, Runnable endAction,
Runnable cancelAction) {
- if (migrateClocksToBlueprint()) {
- return;
- }
final ViewPropertyAnimator viewAnimator = mView.animate();
viewAnimator.cancel();
viewAnimator
@@ -3378,9 +3372,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
/** Cancels fold to AOD transition and resets view state. */
@Override
public void cancelFoldToAodAnimation() {
- if (migrateClocksToBlueprint()) {
- return;
- }
cancelAnimation();
resetAlpha();
resetTranslation();
@@ -4455,13 +4446,11 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
}
}
- if (!migrateClocksToBlueprint()) {
- mKeyguardStatusViewController.setKeyguardStatusViewVisibility(
- statusBarState,
- keyguardFadingAway,
- goingToFullShade,
- mBarState);
- }
+ mKeyguardStatusViewController.setKeyguardStatusViewVisibility(
+ statusBarState,
+ keyguardFadingAway,
+ goingToFullShade,
+ mBarState);
if (!keyguardBottomAreaRefactor()) {
setKeyguardBottomAreaVisibility(statusBarState, goingToFullShade);
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
index 8f9cef37dac7..f7fed537a167 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
@@ -60,7 +60,6 @@ import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.res.R;
-import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.scene.shared.flag.SceneContainerFlags;
import com.android.systemui.scene.ui.view.WindowRootViewComponent;
import com.android.systemui.settings.UserTracker;
@@ -507,7 +506,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
private void applyFitsSystemWindows(NotificationShadeWindowState state) {
boolean fitsSystemWindows = !state.isKeyguardShowingAndNotOccluded();
- if (!SceneContainerFlag.isEnabled() && mWindowRootView != null
+ if (mWindowRootView != null
&& mWindowRootView.getFitsSystemWindows() != fitsSystemWindows) {
mWindowRootView.setFitsSystemWindows(fitsSystemWindows);
mWindowRootView.requestApplyInsets();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
index a4741a509d72..ef4e5308e18e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
@@ -482,42 +482,42 @@ public final class KeyboardShortcutListSearch {
context.getString(R.string.keyboard_shortcut_group_system),
new ArrayList<>());
List<ShortcutKeyGroupMultiMappingInfo> infoList = Arrays.asList(
- /* Access notification shade: Meta + N */
+ /* Access list of all apps and search (i.e. Search/Launcher): Meta */
new ShortcutKeyGroupMultiMappingInfo(
- context.getString(R.string.group_system_access_notification_shade),
+ context.getString(R.string.group_system_access_all_apps_search),
Arrays.asList(
- Pair.create(KeyEvent.KEYCODE_N, KeyEvent.META_META_ON))),
- /* Take a full screenshot: Meta + Ctrl + S */
+ Pair.create(KeyEvent.KEYCODE_UNKNOWN, KeyEvent.META_META_ON))),
+ /* Access home screen: Meta + H, Meta + Enter */
new ShortcutKeyGroupMultiMappingInfo(
- context.getString(R.string.group_system_full_screenshot),
+ context.getString(R.string.group_system_access_home_screen),
Arrays.asList(
- Pair.create(
- KeyEvent.KEYCODE_S,
- KeyEvent.META_META_ON | KeyEvent.META_CTRL_ON))),
- /* Access list of system / apps shortcuts: Meta + / */
+ Pair.create(KeyEvent.KEYCODE_H, KeyEvent.META_META_ON),
+ Pair.create(KeyEvent.KEYCODE_ENTER, KeyEvent.META_META_ON))),
+ /* Overview of open apps: Meta + Tab */
new ShortcutKeyGroupMultiMappingInfo(
- context.getString(R.string.group_system_access_system_app_shortcuts),
+ context.getString(R.string.group_system_overview_open_apps),
Arrays.asList(
- Pair.create(KeyEvent.KEYCODE_SLASH, KeyEvent.META_META_ON))),
+ Pair.create(KeyEvent.KEYCODE_TAB, KeyEvent.META_META_ON))),
/* Back: go back to previous state (back button) */
- /* Meta + Escape, Meta + Grave, Meta + backspace, Meta + left arrow */
+ /* Meta + Escape, Meta + backspace, Meta + left arrow */
new ShortcutKeyGroupMultiMappingInfo(
context.getString(R.string.group_system_go_back),
Arrays.asList(
Pair.create(KeyEvent.KEYCODE_ESCAPE, KeyEvent.META_META_ON),
Pair.create(KeyEvent.KEYCODE_DEL, KeyEvent.META_META_ON),
Pair.create(KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.META_META_ON))),
- /* Access home screen: Meta + H, Meta + Enter */
+ /* Take a full screenshot: Meta + Ctrl + S */
new ShortcutKeyGroupMultiMappingInfo(
- context.getString(R.string.group_system_access_home_screen),
+ context.getString(R.string.group_system_full_screenshot),
Arrays.asList(
- Pair.create(KeyEvent.KEYCODE_H, KeyEvent.META_META_ON),
- Pair.create(KeyEvent.KEYCODE_ENTER, KeyEvent.META_META_ON))),
- /* Overview of open apps: Meta + Tab */
+ Pair.create(
+ KeyEvent.KEYCODE_S,
+ KeyEvent.META_META_ON | KeyEvent.META_CTRL_ON))),
+ /* Access list of system / apps shortcuts: Meta + / */
new ShortcutKeyGroupMultiMappingInfo(
- context.getString(R.string.group_system_overview_open_apps),
+ context.getString(R.string.group_system_access_system_app_shortcuts),
Arrays.asList(
- Pair.create(KeyEvent.KEYCODE_TAB, KeyEvent.META_META_ON))),
+ Pair.create(KeyEvent.KEYCODE_SLASH, KeyEvent.META_META_ON))),
/* Cycle through recent apps (forward): Alt + Tab */
new ShortcutKeyGroupMultiMappingInfo(
context.getString(R.string.group_system_cycle_forward),
@@ -530,26 +530,16 @@ public final class KeyboardShortcutListSearch {
Pair.create(
KeyEvent.KEYCODE_TAB,
KeyEvent.META_SHIFT_ON | KeyEvent.META_ALT_ON))),
- /* Access list of all apps and search (i.e. Search/Launcher): Meta */
- new ShortcutKeyGroupMultiMappingInfo(
- context.getString(R.string.group_system_access_all_apps_search),
- Arrays.asList(
- Pair.create(KeyEvent.KEYCODE_UNKNOWN, KeyEvent.META_META_ON))),
/* Hide and (re)show taskbar: Meta + T */
new ShortcutKeyGroupMultiMappingInfo(
context.getString(R.string.group_system_hide_reshow_taskbar),
Arrays.asList(
Pair.create(KeyEvent.KEYCODE_T, KeyEvent.META_META_ON))),
- /* Access system settings: Meta + I */
- new ShortcutKeyGroupMultiMappingInfo(
- context.getString(R.string.group_system_access_system_settings),
- Arrays.asList(
- Pair.create(KeyEvent.KEYCODE_I, KeyEvent.META_META_ON))),
- /* Access Google Assistant: Meta + A */
+ /* Access notification shade: Meta + N */
new ShortcutKeyGroupMultiMappingInfo(
- context.getString(R.string.group_system_access_google_assistant),
+ context.getString(R.string.group_system_access_notification_shade),
Arrays.asList(
- Pair.create(KeyEvent.KEYCODE_A, KeyEvent.META_META_ON))),
+ Pair.create(KeyEvent.KEYCODE_N, KeyEvent.META_META_ON))),
/* Lock screen: Meta + L */
new ShortcutKeyGroupMultiMappingInfo(
context.getString(R.string.group_system_lock_screen),
@@ -561,7 +551,17 @@ public final class KeyboardShortcutListSearch {
Arrays.asList(
Pair.create(
KeyEvent.KEYCODE_N,
- KeyEvent.META_META_ON | KeyEvent.META_CTRL_ON)))
+ KeyEvent.META_META_ON | KeyEvent.META_CTRL_ON))),
+ /* Access system settings: Meta + I */
+ new ShortcutKeyGroupMultiMappingInfo(
+ context.getString(R.string.group_system_access_system_settings),
+ Arrays.asList(
+ Pair.create(KeyEvent.KEYCODE_I, KeyEvent.META_META_ON))),
+ /* Access Google Assistant: Meta + A */
+ new ShortcutKeyGroupMultiMappingInfo(
+ context.getString(R.string.group_system_access_google_assistant),
+ Arrays.asList(
+ Pair.create(KeyEvent.KEYCODE_A, KeyEvent.META_META_ON)))
);
for (ShortcutKeyGroupMultiMappingInfo info : infoList) {
systemGroup.addItem(info.getShortcutMultiMappingInfo());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java
index 9445d56ab509..ea3036e35c1b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java
@@ -31,6 +31,7 @@ import androidx.asynclayoutinflater.view.AsyncLayoutInflater;
import com.android.systemui.res.R;
import com.android.systemui.statusbar.InflationTask;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.util.time.SystemClock;
import javax.inject.Inject;
@@ -46,9 +47,14 @@ public class RowInflaterTask implements InflationTask, AsyncLayoutInflater.OnInf
private NotificationEntry mEntry;
private boolean mCancelled;
private Throwable mInflateOrigin;
+ private final SystemClock mSystemClock;
+ private final RowInflaterTaskLogger mLogger;
+ private long mInflateStartTimeMs;
@Inject
- public RowInflaterTask() {
+ public RowInflaterTask(SystemClock systemClock, RowInflaterTaskLogger logger) {
+ mSystemClock = systemClock;
+ mLogger = logger;
}
/**
@@ -61,29 +67,49 @@ public class RowInflaterTask implements InflationTask, AsyncLayoutInflater.OnInf
}
mListener = listener;
AsyncLayoutInflater inflater = com.android.systemui.Flags.notificationRowUserContext()
- ? new AsyncLayoutInflater(context, new RowAsyncLayoutInflater(entry))
+ ? new AsyncLayoutInflater(context, makeRowInflater(entry))
: new AsyncLayoutInflater(context);
mEntry = entry;
entry.setInflationTask(this);
+
+ mLogger.logInflateStart(entry);
+ mInflateStartTimeMs = mSystemClock.elapsedRealtime();
inflater.inflate(R.layout.status_bar_notification_row, parent, this);
}
+ private RowAsyncLayoutInflater makeRowInflater(NotificationEntry entry) {
+ return new RowAsyncLayoutInflater(entry, mSystemClock, mLogger);
+ }
+
@VisibleForTesting
static class RowAsyncLayoutInflater implements AsyncLayoutFactory {
private final NotificationEntry mEntry;
+ private final SystemClock mSystemClock;
+ private final RowInflaterTaskLogger mLogger;
- RowAsyncLayoutInflater(NotificationEntry entry) {
+ RowAsyncLayoutInflater(NotificationEntry entry, SystemClock systemClock,
+ RowInflaterTaskLogger logger) {
mEntry = entry;
+ mSystemClock = systemClock;
+ mLogger = logger;
}
@Nullable
@Override
public View onCreateView(@Nullable View parent, @NonNull String name,
@NonNull Context context, @NonNull AttributeSet attrs) {
- if (name.equals(ExpandableNotificationRow.class.getName())) {
- return new ExpandableNotificationRow(context, attrs, mEntry);
+ if (!name.equals(ExpandableNotificationRow.class.getName())) {
+ return null;
}
- return null;
+
+ final long startMs = mSystemClock.elapsedRealtime();
+ final ExpandableNotificationRow row =
+ new ExpandableNotificationRow(context, attrs, mEntry);
+ final long elapsedMs = mSystemClock.elapsedRealtime() - startMs;
+
+ mLogger.logCreatedRow(mEntry, elapsedMs);
+
+ return row;
}
@Nullable
@@ -101,6 +127,9 @@ public class RowInflaterTask implements InflationTask, AsyncLayoutInflater.OnInf
@Override
public void onInflateFinished(View view, int resid, ViewGroup parent) {
+ final long elapsedMs = mSystemClock.elapsedRealtime() - mInflateStartTimeMs;
+ mLogger.logInflateFinish(mEntry, elapsedMs, mCancelled);
+
if (!mCancelled) {
try {
mEntry.onInflationTaskFinished();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTaskLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTaskLogger.kt
new file mode 100644
index 000000000000..94da6bec799b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTaskLogger.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.row
+
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.log.dagger.NotifInflationLog
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.logKey
+import javax.inject.Inject
+
+class RowInflaterTaskLogger @Inject constructor(@NotifInflationLog private val buffer: LogBuffer) {
+ fun logInflateStart(entry: NotificationEntry) {
+ buffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ { str1 = entry.logKey },
+ { "started row inflation for $str1" }
+ )
+ }
+
+ fun logCreatedRow(entry: NotificationEntry, elapsedMs: Long) {
+ buffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ str1 = entry.logKey
+ long1 = elapsedMs
+ },
+ { "created row in $long1 ms for $str1" }
+ )
+ }
+
+ fun logInflateFinish(entry: NotificationEntry, elapsedMs: Long, cancelled: Boolean) {
+ buffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ str1 = entry.logKey
+ long1 = elapsedMs
+ bool1 = cancelled
+ },
+ { "finished ${if (bool1) "cancelled " else ""}row inflation in $long1 ms for $str1" }
+ )
+ }
+}
+
+private const val TAG = "RowInflaterTask"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractor.kt
new file mode 100644
index 000000000000..9cd46f5b3552
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractor.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.stack.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.keyguard.shared.model.StatusBarState
+import com.android.systemui.power.domain.interactor.PowerInteractor
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
+
+/** Interactor exposing states related to the stack's context */
+@SysUISingleton
+class NotificationStackInteractor
+@Inject
+constructor(
+ keyguardInteractor: KeyguardInteractor,
+ powerInteractor: PowerInteractor,
+) {
+ val isShowingOnLockscreen: Flow<Boolean> =
+ combine(
+ // Non-notification UI elements of the notification list should not be visible
+ // on the lockscreen (incl. AOD and bouncer), except if the shade is opened on
+ // top. See b/219680200 for the footer and b/228790482, b/267060171 for the
+ // empty shade.
+ // TODO(b/323187006): There's a plan to eventually get rid of StatusBarState
+ // entirely, so this will have to be replaced at some point.
+ keyguardInteractor.statusBarState.map { it == StatusBarState.KEYGUARD },
+ // The StatusBarState is unfortunately not updated quickly enough when the power
+ // button is pressed, so this is necessary in addition to the KEYGUARD check to
+ // cover the transition to AOD while going to sleep (b/190227875).
+ powerInteractor.isAsleep,
+ ) { (isOnKeyguard, isAsleep) ->
+ isOnKeyguard || isAsleep
+ }
+ .distinctUntilChanged()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt
index 7b502564ecb1..c85a18a8a896 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt
@@ -16,9 +16,6 @@
package com.android.systemui.statusbar.notification.stack.ui.viewmodel
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
-import com.android.systemui.keyguard.shared.model.StatusBarState
-import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.domain.interactor.RemoteInputInteractor
import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
@@ -26,6 +23,7 @@ import com.android.systemui.statusbar.notification.domain.interactor.SeenNotific
import com.android.systemui.statusbar.notification.footer.shared.FooterViewRefactor
import com.android.systemui.statusbar.notification.footer.ui.viewmodel.FooterViewModel
import com.android.systemui.statusbar.notification.shelf.ui.viewmodel.NotificationShelfViewModel
+import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackInteractor
import com.android.systemui.statusbar.policy.domain.interactor.UserSetupInteractor
import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor
import com.android.systemui.util.kotlin.combine
@@ -51,8 +49,7 @@ constructor(
val footer: Optional<FooterViewModel>,
val logger: Optional<NotificationLoggerViewModel>,
activeNotificationsInteractor: ActiveNotificationsInteractor,
- keyguardInteractor: KeyguardInteractor,
- powerInteractor: PowerInteractor,
+ notificationStackInteractor: NotificationStackInteractor,
remoteInputInteractor: RemoteInputInteractor,
seenNotificationsInteractor: SeenNotificationsInteractor,
shadeInteractor: ShadeInteractor,
@@ -71,7 +68,7 @@ constructor(
} else {
combine(
activeNotificationsInteractor.areAnyNotificationsPresent,
- isShowingOnLockscreen,
+ notificationStackInteractor.isShowingOnLockscreen,
) { hasNotifications, isShowingOnLockscreen ->
hasNotifications || !isShowingOnLockscreen
}
@@ -86,7 +83,7 @@ constructor(
combine(
activeNotificationsInteractor.areAnyNotificationsPresent,
shadeInteractor.isQsFullscreen,
- isShowingOnLockscreen,
+ notificationStackInteractor.isShowingOnLockscreen,
) { hasNotifications, isQsFullScreen, isShowingOnLockscreen ->
when {
hasNotifications -> false
@@ -109,7 +106,7 @@ constructor(
combine(
activeNotificationsInteractor.areAnyNotificationsPresent,
userSetupInteractor.isUserSetUp,
- isShowingOnLockscreen,
+ notificationStackInteractor.isShowingOnLockscreen,
shadeInteractor.qsExpansion,
shadeInteractor.isQsFullscreen,
remoteInputInteractor.isRemoteInputActive,
@@ -177,29 +174,6 @@ constructor(
SHOW_WITH_ANIMATION(visible = true, canAnimate = true)
}
- private val isShowingOnLockscreen: Flow<Boolean> by lazy {
- if (FooterViewRefactor.isUnexpectedlyInLegacyMode()) {
- flowOf(false)
- } else {
- combine(
- // Non-notification UI elements of the notification list should not be visible
- // on the lockscreen (incl. AOD and bouncer), except if the shade is opened on
- // top. See b/219680200 for the footer and b/228790482, b/267060171 for the
- // empty shade.
- // TODO(b/323187006): There's a plan to eventually get rid of StatusBarState
- // entirely, so this will have to be replaced at some point.
- keyguardInteractor.statusBarState.map { it == StatusBarState.KEYGUARD },
- // The StatusBarState is unfortunately not updated quickly enough when the power
- // button is pressed, so this is necessary in addition to the KEYGUARD check to
- // cover the transition to AOD while going to sleep (b/190227875).
- powerInteractor.isAsleep,
- ) { (isOnKeyguard, isAsleep) ->
- isOnKeyguard || isAsleep
- }
- .distinctUntilChanged()
- }
- }
-
// TODO(b/308591475): This should be tracked separately by the empty shade.
val areNotificationsHiddenInShade: Flow<Boolean> by lazy {
if (FooterViewRefactor.isUnexpectedlyInLegacyMode()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index d1055c77ab8f..ee844345d2ec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -81,6 +81,9 @@ import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.navigationbar.TaskbarDelegate;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.scene.domain.interactor.SceneInteractor;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
+import com.android.systemui.scene.shared.model.Scenes;
import com.android.systemui.shade.ShadeController;
import com.android.systemui.shade.ShadeExpansionChangeEvent;
import com.android.systemui.shade.ShadeExpansionListener;
@@ -157,6 +160,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
private final AlternateBouncerInteractor mAlternateBouncerInteractor;
private final BouncerView mPrimaryBouncerView;
private final Lazy<ShadeController> mShadeController;
+ private final Lazy<SceneInteractor> mSceneInteractorLazy;
// Local cache of expansion events, to avoid duplicates
private float mFraction = -1f;
@@ -381,7 +385,8 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
Lazy<KeyguardDismissActionInteractor> keyguardDismissActionInteractorLazy,
SelectedUserInteractor selectedUserInteractor,
Lazy<KeyguardSurfaceBehindInteractor> surfaceBehindInteractor,
- JavaAdapter javaAdapter
+ JavaAdapter javaAdapter,
+ Lazy<SceneInteractor> sceneInteractorLazy
) {
mContext = context;
mViewMediatorCallback = callback;
@@ -415,6 +420,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
mSelectedUserInteractor = selectedUserInteractor;
mSurfaceBehindInteractor = surfaceBehindInteractor;
mJavaAdapter = javaAdapter;
+ mSceneInteractorLazy = sceneInteractorLazy;
}
KeyguardTransitionInteractor mKeyguardTransitionInteractor;
@@ -633,8 +639,11 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
public void show(Bundle options) {
Trace.beginSection("StatusBarKeyguardViewManager#show");
mNotificationShadeWindowController.setKeyguardShowing(true);
- mKeyguardStateController.notifyKeyguardState(true,
- mKeyguardStateController.isOccluded());
+ if (SceneContainerFlag.isEnabled()) {
+ mSceneInteractorLazy.get().changeScene(
+ Scenes.Lockscreen, "StatusBarKeyguardViewManager.show");
+ }
+ mKeyguardStateController.notifyKeyguardState(true, mKeyguardStateController.isOccluded());
reset(true /* hideBouncerWhenShowing */);
SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_STATE_CHANGED,
SysUiStatsLog.KEYGUARD_STATE_CHANGED__STATE__SHOWN);
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimation.kt b/packages/SystemUI/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimation.kt
index d19a3364d502..5c53ff98b777 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimation.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimation.kt
@@ -16,8 +16,6 @@
package com.android.systemui.unfold
-import android.animation.Animator
-import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.annotation.BinderThread
import android.content.Context
@@ -25,6 +23,7 @@ import android.os.Handler
import android.os.SystemProperties
import android.util.Log
import android.view.animation.DecelerateInterpolator
+import androidx.core.animation.addListener
import com.android.internal.foldables.FoldLockSettingAvailabilityProvider
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.display.data.repository.DeviceStateRepository
@@ -37,25 +36,17 @@ import com.android.systemui.unfold.FullscreenLightRevealAnimationController.Comp
import com.android.systemui.unfold.dagger.UnfoldBg
import com.android.systemui.util.animation.data.repository.AnimationStatusRepository
import javax.inject.Inject
-import kotlin.coroutines.resume
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.android.asCoroutineDispatcher
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.launch
-import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withTimeout
-@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
class FoldLightRevealOverlayAnimation
@Inject
constructor(
@@ -70,9 +61,6 @@ constructor(
private val revealProgressValueAnimator: ValueAnimator =
ValueAnimator.ofFloat(ALPHA_OPAQUE, ALPHA_TRANSPARENT)
- private val areAnimationEnabled: Flow<Boolean>
- get() = animationStatusRepository.areAnimationsEnabled()
-
private lateinit var controller: FullscreenLightRevealAnimationController
@Volatile private var readyCallback: CompletableDeferred<Runnable>? = null
@@ -101,30 +89,33 @@ constructor(
applicationScope.launch(bgHandler.asCoroutineDispatcher()) {
deviceStateRepository.state
- .map { it == DeviceStateRepository.DeviceState.FOLDED }
+ .map { it != DeviceStateRepository.DeviceState.FOLDED }
.distinctUntilChanged()
- .flatMapLatest { isFolded ->
- flow<Nothing> {
- if (!areAnimationEnabled.first() || !isFolded) {
- return@flow
- }
- withTimeout(WAIT_FOR_ANIMATION_TIMEOUT_MS) {
- readyCallback = CompletableDeferred()
- val onReady = readyCallback?.await()
- readyCallback = null
- controller.addOverlay(ALPHA_OPAQUE, onReady)
- waitForScreenTurnedOn()
- }
- playFoldLightRevealOverlayAnimation()
- }
- .catchTimeoutAndLog()
- .onCompletion {
- val onReady = readyCallback?.takeIf { it.isCompleted }?.getCompleted()
- onReady?.run()
+ .filter { isUnfolded -> isUnfolded }
+ .collect { controller.ensureOverlayRemoved() }
+ }
+
+ applicationScope.launch(bgHandler.asCoroutineDispatcher()) {
+ deviceStateRepository.state
+ .filter {
+ animationStatusRepository.areAnimationsEnabled().first() &&
+ it == DeviceStateRepository.DeviceState.FOLDED
+ }
+ .collect {
+ try {
+ withTimeout(WAIT_FOR_ANIMATION_TIMEOUT_MS) {
+ readyCallback = CompletableDeferred()
+ val onReady = readyCallback?.await()
readyCallback = null
+ controller.addOverlay(ALPHA_OPAQUE, onReady)
+ waitForScreenTurnedOn()
+ playFoldLightRevealOverlayAnimation()
}
+ } catch (e: TimeoutCancellationException) {
+ Log.e(TAG, "Fold light reveal animation timed out")
+ ensureOverlayRemovedInternal()
+ }
}
- .collect {}
}
}
@@ -137,34 +128,19 @@ constructor(
powerInteractor.screenPowerState.filter { it == ScreenPowerState.SCREEN_ON }.first()
}
- private suspend fun playFoldLightRevealOverlayAnimation() {
+ private fun ensureOverlayRemovedInternal() {
+ revealProgressValueAnimator.cancel()
+ controller.ensureOverlayRemoved()
+ }
+
+ private fun playFoldLightRevealOverlayAnimation() {
revealProgressValueAnimator.duration = ANIMATION_DURATION
revealProgressValueAnimator.interpolator = DecelerateInterpolator()
revealProgressValueAnimator.addUpdateListener { animation ->
controller.updateRevealAmount(animation.animatedFraction)
}
- revealProgressValueAnimator.startAndAwaitCompletion()
- }
-
- private suspend fun ValueAnimator.startAndAwaitCompletion(): Unit =
- suspendCancellableCoroutine { continuation ->
- val listener =
- object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator) {
- continuation.resume(Unit)
- removeListener(this)
- }
- }
- addListener(listener)
- continuation.invokeOnCancellation { removeListener(listener) }
- start()
- }
-
- private fun <T> Flow<T>.catchTimeoutAndLog() = catch { exception ->
- when (exception) {
- is TimeoutCancellationException -> Log.e(TAG, "Fold light reveal animation timed out")
- else -> throw exception
- }
+ revealProgressValueAnimator.addListener(onEnd = { controller.ensureOverlayRemoved() })
+ revealProgressValueAnimator.start()
}
private companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/BatteryControllerExt.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/BatteryControllerExt.kt
new file mode 100644
index 000000000000..0128eb762296
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/BatteryControllerExt.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util.kotlin
+
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.statusbar.policy.BatteryController
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.onStart
+
+fun BatteryController.isBatteryPowerSaveEnabled(): Flow<Boolean> {
+ return conflatedCallbackFlow {
+ val batteryCallback =
+ object : BatteryController.BatteryStateChangeCallback {
+ override fun onPowerSaveChanged(isPowerSave: Boolean) {
+ trySend(isPowerSave)
+ }
+ }
+ addCallback(batteryCallback)
+ awaitClose { removeCallback(batteryCallback) }
+ }
+ .onStart { emit(isPowerSave) }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/RotationLockControllerExt.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/RotationLockControllerExt.kt
new file mode 100644
index 000000000000..22cc8dd7745d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/RotationLockControllerExt.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util.kotlin
+
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.statusbar.policy.RotationLockController
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.onStart
+
+fun RotationLockController.isRotationLockEnabled(): Flow<Boolean> {
+ return conflatedCallbackFlow {
+ val rotationLockCallback =
+ RotationLockController.RotationLockControllerCallback { rotationLocked, _ ->
+ trySend(rotationLocked)
+ }
+ addCallback(rotationLockCallback)
+ awaitClose { removeCallback(rotationLockCallback) }
+ }
+ .onStart { emit(isRotationLocked) }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputActionsInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputActionsInteractor.kt
index 170b32c1d0ea..2ab59984d06f 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputActionsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputActionsInteractor.kt
@@ -16,14 +16,11 @@
package com.android.systemui.volume.panel.component.mediaoutput.domain.interactor
-import android.content.Intent
-import android.provider.Settings
import com.android.internal.jank.InteractionJankMonitor
import com.android.systemui.animation.DialogCuj
import com.android.systemui.animation.DialogTransitionAnimator
import com.android.systemui.animation.Expandable
import com.android.systemui.media.dialog.MediaOutputDialogFactory
-import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.volume.panel.component.mediaoutput.domain.model.MediaDeviceSession
import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope
import javax.inject.Inject
@@ -34,17 +31,8 @@ class MediaOutputActionsInteractor
@Inject
constructor(
private val mediaOutputDialogFactory: MediaOutputDialogFactory,
- private val activityStarter: ActivityStarter,
) {
- fun onDeviceClick(expandable: Expandable) {
- activityStarter.startActivity(
- Intent(Settings.ACTION_BLUETOOTH_SETTINGS),
- true,
- expandable.activityTransitionController(),
- )
- }
-
fun onBarClick(session: MediaDeviceSession, expandable: Expandable) {
when (session) {
is MediaDeviceSession.Active -> {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/DeviceIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/DeviceIconViewModel.kt
index e518ed022792..37bf661454c5 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/DeviceIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/DeviceIconViewModel.kt
@@ -26,13 +26,13 @@ sealed interface DeviceIconViewModel {
val iconColor: Color
val backgroundColor: Color
- class IsPlaying(
+ data class IsPlaying(
override val icon: Icon,
override val iconColor: Color,
override val backgroundColor: Color,
) : DeviceIconViewModel
- class IsNotPlaying(
+ data class IsNotPlaying(
override val icon: Icon,
override val iconColor: Color,
override val backgroundColor: Color,
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModel.kt
index 85d6c9e341ac..37661b53c98a 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModel.kt
@@ -113,11 +113,6 @@ constructor(
private fun MediaDeviceSession.isPlaying(): Boolean =
this is MediaDeviceSession.Active && playbackState?.isActive == true
- fun onDeviceClick(expandable: Expandable) {
- actionsInteractor.onDeviceClick(expandable)
- volumePanelViewModel.dismissPanel()
- }
-
fun onBarClick(expandable: Expandable) {
actionsInteractor.onBarClick(mediaDeviceSession.value, expandable)
volumePanelViewModel.dismissPanel()
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java
index 90587d7386ce..13fb42ce8c3e 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java
@@ -16,6 +16,8 @@
package com.android.keyguard;
+import static kotlinx.coroutines.flow.FlowKt.emptyFlow;
+
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -30,6 +32,7 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository;
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory;
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.power.data.repository.FakePowerRepository;
import com.android.systemui.power.domain.interactor.PowerInteractorFactory;
import com.android.systemui.res.R;
@@ -59,6 +62,7 @@ public class KeyguardStatusViewControllerBaseTest extends SysuiTestCase {
@Mock protected KeyguardStatusViewController mControllerMock;
@Mock protected InteractionJankMonitor mInteractionJankMonitor;
@Mock protected ViewTreeObserver mViewTreeObserver;
+ @Mock protected KeyguardTransitionInteractor mKeyguardTransitionInteractor;
@Mock protected DumpManager mDumpManager;
protected FakeKeyguardRepository mFakeKeyguardRepository;
protected FakePowerRepository mFakePowerRepository;
@@ -89,6 +93,7 @@ public class KeyguardStatusViewControllerBaseTest extends SysuiTestCase {
mKeyguardLogger,
mInteractionJankMonitor,
deps.getKeyguardInteractor(),
+ mKeyguardTransitionInteractor,
mDumpManager,
PowerInteractorFactory.create(
mFakePowerRepository
@@ -105,6 +110,7 @@ public class KeyguardStatusViewControllerBaseTest extends SysuiTestCase {
when(mKeyguardStatusView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
when(mKeyguardClockSwitchController.getView()).thenReturn(mKeyguardClockSwitch);
+ when(mKeyguardTransitionInteractor.getGoneToAodTransition()).thenReturn(emptyFlow());
when(mKeyguardStatusView.findViewById(R.id.keyguard_status_area))
.thenReturn(mKeyguardStatusAreaView);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorTest.kt
index d0b1dd52c7e7..df52265384fa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorTest.kt
@@ -122,13 +122,7 @@ class BurnInInteractorTest : SysuiTestCase() {
testScope.runTest {
whenever(burnInHelperWrapper.burnInScale()).thenReturn(0.5f)
- val burnInModel by
- collectLastValue(
- underTest.burnIn(
- xDimenResourceId = R.dimen.burn_in_prevention_offset_x,
- yDimenResourceId = R.dimen.burn_in_prevention_offset_y
- )
- )
+ val burnInModel by collectLastValue(underTest.keyguardBurnIn)
// After time tick, returns the configured values
fakeKeyguardRepository.dozeTimeTick(10)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
index eae04671d581..c65a9ef28bba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
@@ -654,6 +654,30 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
coroutineContext.cancelChildren()
}
+ @Test
+ fun dozingToPrimaryBouncer() =
+ testScope.runTest {
+ // GIVEN a prior transition has run to DOZING
+ runTransitionAndSetWakefulness(KeyguardState.LOCKSCREEN, KeyguardState.DOZING)
+ runCurrent()
+
+ // WHEN awaked by a request to show the primary bouncer, as can happen if SPFS is
+ // touched after boot
+ powerInteractor.setAwakeForTest()
+ bouncerRepository.setPrimaryShow(true)
+ advanceTimeBy(60L)
+
+ assertThat(transitionRepository)
+ .startedTransition(
+ to = KeyguardState.PRIMARY_BOUNCER,
+ from = KeyguardState.DOZING,
+ ownerName = "FromDozingTransitionInteractor",
+ animatorAssertion = { it.isNotNull() }
+ )
+
+ coroutineContext.cancelChildren()
+ }
+
/** This handles security method NONE and screen off with lock timeout */
@Test
fun dozingToGoneWithKeyguardNotShowing() =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelTest.kt
index 02bd810a43d5..4bb0d4781376 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelTest.kt
@@ -27,11 +27,14 @@ import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.keyguardRepository
+import com.android.systemui.keyguard.ui.viewmodel.DeviceEntryIconViewModel.Companion.UNLOCKED_DELAY_MS
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.runner.RunWith
@@ -71,7 +74,10 @@ class DeviceEntryIconViewModelTest : SysuiTestCase() {
fun isLongPressEnabled_unlocked() =
testScope.runTest {
val isLongPressEnabled by collectLastValue(underTest.isLongPressEnabled)
+ fingerprintPropertyRepository.supportsUdfps()
keyguardRepository.setKeyguardDismissible(true)
+ advanceTimeBy(UNLOCKED_DELAY_MS * 2) // wait for unlocked delay
+ runCurrent()
assertThat(isLongPressEnabled).isTrue()
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt
index ce089b1b723a..864acfb1ddb9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt
@@ -16,7 +16,6 @@
package com.android.systemui.keyguard.ui.viewmodel
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.Flags as AConfigFlags
import com.android.systemui.SysuiTestCase
@@ -25,13 +24,9 @@ import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.doze.util.BurnInHelperWrapper
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
-import com.android.systemui.keyguard.domain.interactor.BurnInInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
-import com.android.systemui.keyguard.shared.model.BurnInModel
import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
-import com.android.systemui.kosmos.testScope
-import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
@@ -41,23 +36,18 @@ import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidJUnit4::class)
+@RunWith(JUnit4::class)
class KeyguardIndicationAreaViewModelTest : SysuiTestCase() {
- private val kosmos = testKosmos()
- private val testScope = kosmos.testScope
@Mock private lateinit var burnInHelperWrapper: BurnInHelperWrapper
@Mock private lateinit var shortcutsCombinedViewModel: KeyguardQuickAffordancesCombinedViewModel
- @Mock private lateinit var burnInInteractor: BurnInInteractor
- private val burnInFlow = MutableStateFlow(BurnInModel())
-
- private lateinit var bottomAreaInteractor: KeyguardBottomAreaInteractor
private lateinit var underTest: KeyguardIndicationAreaViewModel
private lateinit var repository: FakeKeyguardRepository
@@ -80,11 +70,9 @@ class KeyguardIndicationAreaViewModelTest : SysuiTestCase() {
MockitoAnnotations.initMocks(this)
mSetFlagsRule.disableFlags(AConfigFlags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR)
- mSetFlagsRule.disableFlags(AConfigFlags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT)
whenever(burnInHelperWrapper.burnInOffset(anyInt(), any()))
.thenReturn(RETURNED_BURN_IN_OFFSET)
- whenever(burnInInteractor.burnIn(anyInt(), anyInt())).thenReturn(burnInFlow)
val withDeps = KeyguardInteractorFactory.create()
val keyguardInteractor = withDeps.keyguardInteractor
@@ -94,85 +82,78 @@ class KeyguardIndicationAreaViewModelTest : SysuiTestCase() {
whenever(bottomAreaViewModel.startButton).thenReturn(startButtonFlow)
whenever(bottomAreaViewModel.endButton).thenReturn(endButtonFlow)
whenever(bottomAreaViewModel.alpha).thenReturn(alphaFlow)
- bottomAreaInteractor = KeyguardBottomAreaInteractor(repository = repository)
underTest =
KeyguardIndicationAreaViewModel(
keyguardInteractor = keyguardInteractor,
- bottomAreaInteractor = bottomAreaInteractor,
+ bottomAreaInteractor = KeyguardBottomAreaInteractor(repository = repository),
keyguardBottomAreaViewModel = bottomAreaViewModel,
burnInHelperWrapper = burnInHelperWrapper,
- burnInInteractor = burnInInteractor,
shortcutsCombinedViewModel = shortcutsCombinedViewModel,
configurationInteractor = ConfigurationInteractor(FakeConfigurationRepository()),
)
}
@Test
- fun alpha() =
- testScope.runTest {
- val value = collectLastValue(underTest.alpha)
-
- assertThat(value()).isEqualTo(1f)
- alphaFlow.value = 0.1f
- assertThat(value()).isEqualTo(0.1f)
- alphaFlow.value = 0.5f
- assertThat(value()).isEqualTo(0.5f)
- alphaFlow.value = 0.2f
- assertThat(value()).isEqualTo(0.2f)
- alphaFlow.value = 0f
- assertThat(value()).isEqualTo(0f)
- }
+ fun alpha() = runTest {
+ val value = collectLastValue(underTest.alpha)
+
+ assertThat(value()).isEqualTo(1f)
+ alphaFlow.value = 0.1f
+ assertThat(value()).isEqualTo(0.1f)
+ alphaFlow.value = 0.5f
+ assertThat(value()).isEqualTo(0.5f)
+ alphaFlow.value = 0.2f
+ assertThat(value()).isEqualTo(0.2f)
+ alphaFlow.value = 0f
+ assertThat(value()).isEqualTo(0f)
+ }
@Test
- fun isIndicationAreaPadded() =
- testScope.runTest {
- repository.setKeyguardShowing(true)
- val value = collectLastValue(underTest.isIndicationAreaPadded)
-
- assertThat(value()).isFalse()
- startButtonFlow.value = startButtonFlow.value.copy(isVisible = true)
- assertThat(value()).isTrue()
- endButtonFlow.value = endButtonFlow.value.copy(isVisible = true)
- assertThat(value()).isTrue()
- startButtonFlow.value = startButtonFlow.value.copy(isVisible = false)
- assertThat(value()).isTrue()
- endButtonFlow.value = endButtonFlow.value.copy(isVisible = false)
- assertThat(value()).isFalse()
- }
+ fun isIndicationAreaPadded() = runTest {
+ repository.setKeyguardShowing(true)
+ val value = collectLastValue(underTest.isIndicationAreaPadded)
+
+ assertThat(value()).isFalse()
+ startButtonFlow.value = startButtonFlow.value.copy(isVisible = true)
+ assertThat(value()).isTrue()
+ endButtonFlow.value = endButtonFlow.value.copy(isVisible = true)
+ assertThat(value()).isTrue()
+ startButtonFlow.value = startButtonFlow.value.copy(isVisible = false)
+ assertThat(value()).isTrue()
+ endButtonFlow.value = endButtonFlow.value.copy(isVisible = false)
+ assertThat(value()).isFalse()
+ }
@Test
- fun indicationAreaTranslationX() =
- testScope.runTest {
- val value = collectLastValue(underTest.indicationAreaTranslationX)
-
- assertThat(value()).isEqualTo(0f)
- bottomAreaInteractor.setClockPosition(100, 100)
- assertThat(value()).isEqualTo(100f)
- bottomAreaInteractor.setClockPosition(200, 100)
- assertThat(value()).isEqualTo(200f)
- bottomAreaInteractor.setClockPosition(200, 200)
- assertThat(value()).isEqualTo(200f)
- bottomAreaInteractor.setClockPosition(300, 100)
- assertThat(value()).isEqualTo(300f)
- }
+ fun indicationAreaTranslationX() = runTest {
+ val value = collectLastValue(underTest.indicationAreaTranslationX)
+
+ assertThat(value()).isEqualTo(0f)
+ repository.setClockPosition(100, 100)
+ assertThat(value()).isEqualTo(100f)
+ repository.setClockPosition(200, 100)
+ assertThat(value()).isEqualTo(200f)
+ repository.setClockPosition(200, 200)
+ assertThat(value()).isEqualTo(200f)
+ repository.setClockPosition(300, 100)
+ assertThat(value()).isEqualTo(300f)
+ }
@Test
- fun indicationAreaTranslationY() =
- testScope.runTest {
- val value =
- collectLastValue(underTest.indicationAreaTranslationY(DEFAULT_BURN_IN_OFFSET))
-
- // Negative 0 - apparently there's a difference in floating point arithmetic - FML
- assertThat(value()).isEqualTo(-0f)
- val expected1 = setDozeAmountAndCalculateExpectedTranslationY(0.1f)
- assertThat(value()).isEqualTo(expected1)
- val expected2 = setDozeAmountAndCalculateExpectedTranslationY(0.2f)
- assertThat(value()).isEqualTo(expected2)
- val expected3 = setDozeAmountAndCalculateExpectedTranslationY(0.5f)
- assertThat(value()).isEqualTo(expected3)
- val expected4 = setDozeAmountAndCalculateExpectedTranslationY(1f)
- assertThat(value()).isEqualTo(expected4)
- }
+ fun indicationAreaTranslationY() = runTest {
+ val value = collectLastValue(underTest.indicationAreaTranslationY(DEFAULT_BURN_IN_OFFSET))
+
+ // Negative 0 - apparently there's a difference in floating point arithmetic - FML
+ assertThat(value()).isEqualTo(-0f)
+ val expected1 = setDozeAmountAndCalculateExpectedTranslationY(0.1f)
+ assertThat(value()).isEqualTo(expected1)
+ val expected2 = setDozeAmountAndCalculateExpectedTranslationY(0.2f)
+ assertThat(value()).isEqualTo(expected2)
+ val expected3 = setDozeAmountAndCalculateExpectedTranslationY(0.5f)
+ assertThat(value()).isEqualTo(expected3)
+ val expected4 = setDozeAmountAndCalculateExpectedTranslationY(1f)
+ assertThat(value()).isEqualTo(expected4)
+ }
private fun setDozeAmountAndCalculateExpectedTranslationY(dozeAmount: Float): Float {
repository.setDozeAmount(dozeAmount)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotSoundControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotSoundControllerTest.kt
index 2f911fffe335..92c240404b24 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotSoundControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotSoundControllerTest.kt
@@ -22,8 +22,10 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import java.lang.IllegalStateException
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
@@ -31,12 +33,14 @@ import org.mockito.Mockito.never
import org.mockito.Mockito.verify
@SmallTest
+@OptIn(ExperimentalCoroutinesApi::class)
class ScreenshotSoundControllerTest : SysuiTestCase() {
private val soundProvider = mock<ScreenshotSoundProvider>()
private val mediaPlayer = mock<MediaPlayer>()
private val bgDispatcher = UnconfinedTestDispatcher()
private val scope = TestScope(bgDispatcher)
+
@Before
fun setup() {
whenever(soundProvider.getScreenshotSound()).thenReturn(mediaPlayer)
@@ -45,52 +49,59 @@ class ScreenshotSoundControllerTest : SysuiTestCase() {
@Test
fun init_soundLoading() {
createController()
- bgDispatcher.scheduler.runCurrent()
+ scope.advanceUntilIdle()
verify(soundProvider).getScreenshotSound()
}
@Test
- fun init_soundLoadingException_playAndReleaseDoNotThrow() = runTest {
- whenever(soundProvider.getScreenshotSound()).thenThrow(IllegalStateException())
+ fun init_soundLoadingException_playAndReleaseDoNotThrow() =
+ scope.runTest {
+ whenever(soundProvider.getScreenshotSound()).thenThrow(IllegalStateException())
- val controller = createController()
+ val controller = createController()
- controller.playCameraSound().await()
- controller.releaseScreenshotSound().await()
+ controller.playScreenshotSound()
+ advanceUntilIdle()
- verify(mediaPlayer, never()).start()
- verify(mediaPlayer, never()).release()
- }
+ verify(mediaPlayer, never()).start()
+ verify(mediaPlayer, never()).release()
+ }
@Test
- fun playCameraSound_soundLoadingSuccessful_mediaPlayerPlays() = runTest {
- val controller = createController()
+ fun playCameraSound_soundLoadingSuccessful_mediaPlayerPlays() =
+ scope.runTest {
+ val controller = createController()
- controller.playCameraSound().await()
+ controller.playScreenshotSound()
+ advanceUntilIdle()
- verify(mediaPlayer).start()
- }
+ verify(mediaPlayer).start()
+ }
@Test
- fun playCameraSound_illegalStateException_doesNotThrow() = runTest {
- whenever(mediaPlayer.start()).thenThrow(IllegalStateException())
+ fun playCameraSound_illegalStateException_doesNotThrow() =
+ scope.runTest {
+ whenever(mediaPlayer.start()).thenThrow(IllegalStateException())
- val controller = createController()
- controller.playCameraSound().await()
+ val controller = createController()
+ controller.playScreenshotSound()
+ advanceUntilIdle()
- verify(mediaPlayer).start()
- verify(mediaPlayer).release()
- }
+ verify(mediaPlayer).start()
+ verify(mediaPlayer).release()
+ }
@Test
- fun playCameraSound_soundLoadingSuccessful_mediaPlayerReleases() = runTest {
- val controller = createController()
+ fun playCameraSound_soundLoadingSuccessful_mediaPlayerReleases() =
+ scope.runTest {
+ val controller = createController()
- controller.releaseScreenshotSound().await()
+ controller.releaseScreenshotSound()
+ advanceUntilIdle()
- verify(mediaPlayer).release()
- }
+ verify(mediaPlayer).release()
+ }
private fun createController() =
ScreenshotSoundControllerImpl(soundProvider, scope, bgDispatcher)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index f8771b26476c..fd7b1399d03f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -461,6 +461,7 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
mKeyguardLogger,
mInteractionJankMonitor,
mKeyguardInteractor,
+ mKeyguardTransitionInteractor,
mDumpManager,
mPowerInteractor));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index e78081fc34bd..fb49499fc29d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -89,6 +89,8 @@ import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder;
import com.android.systemui.statusbar.policy.SmartReplyConstants;
import com.android.systemui.statusbar.policy.SmartReplyStateInflater;
import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent;
+import com.android.systemui.util.time.SystemClock;
+import com.android.systemui.util.time.SystemClockImpl;
import com.android.systemui.wmshell.BubblesManager;
import com.android.systemui.wmshell.BubblesTestActivity;
@@ -136,6 +138,8 @@ public class NotificationTestHelper {
public final Runnable mFutureDismissalRunnable;
private @InflationFlag int mDefaultInflationFlags;
private final FakeFeatureFlags mFeatureFlags;
+ private final SystemClock mSystemClock;
+ private final RowInflaterTaskLogger mRowInflaterTaskLogger;
public NotificationTestHelper(
Context context,
@@ -199,6 +203,9 @@ public class NotificationTestHelper {
mFutureDismissalRunnable = mock(Runnable.class);
when(mOnUserInteractionCallback.registerFutureDismissal(any(), anyInt()))
.thenReturn(mFutureDismissalRunnable);
+
+ mSystemClock = new SystemClockImpl();
+ mRowInflaterTaskLogger = mock(RowInflaterTaskLogger.class);
}
public void setDefaultInflationFlags(@InflationFlag int defaultInflationFlags) {
@@ -572,7 +579,8 @@ public class NotificationTestHelper {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
if (com.android.systemui.Flags.notificationRowUserContext()) {
- inflater.setFactory2(new RowInflaterTask.RowAsyncLayoutInflater(entry));
+ inflater.setFactory2(new RowInflaterTask.RowAsyncLayoutInflater(entry, mSystemClock,
+ mRowInflaterTaskLogger));
}
mRow = (ExpandableNotificationRow) inflater.inflate(
R.layout.status_bar_notification_row,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorTest.kt
new file mode 100644
index 000000000000..1c6bda985a0e
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorTest.kt
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.statusbar.notification.stack.domain.interactor
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
+import com.android.systemui.keyguard.shared.model.StatusBarState
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.power.data.repository.fakePowerRepository
+import com.android.systemui.power.shared.model.WakefulnessState
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class NotificationStackInteractorTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ val underTest
+ get() = kosmos.notificationStackInteractor
+
+ @Test
+ fun testIsShowingOnLockscreen_falseWhenViewingShade() =
+ kosmos.testScope.runTest {
+ val onLockscreen by collectLastValue(underTest.isShowingOnLockscreen)
+
+ // WHEN shade is open
+ kosmos.fakeKeyguardRepository.setStatusBarState(StatusBarState.SHADE)
+ runCurrent()
+
+ // THEN notifications are not showing on lockscreen
+ assertThat(onLockscreen).isFalse()
+ }
+
+ @Test
+ fun testIsShowingOnLockscreen_trueWhenViewingKeyguard() =
+ kosmos.testScope.runTest {
+ val onLockscreen by collectLastValue(underTest.isShowingOnLockscreen)
+
+ // WHEN on keyguard
+ kosmos.fakeKeyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
+ runCurrent()
+
+ // THEN notifications are showing on lockscreen
+ assertThat(onLockscreen).isTrue()
+ }
+
+ @Test
+ fun testIsShowingOnLockscreen_trueWhenStartingToSleep() =
+ kosmos.testScope.runTest {
+ val onLockscreen by collectLastValue(underTest.isShowingOnLockscreen)
+
+ // WHEN shade is open
+ kosmos.fakeKeyguardRepository.setStatusBarState(StatusBarState.SHADE)
+ // AND device is starting to go to sleep
+ kosmos.fakePowerRepository.updateWakefulness(WakefulnessState.STARTING_TO_SLEEP)
+ runCurrent()
+
+ // THEN notifications are showing on lockscreen
+ assertThat(onLockscreen).isTrue()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 3666248d1783..f050857d5df2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -86,6 +86,7 @@ import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.navigationbar.TaskbarDelegate;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
+import com.android.systemui.scene.domain.interactor.SceneInteractor;
import com.android.systemui.shade.NotificationShadeWindowView;
import com.android.systemui.shade.ShadeController;
import com.android.systemui.shade.ShadeExpansionChangeEvent;
@@ -224,7 +225,8 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
() -> mock(KeyguardDismissActionInteractor.class),
mSelectedUserInteractor,
() -> mock(KeyguardSurfaceBehindInteractor.class),
- mock(JavaAdapter.class)) {
+ mock(JavaAdapter.class),
+ () -> mock(SceneInteractor.class)) {
@Override
public ViewRootImpl getViewRootImpl() {
return mViewRootImpl;
@@ -733,7 +735,8 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
() -> mock(KeyguardDismissActionInteractor.class),
mSelectedUserInteractor,
() -> mock(KeyguardSurfaceBehindInteractor.class),
- mock(JavaAdapter.class)) {
+ mock(JavaAdapter.class),
+ () -> mock(SceneInteractor.class)) {
@Override
public ViewRootImpl getViewRootImpl() {
return mViewRootImpl;
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepository.kt
new file mode 100644
index 000000000000..b8284acc997b
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepository.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.camera.data.repository
+
+import android.os.UserHandle
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+
+class FakeCameraAutoRotateRepository : CameraAutoRotateRepository {
+ private val userMap = mutableMapOf<Int, MutableStateFlow<Boolean>>()
+
+ /** Send a Unit signal when value changes */
+ override fun isCameraAutoRotateSettingEnabled(userHandle: UserHandle): StateFlow<Boolean> =
+ getFlow(userHandle.identifier)
+
+ fun setEnabled(userHandle: UserHandle, enabled: Boolean) {
+ getFlow(userHandle.identifier).value = enabled
+ }
+
+ /** initializes the flow if already not */
+ private fun getFlow(userId: Int): MutableStateFlow<Boolean> =
+ userMap.getOrPut(userId) { MutableStateFlow(false) }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/MediaOutputComponentKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepositoryKosmos.kt
index ad8ccb00f45f..615c59661f1d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/MediaOutputComponentKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepositoryKosmos.kt
@@ -14,12 +14,9 @@
* limitations under the License.
*/
-package com.android.systemui.volume.panel
+package com.android.systemui.camera.data.repository
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.media.mediaOutputDialogFactory
-import com.android.systemui.plugins.activityStarter
-import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaOutputActionsInteractor
-val Kosmos.mediaOutputActionsInteractor by
- Kosmos.Fixture { MediaOutputActionsInteractor(mediaOutputDialogFactory, activityStarter) }
+val Kosmos.fakeCameraAutoRotateRepository: FakeCameraAutoRotateRepository by
+ Kosmos.Fixture { FakeCameraAutoRotateRepository() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepository.kt
new file mode 100644
index 000000000000..994e9b2f3683
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepository.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.camera.data.repository
+
+import android.os.UserHandle
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+
+class FakeCameraSensorPrivacyRepository : CameraSensorPrivacyRepository {
+
+ private val userMap = mutableMapOf<Int, MutableStateFlow<Boolean>>()
+ override fun isEnabled(userHandle: UserHandle): StateFlow<Boolean> =
+ getFlow(userHandle.identifier)
+
+ fun setEnabled(userHandle: UserHandle, enabled: Boolean) {
+ getFlow(userHandle.identifier).value = enabled
+ }
+
+ /** initializes the flow if already not */
+ private fun getFlow(userId: Int): MutableStateFlow<Boolean> =
+ userMap.getOrPut(userId) { MutableStateFlow(false) }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepositoryKosmos.kt
new file mode 100644
index 000000000000..c7e704cab42f
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepositoryKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.camera.data.repository
+
+import com.android.systemui.kosmos.Kosmos
+
+val Kosmos.fakeCameraSensorPrivacyRepository: FakeCameraSensorPrivacyRepository by
+ Kosmos.Fixture { FakeCameraSensorPrivacyRepository() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
index 1e305d67d40d..793e2d7efcda 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
@@ -18,6 +18,7 @@
package com.android.systemui.keyguard.data.repository
import android.graphics.Point
+import com.android.systemui.common.shared.model.Position
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
import com.android.systemui.keyguard.shared.model.BiometricUnlockSource
@@ -57,6 +58,9 @@ class FakeKeyguardRepository @Inject constructor() : KeyguardRepository {
private val _bottomAreaAlpha = MutableStateFlow(1f)
override val bottomAreaAlpha: StateFlow<Float> = _bottomAreaAlpha
+ private val _clockPosition = MutableStateFlow(Position(0, 0))
+ override val clockPosition: StateFlow<Position> = _clockPosition
+
private val _isKeyguardShowing = MutableStateFlow(false)
override val isKeyguardShowing: Flow<Boolean> = _isKeyguardShowing
@@ -145,6 +149,10 @@ class FakeKeyguardRepository @Inject constructor() : KeyguardRepository {
_bottomAreaAlpha.value = alpha
}
+ override fun setClockPosition(x: Int, y: Int) {
+ _clockPosition.value = Position(x, y)
+ }
+
fun setKeyguardShowing(isShowing: Boolean) {
_isKeyguardShowing.value = isShowing
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt
index d5d357f81b35..c2300a1ed1ad 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt
@@ -43,6 +43,7 @@ val Kosmos.keyguardRootViewModel by Fixture {
aodToLockscreenTransitionViewModel = aodToLockscreenTransitionViewModel,
dozingToGoneTransitionViewModel = dozingToGoneTransitionViewModel,
dozingToLockscreenTransitionViewModel = dozingToLockscreenTransitionViewModel,
+ dreamingToLockscreenTransitionViewModel = dreamingToLockscreenTransitionViewModel,
glanceableHubToLockscreenTransitionViewModel = glanceableHubToLockscreenTransitionViewModel,
goneToAodTransitionViewModel = goneToAodTransitionViewModel,
goneToDozingTransitionViewModel = goneToDozingTransitionViewModel,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/rotation/RotationLockTileKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/rotation/RotationLockTileKosmos.kt
new file mode 100644
index 000000000000..ecf8ce5bb8b8
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/rotation/RotationLockTileKosmos.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.impl.rotation
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.qsEventLogger
+import com.android.systemui.rotationlock.RotationLockNewModule
+
+val Kosmos.qsRotationLockTileConfig by
+ Kosmos.Fixture { RotationLockNewModule.provideRotationTileConfig(qsEventLogger) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorKosmos.kt
new file mode 100644
index 000000000000..db6ba6284599
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorKosmos.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.stack.domain.interactor
+
+import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.power.domain.interactor.powerInteractor
+
+val Kosmos.notificationStackInteractor by Fixture {
+ NotificationStackInteractor(
+ keyguardInteractor = keyguardInteractor,
+ powerInteractor = powerInteractor,
+ )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelKosmos.kt
index 25e3eac0b4b7..f1767ebb10d1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelKosmos.kt
@@ -16,16 +16,15 @@
package com.android.systemui.statusbar.notification.stack.ui.viewmodel
-import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.statusbar.domain.interactor.remoteInputInteractor
import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
import com.android.systemui.statusbar.notification.domain.interactor.seenNotificationsInteractor
import com.android.systemui.statusbar.notification.footer.ui.viewmodel.footerViewModel
import com.android.systemui.statusbar.notification.shelf.ui.viewmodel.notificationShelfViewModel
+import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationStackInteractor
import com.android.systemui.statusbar.policy.domain.interactor.userSetupInteractor
import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor
import java.util.Optional
@@ -37,8 +36,7 @@ val Kosmos.notificationListViewModel by Fixture {
Optional.of(footerViewModel),
Optional.of(notificationListLoggerViewModel),
activeNotificationsInteractor,
- keyguardInteractor,
- powerInteractor,
+ notificationStackInteractor,
remoteInputInteractor,
seenNotificationsInteractor,
shadeInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/DevicePostureControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/DevicePostureControllerKosmos.kt
new file mode 100644
index 000000000000..89eaf15a52d9
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/DevicePostureControllerKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.util.mockito.mock
+
+val Kosmos.devicePostureController by Kosmos.Fixture { mock<DevicePostureController>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeRotationLockController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeRotationLockController.java
index be57658a4266..4aa85a79c934 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeRotationLockController.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeRotationLockController.java
@@ -19,13 +19,29 @@ import android.testing.LeakCheck;
import com.android.systemui.statusbar.policy.RotationLockController;
import com.android.systemui.statusbar.policy.RotationLockController.RotationLockControllerCallback;
+import java.util.ArrayList;
+import java.util.List;
+
public class FakeRotationLockController extends BaseLeakChecker<RotationLockControllerCallback>
implements RotationLockController {
+ private boolean mIsLocked = false;
+ private final List<RotationLockControllerCallback> mCallbacks = new ArrayList<>();
public FakeRotationLockController(LeakCheck test) {
super(test, "rotation");
}
@Override
+ public void addCallback(RotationLockControllerCallback listener) {
+ mCallbacks.add(listener);
+ listener.onRotationLockStateChanged(mIsLocked, isRotationLockAffordanceVisible());
+ }
+
+ @Override
+ public void removeCallback(RotationLockControllerCallback listener) {
+ mCallbacks.remove(listener);
+ }
+
+ @Override
public void setListening(boolean listening) {
}
@@ -42,12 +58,15 @@ public class FakeRotationLockController extends BaseLeakChecker<RotationLockCont
@Override
public boolean isRotationLocked() {
- return false;
+ return mIsLocked;
}
@Override
public void setRotationLocked(boolean locked, String caller) {
-
+ mIsLocked = locked;
+ for (RotationLockControllerCallback callback : mCallbacks) {
+ callback.onRotationLockStateChanged(locked, isRotationLockAffordanceVisible());
+ }
}
@Override
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/MediaOutputKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/MediaOutputKosmos.kt
index 3f20df3376d9..a3b1a0eb260d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/MediaOutputKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/MediaOutputKosmos.kt
@@ -25,7 +25,6 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testCase
import com.android.systemui.kosmos.testScope
import com.android.systemui.media.mediaOutputDialogFactory
-import com.android.systemui.plugins.activityStarter
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
@@ -43,7 +42,7 @@ val Kosmos.localMediaRepositoryFactory: LocalMediaRepositoryFactory by
Kosmos.Fixture { FakeLocalMediaRepositoryFactory { localMediaRepository } }
val Kosmos.mediaOutputActionsInteractor by
- Kosmos.Fixture { MediaOutputActionsInteractor(mediaOutputDialogFactory, activityStarter) }
+ Kosmos.Fixture { MediaOutputActionsInteractor(mediaOutputDialogFactory) }
val Kosmos.mediaControllerRepository by Kosmos.Fixture { FakeMediaControllerRepository() }
val Kosmos.mediaOutputInteractor by
Kosmos.Fixture {
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
index f4ea754c21ba..279bd72da6e7 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
@@ -1004,17 +1004,19 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
&& overscrollState(event, mFirstPointerDownLocation)
== OVERSCROLL_VERTICAL_EDGE) {
transitionToDelegatingStateAndClear();
- } // TODO(b/319537921): should there be an else here?
- //Primary pointer is swiping, so transit to PanningScalingState
- transitToPanningScalingStateAndClear();
+ } else {
+ //Primary pointer is swiping, so transit to PanningScalingState
+ transitToPanningScalingStateAndClear();
+ }
} else if (mIsSinglePanningEnabled
&& isActivated()
&& event.getPointerCount() == 1) {
if (overscrollState(event, mFirstPointerDownLocation)
== OVERSCROLL_VERTICAL_EDGE) {
transitionToDelegatingStateAndClear();
- } // TODO(b/319537921): should there be an else here?
- transitToSinglePanningStateAndClear();
+ } else {
+ transitToSinglePanningStateAndClear();
+ }
} else if (!mIsTwoFingerCountReached) {
// If it is a two-finger gesture, do not transition to the
// delegating state to ensure the reachability of
@@ -1257,17 +1259,19 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
&& overscrollState(event, mFirstPointerDownLocation)
== OVERSCROLL_VERTICAL_EDGE) {
transitionToDelegatingStateAndClear();
+ } else {
+ //Primary pointer is swiping, so transit to PanningScalingState
+ transitToPanningScalingStateAndClear();
}
- //Primary pointer is swiping, so transit to PanningScalingState
- transitToPanningScalingStateAndClear();
} else if (mIsSinglePanningEnabled
&& isActivated()
&& event.getPointerCount() == 1) {
if (overscrollState(event, mFirstPointerDownLocation)
== OVERSCROLL_VERTICAL_EDGE) {
transitionToDelegatingStateAndClear();
+ } else {
+ transitToSinglePanningStateAndClear();
}
- transitToSinglePanningStateAndClear();
} else {
transitionToDelegatingStateAndClear();
}
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 6f45f60f6dfa..29b9d441cf38 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -476,8 +476,12 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
} else {
// If the package is being updated, we'll receive a PACKAGE_ADDED
// shortly, otherwise it is removed permanently.
- final boolean packageRemovedPermanently = (extras == null
- || !extras.getBoolean(Intent.EXTRA_REPLACING, false));
+ boolean isReplacing = extras != null && extras.getBoolean(Intent.EXTRA_REPLACING,
+ false);
+ boolean isArchival = extras != null && extras.getBoolean(Intent.EXTRA_ARCHIVAL,
+ false);
+ final boolean packageRemovedPermanently =
+ (extras == null || !isReplacing || (isReplacing && isArchival));
if (packageRemovedPermanently) {
for (String pkgName : pkgList) {
@@ -2074,6 +2078,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
private void handleNotifyAppWidgetViewDataChanged(Host host, IAppWidgetHost callbacks,
int appWidgetId, int viewId, long requestId) {
try {
+ Slog.d(TAG, "Trying to notify widget view data changed");
callbacks.viewDataChanged(appWidgetId, viewId);
host.lastWidgetUpdateSequenceNo = requestId;
} catch (RemoteException re) {
@@ -2158,6 +2163,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
private void handleNotifyUpdateAppWidget(Host host, IAppWidgetHost callbacks,
int appWidgetId, RemoteViews views, long requestId) {
try {
+ Slog.d(TAG, "Trying to notify widget update for package "
+ + (views == null ? "null" : views.getPackage())
+ + " with widget id: " + appWidgetId);
callbacks.updateAppWidget(appWidgetId, views);
host.lastWidgetUpdateSequenceNo = requestId;
} catch (RemoteException re) {
@@ -2196,6 +2204,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
private void handleNotifyProviderChanged(Host host, IAppWidgetHost callbacks,
int appWidgetId, AppWidgetProviderInfo info, long requestId) {
try {
+ Slog.d(TAG, "Trying to notify provider update");
callbacks.providerChanged(appWidgetId, info);
host.lastWidgetUpdateSequenceNo = requestId;
} catch (RemoteException re) {
@@ -2239,6 +2248,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
private void handleNotifyAppWidgetRemoved(Host host, IAppWidgetHost callbacks, int appWidgetId,
long requestId) {
try {
+ Slog.d(TAG, "Trying to notify widget removed");
callbacks.appWidgetRemoved(appWidgetId);
host.lastWidgetUpdateSequenceNo = requestId;
} catch (RemoteException re) {
@@ -2286,6 +2296,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
private void handleNotifyProvidersChanged(Host host, IAppWidgetHost callbacks) {
try {
+ Slog.d(TAG, "Trying to notify widget providers changed");
callbacks.providersChanged();
} catch (RemoteException re) {
synchronized (mLock) {
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index d779fbf2eabc..551297b253d1 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -4782,7 +4782,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
}
if (isCredmanIntegrationActive(response)) {
- Slog.d(TAG, "Attempting to add Credential Manager callback to pinned entries");
addCredentialManagerCallback(response);
}
@@ -5713,7 +5712,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
/* isPrimary= */ true);
updateFillDialogTriggerIdsLocked();
updateTrackedIdsLocked();
-
if (mCurrentViewId == null) {
return;
}
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index a478a3d84161..17ba0730c8e4 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -228,8 +228,6 @@ public class CompanionDeviceManagerService extends SystemService {
/* cdmService */ this, mAssociationStore, mPersistentStore,
mSystemDataTransferRequestStore, mAssociationRequestsProcessor);
- loadAssociationsFromDisk();
-
mObservableUuidStore.getObservableUuidsForUser(getContext().getUserId());
mAssociationStore.registerListener(mAssociationStoreChangeListener);
@@ -240,13 +238,18 @@ public class CompanionDeviceManagerService extends SystemService {
mCompanionAppController = new CompanionApplicationController(
context, mAssociationStore, mObservableUuidStore, mDevicePresenceMonitor,
mPowerManagerInternal);
+
+ mAssociationRevokeProcessor = new AssociationRevokeProcessor(this, mAssociationStore,
+ mPackageManagerInternal, mDevicePresenceMonitor, mCompanionAppController,
+ mSystemDataTransferRequestStore);
+
+ loadAssociationsFromDisk();
+
mTransportManager = new CompanionTransportManager(context, mAssociationStore);
mSystemDataTransferProcessor = new SystemDataTransferProcessor(this,
mPackageManagerInternal, mAssociationStore,
mSystemDataTransferRequestStore, mTransportManager);
- mAssociationRevokeProcessor = new AssociationRevokeProcessor(this, mAssociationStore,
- mPackageManagerInternal, mDevicePresenceMonitor, mCompanionAppController,
- mSystemDataTransferRequestStore);
+
// TODO(b/279663946): move context sync to a dedicated system service
mCrossDeviceSyncController = new CrossDeviceSyncController(getContext(), mTransportManager);
diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java
index 9189ea763577..e1d7be121865 100644
--- a/services/core/java/com/android/server/SystemConfig.java
+++ b/services/core/java/com/android/server/SystemConfig.java
@@ -348,6 +348,9 @@ public class SystemConfig {
// marked as stopped by the system
@NonNull private final Set<String> mInitialNonStoppedSystemPackages = new ArraySet<>();
+ // Which packages (key) are allowed to join particular SharedUid (value).
+ @NonNull private final Map<String, String> mPackageToSharedUidAllowList = new ArrayMap<>();
+
// A map of preloaded package names and the path to its app metadata file path.
private final ArrayMap<String, String> mAppMetadataFilePaths = new ArrayMap<>();
@@ -567,6 +570,11 @@ public class SystemConfig {
return mInitialNonStoppedSystemPackages;
}
+ @NonNull
+ public Map<String, String> getPackageToSharedUidAllowList() {
+ return mPackageToSharedUidAllowList;
+ }
+
public ArrayMap<String, String> getAppMetadataFilePaths() {
return mAppMetadataFilePaths;
}
@@ -1563,6 +1571,19 @@ public class SystemConfig {
mInitialNonStoppedSystemPackages.add(pkgName);
}
} break;
+ case "allow-package-shareduid": {
+ String pkgName = parser.getAttributeValue(null, "package");
+ String sharedUid = parser.getAttributeValue(null, "shareduid");
+ if (TextUtils.isEmpty(pkgName)) {
+ Slog.w(TAG, "<" + name + "> without package in " + permFile
+ + " at " + parser.getPositionDescription());
+ } else if (TextUtils.isEmpty(sharedUid)) {
+ Slog.w(TAG, "<" + name + "> without shareduid in " + permFile
+ + " at " + parser.getPositionDescription());
+ } else {
+ mPackageToSharedUidAllowList.put(pkgName, sharedUid);
+ }
+ }
case "asl-file": {
String packageName = parser.getAttributeValue(null, "package");
String path = parser.getAttributeValue(null, "path");
diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING
index 5e9d1cbb32ca..8dc15ade532e 100644
--- a/services/core/java/com/android/server/TEST_MAPPING
+++ b/services/core/java/com/android/server/TEST_MAPPING
@@ -163,6 +163,9 @@
}
],
"file_patterns": ["PinnerService\\.java"]
+ },
+ {
+ "name": "FrameworksVpnTests"
}
]
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index b8e09cce93b9..258f53d982d2 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -372,6 +372,15 @@ public final class ActiveServices {
@Overridable
public static final long FGS_BOOT_COMPLETED_RESTRICTIONS = 296558535L;
+ /**
+ * Disables foreground service background starts in System Alert Window for all types
+ * unless it already has a System Overlay Window.
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = VERSION_CODES.VANILLA_ICE_CREAM)
+ @Overridable
+ public static final long FGS_SAW_RESTRICTIONS = 319471980L;
+
final ActivityManagerService mAm;
// Maximum number of services that we allow to start in the background
@@ -8526,10 +8535,31 @@ public final class ActiveServices {
}
}
+ // The flag being enabled isn't enough to deny background start: we need to also check
+ // if there is a system alert UI present.
if (ret == REASON_DENIED) {
- if (mAm.mAtmInternal.hasSystemAlertWindowPermission(callingUid, callingPid,
- callingPackage)) {
- ret = REASON_SYSTEM_ALERT_WINDOW_PERMISSION;
+ // Flag check: are we disabling SAW FGS background starts?
+ final boolean shouldDisableSaw = Flags.fgsDisableSaw()
+ && CompatChanges.isChangeEnabled(FGS_BOOT_COMPLETED_RESTRICTIONS, callingUid);
+ if (shouldDisableSaw) {
+ final ProcessRecord processRecord = mAm
+ .getProcessRecordLocked(targetService.processName,
+ targetService.appInfo.uid);
+ if (processRecord != null) {
+ if (processRecord.mState.hasOverlayUi()) {
+ if (mAm.mAtmInternal.hasSystemAlertWindowPermission(callingUid, callingPid,
+ callingPackage)) {
+ ret = REASON_SYSTEM_ALERT_WINDOW_PERMISSION;
+ }
+ }
+ } else {
+ Slog.e(TAG, "Could not find process record for SAW check");
+ }
+ } else {
+ if (mAm.mAtmInternal.hasSystemAlertWindowPermission(callingUid, callingPid,
+ callingPackage)) {
+ ret = REASON_SYSTEM_ALERT_WINDOW_PERMISSION;
+ }
}
}
diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig
index c06bdf90a75a..b1823b4ee38f 100644
--- a/services/core/java/com/android/server/am/flags.aconfig
+++ b/services/core/java/com/android/server/am/flags.aconfig
@@ -23,6 +23,13 @@ flag {
}
flag {
+ name: "fgs_disable_saw"
+ namespace: "backstage_power"
+ description: "Disable System Alert Window FGS start"
+ bug: "296558535"
+}
+
+flag {
name: "bfgs_managed_network_access"
namespace: "backstage_power"
description: "Restrict network access for certain applications in BFGS process state"
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
index 6b8586a2e483..68b4e3fb51ba 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
@@ -119,7 +119,7 @@ public class FaceService extends SystemService {
* Receives the incoming binder calls from FaceManager.
*/
@VisibleForTesting final class FaceServiceWrapper extends IFaceService.Stub {
- @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
@NonNull String opPackageName) {
diff --git a/services/core/java/com/android/server/connectivity/TEST_MAPPING b/services/core/java/com/android/server/connectivity/TEST_MAPPING
index 687d4b06b4c0..f50831964303 100644
--- a/services/core/java/com/android/server/connectivity/TEST_MAPPING
+++ b/services/core/java/com/android/server/connectivity/TEST_MAPPING
@@ -7,7 +7,7 @@
"exclude-annotation": "com.android.testutils.SkipPresubmit"
}
],
- "file_patterns": ["Vpn\\.java", "VpnIkeV2Utils\\.java", "VpnProfileStore\\.java"]
+ "file_patterns": ["VpnIkeV2Utils\\.java", "VpnProfileStore\\.java"]
}
],
"presubmit-large": [
@@ -26,5 +26,10 @@
],
"file_patterns": ["Vpn\\.java", "VpnIkeV2Utils\\.java", "VpnProfileStore\\.java"]
}
+ ],
+ "postsubmit":[
+ {
+ "name":"FrameworksVpnTests"
+ }
]
} \ No newline at end of file
diff --git a/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java b/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java
index babc36efcca8..8e844501ab34 100644
--- a/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java
+++ b/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java
@@ -200,12 +200,9 @@ public class DisplayBrightnessStrategySelector {
// We are not checking the targetDisplayState, but rather relying on the policy because
// a user can define a different display state(displayPowerRequest.dozeScreenState) too
// in the request with the Doze policy
- if (displayPowerRequest.policy == DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE) {
- if (!mAllowAutoBrightnessWhileDozingConfig) {
- return true;
- }
- }
- return false;
+ return displayPowerRequest.policy == DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE
+ && !mAllowAutoBrightnessWhileDozingConfig
+ && BrightnessUtils.isValidBrightnessValue(displayPowerRequest.dozeScreenBrightness);
}
@VisibleForTesting
diff --git a/services/core/java/com/android/server/flags/services.aconfig b/services/core/java/com/android/server/flags/services.aconfig
new file mode 100644
index 000000000000..10b5eff06e0c
--- /dev/null
+++ b/services/core/java/com/android/server/flags/services.aconfig
@@ -0,0 +1,8 @@
+package: "com.android.server.flags"
+
+flag {
+ namespace: "wear_frameworks"
+ name: "enable_odp_feature_guard"
+ description: "Enable guard based on system feature to prevent OnDevicePersonalization service from starting on form factors."
+ bug: "322249125"
+} \ No newline at end of file
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index a79e7715f064..05b1cb69235b 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -54,6 +54,7 @@ import android.hardware.input.InputManager;
import android.hardware.input.InputSensorInfo;
import android.hardware.input.InputSettings;
import android.hardware.input.KeyboardLayout;
+import android.hardware.input.KeyboardLayoutSelectionResult;
import android.hardware.input.TouchCalibration;
import android.hardware.lights.Light;
import android.hardware.lights.LightState;
@@ -1244,9 +1245,9 @@ public class InputManagerService extends IInputManager.Stub
}
@Override // Binder call
- public String getKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier,
- @UserIdInt int userId, @NonNull InputMethodInfo imeInfo,
- @Nullable InputMethodSubtype imeSubtype) {
+ public KeyboardLayoutSelectionResult getKeyboardLayoutForInputDevice(
+ InputDeviceIdentifier identifier, @UserIdInt int userId,
+ @NonNull InputMethodInfo imeInfo, @Nullable InputMethodSubtype imeSubtype) {
return mKeyboardLayoutManager.getKeyboardLayoutForInputDevice(identifier, userId,
imeInfo, imeSubtype);
}
diff --git a/services/core/java/com/android/server/input/KeyboardLayoutManager.java b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
index 46668de042d4..283e692ffbab 100644
--- a/services/core/java/com/android/server/input/KeyboardLayoutManager.java
+++ b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
@@ -16,10 +16,11 @@
package com.android.server.input;
-import static com.android.server.input.KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEFAULT;
-import static com.android.server.input.KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEVICE;
-import static com.android.server.input.KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_USER;
-import static com.android.server.input.KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD;
+import static android.hardware.input.KeyboardLayoutSelectionResult.FAILED;
+import static android.hardware.input.KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_USER;
+import static android.hardware.input.KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_DEVICE;
+import static android.hardware.input.KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD;
+import static android.hardware.input.KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_DEFAULT;
import android.annotation.AnyThread;
import android.annotation.MainThread;
@@ -46,6 +47,7 @@ import android.content.res.XmlResourceParser;
import android.hardware.input.InputDeviceIdentifier;
import android.hardware.input.InputManager;
import android.hardware.input.KeyboardLayout;
+import android.hardware.input.KeyboardLayoutSelectionResult;
import android.icu.lang.UScript;
import android.icu.util.ULocale;
import android.os.Bundle;
@@ -79,7 +81,6 @@ import com.android.internal.util.XmlUtils;
import com.android.server.LocalServices;
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
import com.android.server.input.KeyboardMetricsCollector.KeyboardConfigurationEvent;
-import com.android.server.input.KeyboardMetricsCollector.LayoutSelectionCriteria;
import com.android.server.inputmethod.InputMethodManagerInternal;
import libcore.io.Streams;
@@ -130,7 +131,8 @@ class KeyboardLayoutManager implements InputManager.InputDeviceListener {
// This cache stores "best-matched" layouts so that we don't need to run the matching
// algorithm repeatedly.
@GuardedBy("mKeyboardLayoutCache")
- private final Map<String, KeyboardLayoutInfo> mKeyboardLayoutCache = new ArrayMap<>();
+ private final Map<String, KeyboardLayoutSelectionResult> mKeyboardLayoutCache =
+ new ArrayMap<>();
private final Object mImeInfoLock = new Object();
@Nullable
@GuardedBy("mImeInfoLock")
@@ -222,17 +224,17 @@ class KeyboardLayoutManager implements InputManager.InputDeviceListener {
} else {
Set<String> selectedLayouts = new HashSet<>();
List<ImeInfo> imeInfoList = getImeInfoListForLayoutMapping();
- List<KeyboardLayoutInfo> layoutInfoList = new ArrayList<>();
+ List<KeyboardLayoutSelectionResult> resultList = new ArrayList<>();
boolean hasMissingLayout = false;
for (ImeInfo imeInfo : imeInfoList) {
// Check if the layout has been previously configured
- KeyboardLayoutInfo layoutInfo = getKeyboardLayoutForInputDeviceInternal(
+ KeyboardLayoutSelectionResult result = getKeyboardLayoutForInputDeviceInternal(
keyboardIdentifier, imeInfo);
- boolean noLayoutFound = layoutInfo == null || layoutInfo.mDescriptor == null;
+ boolean noLayoutFound = result.getLayoutDescriptor() == null;
if (!noLayoutFound) {
- selectedLayouts.add(layoutInfo.mDescriptor);
+ selectedLayouts.add(result.getLayoutDescriptor());
}
- layoutInfoList.add(layoutInfo);
+ resultList.add(result);
hasMissingLayout |= noLayoutFound;
}
@@ -260,7 +262,7 @@ class KeyboardLayoutManager implements InputManager.InputDeviceListener {
}
if (shouldLogConfiguration) {
- logKeyboardConfigurationEvent(inputDevice, imeInfoList, layoutInfoList,
+ logKeyboardConfigurationEvent(inputDevice, imeInfoList, resultList,
!mDataStore.hasInputDeviceEntry(key));
}
} finally {
@@ -757,10 +759,10 @@ class KeyboardLayoutManager implements InputManager.InputDeviceListener {
String keyboardLayoutDescriptor;
if (useNewSettingsUi()) {
synchronized (mImeInfoLock) {
- KeyboardLayoutInfo layoutInfo = getKeyboardLayoutForInputDeviceInternal(
+ KeyboardLayoutSelectionResult result = getKeyboardLayoutForInputDeviceInternal(
new KeyboardIdentifier(identifier, languageTag, layoutType),
mCurrentImeInfo);
- keyboardLayoutDescriptor = layoutInfo == null ? null : layoutInfo.mDescriptor;
+ keyboardLayoutDescriptor = result.getLayoutDescriptor();
}
} else {
keyboardLayoutDescriptor = getCurrentKeyboardLayoutForInputDevice(identifier);
@@ -788,26 +790,26 @@ class KeyboardLayoutManager implements InputManager.InputDeviceListener {
}
@AnyThread
- @Nullable
- public String getKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier,
- @UserIdInt int userId, @NonNull InputMethodInfo imeInfo,
- @Nullable InputMethodSubtype imeSubtype) {
+ @NonNull
+ public KeyboardLayoutSelectionResult getKeyboardLayoutForInputDevice(
+ InputDeviceIdentifier identifier, @UserIdInt int userId,
+ @NonNull InputMethodInfo imeInfo, @Nullable InputMethodSubtype imeSubtype) {
if (!useNewSettingsUi()) {
Slog.e(TAG, "getKeyboardLayoutForInputDevice() API not supported");
- return null;
+ return FAILED;
}
InputDevice inputDevice = getInputDevice(identifier);
if (inputDevice == null || inputDevice.isVirtual() || !inputDevice.isFullKeyboard()) {
- return null;
+ return FAILED;
}
KeyboardIdentifier keyboardIdentifier = new KeyboardIdentifier(inputDevice);
- KeyboardLayoutInfo layoutInfo = getKeyboardLayoutForInputDeviceInternal(
+ KeyboardLayoutSelectionResult result = getKeyboardLayoutForInputDeviceInternal(
keyboardIdentifier, new ImeInfo(userId, imeInfo, imeSubtype));
if (DEBUG) {
Slog.d(TAG, "getKeyboardLayoutForInputDevice() " + identifier.toString() + ", userId : "
- + userId + ", subtype = " + imeSubtype + " -> " + layoutInfo);
+ + userId + ", subtype = " + imeSubtype + " -> " + result);
}
- return layoutInfo != null ? layoutInfo.mDescriptor : null;
+ return result;
}
@AnyThread
@@ -942,13 +944,13 @@ class KeyboardLayoutManager implements InputManager.InputDeviceListener {
}
@Nullable
- private KeyboardLayoutInfo getKeyboardLayoutForInputDeviceInternal(
+ private KeyboardLayoutSelectionResult getKeyboardLayoutForInputDeviceInternal(
KeyboardIdentifier keyboardIdentifier, @Nullable ImeInfo imeInfo) {
String layoutKey = new LayoutKey(keyboardIdentifier, imeInfo).toString();
synchronized (mDataStore) {
String layout = mDataStore.getKeyboardLayout(keyboardIdentifier.toString(), layoutKey);
if (layout != null) {
- return new KeyboardLayoutInfo(layout, LAYOUT_SELECTION_CRITERIA_USER);
+ return new KeyboardLayoutSelectionResult(layout, LAYOUT_SELECTION_CRITERIA_USER);
}
}
@@ -961,17 +963,17 @@ class KeyboardLayoutManager implements InputManager.InputDeviceListener {
KeyboardLayout[] layoutList = getKeyboardLayoutListForInputDeviceInternal(
keyboardIdentifier, imeInfo);
// Call auto-matching algorithm to find the best matching layout
- KeyboardLayoutInfo layoutInfo =
+ KeyboardLayoutSelectionResult result =
getDefaultKeyboardLayoutBasedOnImeInfo(keyboardIdentifier, imeInfo,
layoutList);
- mKeyboardLayoutCache.put(layoutKey, layoutInfo);
- return layoutInfo;
+ mKeyboardLayoutCache.put(layoutKey, result);
+ return result;
}
}
}
- @Nullable
- private static KeyboardLayoutInfo getDefaultKeyboardLayoutBasedOnImeInfo(
+ @NonNull
+ private static KeyboardLayoutSelectionResult getDefaultKeyboardLayoutBasedOnImeInfo(
KeyboardIdentifier keyboardIdentifier, @Nullable ImeInfo imeInfo,
KeyboardLayout[] layoutList) {
Arrays.sort(layoutList);
@@ -986,7 +988,7 @@ class KeyboardLayoutManager implements InputManager.InputDeviceListener {
+ "vendor and product Ids. " + keyboardIdentifier
+ " : " + layout.getDescriptor());
}
- return new KeyboardLayoutInfo(layout.getDescriptor(),
+ return new KeyboardLayoutSelectionResult(layout.getDescriptor(),
LAYOUT_SELECTION_CRITERIA_DEVICE);
}
}
@@ -1004,13 +1006,14 @@ class KeyboardLayoutManager implements InputManager.InputDeviceListener {
+ "HW information (Language tag and Layout type). "
+ keyboardIdentifier + " : " + layoutDesc);
}
- return new KeyboardLayoutInfo(layoutDesc, LAYOUT_SELECTION_CRITERIA_DEVICE);
+ return new KeyboardLayoutSelectionResult(layoutDesc,
+ LAYOUT_SELECTION_CRITERIA_DEVICE);
}
}
if (imeInfo == null || imeInfo.mImeSubtypeHandle == null || imeInfo.mImeSubtype == null) {
// Can't auto select layout based on IME info is null
- return null;
+ return FAILED;
}
InputMethodSubtype subtype = imeInfo.mImeSubtype;
@@ -1027,9 +1030,10 @@ class KeyboardLayoutManager implements InputManager.InputDeviceListener {
+ layoutDesc);
}
if (layoutDesc != null) {
- return new KeyboardLayoutInfo(layoutDesc, LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD);
+ return new KeyboardLayoutSelectionResult(layoutDesc,
+ LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD);
}
- return null;
+ return FAILED;
}
@Nullable
@@ -1246,21 +1250,23 @@ class KeyboardLayoutManager implements InputManager.InputDeviceListener {
}
private void logKeyboardConfigurationEvent(@NonNull InputDevice inputDevice,
- @NonNull List<ImeInfo> imeInfoList, @NonNull List<KeyboardLayoutInfo> layoutInfoList,
+ @NonNull List<ImeInfo> imeInfoList,
+ @NonNull List<KeyboardLayoutSelectionResult> resultList,
boolean isFirstConfiguration) {
- if (imeInfoList.isEmpty() || layoutInfoList.isEmpty()) {
+ if (imeInfoList.isEmpty() || resultList.isEmpty()) {
return;
}
KeyboardConfigurationEvent.Builder configurationEventBuilder =
new KeyboardConfigurationEvent.Builder(inputDevice).setIsFirstTimeConfiguration(
isFirstConfiguration);
for (int i = 0; i < imeInfoList.size(); i++) {
- KeyboardLayoutInfo layoutInfo = layoutInfoList.get(i);
+ KeyboardLayoutSelectionResult result = resultList.get(i);
String layoutName = null;
int layoutSelectionCriteria = LAYOUT_SELECTION_CRITERIA_DEFAULT;
- if (layoutInfo != null && layoutInfo.mDescriptor != null) {
- layoutSelectionCriteria = layoutInfo.mSelectionCriteria;
- KeyboardLayoutDescriptor d = KeyboardLayoutDescriptor.parse(layoutInfo.mDescriptor);
+ if (result != null && result.getLayoutDescriptor() != null) {
+ layoutSelectionCriteria = result.getSelectionCriteria();
+ KeyboardLayoutDescriptor d = KeyboardLayoutDescriptor.parse(
+ result.getLayoutDescriptor());
if (d != null) {
layoutName = d.keyboardLayoutName;
}
@@ -1477,33 +1483,6 @@ class KeyboardLayoutManager implements InputManager.InputDeviceListener {
}
}
- private static class KeyboardLayoutInfo {
- @Nullable
- private final String mDescriptor;
- @LayoutSelectionCriteria
- private final int mSelectionCriteria;
-
- private KeyboardLayoutInfo(@Nullable String descriptor,
- @LayoutSelectionCriteria int selectionCriteria) {
- mDescriptor = descriptor;
- mSelectionCriteria = selectionCriteria;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof KeyboardLayoutInfo) {
- return Objects.equals(mDescriptor, ((KeyboardLayoutInfo) obj).mDescriptor)
- && mSelectionCriteria == ((KeyboardLayoutInfo) obj).mSelectionCriteria;
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return 31 * mSelectionCriteria + mDescriptor.hashCode();
- }
- }
-
private interface KeyboardLayoutVisitor {
void visitKeyboardLayout(Resources resources,
int keyboardLayoutResId, KeyboardLayout layout);
diff --git a/services/core/java/com/android/server/input/KeyboardMetricsCollector.java b/services/core/java/com/android/server/input/KeyboardMetricsCollector.java
index f53b9411a6a7..b8ae737919d9 100644
--- a/services/core/java/com/android/server/input/KeyboardMetricsCollector.java
+++ b/services/core/java/com/android/server/input/KeyboardMetricsCollector.java
@@ -16,14 +16,18 @@
package com.android.server.input;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static android.hardware.input.KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_USER;
+import static android.hardware.input.KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_DEVICE;
+import static android.hardware.input.KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD;
+import static android.hardware.input.KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_DEFAULT;
+import static android.hardware.input.KeyboardLayoutSelectionResult.layoutSelectionCriteriaToString;
-import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.role.RoleManager;
import android.content.Intent;
import android.hardware.input.KeyboardLayout;
+import android.hardware.input.KeyboardLayoutSelectionResult.LayoutSelectionCriteria;
import android.icu.util.ULocale;
import android.text.TextUtils;
import android.util.Log;
@@ -40,7 +44,6 @@ import com.android.internal.os.KeyboardConfiguredProto.RepeatedKeyboardLayoutCon
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.policy.ModifierShortcutManager;
-import java.lang.annotation.Retention;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -57,32 +60,6 @@ public final class KeyboardMetricsCollector {
// (requires restart)
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- @Retention(SOURCE)
- @IntDef(prefix = {"LAYOUT_SELECTION_CRITERIA_"}, value = {
- LAYOUT_SELECTION_CRITERIA_UNSPECIFIED,
- LAYOUT_SELECTION_CRITERIA_USER,
- LAYOUT_SELECTION_CRITERIA_DEVICE,
- LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD,
- LAYOUT_SELECTION_CRITERIA_DEFAULT
- })
- public @interface LayoutSelectionCriteria {
- }
-
- /** Unspecified layout selection criteria */
- public static final int LAYOUT_SELECTION_CRITERIA_UNSPECIFIED = 0;
-
- /** Manual selection by user */
- public static final int LAYOUT_SELECTION_CRITERIA_USER = 1;
-
- /** Auto-detection based on device provided language tag and layout type */
- public static final int LAYOUT_SELECTION_CRITERIA_DEVICE = 2;
-
- /** Auto-detection based on IME provided language tag and layout type */
- public static final int LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD = 3;
-
- /** Default selection */
- public static final int LAYOUT_SELECTION_CRITERIA_DEFAULT = 4;
-
@VisibleForTesting
static final String DEFAULT_LAYOUT_NAME = "Default";
@@ -629,30 +606,16 @@ public final class KeyboardMetricsCollector {
@Override
public String toString() {
- return "{keyboardLanguageTag = " + keyboardLanguageTag + " keyboardLayoutType = "
+ return "{keyboardLanguageTag = " + keyboardLanguageTag
+ + " keyboardLayoutType = "
+ KeyboardLayout.LayoutType.getLayoutNameFromValue(keyboardLayoutType)
- + " keyboardLayoutName = " + keyboardLayoutName + " layoutSelectionCriteria = "
- + getStringForSelectionCriteria(layoutSelectionCriteria)
- + "imeLanguageTag = " + imeLanguageTag + " imeLayoutType = "
- + KeyboardLayout.LayoutType.getLayoutNameFromValue(imeLayoutType) + "}";
- }
- }
-
- private static String getStringForSelectionCriteria(
- @LayoutSelectionCriteria int layoutSelectionCriteria) {
- switch (layoutSelectionCriteria) {
- case LAYOUT_SELECTION_CRITERIA_UNSPECIFIED:
- return "LAYOUT_SELECTION_CRITERIA_UNSPECIFIED";
- case LAYOUT_SELECTION_CRITERIA_USER:
- return "LAYOUT_SELECTION_CRITERIA_USER";
- case LAYOUT_SELECTION_CRITERIA_DEVICE:
- return "LAYOUT_SELECTION_CRITERIA_DEVICE";
- case LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD:
- return "LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD";
- case LAYOUT_SELECTION_CRITERIA_DEFAULT:
- return "LAYOUT_SELECTION_CRITERIA_DEFAULT";
- default:
- return "INVALID_CRITERIA";
+ + " keyboardLayoutName = " + keyboardLayoutName
+ + " layoutSelectionCriteria = "
+ + layoutSelectionCriteriaToString(layoutSelectionCriteria)
+ + " imeLanguageTag = " + imeLanguageTag
+ + " imeLayoutType = " + KeyboardLayout.LayoutType.getLayoutNameFromValue(
+ imeLayoutType)
+ + "}";
}
}
diff --git a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
index 8826e3d2d345..73f1aad31d72 100644
--- a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
+++ b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
@@ -91,10 +91,10 @@ final class DefaultImeVisibilityApplier implements ImeVisibilityApplier {
if (DEBUG_IME_VISIBILITY) {
EventLog.writeEvent(IMF_SHOW_IME,
statsToken != null ? statsToken.getTag() : ImeTracker.TOKEN_NONE,
- Objects.toString(mService.mCurFocusedWindow),
+ Objects.toString(mService.mImeBindingState.mFocusedWindow),
InputMethodDebug.softInputDisplayReasonToString(reason),
InputMethodDebug.softInputModeToString(
- mService.mCurFocusedWindowSoftInputMode));
+ mService.mImeBindingState.mFocusedWindowSoftInputMode));
}
mService.onShowHideSoftInputRequested(true /* show */, showInputToken, reason,
statsToken);
@@ -122,10 +122,10 @@ final class DefaultImeVisibilityApplier implements ImeVisibilityApplier {
if (DEBUG_IME_VISIBILITY) {
EventLog.writeEvent(IMF_HIDE_IME,
statsToken != null ? statsToken.getTag() : ImeTracker.TOKEN_NONE,
- Objects.toString(mService.mCurFocusedWindow),
+ Objects.toString(mService.mImeBindingState.mFocusedWindow),
InputMethodDebug.softInputDisplayReasonToString(reason),
InputMethodDebug.softInputModeToString(
- mService.mCurFocusedWindowSoftInputMode));
+ mService.mImeBindingState.mFocusedWindowSoftInputMode));
}
mService.onShowHideSoftInputRequested(false /* show */, hideInputToken, reason,
statsToken);
@@ -207,7 +207,8 @@ final class DefaultImeVisibilityApplier implements ImeVisibilityApplier {
@Override
public boolean removeImeScreenshot(int displayId) {
if (mImeTargetVisibilityPolicy.removeImeScreenshot(displayId)) {
- mService.onShowHideSoftInputRequested(false /* show */, mService.mCurFocusedWindow,
+ mService.onShowHideSoftInputRequested(false /* show */,
+ mService.mImeBindingState.mFocusedWindow,
REMOVE_IME_SCREENSHOT_FROM_IMMS, null /* statsToken */);
return true;
}
diff --git a/services/core/java/com/android/server/inputmethod/ImeBindingState.java b/services/core/java/com/android/server/inputmethod/ImeBindingState.java
new file mode 100644
index 000000000000..4c20c3b9784a
--- /dev/null
+++ b/services/core/java/com/android/server/inputmethod/ImeBindingState.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.inputmethod;
+
+import static android.server.inputmethod.InputMethodManagerServiceProto.CUR_FOCUSED_WINDOW_NAME;
+import static android.server.inputmethod.InputMethodManagerServiceProto.CUR_FOCUSED_WINDOW_SOFT_INPUT_MODE;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED;
+
+import android.annotation.Nullable;
+import android.os.IBinder;
+import android.util.Printer;
+import android.util.proto.ProtoOutputStream;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
+import android.view.inputmethod.EditorInfo;
+
+import com.android.internal.inputmethod.InputMethodDebug;
+import com.android.server.wm.WindowManagerInternal;
+
+/**
+ * Stores information related to one active IME client on one display.
+ */
+final class ImeBindingState {
+
+ /**
+ * The last window token that we confirmed to be focused. This is always updated upon
+ * reports from the input method client. If the window state is already changed before the
+ * report is handled, this field just keeps the last value.
+ */
+ @Nullable
+ final IBinder mFocusedWindow;
+
+ /**
+ * {@link WindowManager.LayoutParams#softInputMode} of {@link #mFocusedWindow}.
+ *
+ * @see #mFocusedWindow
+ */
+ @SoftInputModeFlags
+ final int mFocusedWindowSoftInputMode;
+
+ /**
+ * The client by which {@link #mFocusedWindow} was reported. This gets updated whenever
+ * an
+ * IME-focusable window gained focus (without necessarily starting an input connection),
+ * while {@link InputMethodManagerService#mClient} only gets updated when we actually start an
+ * input connection.
+ *
+ * @see #mFocusedWindow
+ */
+ @Nullable
+ final ClientState mFocusedWindowClient;
+
+ /**
+ * The editor info by which {@link #mFocusedWindow} was reported. This differs from
+ * {@link InputMethodManagerService#mCurEditorInfo} the same way {@link #mFocusedWindowClient}
+ * differs from {@link InputMethodManagerService#mCurClient}.
+ *
+ * @see #mFocusedWindow
+ */
+ @Nullable
+ final EditorInfo mFocusedWindowEditorInfo;
+
+ void dumpDebug(ProtoOutputStream proto, WindowManagerInternal windowManagerInternal) {
+ proto.write(CUR_FOCUSED_WINDOW_NAME,
+ windowManagerInternal.getWindowName(mFocusedWindow));
+ proto.write(CUR_FOCUSED_WINDOW_SOFT_INPUT_MODE,
+ InputMethodDebug.softInputModeToString(mFocusedWindowSoftInputMode));
+ }
+
+ void dump(String prefix, Printer p) {
+ p.println(prefix + "mFocusedWindow()=" + mFocusedWindow);
+ p.println(prefix + "softInputMode=" + InputMethodDebug.softInputModeToString(
+ mFocusedWindowSoftInputMode));
+ p.println(prefix + "mFocusedWindowClient=" + mFocusedWindowClient);
+ }
+
+ static ImeBindingState newEmptyState() {
+ return new ImeBindingState(
+ /*focusedWindow=*/ null,
+ /*focusedWindowSoftInputMode=*/ SOFT_INPUT_STATE_UNSPECIFIED,
+ /*focusedWindowClient=*/ null,
+ /*focusedWindowEditorInfo=*/ null
+ );
+ }
+
+ ImeBindingState(@Nullable IBinder focusedWindow,
+ @SoftInputModeFlags int focusedWindowSoftInputMode,
+ @Nullable ClientState focusedWindowClient,
+ @Nullable EditorInfo focusedWindowEditorInfo) {
+ mFocusedWindow = focusedWindow;
+ mFocusedWindowSoftInputMode = focusedWindowSoftInputMode;
+ mFocusedWindowClient = focusedWindowClient;
+ mFocusedWindowEditorInfo = focusedWindowEditorInfo;
+ }
+}
diff --git a/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java b/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
index 743b8e382347..cdfde87f042f 100644
--- a/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
+++ b/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
@@ -548,7 +548,7 @@ public final class ImeVisibilityStateComputer {
}
}
// Fallback to the focused window for some edge cases (e.g. relaunching the activity)
- return mService.mCurFocusedWindow;
+ return mService.mImeBindingState.mFocusedWindow;
}
IBinder getWindowTokenFrom(ImeTargetWindowState windowState) {
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 1564b2f86218..fee0342a9f99 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -28,7 +28,6 @@ import static android.server.inputmethod.InputMethodManagerServiceProto.BACK_DIS
import static android.server.inputmethod.InputMethodManagerServiceProto.BOUND_TO_METHOD;
import static android.server.inputmethod.InputMethodManagerServiceProto.CUR_ATTRIBUTE;
import static android.server.inputmethod.InputMethodManagerServiceProto.CUR_CLIENT;
-import static android.server.inputmethod.InputMethodManagerServiceProto.CUR_FOCUSED_WINDOW_NAME;
import static android.server.inputmethod.InputMethodManagerServiceProto.CUR_FOCUSED_WINDOW_SOFT_INPUT_MODE;
import static android.server.inputmethod.InputMethodManagerServiceProto.CUR_ID;
import static android.server.inputmethod.InputMethodManagerServiceProto.CUR_METHOD_ID;
@@ -423,6 +422,11 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
private final ClientController mClientController;
/**
+ * Holds the current IME binding state info.
+ */
+ ImeBindingState mImeBindingState;
+
+ /**
* Set once the system is ready to run third party code.
*/
boolean mSystemReady;
@@ -482,13 +486,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
private ClientState mCurClient;
/**
- * The last window token that we confirmed to be focused. This is always updated upon reports
- * from the input method client. If the window state is already changed before the report is
- * handled, this field just keeps the last value.
- */
- IBinder mCurFocusedWindow;
-
- /**
* The last window token that we confirmed that IME started talking to. This is always updated
* upon reports from the input method. If the window state is already changed before the report
* is handled, this field just keeps the last value.
@@ -496,34 +493,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
IBinder mLastImeTargetWindow;
/**
- * {@link LayoutParams#softInputMode} of {@link #mCurFocusedWindow}.
- *
- * @see #mCurFocusedWindow
- */
- @SoftInputModeFlags
- int mCurFocusedWindowSoftInputMode;
-
- /**
- * The client by which {@link #mCurFocusedWindow} was reported. This gets updated whenever an
- * IME-focusable window gained focus (without necessarily starting an input connection),
- * while {@link #mCurClient} only gets updated when we actually start an input connection.
- *
- * @see #mCurFocusedWindow
- */
- @Nullable
- ClientState mCurFocusedWindowClient;
-
- /**
- * The editor info by which {@link #mCurFocusedWindow} was reported. This differs from
- * {@link #mCurEditorInfo} the same way {@link #mCurFocusedWindowClient} differs
- * from {@link #mCurClient}.
- *
- * @see #mCurFocusedWindow
- */
- @Nullable
- EditorInfo mCurFocusedWindowEditorInfo;
-
- /**
* The {@link IRemoteInputConnection} last provided by the current client.
*/
IRemoteInputConnection mCurInputConnection;
@@ -1131,10 +1100,11 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
mVisibilityStateComputer.getImePolicy().setA11yRequestNoSoftKeyboard(
accessibilitySoftKeyboardSetting);
if (mVisibilityStateComputer.getImePolicy().isA11yRequestNoSoftKeyboard()) {
- hideCurrentInputLocked(mCurFocusedWindow, 0 /* flags */,
+ hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
SoftInputShowHideReason.HIDE_SETTINGS_ON_CHANGE);
} else if (isShowRequestedForCurrentWindow()) {
- showCurrentInputLocked(mCurFocusedWindow, InputMethodManager.SHOW_IMPLICIT,
+ showCurrentInputLocked(mImeBindingState.mFocusedWindow,
+ InputMethodManager.SHOW_IMPLICIT,
SoftInputShowHideReason.SHOW_SETTINGS_ON_CHANGE);
}
} else if (stylusHandwritingEnabledUri.equals(uri)) {
@@ -1629,7 +1599,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
}
// Hide soft input before user switch task since switch task may block main handler a while
// and delayed the hideCurrentInputLocked().
- hideCurrentInputLocked(mCurFocusedWindow, 0 /* flags */,
+ hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
SoftInputShowHideReason.HIDE_SWITCH_USER);
final UserSwitchHandlerTask task = new UserSwitchHandlerTask(this, userId,
clientToBeReset);
@@ -1704,6 +1674,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
mClientController = new ClientController(mPackageManagerInternal);
synchronized (ImfLock.class) {
mClientController.addClientControllerCallback(c -> onClientRemoved(c));
+ mImeBindingState = ImeBindingState.newEmptyState();
}
mPreventImeStartupUnlessTextEditor = mRes.getBoolean(
@@ -2218,7 +2189,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
clearClientSessionLocked(client);
clearClientSessionForAccessibilityLocked(client);
if (mCurClient == client) {
- hideCurrentInputLocked(mCurFocusedWindow, 0 /* flags */,
+ hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
SoftInputShowHideReason.HIDE_REMOVE_CLIENT);
if (mBoundToMethod) {
mBoundToMethod = false;
@@ -2232,9 +2203,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
}
mBoundToAccessibility = false;
mCurClient = null;
- if (mCurFocusedWindowClient == client) {
- mCurFocusedWindowClient = null;
- mCurFocusedWindowEditorInfo = null;
+ if (mImeBindingState.mFocusedWindowClient == client) {
+ mImeBindingState = ImeBindingState.newEmptyState();
}
}
}
@@ -2283,7 +2253,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
@GuardedBy("ImfLock.class")
void onUnbindCurrentMethodByReset() {
final ImeTargetWindowState winState = mVisibilityStateComputer.getWindowStateOrNull(
- mCurFocusedWindow);
+ mImeBindingState.mFocusedWindow);
if (winState != null && !winState.isRequestedImeVisible()
&& !mVisibilityStateComputer.isInputShown()) {
// Normally, the focus window will apply the IME visibility state to
@@ -2295,7 +2265,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
// binding states in the first place.
final var statsToken = createStatsTokenForFocusedClient(false /* show */,
SoftInputShowHideReason.UNBIND_CURRENT_METHOD);
- mVisibilityApplier.applyImeVisibility(mCurFocusedWindow, statsToken, STATE_HIDE_IME);
+ mVisibilityApplier.applyImeVisibility(mImeBindingState.mFocusedWindow, statsToken,
+ STATE_HIDE_IME);
}
}
@@ -2328,7 +2299,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
@GuardedBy("ImfLock.class")
private boolean isShowRequestedForCurrentWindow() {
final ImeTargetWindowState state = mVisibilityStateComputer.getWindowStateOrNull(
- mCurFocusedWindow);
+ mImeBindingState.mFocusedWindow);
return state != null && state.isRequestedImeVisible();
}
@@ -2346,10 +2317,9 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
getCurTokenLocked(),
mCurTokenDisplayId, getCurIdLocked(), startInputReason, restarting,
UserHandle.getUserId(mCurClient.mUid),
- mCurClient.mSelfReportedDisplayId,
- mCurFocusedWindow, mCurEditorInfo, mCurFocusedWindowSoftInputMode,
- getSequenceNumberLocked());
- mImeTargetWindowMap.put(startInputToken, mCurFocusedWindow);
+ mCurClient.mSelfReportedDisplayId, mImeBindingState.mFocusedWindow, mCurEditorInfo,
+ mImeBindingState.mFocusedWindowSoftInputMode, getSequenceNumberLocked());
+ mImeTargetWindowMap.put(startInputToken, mImeBindingState.mFocusedWindow);
mStartInputHistory.addEntry(info);
// Seems that PackageManagerInternal#grantImplicitAccess() doesn't handle cross-user
@@ -2376,7 +2346,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
: createStatsTokenForFocusedClient(true /* show */,
SoftInputShowHideReason.ATTACH_NEW_INPUT);
mCurStatsToken = null;
- showCurrentInputLocked(mCurFocusedWindow, statsToken,
+ showCurrentInputLocked(mImeBindingState.mFocusedWindow, statsToken,
mVisibilityStateComputer.getShowFlags(), MotionEvent.TOOL_TYPE_UNKNOWN,
null /* resultReceiver */, SoftInputShowHideReason.ATTACH_NEW_INPUT);
}
@@ -2450,7 +2420,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
// Compute the final shown display ID with validated cs.selfReportedDisplayId for this
// session & other conditions.
ImeTargetWindowState winState = mVisibilityStateComputer.getWindowStateOrNull(
- mCurFocusedWindow);
+ mImeBindingState.mFocusedWindow);
if (winState == null) {
return InputBindResult.NOT_IME_TARGET_WINDOW;
}
@@ -2469,7 +2439,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
}
if (mVisibilityStateComputer.getImePolicy().isImeHiddenByDisplayPolicy()) {
- hideCurrentInputLocked(mCurFocusedWindow, 0 /* flags */,
+ hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
SoftInputShowHideReason.HIDE_DISPLAY_IME_POLICY_HIDE);
return InputBindResult.NO_IME;
}
@@ -3638,7 +3608,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
Binder.withCleanCallingIdentity(() -> {
Objects.requireNonNull(windowToken, "windowToken must not be null");
synchronized (ImfLock.class) {
- if (mCurFocusedWindow != windowToken || mCurPerceptible == perceptible) {
+ if (mImeBindingState.mFocusedWindow != windowToken
+ || mCurPerceptible == perceptible) {
return;
}
mCurPerceptible = perceptible;
@@ -3732,7 +3703,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
super.hideSoftInputFromServerForTest_enforcePermission();
synchronized (ImfLock.class) {
- hideCurrentInputLocked(mCurFocusedWindow, 0 /* flags */,
+ hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
SoftInputShowHideReason.HIDE_SOFT_INPUT);
}
}
@@ -3907,7 +3878,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
final boolean shouldClearFlag =
mImePlatformCompatUtils.shouldClearShowForcedFlag(cs.mUid);
final boolean showForced = mVisibilityStateComputer.mShowForced;
- if (mCurFocusedWindow != windowToken && showForced && shouldClearFlag) {
+ if (mImeBindingState.mFocusedWindow != windowToken
+ && showForced && shouldClearFlag) {
mVisibilityStateComputer.mShowForced = false;
}
@@ -3925,7 +3897,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
Slog.w(TAG, "If you need to impersonate a foreground user/profile from"
+ " a background user, use EditorInfo.targetInputMethodUser with"
+ " INTERACT_ACROSS_USERS_FULL permission.");
- hideCurrentInputLocked(mCurFocusedWindow, 0 /* flags */,
+ hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
SoftInputShowHideReason.HIDE_INVALID_USER);
return InputBindResult.INVALID_USER;
}
@@ -3986,7 +3958,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
+ " cs=" + cs);
}
- final boolean sameWindowFocused = mCurFocusedWindow == windowToken;
+ final boolean sameWindowFocused = mImeBindingState.mFocusedWindow == windowToken;
final boolean isTextEditor = (startInputFlags & StartInputFlags.IS_TEXT_EDITOR) != 0;
final boolean startInputByWinGainedFocus =
(startInputFlags & StartInputFlags.WINDOW_GAINED_FOCUS) != 0;
@@ -4017,10 +3989,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
null, null, null, null, -1, false);
}
- mCurFocusedWindow = windowToken;
- mCurFocusedWindowSoftInputMode = softInputMode;
- mCurFocusedWindowClient = cs;
- mCurFocusedWindowEditorInfo = editorInfo;
+ mImeBindingState = new ImeBindingState(windowToken, softInputMode, cs, editorInfo);
mCurPerceptible = true;
// We want to start input before showing the IME, but after closing
@@ -4051,9 +4020,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
break;
}
final var statsToken = createStatsTokenForFocusedClient(isShow, imeVisRes.getReason());
- mVisibilityApplier.applyImeVisibility(mCurFocusedWindow, statsToken,
+ mVisibilityApplier.applyImeVisibility(mImeBindingState.mFocusedWindow, statsToken,
imeVisRes.getState(), imeVisRes.getReason());
-
if (imeVisRes.getReason() == SoftInputShowHideReason.HIDE_UNSPECIFIED_WINDOW) {
// If focused display changed, we should unbind current method
// to make app window in previous display relayout after Ime
@@ -4092,7 +4060,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
throw new IllegalArgumentException("unknown client " + client.asBinder());
}
ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_CLIENT_KNOWN);
- if (!isImeClientFocused(mCurFocusedWindow, cs)) {
+ if (!isImeClientFocused(mImeBindingState.mFocusedWindow, cs)) {
Slog.w(TAG, String.format("Ignoring %s of uid %d : %s", methodName, uid, client));
return false;
}
@@ -4104,8 +4072,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
@GuardedBy("ImfLock.class")
private boolean canShowInputMethodPickerLocked(IInputMethodClient client) {
final int uid = Binder.getCallingUid();
- if (mCurFocusedWindowClient != null && client != null
- && mCurFocusedWindowClient.mClient.asBinder() == client.asBinder()) {
+ if (mImeBindingState.mFocusedWindowClient != null && client != null
+ && mImeBindingState.mFocusedWindowClient.mClient.asBinder() == client.asBinder()) {
return true;
}
if (mSettings.getUserId() != UserHandle.getUserId(uid)) {
@@ -4728,12 +4696,11 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
proto.write(CUR_METHOD_ID, getSelectedMethodIdLocked());
proto.write(CUR_SEQ, getSequenceNumberLocked());
proto.write(CUR_CLIENT, Objects.toString(mCurClient));
- proto.write(CUR_FOCUSED_WINDOW_NAME,
- mWindowManagerInternal.getWindowName(mCurFocusedWindow));
+ mImeBindingState.dumpDebug(proto, mWindowManagerInternal);
proto.write(LAST_IME_TARGET_WINDOW_NAME,
mWindowManagerInternal.getWindowName(mLastImeTargetWindow));
- proto.write(CUR_FOCUSED_WINDOW_SOFT_INPUT_MODE,
- InputMethodDebug.softInputModeToString(mCurFocusedWindowSoftInputMode));
+ proto.write(CUR_FOCUSED_WINDOW_SOFT_INPUT_MODE, InputMethodDebug.softInputModeToString(
+ mImeBindingState.mFocusedWindowSoftInputMode));
if (mCurEditorInfo != null) {
mCurEditorInfo.dumpDebug(proto, CUR_ATTRIBUTE);
}
@@ -4855,12 +4822,12 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
final IBinder requestToken = mVisibilityStateComputer.getWindowTokenFrom(requestImeToken);
final WindowManagerInternal.ImeTargetInfo info =
mWindowManagerInternal.onToggleImeRequested(
- show, mCurFocusedWindow, requestToken, mCurTokenDisplayId);
+ show, mImeBindingState.mFocusedWindow, requestToken, mCurTokenDisplayId);
mSoftInputShowHideHistory.addEntry(new SoftInputShowHideHistory.Entry(
- mCurFocusedWindowClient, mCurFocusedWindowEditorInfo, info.focusedWindowName,
- mCurFocusedWindowSoftInputMode, reason, mInFullscreenMode,
- info.requestWindowName, info.imeControlTargetName, info.imeLayerTargetName,
- info.imeSurfaceParentName));
+ mImeBindingState.mFocusedWindowClient, mImeBindingState.mFocusedWindowEditorInfo,
+ info.focusedWindowName, mImeBindingState.mFocusedWindowSoftInputMode, reason,
+ mInFullscreenMode, info.requestWindowName, info.imeControlTargetName,
+ info.imeLayerTargetName, info.imeSurfaceParentName));
if (statsToken != null) {
mImeTrackerService.onImmsUpdate(statsToken, info.requestWindowName);
@@ -5031,8 +4998,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
case MSG_HIDE_ALL_INPUT_METHODS:
synchronized (ImfLock.class) {
@SoftInputShowHideReason final int reason = (int) msg.obj;
- hideCurrentInputLocked(mCurFocusedWindow, 0 /* flags */, reason);
-
+ hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */, reason);
}
return true;
case MSG_REMOVE_IME_SURFACE: {
@@ -5051,7 +5017,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
IBinder windowToken = (IBinder) msg.obj;
synchronized (ImfLock.class) {
try {
- if (windowToken == mCurFocusedWindow
+ if (windowToken == mImeBindingState.mFocusedWindow
&& mEnabledSession != null && mEnabledSession.mSession != null) {
mEnabledSession.mSession.removeImeSurface();
}
@@ -5126,7 +5092,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
case MSG_START_HANDWRITING:
synchronized (ImfLock.class) {
IInputMethodInvoker curMethod = getCurMethodLocked();
- if (curMethod == null || mCurFocusedWindow == null) {
+ if (curMethod == null || mImeBindingState.mFocusedWindow == null) {
return true;
}
final HandwritingModeController.HandwritingSession session =
@@ -5134,7 +5100,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
msg.arg1 /*requestId*/,
msg.arg2 /*pid*/,
mBindingController.getCurMethodUid(),
- mCurFocusedWindow);
+ mImeBindingState.mFocusedWindow);
if (session == null) {
Slog.e(TAG,
"Failed to start handwriting session for requestId: " + msg.arg1);
@@ -5187,11 +5153,11 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
// Handle IME visibility when interactive changed before finishing the input to
// ensure we preserve the last state as possible.
final ImeVisibilityResult imeVisRes = mVisibilityStateComputer.onInteractiveChanged(
- mCurFocusedWindow, interactive);
+ mImeBindingState.mFocusedWindow, interactive);
if (imeVisRes != null) {
// Pass in a null statsToken as the IME snapshot is not tracked by ImeTracker.
- mVisibilityApplier.applyImeVisibility(mCurFocusedWindow, null /* statsToken */,
- imeVisRes.getState(), imeVisRes.getReason());
+ mVisibilityApplier.applyImeVisibility(mImeBindingState.mFocusedWindow,
+ null /* statsToken */, imeVisRes.getState(), imeVisRes.getReason());
}
// Eligible IME processes use new "setInteractive" protocol.
mCurClient.mClient.setInteractive(mIsInteractive, mInFullscreenMode);
@@ -5881,7 +5847,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
@Override
public void reportImeControl(@Nullable IBinder windowToken) {
synchronized (ImfLock.class) {
- if (mCurFocusedWindow != windowToken) {
+ if (mImeBindingState.mFocusedWindow != windowToken) {
// mCurPerceptible was set by the focused window, but it is no longer in
// control, so we reset mCurPerceptible.
mCurPerceptible = true;
@@ -5895,7 +5861,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
// Hide the IME method menu only when the IME surface parent is changed by the
// input target changed, in case seeing the dialog dismiss flickering during
// the next focused window starting the input connection.
- if (mLastImeTargetWindow != mCurFocusedWindow) {
+ if (mLastImeTargetWindow != mImeBindingState.mFocusedWindow) {
mMenuController.hideInputMethodMenuLocked();
}
}
@@ -6189,11 +6155,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
client = mCurClient;
p.println(" mCurClient=" + client + " mCurSeq=" + getSequenceNumberLocked());
p.println(" mCurPerceptible=" + mCurPerceptible);
- p.println(" mCurFocusedWindow=" + mCurFocusedWindow
- + " softInputMode="
- + InputMethodDebug.softInputModeToString(mCurFocusedWindowSoftInputMode)
- + " client=" + mCurFocusedWindowClient);
- focusedWindowClient = mCurFocusedWindowClient;
+ mImeBindingState.dump(" ", p);
p.println(" mCurId=" + getCurIdLocked() + " mHaveConnection=" + hasConnectionLocked()
+ " mBoundToMethod=" + mBoundToMethod + " mVisibleBound="
+ mBindingController.isVisibleBound());
@@ -6244,7 +6206,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
p.println("No input method client.");
}
- if (focusedWindowClient != null && client != focusedWindowClient) {
+ if (mImeBindingState.mFocusedWindowClient != null
+ && client != mImeBindingState.mFocusedWindowClient) {
p.println(" ");
p.println("Warning: Current input method client doesn't match the last focused. "
+ "window.");
@@ -6252,7 +6215,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
p.println(" ");
pw.flush();
try {
- TransferPipe.dumpAsync(focusedWindowClient.mClient.asBinder(), fd, args);
+ TransferPipe.dumpAsync(
+ mImeBindingState.mFocusedWindowClient.mClient.asBinder(), fd, args);
} catch (IOException | RemoteException e) {
p.println("Failed to dump input method client in focused window: " + e);
}
@@ -6698,7 +6662,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
final String nextIme;
final List<InputMethodInfo> nextEnabledImes;
if (userId == mSettings.getUserId()) {
- hideCurrentInputLocked(mCurFocusedWindow, 0 /* flags */,
+ hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND);
mBindingController.unbindCurrentMethod();
@@ -6832,11 +6796,11 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
@NonNull
private ImeTracker.Token createStatsTokenForFocusedClient(boolean show,
@SoftInputShowHideReason int reason) {
- final int uid = mCurFocusedWindowClient != null
- ? mCurFocusedWindowClient.mUid
+ final int uid = mImeBindingState.mFocusedWindowClient != null
+ ? mImeBindingState.mFocusedWindowClient.mUid
: -1;
- final var packageName = mCurFocusedWindowEditorInfo != null
- ? mCurFocusedWindowEditorInfo.packageName
+ final var packageName = mImeBindingState.mFocusedWindowEditorInfo != null
+ ? mImeBindingState.mFocusedWindowEditorInfo.packageName
: "uid(" + uid + ")";
return ImeTracker.forLogging().onStart(packageName, uid,
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 3a7ac0bd659d..ba5882cc7e98 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -12050,11 +12050,12 @@ public class NotificationManagerService extends SystemService {
@Override
public void onServiceAdded(ManagedServiceInfo info) {
if (lifetimeExtensionRefactor()) {
- // Generally, only System or System UI should have the permissions to call
- // registerSystemService.
- // isCallerSystemorPhone tells us whether the caller is System. Then, if it's not
- // the system, we know it's system UI.
- info.isSystemUi = !isCallerSystemOrPhone();
+ // We explicitly check the status bar permission for the uid in the info object.
+ // We can't use the calling uid here because it's probably always system server.
+ // Note that this will also be true for the shell.
+ info.isSystemUi = getContext().checkPermission(
+ android.Manifest.permission.STATUS_BAR_SERVICE, -1, info.uid)
+ == PERMISSION_GRANTED;
}
final INotificationListener listener = (INotificationListener) info.service;
final NotificationRankingUpdate update;
diff --git a/services/core/java/com/android/server/notification/ZenModeEventLogger.java b/services/core/java/com/android/server/notification/ZenModeEventLogger.java
index b9a267f37ff9..8e37b4f24880 100644
--- a/services/core/java/com/android/server/notification/ZenModeEventLogger.java
+++ b/services/core/java/com/android/server/notification/ZenModeEventLogger.java
@@ -32,6 +32,7 @@ import android.app.NotificationManager;
import android.content.pm.PackageManager;
import android.os.Process;
import android.service.notification.DNDPolicyProto;
+import android.service.notification.ZenAdapters;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeConfig.ConfigChangeOrigin;
import android.service.notification.ZenModeConfig.ZenRule;
@@ -591,9 +592,11 @@ class ZenModeEventLogger {
// This applies to both call and message senders, but not conversation senders,
// where they use the same enum values.
proto.write(DNDPolicyProto.ALLOW_CALLS_FROM,
- ZenModeConfig.getZenPolicySenders(mNewPolicy.allowCallsFrom()));
+ ZenAdapters.notificationPolicySendersToZenPolicyPeopleType(
+ mNewPolicy.allowCallsFrom()));
proto.write(DNDPolicyProto.ALLOW_MESSAGES_FROM,
- ZenModeConfig.getZenPolicySenders(mNewPolicy.allowMessagesFrom()));
+ ZenAdapters.notificationPolicySendersToZenPolicyPeopleType(
+ mNewPolicy.allowMessagesFrom()));
proto.write(DNDPolicyProto.ALLOW_CONVERSATIONS_FROM,
mNewPolicy.allowConversationsFrom());
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 6857869e3776..bc86c8216952 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -84,6 +84,7 @@ import android.provider.Settings.Global;
import android.service.notification.Condition;
import android.service.notification.ConditionProviderService;
import android.service.notification.DeviceEffectsApplier;
+import android.service.notification.ZenAdapters;
import android.service.notification.ZenDeviceEffects;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeConfig.ConfigChangeOrigin;
diff --git a/services/core/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java b/services/core/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java
index a4c4347b7cef..0abe50f12772 100644
--- a/services/core/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java
+++ b/services/core/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java
@@ -16,6 +16,8 @@
package com.android.server.ondeviceintelligence;
+import static android.service.ondeviceintelligence.OnDeviceIntelligenceService.OnDeviceUpdateProcessingException.PROCESSING_UPDATE_STATUS_CONNECTION_FAILED;
+
import android.Manifest;
import android.annotation.NonNull;
import android.app.AppGlobals;
@@ -36,6 +38,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
+import android.os.Bundle;
import android.os.ICancellationSignal;
import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
@@ -43,8 +46,12 @@ import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.DeviceConfig;
+import android.service.ondeviceintelligence.IOnDeviceIntelligenceService;
import android.service.ondeviceintelligence.IOnDeviceTrustedInferenceService;
+import android.service.ondeviceintelligence.IRemoteProcessingService;
import android.service.ondeviceintelligence.IRemoteStorageService;
+import android.service.ondeviceintelligence.IProcessingUpdateStatusCallback;
+import android.service.ondeviceintelligence.OnDeviceIntelligenceService;
import android.text.TextUtils;
import android.util.Slog;
@@ -59,10 +66,11 @@ import java.util.Objects;
import java.util.Set;
/**
- * This is the system service for handling calls on the {@link OnDeviceIntelligenceManager}. This
+ * This is the system service for handling calls on the
+ * {@link android.app.ondeviceintelligence.OnDeviceIntelligenceManager}. This
* service holds connection references to the underlying remote services i.e. the isolated service
- * {@link android.service.ondeviceintelligence.OnDeviceTrustedInferenceService} and a regular
- * service counter part {@link android.service.ondeviceintelligence.OnDeviceIntelligenceService}.
+ * {@link OnDeviceTrustedInferenceService} and a regular
+ * service counter part {@link OnDeviceIntelligenceService}.
*
* Note: Both the remote services run under the SYSTEM user, as we cannot have separate instance of
* the Inference service for each user, due to possible high memory footprint.
@@ -313,10 +321,48 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
mRemoteOnDeviceIntelligenceService = new RemoteOnDeviceIntelligenceService(mContext,
ComponentName.unflattenFromString(serviceName),
UserHandle.SYSTEM.getIdentifier());
+ mRemoteOnDeviceIntelligenceService.setServiceLifecycleCallbacks(
+ new ServiceConnector.ServiceLifecycleCallbacks<>() {
+ @Override
+ public void onConnected(
+ @NonNull IOnDeviceIntelligenceService service) {
+ try {
+ service.registerRemoteServices(
+ getRemoteProcessingService());
+ } catch (RemoteException ex) {
+ Slog.w(TAG, "Failed to send connected event", ex);
+ }
+ }
+ });
}
}
}
+ @NonNull
+ private IRemoteProcessingService.Stub getRemoteProcessingService() {
+ return new IRemoteProcessingService.Stub() {
+ @Override
+ public void updateProcessingState(
+ Bundle processingState,
+ IProcessingUpdateStatusCallback callback) {
+ try {
+ ensureRemoteTrustedInferenceServiceInitialized();
+ mRemoteInferenceService.post(
+ service -> service.updateProcessingState(
+ processingState, callback));
+ } catch (RemoteException unused) {
+ try {
+ callback.onFailure(
+ PROCESSING_UPDATE_STATUS_CONNECTION_FAILED,
+ "Received failure invoking the remote processing service.");
+ } catch (RemoteException ex) {
+ Slog.w(TAG, "Failed to send failure status.", ex);
+ }
+ }
+ }
+ };
+ }
+
private void ensureRemoteTrustedInferenceServiceInitialized() throws RemoteException {
synchronized (mLock) {
if (mRemoteInferenceService == null) {
@@ -332,6 +378,7 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
public void onConnected(
@NonNull IOnDeviceTrustedInferenceService service) {
try {
+ ensureRemoteIntelligenceServiceInitialized();
service.registerRemoteStorageService(
getIRemoteStorageService());
} catch (RemoteException ex) {
@@ -358,8 +405,7 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
@Override
public void getReadOnlyFeatureFileDescriptorMap(
Feature feature,
- RemoteCallback remoteCallback)
- throws RemoteException {
+ RemoteCallback remoteCallback) {
mRemoteOnDeviceIntelligenceService.post(
service -> service.getReadOnlyFeatureFileDescriptorMap(
feature, remoteCallback));
diff --git a/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java b/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java
index 8452c0e61a81..4f86adfe2d8d 100644
--- a/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java
+++ b/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java
@@ -21,7 +21,6 @@ import static android.app.admin.flags.Flags.onboardingBugreportV2Enabled;
import android.Manifest;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
-import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.admin.DevicePolicyManager;
import android.app.role.RoleManager;
@@ -39,6 +38,7 @@ import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.os.UserManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -96,6 +96,7 @@ class BugreportManagerServiceImpl extends IDumpstate.Stub {
private static final long DEFAULT_BUGREPORT_SERVICE_TIMEOUT_MILLIS = 30 * 1000;
private final Object mLock = new Object();
+ private final Injector mInjector;
private final Context mContext;
private final AppOpsManager mAppOps;
private final TelephonyManager mTelephonyManager;
@@ -345,6 +346,14 @@ class BugreportManagerServiceImpl extends IDumpstate.Stub {
AtomicFile getMappingFile() {
return mMappingFile;
}
+
+ UserManager getUserManager() {
+ return mContext.getSystemService(UserManager.class);
+ }
+
+ DevicePolicyManager getDevicePolicyManager() {
+ return mContext.getSystemService(DevicePolicyManager.class);
+ }
}
BugreportManagerServiceImpl(Context context) {
@@ -356,6 +365,7 @@ class BugreportManagerServiceImpl extends IDumpstate.Stub {
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
BugreportManagerServiceImpl(Injector injector) {
+ mInjector = injector;
mContext = injector.getContext();
mAppOps = mContext.getSystemService(AppOpsManager.class);
mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
@@ -388,12 +398,7 @@ class BugreportManagerServiceImpl extends IDumpstate.Stub {
int callingUid = Binder.getCallingUid();
enforcePermission(callingPackage, callingUid, bugreportMode
== BugreportParams.BUGREPORT_MODE_TELEPHONY /* checkCarrierPrivileges */);
- final long identity = Binder.clearCallingIdentity();
- try {
- ensureUserCanTakeBugReport(bugreportMode);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
+ ensureUserCanTakeBugReport(bugreportMode);
Slogf.i(TAG, "Starting bugreport for %s / %d", callingPackage, callingUid);
synchronized (mLock) {
@@ -432,7 +437,6 @@ class BugreportManagerServiceImpl extends IDumpstate.Stub {
@RequiresPermission(value = Manifest.permission.DUMP, conditional = true)
public void retrieveBugreport(int callingUidUnused, String callingPackage, int userId,
FileDescriptor bugreportFd, String bugreportFile,
-
boolean keepBugreportOnRetrievalUnused, IDumpstateListener listener) {
int callingUid = Binder.getCallingUid();
enforcePermission(callingPackage, callingUid, false);
@@ -564,54 +568,59 @@ class BugreportManagerServiceImpl extends IDumpstate.Stub {
}
/**
- * Validates that the current user is an admin user or, when bugreport is requested remotely
- * that the current user is an affiliated user.
+ * Validates that the calling user is an admin user or, when bugreport is requested remotely
+ * that the user is an affiliated user.
*
- * @throws IllegalArgumentException if the current user is not an admin user
+ * @throws IllegalArgumentException if the calling user or the parent of the calling profile
+ * user is not an admin user.
*/
private void ensureUserCanTakeBugReport(int bugreportMode) {
- UserInfo currentUser = null;
+ // Get the calling userId before clearing the caller identity.
+ int effectiveCallingUserId = UserHandle.getUserId(Binder.getCallingUid());
+ boolean isAdminUser = false;
+ final long identity = Binder.clearCallingIdentity();
try {
- currentUser = ActivityManager.getService().getCurrentUser();
- } catch (RemoteException e) {
- // Impossible to get RemoteException for an in-process call.
- }
-
- if (currentUser == null) {
- logAndThrow("There is no current user, so no bugreport can be requested.");
+ UserInfo profileParent =
+ mInjector.getUserManager().getProfileParent(effectiveCallingUserId);
+ if (profileParent == null) {
+ isAdminUser = mInjector.getUserManager().isUserAdmin(effectiveCallingUserId);
+ } else {
+ // If the caller is a profile, we need to check its parent user instead.
+ // Therefore setting the profile parent user as the effective calling user.
+ effectiveCallingUserId = profileParent.id;
+ isAdminUser = profileParent.isAdmin();
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
-
- if (!currentUser.isAdmin()) {
+ if (!isAdminUser) {
if (bugreportMode == BugreportParams.BUGREPORT_MODE_REMOTE
- && isCurrentUserAffiliated(currentUser.id)) {
+ && isUserAffiliated(effectiveCallingUserId)) {
return;
}
- logAndThrow(TextUtils.formatSimple("Current user %s is not an admin user."
- + " Only admin users are allowed to take bugreport.", currentUser.id));
+ logAndThrow(TextUtils.formatSimple("Calling user %s is not an admin user."
+ + " Only admin users and their profiles are allowed to take bugreport.",
+ effectiveCallingUserId));
}
}
/**
- * Returns {@code true} if the device has device owner and the current user is affiliated
+ * Returns {@code true} if the device has device owner and the specified user is affiliated
* with the device owner.
*/
- private boolean isCurrentUserAffiliated(int currentUserId) {
- DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
+ private boolean isUserAffiliated(int userId) {
+ DevicePolicyManager dpm = mInjector.getDevicePolicyManager();
int deviceOwnerUid = dpm.getDeviceOwnerUserId();
if (deviceOwnerUid == UserHandle.USER_NULL) {
return false;
}
- int callingUserId = UserHandle.getUserId(Binder.getCallingUid());
-
- Slog.i(TAG, "callingUid: " + callingUserId + " deviceOwnerUid: " + deviceOwnerUid
- + " currentUserId: " + currentUserId);
-
- if (callingUserId != deviceOwnerUid) {
- logAndThrow("Caller is not device owner on provisioned device.");
+ if (DEBUG) {
+ Slog.d(TAG, "callingUid: " + userId + " deviceOwnerUid: " + deviceOwnerUid);
}
- if (!dpm.isAffiliatedUser(currentUserId)) {
- logAndThrow("Current user is not affiliated to the device owner.");
+
+ if (userId != deviceOwnerUid && !dpm.isAffiliatedUser(userId)) {
+ logAndThrow("User " + userId + " is not affiliated to the device owner.");
}
return true;
}
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 186cf5e37003..4bfd077760e4 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -1080,7 +1080,7 @@ final class InstallPackageHelper {
reconciledPackages = ReconcilePackageUtils.reconcilePackages(
requests, Collections.unmodifiableMap(mPm.mPackages),
versionInfos, mSharedLibraries, mPm.mSettings.getKeySetManagerService(),
- mPm.mSettings);
+ mPm.mSettings, mPm.mInjector.getSystemConfig());
} catch (ReconcileFailure e) {
for (InstallRequest request : requests) {
request.setError("Reconciliation failed...", e);
@@ -3810,7 +3810,7 @@ final class InstallPackageHelper {
mPm.mPackages, Collections.singletonMap(pkgName,
mPm.getSettingsVersionForPackage(parsedPackage)),
mSharedLibraries, mPm.mSettings.getKeySetManagerService(),
- mPm.mSettings);
+ mPm.mSettings, mPm.mInjector.getSystemConfig());
if ((scanFlags & SCAN_AS_APEX) == 0) {
appIdCreated = optimisticallyRegisterAppId(installRequest);
} else {
diff --git a/services/core/java/com/android/server/pm/ReconcilePackageUtils.java b/services/core/java/com/android/server/pm/ReconcilePackageUtils.java
index 9a7916a7b215..90d6adc4fa52 100644
--- a/services/core/java/com/android/server/pm/ReconcilePackageUtils.java
+++ b/services/core/java/com/android/server/pm/ReconcilePackageUtils.java
@@ -17,6 +17,7 @@
package com.android.server.pm;
import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
+import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
import static android.content.pm.SigningDetails.CapabilityMergeRule.MERGE_RESTRICTED_CAPABILITY;
@@ -25,6 +26,7 @@ import static com.android.server.pm.PackageManagerService.SCAN_BOOTING;
import static com.android.server.pm.PackageManagerService.SCAN_DONT_KILL_APP;
import static com.android.server.pm.PackageManagerService.TAG;
+import android.content.pm.Flags;
import android.content.pm.PackageManager;
import android.content.pm.SharedLibraryInfo;
import android.content.pm.SigningDetails;
@@ -36,6 +38,7 @@ import android.util.Slog;
import com.android.internal.pm.parsing.pkg.ParsedPackage;
import com.android.internal.pm.pkg.parsing.ParsingPackageUtils;
+import com.android.server.SystemConfig;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.utils.WatchedLongSparseArray;
@@ -53,14 +56,17 @@ import java.util.Map;
* as install) led to the request.
*/
final class ReconcilePackageUtils {
- private static final boolean ALLOW_NON_PRELOADS_SYSTEM_SIGNATURE = Build.IS_DEBUGGABLE || true;
+ // TODO(b/308573259): with allow-list, we should be able to disallow such installs even in
+ // debuggable builds.
+ private static final boolean ALLOW_NON_PRELOADS_SYSTEM_SHAREDUIDS = Build.IS_DEBUGGABLE
+ || !Flags.restrictNonpreloadsSystemShareduids();
public static List<ReconciledPackage> reconcilePackages(
List<InstallRequest> installRequests,
Map<String, AndroidPackage> allPackages,
Map<String, Settings.VersionInfo> versionInfos,
SharedLibrariesImpl sharedLibraries,
- KeySetManagerService ksms, Settings settings)
+ KeySetManagerService ksms, Settings settings, SystemConfig systemConfig)
throws ReconcileFailure {
final List<ReconciledPackage> result = new ArrayList<>(installRequests.size());
@@ -187,11 +193,19 @@ final class ReconcilePackageUtils {
SigningDetails.CertCapabilities.PERMISSION)) {
Slog.d(TAG, "Non-preload app associated with system signature: "
+ signatureCheckPs.getPackageName());
- if (!ALLOW_NON_PRELOADS_SYSTEM_SIGNATURE) {
- throw new ReconcileFailure(
- INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
- "Non-preload app associated with system signature: "
- + signatureCheckPs.getPackageName());
+ if (sharedUserSetting != null && !ALLOW_NON_PRELOADS_SYSTEM_SHAREDUIDS) {
+ // Check the allow-list.
+ var allowList = systemConfig.getPackageToSharedUidAllowList();
+ var sharedUidName = allowList.get(signatureCheckPs.getPackageName());
+ if (sharedUidName == null
+ || !sharedUserSetting.name.equals(sharedUidName)) {
+ var msg = "Non-preload app " + signatureCheckPs.getPackageName()
+ + " signed with platform signature and joining shared uid: "
+ + sharedUserSetting.name;
+ Slog.e(TAG, msg + ", allowList: " + allowList);
+ throw new ReconcileFailure(
+ INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID, msg);
+ }
}
}
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index c1ab3f9e3eb9..211b7546bd8a 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -3795,6 +3795,7 @@ public class ShortcutService extends IShortcutService.Stub {
}
final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
+ final boolean archival = intent.getBooleanExtra(Intent.EXTRA_ARCHIVAL, false);
switch (action) {
case Intent.ACTION_PACKAGE_ADDED:
@@ -3805,7 +3806,7 @@ public class ShortcutService extends IShortcutService.Stub {
}
break;
case Intent.ACTION_PACKAGE_REMOVED:
- if (!replacing) {
+ if (!replacing || (replacing && archival)) {
handlePackageRemoved(packageName, userId);
}
break;
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInterface.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInterface.java
index 47032ea2d6af..754b141ff10d 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInterface.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInterface.java
@@ -408,6 +408,9 @@ public interface PermissionManagerServiceInterface extends PermissionManagerInte
/**
* Gets the permission states for requested package, persistent device and user.
+ * <p>
+ * <strong>Note: </strong>Default device permissions are not inherited in this API. Returns the
+ * exact permission states for the requested device.
*
* @param packageName name of the package you are checking against
* @param deviceId id of the persistent device you are checking against
diff --git a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
index 32a21c587f08..cebf7fb9a627 100644
--- a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
+++ b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
@@ -21,7 +21,6 @@ import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
import static android.app.AppOpsManager.OP_LEGACY_STORAGE;
import static android.app.AppOpsManager.OP_NONE;
-import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
@@ -148,7 +147,7 @@ public abstract class SoftRestrictedPermissionPolicy {
pkg.hasPreserveLegacyExternalStorage();
targetSDK = getMinimumTargetSDK(context, appInfo, user);
- shouldApplyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
+ shouldApplyRestriction = !isWhiteListed;
isForcedScopedStorage = sForcedScopedStorageAppWhitelist
.contains(appInfo.packageName);
} else {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 7d5aa96db0b8..d30a2167a183 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -553,7 +553,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
boolean launchFailed; // set if a launched failed, to abort on 2nd try
boolean delayedResume; // not yet resumed because of stopped app switches?
boolean finishing; // activity in pending finish list?
- int configChangeFlags; // which config values have changed
private boolean keysPaused; // has key dispatching been paused for it?
int launchMode; // the launch mode activity attribute.
int lockTaskLaunchMode; // the lockTaskMode manifest attribute, subject to override
@@ -1295,10 +1294,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (mDeferHidingClient) {
pw.println(prefix + "mDeferHidingClient=" + mDeferHidingClient);
}
- if (configChangeFlags != 0) {
- pw.print(prefix); pw.print(" configChangeFlags=");
- pw.println(Integer.toHexString(configChangeFlags));
- }
if (mServiceConnectionsHolder != null) {
pw.print(prefix); pw.print("connections="); pw.println(mServiceConnectionsHolder);
}
@@ -4064,7 +4059,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
try {
if (DEBUG_SWITCH) Slog.i(TAG_SWITCH, "Destroying: " + this);
mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(),
- DestroyActivityItem.obtain(token, finishing, configChangeFlags));
+ DestroyActivityItem.obtain(token, finishing));
} catch (Exception e) {
// We can just ignore exceptions here... if the process has crashed, our death
// notification will clean things up.
@@ -4106,8 +4101,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
}
- configChangeFlags = 0;
-
return removedFromHistory;
}
@@ -5026,7 +5019,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return PauseActivityItem.obtain(token);
case STOPPING:
case STOPPED:
- return StopActivityItem.obtain(token, configChangeFlags);
+ return StopActivityItem.obtain(token);
default:
// Do not send a result immediately if the activity is in state INITIALIZING,
// RESTARTING_PROCESS, FINISHING, DESTROYING, or DESTROYED.
@@ -6300,7 +6293,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
try {
mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(),
PauseActivityItem.obtain(token, finishing, false /* userLeaving */,
- configChangeFlags, false /* dontReport */, mAutoEnteringPip));
+ false /* dontReport */, mAutoEnteringPip));
} catch (Exception e) {
Slog.w(TAG, "Exception thrown sending pause: " + intent.getComponent(), e);
}
@@ -6614,7 +6607,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
EventLogTags.writeWmStopActivity(
mUserId, System.identityHashCode(this), shortComponentName);
mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(),
- StopActivityItem.obtain(token, configChangeFlags));
+ StopActivityItem.obtain(token));
mAtmService.mH.postDelayed(mStopTimeoutRunnable, STOP_TIMEOUT);
} catch (Exception e) {
@@ -9858,7 +9851,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (shouldRelaunchLocked(changes, mTmpConfig)) {
// Aha, the activity isn't handling the change, so DIE DIE DIE.
- configChangeFlags |= changes;
if (mVisible && mAtmService.mTmpUpdateConfigurationResult.mIsUpdating
&& !mTransitionController.isShellTransitionsEnabled()) {
startFreezingScreenLocked(app, mAtmService.mTmpUpdateConfigurationResult.changes);
@@ -9887,7 +9879,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
ProtoLog.v(WM_DEBUG_STATES, "Config is relaunching invisible "
+ "activity %s called by %s", this, Debug.getCallers(4));
}
- relaunchActivityLocked(preserveWindow);
+ relaunchActivityLocked(preserveWindow, changes);
// All done... tell the caller we weren't able to keep this activity around.
return false;
@@ -10029,9 +10021,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
| CONFIG_SCREEN_LAYOUT)) != 0;
}
- void relaunchActivityLocked(boolean preserveWindow) {
+ void relaunchActivityLocked(boolean preserveWindow, int configChangeFlags) {
if (mAtmService.mSuppressResizeConfigChanges && preserveWindow) {
- configChangeFlags = 0;
return;
}
if (!preserveWindow) {
@@ -10104,8 +10095,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// The activity may be waiting for stop, but that is no longer appropriate for it.
mTaskSupervisor.mStoppingActivities.remove(this);
-
- configChangeFlags = 0;
}
/**
@@ -10174,7 +10163,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// {@link ActivityTaskManagerService.activityStopped}).
try {
mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(),
- StopActivityItem.obtain(token, 0 /* configChanges */));
+ StopActivityItem.obtain(token));
} catch (RemoteException e) {
Slog.w(TAG, "Exception thrown during restart " + this, e);
}
diff --git a/services/core/java/com/android/server/wm/SnapshotCache.java b/services/core/java/com/android/server/wm/SnapshotCache.java
index 64d8c7555fa6..86804360f6f4 100644
--- a/services/core/java/com/android/server/wm/SnapshotCache.java
+++ b/services/core/java/com/android/server/wm/SnapshotCache.java
@@ -16,7 +16,6 @@
package com.android.server.wm;
import android.annotation.Nullable;
-import android.hardware.HardwareBuffer;
import android.util.ArrayMap;
import android.window.TaskSnapshot;
@@ -93,10 +92,6 @@ abstract class SnapshotCache<TYPE extends WindowContainer> {
if (entry != null) {
mAppIdMap.remove(entry.topApp);
mRunningCache.remove(id);
- final HardwareBuffer buffer = entry.snapshot.getHardwareBuffer();
- if (buffer != null) {
- buffer.close();
- }
}
}
}
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 85d81c4db2ca..78ababc6473f 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -1881,7 +1881,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
mAtmService.getLifecycleManager().scheduleTransactionItem(prev.app.getThread(),
PauseActivityItem.obtain(prev.token, prev.finishing, userLeaving,
- prev.configChangeFlags, pauseImmediately, autoEnteringPip));
+ pauseImmediately, autoEnteringPip));
} catch (Exception e) {
// Ignore exception, if process died other code will cleanup.
Slog.w(TAG, "Exception thrown during pause", e);
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java b/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
index 027337f04b6e..f5e1e41dbae4 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
@@ -113,8 +113,8 @@ public class CredentialManagerUi {
/** Creates intent that is ot be invoked to cancel an in-progress UI session. */
public Intent createCancelIntent(IBinder requestId, String packageName) {
- return IntentFactory.createCancelUiIntent(requestId, /*shouldShowCancellationUi=*/ true,
- packageName);
+ return IntentFactory.createCancelUiIntent(mContext, requestId,
+ /*shouldShowCancellationUi=*/ true, packageName);
}
/**
diff --git a/services/credentials/java/com/android/server/credentials/GetCandidateRequestSession.java b/services/credentials/java/com/android/server/credentials/GetCandidateRequestSession.java
index 3cb98eb4cd7a..eff53de75ff4 100644
--- a/services/credentials/java/com/android/server/credentials/GetCandidateRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/GetCandidateRequestSession.java
@@ -41,6 +41,8 @@ import android.service.credentials.CredentialProviderService;
import android.service.credentials.PermissionUtils;
import android.util.Slog;
+import com.android.server.credentials.metrics.ApiStatus;
+
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -180,7 +182,7 @@ public class GetCandidateRequestSession extends RequestSession<GetCredentialRequ
} else {
Slog.w(TAG, "onUiCancellation called but finalResponseReceiver not found");
}
- finishSession(/*propagateCancellation=*/false);
+ finishSession(/*propagateCancellation=*/false, ApiStatus.FAILURE.getMetricCode());
}
@Override
@@ -221,9 +223,10 @@ public class GetCandidateRequestSession extends RequestSession<GetCredentialRequ
resultData.putParcelable(
CredentialProviderService.EXTRA_GET_CREDENTIAL_RESPONSE, response);
mFinalResponseReceiver.send(Constants.SUCCESS_CREDMAN_SELECTOR, resultData);
- finishSession(/*propagateCancellation=*/ false);
+ finishSession(/*propagateCancellation=*/ false, ApiStatus.SUCCESS.getMetricCode());
} else {
Slog.w(TAG, "onFinalResponseReceived result receiver not found for pinned entry");
+ finishSession(/*propagateCancellation=*/ false, ApiStatus.FAILURE.getMetricCode());
}
}
diff --git a/services/credentials/java/com/android/server/credentials/RequestSession.java b/services/credentials/java/com/android/server/credentials/RequestSession.java
index 633c9c4cb8e1..a5b9aa68b22e 100644
--- a/services/credentials/java/com/android/server/credentials/RequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/RequestSession.java
@@ -175,7 +175,7 @@ abstract class RequestSession<T, U, V> implements CredentialManagerUi.Credential
() -> {
Slog.d(TAG, "Cancellation invoked from the client - clearing session");
boolean isUiActive = maybeCancelUi();
- finishSession(!isUiActive);
+ finishSession(!isUiActive, ApiStatus.CLIENT_CANCELED.getMetricCode());
}
);
}
@@ -231,7 +231,8 @@ abstract class RequestSession<T, U, V> implements CredentialManagerUi.Credential
return;
}
if (isSessionCancelled()) {
- finishSession(/*propagateCancellation=*/true);
+ finishSession(/*propagateCancellation=*/true,
+ ApiStatus.CLIENT_CANCELED.getMetricCode());
return;
}
String providerId = selection.getProviderId();
@@ -257,11 +258,12 @@ abstract class RequestSession<T, U, V> implements CredentialManagerUi.Credential
}
}
- protected void finishSession(boolean propagateCancellation) {
+ protected void finishSession(boolean propagateCancellation, int apiStatus) {
Slog.i(TAG, "finishing session with propagateCancellation " + propagateCancellation);
if (propagateCancellation) {
mProviders.values().forEach(ProviderSession::cancelProviderRemoteSession);
}
+ mRequestSessionMetric.logApiCalledAtFinish(apiStatus);
mRequestSessionStatus = RequestSessionStatus.COMPLETE;
mProviders.clear();
clearRequestSessionLocked();
@@ -326,7 +328,8 @@ abstract class RequestSession<T, U, V> implements CredentialManagerUi.Credential
mRequestSessionMetric.logCandidatePhaseMetrics(mProviders);
if (isSessionCancelled()) {
- finishSession(/*propagateCancellation=*/true);
+ finishSession(/*propagateCancellation=*/true,
+ ApiStatus.CLIENT_CANCELED.getMetricCode());
return providerDataList;
}
@@ -353,23 +356,20 @@ abstract class RequestSession<T, U, V> implements CredentialManagerUi.Credential
return;
}
if (isSessionCancelled()) {
- mRequestSessionMetric.logApiCalledAtFinish(
- /*apiStatus=*/ ApiStatus.CLIENT_CANCELED.getMetricCode());
- finishSession(/*propagateCancellation=*/true);
+ finishSession(/*propagateCancellation=*/true,
+ ApiStatus.CLIENT_CANCELED.getMetricCode());
return;
}
try {
invokeClientCallbackSuccess(response);
- mRequestSessionMetric.logApiCalledAtFinish(
- /*apiStatus=*/ ApiStatus.SUCCESS.getMetricCode());
+ finishSession(/*propagateCancellation=*/false,
+ ApiStatus.SUCCESS.getMetricCode());
} catch (RemoteException e) {
mRequestSessionMetric.collectFinalPhaseProviderMetricStatus(
/*has_exception=*/ true, ProviderStatusForMetrics.FINAL_FAILURE);
Slog.e(TAG, "Issue while responding to client with a response : " + e);
- mRequestSessionMetric.logApiCalledAtFinish(
- /*apiStatus=*/ ApiStatus.FAILURE.getMetricCode());
+ finishSession(/*propagateCancellation=*/false, ApiStatus.FAILURE.getMetricCode());
}
- finishSession(/*propagateCancellation=*/false);
}
/**
@@ -387,9 +387,7 @@ abstract class RequestSession<T, U, V> implements CredentialManagerUi.Credential
return;
}
if (isSessionCancelled()) {
- mRequestSessionMetric.logApiCalledAtFinish(
- /*apiStatus=*/ ApiStatus.CLIENT_CANCELED.getMetricCode());
- finishSession(/*propagateCancellation=*/true);
+ finishSession(/*propagateCancellation=*/true, ApiStatus.CLIENT_CANCELED.getMetricCode());
return;
}
@@ -399,8 +397,14 @@ abstract class RequestSession<T, U, V> implements CredentialManagerUi.Credential
Slog.e(TAG, "Issue while responding to client with error : " + e);
}
boolean isUserCanceled = errorType.contains(MetricUtilities.USER_CANCELED_SUBSTRING);
- mRequestSessionMetric.logFailureOrUserCancel(isUserCanceled);
- finishSession(/*propagateCancellation=*/false);
+ if (isUserCanceled) {
+ mRequestSessionMetric.setHasExceptionFinalPhase(/* has_exception */ false);
+ finishSession(/*propagateCancellation=*/false,
+ ApiStatus.USER_CANCELED.getMetricCode());
+ } else {
+ finishSession(/*propagateCancellation=*/false,
+ ApiStatus.FAILURE.getMetricCode());
+ }
}
/**
@@ -419,7 +423,7 @@ abstract class RequestSession<T, U, V> implements CredentialManagerUi.Credential
@Override
public void binderDied() {
Slog.d(TAG, "Client binder died - clearing session");
- finishSession(isUiWaitingForData());
+ finishSession(isUiWaitingForData(), ApiStatus.CLIENT_CANCELED.getMetricCode());
}
}
}
diff --git a/services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java b/services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java
index 8adcfbcb974c..a77bd3e280dd 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java
@@ -247,7 +247,7 @@ public class RequestSessionMetric {
*
* @param exceptionBitFinalPhase represents if the final phase provider had an exception
*/
- private void setHasExceptionFinalPhase(boolean exceptionBitFinalPhase) {
+ public void setHasExceptionFinalPhase(boolean exceptionBitFinalPhase) {
try {
mChosenProviderFinalPhaseMetric.setHasException(exceptionBitFinalPhase);
} catch (Exception e) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
index 12f44074a4ad..6aeb4fd53905 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
@@ -225,7 +225,7 @@ final class DevicePolicyEngine {
synchronized (mLock) {
PolicyState<V> localPolicyState = getLocalPolicyStateLocked(policyDefinition, userId);
- if (Flags.devicePolicySizeTrackingEnabled() && false) {
+ if (Flags.devicePolicySizeTrackingInternalEnabled()) {
if (!handleAdminPolicySizeLimit(localPolicyState, enforcingAdmin, value,
policyDefinition, userId)) {
return;
@@ -350,7 +350,7 @@ final class DevicePolicyEngine {
}
PolicyState<V> localPolicyState = getLocalPolicyStateLocked(policyDefinition, userId);
- if (Flags.devicePolicySizeTrackingEnabled() && false) {
+ if (Flags.devicePolicySizeTrackingInternalEnabled()) {
decreasePolicySizeForAdmin(localPolicyState, enforcingAdmin);
}
@@ -496,7 +496,7 @@ final class DevicePolicyEngine {
synchronized (mLock) {
PolicyState<V> globalPolicyState = getGlobalPolicyStateLocked(policyDefinition);
- if (Flags.devicePolicySizeTrackingEnabled() && false) {
+ if (Flags.devicePolicySizeTrackingInternalEnabled()) {
if (!handleAdminPolicySizeLimit(globalPolicyState, enforcingAdmin, value,
policyDefinition, UserHandle.USER_ALL)) {
return;
@@ -568,7 +568,7 @@ final class DevicePolicyEngine {
synchronized (mLock) {
PolicyState<V> policyState = getGlobalPolicyStateLocked(policyDefinition);
- if (Flags.devicePolicySizeTrackingEnabled() && false) {
+ if (Flags.devicePolicySizeTrackingInternalEnabled()) {
decreasePolicySizeForAdmin(policyState, enforcingAdmin);
}
@@ -1892,7 +1892,7 @@ final class DevicePolicyEngine {
private void writeEnforcingAdminSizeInner(TypedXmlSerializer serializer)
throws IOException {
- if (Flags.devicePolicySizeTrackingEnabled() && false) {
+ if (Flags.devicePolicySizeTrackingInternalEnabled()) {
if (mAdminPolicySize != null) {
for (int i = 0; i < mAdminPolicySize.size(); i++) {
int userId = mAdminPolicySize.keyAt(i);
@@ -1916,7 +1916,7 @@ final class DevicePolicyEngine {
private void writeMaxPolicySizeInner(TypedXmlSerializer serializer)
throws IOException {
- if (!Flags.devicePolicySizeTrackingEnabled() || true) {
+ if (!Flags.devicePolicySizeTrackingInternalEnabled()) {
return;
}
serializer.startTag(/* namespace= */ null, TAG_MAX_POLICY_SIZE_LIMIT);
@@ -2081,7 +2081,7 @@ final class DevicePolicyEngine {
private void readMaxPolicySizeInner(TypedXmlPullParser parser)
throws XmlPullParserException, IOException {
- if (!Flags.devicePolicySizeTrackingEnabled() || true) {
+ if (!Flags.devicePolicySizeTrackingInternalEnabled()) {
return;
}
mPolicySizeLimit = parser.getAttributeInt(/* namespace= */ null, ATTR_POLICY_SUM_SIZE);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 0f97f4a7cdc0..80046b6075ee 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -27,6 +27,7 @@ import static android.Manifest.permission.MANAGE_DEVICE_POLICY_ACROSS_USERS_SECU
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_AIRPLANE_MODE;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_APPS_CONTROL;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_APP_RESTRICTIONS;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_ASSIST_CONTENT;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_AUDIO_OUTPUT;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_AUTOFILL;
@@ -83,7 +84,6 @@ import static android.Manifest.permission.MANAGE_DEVICE_POLICY_THREAD_NETWORK;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_TIME;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_USB_DATA_SIGNALLING;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_USB_FILE_TRANSFER;
-import static android.Manifest.permission.MANAGE_DEVICE_POLICY_ASSIST_CONTENT;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_VPN;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_WALLPAPER;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_WIFI;
@@ -196,11 +196,11 @@ import static android.app.admin.DevicePolicyManager.STATUS_CANNOT_ADD_MANAGED_PR
import static android.app.admin.DevicePolicyManager.STATUS_DEVICE_ADMIN_NOT_SUPPORTED;
import static android.app.admin.DevicePolicyManager.STATUS_HAS_DEVICE_OWNER;
import static android.app.admin.DevicePolicyManager.STATUS_HAS_PAIRED;
+import static android.app.admin.DevicePolicyManager.STATUS_HEADLESS_ONLY_SYSTEM_USER;
import static android.app.admin.DevicePolicyManager.STATUS_HEADLESS_SYSTEM_USER_MODE_NOT_SUPPORTED;
import static android.app.admin.DevicePolicyManager.STATUS_MANAGED_USERS_NOT_SUPPORTED;
import static android.app.admin.DevicePolicyManager.STATUS_NONSYSTEM_USER_EXISTS;
import static android.app.admin.DevicePolicyManager.STATUS_NOT_SYSTEM_USER;
-import static android.app.admin.DevicePolicyManager.STATUS_HEADLESS_ONLY_SYSTEM_USER;
import static android.app.admin.DevicePolicyManager.STATUS_OK;
import static android.app.admin.DevicePolicyManager.STATUS_PROVISIONING_NOT_ALLOWED_FOR_NON_DEVELOPER_USERS;
import static android.app.admin.DevicePolicyManager.STATUS_SYSTEM_USER;
@@ -12062,7 +12062,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
if (packageList != null) {
- if (!Flags.devicePolicySizeTrackingEnabled()) {
+ if (!Flags.devicePolicySizeTrackingInternalEnabled()) {
for (String pkg : packageList) {
PolicySizeVerifier.enforceMaxPackageNameLength(pkg);
}
@@ -13771,7 +13771,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return;
}
- if (!Flags.devicePolicySizeTrackingEnabled()) {
+ if (!Flags.devicePolicySizeTrackingInternalEnabled()) {
PolicySizeVerifier.enforceMaxStringLength(accountType, "account type");
}
@@ -14385,7 +14385,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
public void setLockTaskPackages(ComponentName who, String callerPackageName, String[] packages)
throws SecurityException {
Objects.requireNonNull(packages, "packages is null");
- if (!Flags.devicePolicySizeTrackingEnabled()) {
+ if (!Flags.devicePolicySizeTrackingInternalEnabled()) {
for (String pkg : packages) {
PolicySizeVerifier.enforceMaxPackageNameLength(pkg);
}
@@ -24235,7 +24235,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public void setMaxPolicyStorageLimit(String callerPackageName, int storageLimit) {
- if (!Flags.devicePolicySizeTrackingEnabled() || true) {
+ if (!Flags.devicePolicySizeTrackingInternalEnabled()) {
return;
}
CallerIdentity caller = getCallerIdentity(callerPackageName);
@@ -24247,7 +24247,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public int getMaxPolicyStorageLimit(String callerPackageName) {
- if (!Flags.devicePolicySizeTrackingEnabled() || true) {
+ if (!Flags.devicePolicySizeTrackingInternalEnabled()) {
return -1;
}
CallerIdentity caller = getCallerIdentity(callerPackageName);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e19f08cb04a1..9d95c5b4f649 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -2774,9 +2774,12 @@ public final class SystemServer implements Dumpable {
t.traceEnd();
// OnDevicePersonalizationSystemService
- t.traceBegin("StartOnDevicePersonalizationSystemService");
- mSystemServiceManager.startService(ON_DEVICE_PERSONALIZATION_SYSTEM_SERVICE_CLASS);
- t.traceEnd();
+ if (!com.android.server.flags.Flags.enableOdpFeatureGuard()
+ || SystemProperties.getBoolean("ro.system_settings.service.odp_enabled", true)) {
+ t.traceBegin("StartOnDevicePersonalizationSystemService");
+ mSystemServiceManager.startService(ON_DEVICE_PERSONALIZATION_SYSTEM_SERVICE_CLASS);
+ t.traceEnd();
+ }
// Profiling
if (android.server.Flags.telemetryApisService()) {
diff --git a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
index 4b086b3aca17..67df67fdf6c1 100644
--- a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
@@ -227,25 +227,59 @@ class AppIdPermissionPolicy : SchemePolicy() {
if (isRequestedBySystemPackage) {
return@forEach
}
- val oldFlags = getPermissionFlags(appId, userId, permissionName)
- var newFlags = oldFlags andInv PermissionFlags.UPGRADE_EXEMPT
- val isExempt = newFlags.hasAnyBit(PermissionFlags.MASK_EXEMPT)
- newFlags =
- if (permission.isHardRestricted && !isExempt) {
- newFlags or PermissionFlags.RESTRICTION_REVOKED
- } else {
- newFlags andInv PermissionFlags.RESTRICTION_REVOKED
- }
- newFlags =
- if (permission.isSoftRestricted && !isExempt) {
- newFlags or PermissionFlags.SOFT_RESTRICTED
- } else {
- newFlags andInv PermissionFlags.SOFT_RESTRICTED
- }
- setPermissionFlags(appId, userId, permissionName, newFlags)
+ updatePermissionExemptFlags(
+ appId,
+ userId,
+ permission,
+ PermissionFlags.UPGRADE_EXEMPT,
+ 0
+ )
}
}
+ fun MutateStateScope.updatePermissionExemptFlags(
+ appId: Int,
+ userId: Int,
+ permission: Permission,
+ exemptFlagMask: Int,
+ exemptFlagValues: Int
+ ) {
+ val permissionName = permission.name
+ val oldFlags = getPermissionFlags(appId, userId, permissionName)
+ var newFlags = (oldFlags andInv exemptFlagMask) or (exemptFlagValues and exemptFlagMask)
+ if (oldFlags == newFlags) {
+ return
+ }
+ val isExempt = newFlags.hasAnyBit(PermissionFlags.MASK_EXEMPT)
+ if (permission.isHardRestricted && !isExempt) {
+ newFlags = newFlags or PermissionFlags.RESTRICTION_REVOKED
+ // If the permission was policy fixed as granted but it is no longer on any of the
+ // allowlists we need to clear the policy fixed flag as allowlisting trumps policy i.e.
+ // policy cannot grant a non grantable permission.
+ if (PermissionFlags.isPermissionGranted(oldFlags)) {
+ newFlags = newFlags andInv PermissionFlags.POLICY_FIXED
+ }
+ } else {
+ newFlags = newFlags andInv PermissionFlags.RESTRICTION_REVOKED
+ }
+ newFlags =
+ if (
+ permission.isSoftRestricted && !isExempt &&
+ !anyPackageInAppId(appId) {
+ permissionName in it.androidPackage!!.requestedPermissions &&
+ isSoftRestrictedPermissionExemptForPackage(it, permissionName)
+ }
+ ) {
+ newFlags or PermissionFlags.SOFT_RESTRICTED
+ } else {
+ newFlags andInv PermissionFlags.SOFT_RESTRICTED
+ }
+ if (oldFlags == newFlags) {
+ return
+ }
+ setPermissionFlags(appId, userId, permissionName, newFlags)
+ }
+
override fun MutateStateScope.onPackageUninstalled(
packageName: String,
appId: Int,
@@ -1118,7 +1152,12 @@ class AppIdPermissionPolicy : SchemePolicy() {
newFlags andInv PermissionFlags.RESTRICTION_REVOKED
}
newFlags =
- if (permission.isSoftRestricted && !isExempt) {
+ if (
+ permission.isSoftRestricted && !isExempt &&
+ !requestingPackageStates.anyIndexed { _, it ->
+ isSoftRestrictedPermissionExemptForPackage(it, permissionName)
+ }
+ ) {
newFlags or PermissionFlags.SOFT_RESTRICTED
} else {
newFlags andInv PermissionFlags.SOFT_RESTRICTED
@@ -1398,6 +1437,17 @@ class AppIdPermissionPolicy : SchemePolicy() {
}
}
+ // See also SoftRestrictedPermissionPolicy.mayGrantPermission()
+ private fun isSoftRestrictedPermissionExemptForPackage(
+ packageState: PackageState,
+ permissionName: String
+ ): Boolean =
+ when (permissionName) {
+ Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE ->
+ packageState.androidPackage!!.targetSdkVersion >= Build.VERSION_CODES.Q
+ else -> false
+ }
+
private inline fun MutateStateScope.anyPackageInAppId(
appId: Int,
state: AccessState = newState,
diff --git a/services/permission/java/com/android/server/permission/access/permission/PermissionFlags.kt b/services/permission/java/com/android/server/permission/access/permission/PermissionFlags.kt
index 28889de4bbb1..c5c921dc3515 100644
--- a/services/permission/java/com/android/server/permission/access/permission/PermissionFlags.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/PermissionFlags.kt
@@ -346,9 +346,18 @@ object PermissionFlags {
return flags.hasBits(RUNTIME_GRANTED)
}
- fun isAppOpGranted(flags: Int): Boolean =
- isPermissionGranted(flags) && !flags.hasBits(RESTRICTION_REVOKED) &&
- !flags.hasBits(APP_OP_REVOKED)
+ fun isAppOpGranted(flags: Int): Boolean {
+ if (!isPermissionGranted(flags)) {
+ return false
+ }
+ if (flags.hasAnyBit(MASK_RESTRICTED)) {
+ return false
+ }
+ if (flags.hasBits(APP_OP_REVOKED)) {
+ return false
+ }
+ return true
+ }
fun toApiFlags(flags: Int): Int {
var apiFlags = 0
diff --git a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
index 0704c8ffca25..1f654631f902 100644
--- a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
@@ -88,7 +88,6 @@ import com.android.server.pm.PackageInstallerService
import com.android.server.pm.PackageManagerLocal
import com.android.server.pm.UserManagerInternal
import com.android.server.pm.UserManagerService
-import com.android.server.pm.parsing.pkg.AndroidPackageUtils
import com.android.server.pm.permission.LegacyPermission
import com.android.server.pm.permission.LegacyPermissionSettings
import com.android.server.pm.permission.LegacyPermissionState
@@ -97,7 +96,6 @@ import com.android.server.pm.permission.PermissionManagerServiceInterface
import com.android.server.pm.permission.PermissionManagerServiceInternal
import com.android.server.pm.pkg.AndroidPackage
import com.android.server.pm.pkg.PackageState
-import com.android.server.policy.SoftRestrictedPermissionPolicy
import java.io.FileDescriptor
import java.io.PrintWriter
import java.util.concurrent.CompletableFuture
@@ -1006,25 +1004,14 @@ class PermissionService(private val service: AccessCheckingService) :
}
if (isGranted && oldFlags.hasBits(PermissionFlags.SOFT_RESTRICTED)) {
- // TODO: Refactor SoftRestrictedPermissionPolicy.
- val softRestrictedPermissionPolicy =
- SoftRestrictedPermissionPolicy.forPermission(
- context,
- AndroidPackageUtils.generateAppInfoWithoutState(androidPackage),
- androidPackage,
- UserHandle.of(userId),
- permissionName
+ if (reportError) {
+ Slog.e(
+ LOG_TAG,
+ "$methodName: Cannot grant soft-restricted non-exempt permission" +
+ " $permissionName to package $packageName"
)
- if (!softRestrictedPermissionPolicy.mayGrantPermission()) {
- if (reportError) {
- Slog.e(
- LOG_TAG,
- "$methodName: Cannot grant soft-restricted non-exempt permission" +
- " $permissionName to package $packageName"
- )
- }
- return
}
+ return
}
val newFlags = PermissionFlags.updateRuntimePermissionGranted(oldFlags, isGranted)
@@ -1135,25 +1122,23 @@ class PermissionService(private val service: AccessCheckingService) :
return emptyMap()
}
- val permissionFlagsMap =
- service.getState {
+ service.getState {
+ val permissionFlags =
if (deviceId == VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT) {
with(policy) { getAllPermissionFlags(packageState.appId, userId) }
} else {
with(devicePolicy) {
getAllPermissionFlags(packageState.appId, deviceId, userId)
}
- }
+ } ?: return emptyMap()
+ val permissionStates = ArrayMap<String, PermissionState>()
+ permissionFlags.forEachIndexed { _, permissionName, flags ->
+ val granted = isPermissionGranted(packageState, userId, permissionName, deviceId)
+ val apiFlags = PermissionFlags.toApiFlags(flags)
+ permissionStates[permissionName] = PermissionState(granted, apiFlags)
}
- ?: return emptyMap()
-
- val permissionStates = ArrayMap<String, PermissionState>()
- permissionFlagsMap.forEachIndexed { _, permissionName, flags ->
- val granted = PermissionFlags.isPermissionGranted(flags)
- val apiFlags = PermissionFlags.toApiFlags(flags)
- permissionStates[permissionName] = PermissionState(granted, apiFlags)
+ return permissionStates
}
- return permissionStates
}
override fun isPermissionRevokedByPolicy(
@@ -1852,10 +1837,19 @@ class PermissionService(private val service: AccessCheckingService) :
allowlistedFlags: Int,
userId: Int
) {
+ var exemptMask = 0
+ if (allowlistedFlags.hasBits(PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM)) {
+ exemptMask = exemptMask or PermissionFlags.SYSTEM_EXEMPT
+ }
+ if (allowlistedFlags.hasBits(PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE)) {
+ exemptMask = exemptMask or PermissionFlags.UPGRADE_EXEMPT
+ }
+ if (allowlistedFlags.hasBits(PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER)) {
+ exemptMask = exemptMask or PermissionFlags.INSTALLER_EXEMPT
+ }
+
service.mutateState {
with(policy) {
- val permissionsFlags = getUidPermissionFlags(appId, userId) ?: return@mutateState
-
val permissions = getPermissions()
androidPackage.requestedPermissions.forEachIndexed { _, requestedPermission ->
val permission = permissions[requestedPermission]
@@ -1863,81 +1857,8 @@ class PermissionService(private val service: AccessCheckingService) :
return@forEachIndexed
}
- val oldFlags = permissionsFlags[requestedPermission] ?: 0
- val wasGranted = PermissionFlags.isPermissionGranted(oldFlags)
-
- var newFlags = oldFlags
- var mask = 0
- var allowlistFlagsCopy = allowlistedFlags
- while (allowlistFlagsCopy != 0) {
- val flag = 1 shl allowlistFlagsCopy.countTrailingZeroBits()
- allowlistFlagsCopy = allowlistFlagsCopy and flag.inv()
- when (flag) {
- PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM -> {
- mask = mask or PermissionFlags.SYSTEM_EXEMPT
- newFlags =
- if (permissionNames.contains(requestedPermission)) {
- newFlags or PermissionFlags.SYSTEM_EXEMPT
- } else {
- newFlags andInv PermissionFlags.SYSTEM_EXEMPT
- }
- }
- PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE -> {
- mask = mask or PermissionFlags.UPGRADE_EXEMPT
- newFlags =
- if (permissionNames.contains(requestedPermission)) {
- newFlags or PermissionFlags.UPGRADE_EXEMPT
- } else {
- newFlags andInv PermissionFlags.UPGRADE_EXEMPT
- }
- }
- PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER -> {
- mask = mask or PermissionFlags.INSTALLER_EXEMPT
- newFlags =
- if (permissionNames.contains(requestedPermission)) {
- newFlags or PermissionFlags.INSTALLER_EXEMPT
- } else {
- newFlags andInv PermissionFlags.INSTALLER_EXEMPT
- }
- }
- }
- }
-
- if (oldFlags == newFlags) {
- return@forEachIndexed
- }
-
- val isExempt = newFlags.hasAnyBit(PermissionFlags.MASK_EXEMPT)
-
- // If the permission is policy fixed as granted but it is no longer
- // on any of the allowlists we need to clear the policy fixed flag
- // as allowlisting trumps policy i.e. policy cannot grant a non
- // grantable permission.
- if (oldFlags.hasBits(PermissionFlags.POLICY_FIXED)) {
- if (!isExempt && wasGranted) {
- mask = mask or PermissionFlags.POLICY_FIXED
- newFlags = newFlags andInv PermissionFlags.POLICY_FIXED
- }
- }
-
- newFlags =
- if (permission.isHardRestricted && !isExempt) {
- newFlags or PermissionFlags.RESTRICTION_REVOKED
- } else {
- newFlags andInv PermissionFlags.RESTRICTION_REVOKED
- }
- newFlags =
- if (permission.isSoftRestricted && !isExempt) {
- newFlags or PermissionFlags.SOFT_RESTRICTED
- } else {
- newFlags andInv PermissionFlags.SOFT_RESTRICTED
- }
- mask =
- mask or
- PermissionFlags.RESTRICTION_REVOKED or
- PermissionFlags.SOFT_RESTRICTED
-
- updatePermissionFlags(appId, userId, requestedPermission, mask, newFlags)
+ var exemptFlags = if (requestedPermission in permissionNames) exemptMask else 0
+ updatePermissionExemptFlags(appId, userId, permission, exemptMask, exemptFlags)
}
}
}
diff --git a/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyTest.kt b/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyTest.kt
index cde46abafe95..96753b6d2bcc 100644
--- a/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyTest.kt
+++ b/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyTest.kt
@@ -233,24 +233,6 @@ class AppIdPermissionPolicyTest : BasePermissionPolicyTest() {
.isEqualTo(expectedNewFlags)
}
- @Test
- fun testOnPackageInstalled_restrictedPermissionsIsExempted_clearsRestrictionFlags() {
- val oldFlags = PermissionFlags.SOFT_RESTRICTED or PermissionFlags.INSTALLER_EXEMPT
- testOnPackageInstalled(
- oldFlags,
- permissionInfoFlags = PermissionInfo.FLAG_SOFT_RESTRICTED
- ) {}
- val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
- val expectedNewFlags = PermissionFlags.INSTALLER_EXEMPT
- assertWithMessage(
- "After onPackageInstalled() is called for a non-system app that requests a runtime" +
- " soft restricted permission that is exempted. The actual permission flags" +
- " $actualFlags should match the expected flags $expectedNewFlags"
- )
- .that(actualFlags)
- .isEqualTo(expectedNewFlags)
- }
-
private fun testOnPackageInstalled(
oldFlags: Int,
permissionInfoFlags: Int = 0,
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java
index 37958faed1ca..1c681ce21f02 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java
@@ -27,6 +27,7 @@ import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.Resources;
import android.hardware.display.DisplayManagerInternal;
+import android.os.PowerManager;
import android.view.Display;
import androidx.test.core.app.ApplicationProvider;
@@ -155,6 +156,7 @@ public final class DisplayBrightnessStrategySelectorTest {
DisplayManagerInternal.DisplayPowerRequest displayPowerRequest = mock(
DisplayManagerInternal.DisplayPowerRequest.class);
displayPowerRequest.policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
+ displayPowerRequest.dozeScreenBrightness = 0.2f;
when(mResources.getBoolean(R.bool.config_allowAutoBrightnessWhileDozing)).thenReturn(
DISALLOW_AUTO_BRIGHTNESS_WHILE_DOZING);
assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(displayPowerRequest,
@@ -162,6 +164,18 @@ public final class DisplayBrightnessStrategySelectorTest {
}
@Test
+ public void selectStrategyDoesNotSelectDozeStrategyWhenInvalidBrightness() {
+ DisplayManagerInternal.DisplayPowerRequest displayPowerRequest = mock(
+ DisplayManagerInternal.DisplayPowerRequest.class);
+ displayPowerRequest.policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
+ displayPowerRequest.dozeScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
+ when(mResources.getBoolean(R.bool.config_allowAutoBrightnessWhileDozing)).thenReturn(
+ DISALLOW_AUTO_BRIGHTNESS_WHILE_DOZING);
+ assertNotEquals(mDisplayBrightnessStrategySelector.selectStrategy(displayPowerRequest,
+ Display.STATE_DOZE), mDozeBrightnessModeStrategy);
+ }
+
+ @Test
public void selectStrategySelectsScreenOffStrategyWhenValid() {
DisplayManagerInternal.DisplayPowerRequest displayPowerRequest = mock(
DisplayManagerInternal.DisplayPowerRequest.class);
diff --git a/services/tests/servicestests/src/com/android/server/os/BugreportManagerServiceImplTest.java b/services/tests/servicestests/src/com/android/server/os/BugreportManagerServiceImplTest.java
index ea84eb2fbf73..e0ef035de735 100644
--- a/services/tests/servicestests/src/com/android/server/os/BugreportManagerServiceImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/os/BugreportManagerServiceImplTest.java
@@ -16,8 +16,6 @@
package com.android.server.os;
-import android.app.admin.flags.Flags;
-
import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
import static com.google.common.truth.Truth.assertThat;
@@ -27,15 +25,19 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
+import android.app.admin.DevicePolicyManager;
+import android.app.admin.flags.Flags;
import android.app.role.RoleManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.BugreportManager.BugreportCallback;
+import android.os.BugreportParams;
import android.os.IBinder;
import android.os.IDumpstateListener;
import android.os.Process;
import android.os.RemoteException;
+import android.os.UserManager;
import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
@@ -75,6 +77,10 @@ public class BugreportManagerServiceImplTest {
@Mock
private PackageManager mPackageManager;
+ @Mock
+ private UserManager mMockUserManager;
+ @Mock
+ private DevicePolicyManager mMockDevicePolicyManager;
private int mCallingUid = 1234;
private String mCallingPackage = "test.package";
@@ -91,10 +97,12 @@ public class BugreportManagerServiceImplTest {
ArraySet<String> mAllowlistedPackages = new ArraySet<>();
mAllowlistedPackages.add(mContext.getPackageName());
mService = new BugreportManagerServiceImpl(
- new BugreportManagerServiceImpl.Injector(mContext, mAllowlistedPackages,
- mMappingFile));
+ new TestInjector(mContext, mAllowlistedPackages, mMappingFile,
+ mMockUserManager, mMockDevicePolicyManager));
mBugreportFileManager = new BugreportManagerServiceImpl.BugreportFileManager(mMappingFile);
when(mPackageManager.getPackageUidAsUser(anyString(), anyInt())).thenReturn(mCallingUid);
+ // The calling user is an admin user by default.
+ when(mMockUserManager.isUserAdmin(anyInt())).thenReturn(true);
}
@After
@@ -182,6 +190,36 @@ public class BugreportManagerServiceImplTest {
}
@Test
+ public void testStartBugreport_throwsForNonAdminUser() throws Exception {
+ when(mMockUserManager.isUserAdmin(anyInt())).thenReturn(false);
+
+ Exception thrown = assertThrows(IllegalArgumentException.class,
+ () -> mService.startBugreport(mCallingUid, mContext.getPackageName(),
+ new FileDescriptor(), /* screenshotFd= */ null,
+ BugreportParams.BUGREPORT_MODE_FULL,
+ /* flags= */ 0, new Listener(new CountDownLatch(1)),
+ /* isScreenshotRequested= */ false));
+
+ assertThat(thrown.getMessage()).contains("not an admin user");
+ }
+
+ @Test
+ public void testStartBugreport_throwsForNotAffiliatedUser() throws Exception {
+ when(mMockUserManager.isUserAdmin(anyInt())).thenReturn(false);
+ when(mMockDevicePolicyManager.getDeviceOwnerUserId()).thenReturn(-1);
+ when(mMockDevicePolicyManager.isAffiliatedUser(anyInt())).thenReturn(false);
+
+ Exception thrown = assertThrows(IllegalArgumentException.class,
+ () -> mService.startBugreport(mCallingUid, mContext.getPackageName(),
+ new FileDescriptor(), /* screenshotFd= */ null,
+ BugreportParams.BUGREPORT_MODE_REMOTE,
+ /* flags= */ 0, new Listener(new CountDownLatch(1)),
+ /* isScreenshotRequested= */ false));
+
+ assertThat(thrown.getMessage()).contains("not affiliated to the device owner");
+ }
+
+ @Test
public void testRetrieveBugreportWithoutFilesForCaller() throws Exception {
CountDownLatch latch = new CountDownLatch(1);
Listener listener = new Listener(latch);
@@ -224,7 +262,8 @@ public class BugreportManagerServiceImplTest {
private void clearAllowlist() {
mService = new BugreportManagerServiceImpl(
- new BugreportManagerServiceImpl.Injector(mContext, new ArraySet<>(), mMappingFile));
+ new TestInjector(mContext, new ArraySet<>(), mMappingFile,
+ mMockUserManager, mMockDevicePolicyManager));
}
private static class Listener implements IDumpstateListener {
@@ -275,4 +314,27 @@ public class BugreportManagerServiceImplTest {
complete(successful);
}
}
+
+ private static class TestInjector extends BugreportManagerServiceImpl.Injector {
+
+ private final UserManager mUserManager;
+ private final DevicePolicyManager mDevicePolicyManager;
+
+ TestInjector(Context context, ArraySet<String> allowlistedPackages, AtomicFile mappingFile,
+ UserManager um, DevicePolicyManager dpm) {
+ super(context, allowlistedPackages, mappingFile);
+ mUserManager = um;
+ mDevicePolicyManager = dpm;
+ }
+
+ @Override
+ public UserManager getUserManager() {
+ return mUserManager;
+ }
+
+ @Override
+ public DevicePolicyManager getDevicePolicyManager() {
+ return mDevicePolicyManager;
+ }
+ }
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenAdaptersTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenAdaptersTest.java
index 99d5a6d9118a..75552bc433c5 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenAdaptersTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenAdaptersTest.java
@@ -16,7 +16,7 @@
package com.android.server.notification;
-import static com.android.server.notification.ZenAdapters.notificationPolicyToZenPolicy;
+import static android.service.notification.ZenAdapters.notificationPolicyToZenPolicy;
import static com.google.common.truth.Truth.assertThat;
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index 495e01a640de..7c1adbc39033 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -136,6 +136,7 @@ import android.provider.Settings;
import android.provider.Settings.Global;
import android.service.notification.Condition;
import android.service.notification.DeviceEffectsApplier;
+import android.service.notification.ZenAdapters;
import android.service.notification.ZenDeviceEffects;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeConfig.ConfigChangeOrigin;
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index 60130635108c..da11e6ad613a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -554,7 +554,7 @@ public class RootWindowContainerTests extends WindowTestsBase {
mRootWindowContainer.applySleepTokens(true);
// The display orientation should be changed by the activity so there is no relaunch.
- verify(activity, never()).relaunchActivityLocked(anyBoolean());
+ verify(activity, never()).relaunchActivityLocked(anyBoolean(), anyInt());
assertEquals(rotatedConfig.orientation, display.getConfiguration().orientation);
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 1e1dd00b8df5..5a5296836089 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -66,7 +66,6 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
-import android.os.PermissionEnforcer;
import android.os.PersistableBundle;
import android.os.RemoteCallback;
import android.os.RemoteCallbackList;
@@ -76,7 +75,6 @@ import android.os.SharedMemory;
import android.os.ShellCallback;
import android.os.Trace;
import android.os.UserHandle;
-import android.permission.flags.Flags;
import android.provider.Settings;
import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback;
import android.service.voice.IVisualQueryDetectionVoiceInteractionCallback;
@@ -1407,17 +1405,6 @@ public class VoiceInteractionManagerService extends SystemService {
}
}
- // Enforce permissions that are flag controlled. The flag value decides if the permission
- // should be enforced.
- private void initAndVerifyDetector_enforcePermissionWithFlags() {
- PermissionEnforcer enforcer = mContext.getSystemService(PermissionEnforcer.class);
- if (Flags.voiceActivationPermissionApis()) {
- enforcer.enforcePermission(
- android.Manifest.permission.RECEIVE_SANDBOX_TRIGGER_AUDIO,
- getCallingPid(), getCallingUid());
- }
- }
-
@android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_HOTWORD_DETECTION)
@Override
public void initAndVerifyDetector(
@@ -1427,13 +1414,7 @@ public class VoiceInteractionManagerService extends SystemService {
@NonNull IBinder token,
IHotwordRecognitionStatusCallback callback,
int detectorType) {
- // TODO(b/305787465): Remove the MANAGE_HOTWORD_DETECTION permission enforcement on the
- // {@link #initAndVerifyDetector(Identity, PersistableBundle, ShareMemory, IBinder,
- // IHotwordRecognitionStatusCallback, int)}
- // and replace with the permission RECEIVE_SANDBOX_TRIGGER_AUDIO when it is fully
- // launched.
super.initAndVerifyDetector_enforcePermission();
- initAndVerifyDetector_enforcePermissionWithFlags();
synchronized (this) {
enforceIsCurrentVoiceInteractionService();
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 9792cdd80a00..048b1b290dde 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1434,11 +1434,14 @@ public class TelecomManager {
}
/**
- * This API will return all {@link PhoneAccount}s registered via
- * {@link TelecomManager#registerPhoneAccount(PhoneAccount)}. If a {@link PhoneAccount} appears
- * to be missing from the list, Telecom has either unregistered the {@link PhoneAccount}
- * or the caller registered the {@link PhoneAccount} under a different user and does not
- * have the {@link android.Manifest.permission#INTERACT_ACROSS_USERS} permission.
+ * This API will return all {@link PhoneAccount}s the caller registered via
+ * {@link TelecomManager#registerPhoneAccount(PhoneAccount)}. If a {@link PhoneAccount} appears
+ * to be missing from the list, Telecom has either unregistered the {@link PhoneAccount} (for
+ * cleanup purposes) or the caller registered the {@link PhoneAccount} under a different user
+ * and does not have the {@link android.Manifest.permission#INTERACT_ACROSS_USERS} permission.
+ * <b>Note:</b> This API will only return {@link PhoneAccount}s registered by the same app. For
+ * system Dialers that need all the {@link PhoneAccount}s registered by every application, see
+ * {@link TelecomManager#getAllPhoneAccounts()}.
*
* @return all the {@link PhoneAccount}s registered by the caller.
*/
diff --git a/telephony/java/android/telephony/TelephonyFrameworkInitializer.java b/telephony/java/android/telephony/TelephonyFrameworkInitializer.java
index c2f5b8f3e7da..901daf813e86 100644
--- a/telephony/java/android/telephony/TelephonyFrameworkInitializer.java
+++ b/telephony/java/android/telephony/TelephonyFrameworkInitializer.java
@@ -19,12 +19,14 @@ package android.telephony;
import android.annotation.NonNull;
import android.app.SystemServiceRegistry;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.os.TelephonyServiceManager;
import android.telephony.euicc.EuiccCardManager;
import android.telephony.euicc.EuiccManager;
import android.telephony.ims.ImsManager;
import android.telephony.satellite.SatelliteManager;
+import com.android.internal.telephony.flags.Flags;
import com.android.internal.util.Preconditions;
@@ -55,6 +57,11 @@ public class TelephonyFrameworkInitializer {
sTelephonyServiceManager = Preconditions.checkNotNull(telephonyServiceManager);
}
+ private static boolean hasSystemFeature(Context context, String feature) {
+ if (!Flags.minimalTelephonyManagersConditionalOnFeatures()) return true;
+ return context.getPackageManager().hasSystemFeature(feature);
+ }
+
/**
* Called by {@link SystemServiceRegistry}'s static initializer and registers all telephony
* services to {@link Context}, so that {@link Context#getSystemService} can return them.
@@ -76,33 +83,39 @@ public class TelephonyFrameworkInitializer {
SystemServiceRegistry.registerContextAwareService(
Context.CARRIER_CONFIG_SERVICE,
CarrierConfigManager.class,
- context -> new CarrierConfigManager(context)
+ context -> hasSystemFeature(context, PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
+ ? new CarrierConfigManager(context) : null
);
SystemServiceRegistry.registerContextAwareService(
Context.EUICC_SERVICE,
EuiccManager.class,
- context -> new EuiccManager(context)
+ context -> hasSystemFeature(context, PackageManager.FEATURE_TELEPHONY_EUICC)
+ ? new EuiccManager(context) : null
);
SystemServiceRegistry.registerContextAwareService(
Context.EUICC_CARD_SERVICE,
EuiccCardManager.class,
- context -> new EuiccCardManager(context)
+ context -> hasSystemFeature(context, PackageManager.FEATURE_TELEPHONY_EUICC)
+ ? new EuiccCardManager(context) : null
);
SystemServiceRegistry.registerContextAwareService(
Context.TELEPHONY_IMS_SERVICE,
ImsManager.class,
- context -> new ImsManager(context)
+ context -> hasSystemFeature(context, PackageManager.FEATURE_TELEPHONY_IMS)
+ ? new ImsManager(context) : null
);
SystemServiceRegistry.registerContextAwareService(
Context.SMS_SERVICE,
SmsManager.class,
- context -> SmsManager.getSmsManagerForContextAndSubscriptionId(context,
- SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)
+ context -> hasSystemFeature(context, PackageManager.FEATURE_TELEPHONY_MESSAGING)
+ ? SmsManager.getSmsManagerForContextAndSubscriptionId(context,
+ SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) : null
);
SystemServiceRegistry.registerContextAwareService(
Context.SATELLITE_SERVICE,
SatelliteManager.class,
- context -> new SatelliteManager(context)
+ context -> hasSystemFeature(context, PackageManager.FEATURE_TELEPHONY_SATELLITE)
+ ? new SatelliteManager(context) : null
);
}
diff --git a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTest.kt b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTest.kt
index d47329ea97b4..57da05f13bbb 100644
--- a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTest.kt
+++ b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTest.kt
@@ -52,6 +52,7 @@ class OpenAppFromIntentColdAfterCameraTest(flicker: LegacyFlickerTest) :
// Can't use TAPL due to Recents not showing in 3 Button Nav in full screen mode
device.pressHome()
tapl.getWorkspace()
+ wmHelper.StateSyncBuilder().withHomeActivityVisible().waitForAndVerify()
}
teardown { testApp.exit(wmHelper) }
transitions { testApp.launchViaIntent(wmHelper) }
diff --git a/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt b/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
index 7343ba1c1ce7..e60764f137af 100644
--- a/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
+++ b/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
@@ -24,6 +24,7 @@ import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import android.content.pm.ServiceInfo
+import android.hardware.input.KeyboardLayoutSelectionResult
import android.hardware.input.IInputManager
import android.hardware.input.InputManager
import android.hardware.input.InputManagerGlobal
@@ -525,13 +526,13 @@ class KeyboardLayoutManagerTests {
keyboardDevice.identifier, USER_ID, imeInfo, imeSubtype,
ENGLISH_UK_LAYOUT_DESCRIPTOR
)
- val keyboardLayout =
+ assertEquals(
+ "Default UI: getKeyboardLayoutForInputDevice API should always return " +
+ "KeyboardLayoutSelectionResult.FAILED",
+ KeyboardLayoutSelectionResult.FAILED,
keyboardLayoutManager.getKeyboardLayoutForInputDevice(
keyboardDevice.identifier, USER_ID, imeInfo, imeSubtype
)
- assertNull(
- "Default UI: getKeyboardLayoutForInputDevice API should always return null",
- keyboardLayout
)
}
}
@@ -545,12 +546,14 @@ class KeyboardLayoutManagerTests {
keyboardDevice.identifier, USER_ID, imeInfo, imeSubtype,
ENGLISH_UK_LAYOUT_DESCRIPTOR
)
- assertEquals(
- "New UI: getKeyboardLayoutForInputDevice API should return the set layout",
- ENGLISH_UK_LAYOUT_DESCRIPTOR,
+ var result =
keyboardLayoutManager.getKeyboardLayoutForInputDevice(
keyboardDevice.identifier, USER_ID, imeInfo, imeSubtype
)
+ assertEquals(
+ "New UI: getKeyboardLayoutForInputDevice API should return the set layout",
+ ENGLISH_UK_LAYOUT_DESCRIPTOR,
+ result.layoutDescriptor
)
// This should replace previously set layout
@@ -558,12 +561,14 @@ class KeyboardLayoutManagerTests {
keyboardDevice.identifier, USER_ID, imeInfo, imeSubtype,
ENGLISH_US_LAYOUT_DESCRIPTOR
)
- assertEquals(
- "New UI: getKeyboardLayoutForInputDevice API should return the last set layout",
- ENGLISH_US_LAYOUT_DESCRIPTOR,
+ result =
keyboardLayoutManager.getKeyboardLayoutForInputDevice(
keyboardDevice.identifier, USER_ID, imeInfo, imeSubtype
)
+ assertEquals(
+ "New UI: getKeyboardLayoutForInputDevice API should return the last set layout",
+ ENGLISH_US_LAYOUT_DESCRIPTOR,
+ result.layoutDescriptor
)
}
}
@@ -734,17 +739,20 @@ class KeyboardLayoutManagerTests {
createImeSubtypeForLanguageTag("ru"),
createLayoutDescriptor("keyboard_layout_russian")
)
- assertNull(
- "New UI: getDefaultKeyboardLayoutForInputDevice should return null when no " +
- "layout available",
+ assertEquals(
+ "New UI: getDefaultKeyboardLayoutForInputDevice should return " +
+ "KeyboardLayoutSelectionResult.FAILED when no layout available",
+ KeyboardLayoutSelectionResult.FAILED,
keyboardLayoutManager.getKeyboardLayoutForInputDevice(
keyboardDevice.identifier, USER_ID, imeInfo,
createImeSubtypeForLanguageTag("it")
)
)
- assertNull(
- "New UI: getDefaultKeyboardLayoutForInputDevice should return null when no " +
- "layout for script code is available",
+ assertEquals(
+ "New UI: getDefaultKeyboardLayoutForInputDevice should return " +
+ "KeyboardLayoutSelectionResult.FAILED when no layout for script code is" +
+ "available",
+ KeyboardLayoutSelectionResult.FAILED,
keyboardLayoutManager.getKeyboardLayoutForInputDevice(
keyboardDevice.identifier, USER_ID, imeInfo,
createImeSubtypeForLanguageTag("en-Deva")
@@ -811,8 +819,10 @@ class KeyboardLayoutManagerTests {
createImeSubtypeForLanguageTagAndLayoutType("ru", ""),
createLayoutDescriptor("keyboard_layout_russian")
)
- assertNull("New UI: getDefaultKeyboardLayoutForInputDevice should return null when " +
- "no layout for script code is available",
+ assertEquals("New UI: getDefaultKeyboardLayoutForInputDevice should return " +
+ "KeyboardLayoutSelectionResult.FAILED when no layout for script code is" +
+ "available",
+ KeyboardLayoutSelectionResult.FAILED,
keyboardLayoutManager.getKeyboardLayoutForInputDevice(
keyboardDevice.identifier, USER_ID, imeInfo,
createImeSubtypeForLanguageTagAndLayoutType("en-Deva-US", "")
@@ -865,14 +875,16 @@ class KeyboardLayoutManagerTests {
ArgumentMatchers.anyBoolean(),
ArgumentMatchers.eq(keyboardDevice.vendorId),
ArgumentMatchers.eq(keyboardDevice.productId),
- ArgumentMatchers.eq(createByteArray(
+ ArgumentMatchers.eq(
+ createByteArray(
KeyboardMetricsCollector.DEFAULT_LANGUAGE_TAG,
LAYOUT_TYPE_DEFAULT,
GERMAN_LAYOUT_NAME,
- KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD,
+ KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD,
"de-Latn",
- LAYOUT_TYPE_QWERTZ),
+ LAYOUT_TYPE_QWERTZ
),
+ ),
ArgumentMatchers.eq(keyboardDevice.deviceBus),
)
}
@@ -893,13 +905,16 @@ class KeyboardLayoutManagerTests {
ArgumentMatchers.anyBoolean(),
ArgumentMatchers.eq(englishQwertyKeyboardDevice.vendorId),
ArgumentMatchers.eq(englishQwertyKeyboardDevice.productId),
- ArgumentMatchers.eq(createByteArray(
+ ArgumentMatchers.eq(
+ createByteArray(
"en",
LAYOUT_TYPE_QWERTY,
ENGLISH_US_LAYOUT_NAME,
- KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEVICE,
+ KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_DEVICE,
"de-Latn",
- LAYOUT_TYPE_QWERTZ)),
+ LAYOUT_TYPE_QWERTZ
+ )
+ ),
ArgumentMatchers.eq(keyboardDevice.deviceBus),
)
}
@@ -918,14 +933,16 @@ class KeyboardLayoutManagerTests {
ArgumentMatchers.anyBoolean(),
ArgumentMatchers.eq(keyboardDevice.vendorId),
ArgumentMatchers.eq(keyboardDevice.productId),
- ArgumentMatchers.eq(createByteArray(
+ ArgumentMatchers.eq(
+ createByteArray(
KeyboardMetricsCollector.DEFAULT_LANGUAGE_TAG,
LAYOUT_TYPE_DEFAULT,
"Default",
- KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEFAULT,
+ KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_DEFAULT,
KeyboardMetricsCollector.DEFAULT_LANGUAGE_TAG,
- LAYOUT_TYPE_DEFAULT),
+ LAYOUT_TYPE_DEFAULT
),
+ ),
ArgumentMatchers.eq(keyboardDevice.deviceBus),
)
}
@@ -998,12 +1015,13 @@ class KeyboardLayoutManagerTests {
imeSubtype: InputMethodSubtype,
expectedLayout: String
) {
+ val result = keyboardLayoutManager.getKeyboardLayoutForInputDevice(
+ device.identifier, USER_ID, imeInfo, imeSubtype
+ )
assertEquals(
"New UI: getDefaultKeyboardLayoutForInputDevice should return $expectedLayout",
expectedLayout,
- keyboardLayoutManager.getKeyboardLayoutForInputDevice(
- device.identifier, USER_ID, imeInfo, imeSubtype
- )
+ result.layoutDescriptor
)
}
diff --git a/tests/Input/src/com/android/server/input/KeyboardMetricsCollectorTests.kt b/tests/Input/src/com/android/server/input/KeyboardMetricsCollectorTests.kt
index 89a47b9b736a..0615941eda09 100644
--- a/tests/Input/src/com/android/server/input/KeyboardMetricsCollectorTests.kt
+++ b/tests/Input/src/com/android/server/input/KeyboardMetricsCollectorTests.kt
@@ -17,6 +17,7 @@
package com.android.server.input
import android.hardware.input.KeyboardLayout
+import android.hardware.input.KeyboardLayoutSelectionResult
import android.icu.util.ULocale
import android.platform.test.annotations.Presubmit
import android.view.InputDevice
@@ -120,15 +121,15 @@ class KeyboardMetricsCollectorTests {
val event = builder.addLayoutSelection(
createImeSubtype(1, ULocale.forLanguageTag("en-US"), "qwerty"),
"English(US)(Qwerty)",
- KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD
+ KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD
).addLayoutSelection(
createImeSubtype(2, ULocale.forLanguageTag("en-US"), "azerty"),
null, // Default layout type
- KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_USER
+ KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_USER
).addLayoutSelection(
createImeSubtype(3, ULocale.forLanguageTag("en-US"), "qwerty"),
"German",
- KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEVICE
+ KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_DEVICE
).setIsFirstTimeConfiguration(true).build()
assertEquals(
@@ -158,7 +159,7 @@ class KeyboardMetricsCollectorTests {
"de-CH",
KeyboardLayout.LayoutType.getLayoutTypeEnumValue("qwertz"),
"English(US)(Qwerty)",
- KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD,
+ KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD,
"en-US",
KeyboardLayout.LayoutType.getLayoutTypeEnumValue("qwerty"),
)
@@ -167,7 +168,7 @@ class KeyboardMetricsCollectorTests {
"de-CH",
KeyboardLayout.LayoutType.getLayoutTypeEnumValue("qwertz"),
KeyboardMetricsCollector.DEFAULT_LAYOUT_NAME,
- KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_USER,
+ KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_USER,
"en-US",
KeyboardLayout.LayoutType.getLayoutTypeEnumValue("azerty"),
)
@@ -176,7 +177,7 @@ class KeyboardMetricsCollectorTests {
"de-CH",
KeyboardLayout.LayoutType.getLayoutTypeEnumValue("qwertz"),
"German",
- KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEVICE,
+ KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_DEVICE,
"en-US",
KeyboardLayout.LayoutType.getLayoutTypeEnumValue("qwerty"),
)
@@ -197,7 +198,7 @@ class KeyboardMetricsCollectorTests {
val event = builder.addLayoutSelection(
createImeSubtype(4, null, "qwerty"), // Default language tag
"German",
- KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEVICE
+ KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_DEVICE
).build()
assertExpectedLayoutConfiguration(
@@ -205,7 +206,7 @@ class KeyboardMetricsCollectorTests {
KeyboardMetricsCollector.DEFAULT_LANGUAGE_TAG,
KeyboardLayout.LayoutType.getLayoutTypeEnumValue("azerty"),
"German",
- KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEVICE,
+ KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_DEVICE,
KeyboardMetricsCollector.DEFAULT_LANGUAGE_TAG,
KeyboardLayout.LayoutType.getLayoutTypeEnumValue("qwerty"),
)
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp
index b054a57e85af..b4e2758f4abe 100644
--- a/tools/aapt2/Android.bp
+++ b/tools/aapt2/Android.bp
@@ -15,12 +15,7 @@
//
package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_base_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_base_license"],
+ default_applicable_licenses: ["Android-Apache-2.0"],
}
toolSources = [
diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk
deleted file mode 100644
index 15ae2baa73df..000000000000
--- a/tools/aapt2/Android.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-include $(CLEAR_VARS)
-aapt2_results := ./out/soong/.intermediates/frameworks/base/tools/aapt2/aapt2_results
-$(call declare-1p-target,$(aapt2_results))
-aapt2_results :=