summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PREUPLOAD.cfg3
-rw-r--r--Ravenwood.bp1
-rw-r--r--apct-tests/perftests/core/src/android/input/MotionPredictorBenchmark.kt78
-rw-r--r--apct-tests/perftests/core/src/android/input/VelocityTrackerBenchmarkTest.kt61
-rw-r--r--apct-tests/perftests/core/src/android/view/ViewConfigurationPerfTest.java278
-rw-r--r--apct-tests/perftests/core/src/android/view/ViewPerfTest.java2
-rw-r--r--apct-tests/perftests/healthconnect/src/com/android/perftests/healthconnect/HealthConnectReadWritePerfTest.kt9
-rw-r--r--apct-tests/perftests/packagemanager/src/android/os/PackageParsingPerfTest.kt168
-rw-r--r--apct-tests/perftests/permission/src/android/perftests/permission/AppOpsPerfTest.kt4
-rw-r--r--apct-tests/perftests/permission/src/android/perftests/permission/PermissionServicePerfTest.kt27
-rw-r--r--core/java/Android.bp9
-rw-r--r--core/java/android/app/ActivityManager.java19
-rw-r--r--core/java/android/app/ContextImpl.java6
-rw-r--r--core/java/android/database/sqlite/SQLiteConnection.java9
-rw-r--r--core/java/android/database/sqlite/flags.aconfig9
-rw-r--r--core/java/android/os/CombinedMessageQueue/MessageQueue.java17
-rw-r--r--core/java/android/os/PerfettoTrackEventExtra.java5
-rw-r--r--core/java/android/os/Process.java7
-rw-r--r--core/java/android/os/flags.aconfig8
-rw-r--r--core/java/android/permission/flags.aconfig11
-rw-r--r--core/java/android/preference/PreferenceScreen.java18
-rw-r--r--core/java/android/view/ViewConfiguration.java231
-rw-r--r--core/java/android/webkit/LegacyErrorStrings.java2
-rw-r--r--core/java/android/webkit/WebIconDatabase.java2
-rw-r--r--core/java/android/window/DesktopExperienceFlags.java2
-rw-r--r--core/java/android/window/flags/lse_desktop_experience.aconfig23
-rw-r--r--core/java/android/window/flags/windowing_frontend.aconfig11
-rw-r--r--core/java/com/android/internal/widget/LockPatternView.java7
-rw-r--r--core/jni/android_database_SQLiteConnection.cpp19
-rw-r--r--core/jni/com_android_internal_os_Zygote.cpp10
-rw-r--r--core/proto/android/server/windowmanagerservice.proto28
-rw-r--r--core/res/AndroidManifest.xml3
-rw-r--r--core/res/res/values-af/strings.xml1
-rw-r--r--core/res/res/values-am/strings.xml1
-rw-r--r--core/res/res/values-ar/strings.xml1
-rw-r--r--core/res/res/values-as/strings.xml1
-rw-r--r--core/res/res/values-az/strings.xml1
-rw-r--r--core/res/res/values-b+sr+Latn/strings.xml4
-rw-r--r--core/res/res/values-be/strings.xml3
-rw-r--r--core/res/res/values-bg/strings.xml1
-rw-r--r--core/res/res/values-bn/strings.xml3
-rw-r--r--core/res/res/values-bs/strings.xml1
-rw-r--r--core/res/res/values-ca/strings.xml1
-rw-r--r--core/res/res/values-cs/strings.xml1
-rw-r--r--core/res/res/values-da/strings.xml1
-rw-r--r--core/res/res/values-de/strings.xml1
-rw-r--r--core/res/res/values-el/strings.xml1
-rw-r--r--core/res/res/values-en-rAU/strings.xml1
-rw-r--r--core/res/res/values-en-rCA/strings.xml1
-rw-r--r--core/res/res/values-en-rGB/strings.xml1
-rw-r--r--core/res/res/values-en-rIN/strings.xml1
-rw-r--r--core/res/res/values-es-rUS/strings.xml1
-rw-r--r--core/res/res/values-es/strings.xml1
-rw-r--r--core/res/res/values-et/strings.xml9
-rw-r--r--core/res/res/values-eu/strings.xml1
-rw-r--r--core/res/res/values-fa/strings.xml1
-rw-r--r--core/res/res/values-fi/strings.xml1
-rw-r--r--core/res/res/values-fr-rCA/strings.xml1
-rw-r--r--core/res/res/values-fr/strings.xml1
-rw-r--r--core/res/res/values-gl/strings.xml1
-rw-r--r--core/res/res/values-gu/strings.xml1
-rw-r--r--core/res/res/values-hi/strings.xml1
-rw-r--r--core/res/res/values-hr/strings.xml17
-rw-r--r--core/res/res/values-hu/strings.xml1
-rw-r--r--core/res/res/values-hy/strings.xml1
-rw-r--r--core/res/res/values-in/strings.xml1
-rw-r--r--core/res/res/values-is/strings.xml3
-rw-r--r--core/res/res/values-it/strings.xml8
-rw-r--r--core/res/res/values-iw/strings.xml1
-rw-r--r--core/res/res/values-ja/strings.xml4
-rw-r--r--core/res/res/values-ka/strings.xml1
-rw-r--r--core/res/res/values-kk/strings.xml1
-rw-r--r--core/res/res/values-km/strings.xml1
-rw-r--r--core/res/res/values-kn/strings.xml1
-rw-r--r--core/res/res/values-ko/strings.xml1
-rw-r--r--core/res/res/values-ky/strings.xml5
-rw-r--r--core/res/res/values-lo/strings.xml1
-rw-r--r--core/res/res/values-lt/strings.xml1
-rw-r--r--core/res/res/values-lv/strings.xml1
-rw-r--r--core/res/res/values-mk/strings.xml1
-rw-r--r--core/res/res/values-ml/strings.xml4
-rw-r--r--core/res/res/values-mn/strings.xml3
-rw-r--r--core/res/res/values-mr/strings.xml41
-rw-r--r--core/res/res/values-ms/strings.xml4
-rw-r--r--core/res/res/values-my/strings.xml1
-rw-r--r--core/res/res/values-nb/strings.xml1
-rw-r--r--core/res/res/values-ne/strings.xml1
-rw-r--r--core/res/res/values-nl/strings.xml1
-rw-r--r--core/res/res/values-or/strings.xml4
-rw-r--r--core/res/res/values-pa/strings.xml4
-rw-r--r--core/res/res/values-pl/strings.xml3
-rw-r--r--core/res/res/values-pt-rBR/strings.xml1
-rw-r--r--core/res/res/values-pt-rPT/strings.xml3
-rw-r--r--core/res/res/values-pt/strings.xml1
-rw-r--r--core/res/res/values-ro/strings.xml3
-rw-r--r--core/res/res/values-ru/strings.xml1
-rw-r--r--core/res/res/values-si/strings.xml3
-rw-r--r--core/res/res/values-sk/strings.xml1
-rw-r--r--core/res/res/values-sl/strings.xml1
-rw-r--r--core/res/res/values-sq/strings.xml9
-rw-r--r--core/res/res/values-sr/strings.xml4
-rw-r--r--core/res/res/values-sv/strings.xml3
-rw-r--r--core/res/res/values-sw/strings.xml1
-rw-r--r--core/res/res/values-ta/strings.xml1
-rw-r--r--core/res/res/values-te/strings.xml1
-rw-r--r--core/res/res/values-th/strings.xml6
-rw-r--r--core/res/res/values-tl/strings.xml1
-rw-r--r--core/res/res/values-tr/strings.xml1
-rw-r--r--core/res/res/values-uk/strings.xml1
-rw-r--r--core/res/res/values-ur/strings.xml1
-rw-r--r--core/res/res/values-uz/strings.xml1
-rw-r--r--core/res/res/values-vi/strings.xml1
-rw-r--r--core/res/res/values-zh-rCN/strings.xml1
-rw-r--r--core/res/res/values-zh-rHK/strings.xml1
-rw-r--r--core/res/res/values-zh-rTW/strings.xml1
-rw-r--r--core/res/res/values-zu/strings.xml1
-rw-r--r--core/res/res/values/config.xml37
-rw-r--r--core/res/res/values/config_telephony.xml5
-rw-r--r--core/res/res/values/strings.xml2
-rw-r--r--core/res/res/values/symbols.xml11
-rw-r--r--libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-es-rUS/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-it/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-ja/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-ml/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-ms/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-or/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-pa/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-sq/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-sr/strings.xml30
-rw-r--r--libs/WindowManager/Shell/res/values-th/strings.xml30
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DeviceConfig.kt20
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DropTargetManager.kt7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt34
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java79
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDesktopState.java73
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java15
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java25
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java19
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java33
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt44
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt143
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt15
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/desktopwallpaperactivity/DesktopWallpaperActivityTokenProvider.kt14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/docs/dagger.md66
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipInteractionHandler.java88
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java39
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java19
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/transition/PipExpandHandler.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/WindowDecorationViewHolder.kt5
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipDesktopStateTest.java89
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt34
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt118
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt47
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipInteractionHandlerTest.java95
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTransitionStateTest.java33
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/transition/PipExpandHandlerTest.java24
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/bubbles/DropTargetManagerTest.kt23
-rw-r--r--media/java/android/media/MediaRoute2ProviderService.java17
-rw-r--r--native/android/thermal.cpp14
-rw-r--r--packages/CompanionDeviceManager/res/values-ar/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-be/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-bg/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-el/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-en-rCA/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-es-rUS/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-et/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-hi/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-hu/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-it/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ja/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-km/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-lt/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-nl/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-tl/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ur/strings.xml6
-rw-r--r--packages/DynamicSystemInstallationService/res/values-mr/strings.xml12
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/layout-v36/settingslib_expressive_main_switch_layout.xml6
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_layout.xml6
-rw-r--r--packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java21
-rw-r--r--packages/SettingsLib/SelectorWithWidgetPreference/res/layout-v36/settingslib_expressive_preference_selector_with_widget.xml (renamed from packages/SettingsLib/SelectorWithWidgetPreference/res/layout-v36/preference_selector_with_widget.xml)0
-rw-r--r--packages/SettingsLib/SelectorWithWidgetPreference/src/com/android/settingslib/widget/SelectorWithWidgetPreference.java5
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background.xml8
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom.xml8
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom_highlighted.xml6
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom_selected.xml8
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center.xml5
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center_highlighted.xml5
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center_selected.xml5
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_highlighted.xml6
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_selected.xml8
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top.xml5
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top_highlighted.xml5
-rw-r--r--packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top_selected.xml5
-rw-r--r--packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/SettingsBasePreferenceFragment.kt17
-rw-r--r--packages/SettingsLib/res/values-fr/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-mr/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-pt-rPT/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-vi/strings.xml2
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/BatteryLevelsInfo.kt28
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java88
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java76
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java36
-rw-r--r--packages/SystemUI/aconfig/systemui.aconfig20
-rw-r--r--packages/SystemUI/compose/core/src/com/android/compose/animation/Bounceable.kt56
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/compose/modifiers/SysuiTestTag.kt10
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt41
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt1
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt47
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt9
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Scene.kt1
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/TransitionState.kt17
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/mechanics/TransitionScopedMechanicsAdapter.kt135
-rw-r--r--packages/SystemUI/compose/scene/tests/goldens/motionValue_interruptedAnimation_completes.json70
-rw-r--r--packages/SystemUI/compose/scene/tests/goldens/motionValue_withAnimation_prolongsTransition.json48
-rw-r--r--packages/SystemUI/compose/scene/tests/goldens/motionValue_withoutAnimation_terminatesImmediately.json26
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt34
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/mechanics/TransitionScopedMechanicsAdapterTest.kt519
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/FlexClockView.kt24
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt12
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt18
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/common/domain/interactor/SysUIStatePerDisplayInteractorTest.kt113
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt110
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/model/SceneContainerPluginTest.kt93
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUIStateDispatcherTest.kt87
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUiStateExtTest.kt14
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUiStateTest.java85
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/view/WindowRootViewKeyEventHandlerTest.kt69
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java9
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java31
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt9
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java32
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationMediaManagerTest.kt16
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarOrchestratorStoreTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarterTest.kt276
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/LightBarControllerStoreImplTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayDarkIconDispatcherStoreTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarContentInsetsProviderStoreTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarModeRepositoryStoreTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStoreImplTest.kt7
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayStoreImplTest.kt88
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStoreImplTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorTest.kt6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/MultiDisplayAutoHideControllerStoreTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt281
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/MultiDisplayStatusBarWindowControllerStoreTest.kt7
-rw-r--r--packages/SystemUI/res/values-af/strings.xml17
-rw-r--r--packages/SystemUI/res/values-am/strings.xml17
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml29
-rw-r--r--packages/SystemUI/res/values-as/strings.xml17
-rw-r--r--packages/SystemUI/res/values-az/strings.xml17
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml17
-rw-r--r--packages/SystemUI/res/values-be/strings.xml16
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml7
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml19
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml8
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml17
-rw-r--r--packages/SystemUI/res/values-da/strings.xml17
-rw-r--r--packages/SystemUI/res/values-de/strings.xml17
-rw-r--r--packages/SystemUI/res/values-el/strings.xml7
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml17
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings.xml7
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml17
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml17
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml7
-rw-r--r--packages/SystemUI/res/values-es/strings.xml19
-rw-r--r--packages/SystemUI/res/values-et/strings.xml16
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml17
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml8
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml17
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml17
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml8
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml8
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml17
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml18
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml8
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml16
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml8
-rw-r--r--packages/SystemUI/res/values-in/strings.xml17
-rw-r--r--packages/SystemUI/res/values-is/strings.xml8
-rw-r--r--packages/SystemUI/res/values-it/strings.xml16
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml39
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml16
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml8
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml21
-rw-r--r--packages/SystemUI/res/values-km/strings.xml7
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml19
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml17
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml8
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml7
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml8
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml17
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml17
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml17
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml20
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml17
-rw-r--r--packages/SystemUI/res/values-my/strings.xml17
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml17
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml8
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml16
-rw-r--r--packages/SystemUI/res/values-or/strings.xml26
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml17
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml23
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml19
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml7
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml19
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml17
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml8
-rw-r--r--packages/SystemUI/res/values-si/strings.xml17
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml17
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml17
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml17
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml17
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml8
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml17
-rw-r--r--packages/SystemUI/res/values-sw/tiles_states_strings.xml2
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml17
-rw-r--r--packages/SystemUI/res/values-te/strings.xml8
-rw-r--r--packages/SystemUI/res/values-th/strings.xml26
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml7
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml17
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml17
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml7
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml17
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml19
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml17
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml8
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml8
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml17
-rw-r--r--packages/SystemUI/res/values/strings.xml3
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/ILauncherProxy.aidl2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/ClockEventController.kt2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPasswordViewBinder.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModel.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/common/domain/interactor/SysUIStateDisplaysInteractor.kt45
-rw-r--r--packages/SystemUI/src/com/android/systemui/common/shared/model/Color.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/common/shared/model/ContentDescription.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/common/shared/model/Icon.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/PerDisplayRepositoriesModule.kt45
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/development/domain/interactor/BuildNumberInteractor.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/development/ui/viewmodel/BuildNumberViewModel.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayScopeRepository.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/display/data/repository/FakePerDisplayRepository.kt40
-rw-r--r--packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepository.kt210
-rw-r--r--packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/RefactorFlagUtils.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModel.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/remedia/shared/model/MediaSessionState.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt230
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaOutputSwitcherChipViewModel.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaPlayPauseActionViewModel.kt28
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaSecondaryActionViewModel.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/model/SysUIStateChange.kt82
-rw-r--r--packages/SystemUI/src/com/android/systemui/model/SysUIStateDispatcher.kt77
-rw-r--r--packages/SystemUI/src/com/android/systemui/model/SysUiState.kt195
-rw-r--r--packages/SystemUI/src/com/android/systemui/modes/shared/ModesUi.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/modes/shared/ModesUiIcons.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/flags/QsDetailedView.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsButtonViewModel.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt47
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt84
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/Selection.kt41
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/toolbar/Toolbar.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/model/TileGridCell.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/QSPipelineFlagsRepository.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/LauncherProxyService.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/startable/KeyguardStateCallbackStartable.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootViewKeyEventHandler.kt49
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java39
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java31
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java33
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ShadeExpandsOnStatusBarLongPress.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDialogContextInteractor.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/shared/flag/ShadeWindowGoesAround.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java78
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractor.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/shared/StatusBarNotifChips.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModel.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/core/CommandQueueInitializer.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarOrchestratorStore.kt36
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/core/NewStatusBarIcons.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarConnectedDisplays.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializerStore.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarOrchestrator.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarRootModernization.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStore.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStore.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationControllerStore.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarContentInsetsProviderStore.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryStore.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayStoreImpl.kt47
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStore.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/events/MultiDisplaySystemEventChipAnimationController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/events/ui/view/BatteryStatusEventComposeChip.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/StatusBarPopupChips.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/headsup/shared/StatusBarNoHunBehavior.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/layout/StatusBarContentInsetsProvider.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/layout/ui/viewmodel/StatusBarContentInsetsViewModelStore.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/PhysicsPropertyAnimator.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StabilizeHeadsUpGroup.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerImpl.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/emptyshade/shared/ModesEmptyShadeFix.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/emptyshade/ui/viewmodel/EmptyShadeViewModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/shared/NotifRedesignFooter.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpAnimator.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/NotificationsHunSharedAnimationValues.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUi.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiAod.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiForceExpanded.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/AODPromotedNotificationInteractor.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractor.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationBundleUi.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java60
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerStore.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/StatusBarChipsModernization.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ethernet/shared/StatusBarSignalPolicyRefactorEthernet.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt190
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/ChipsVisibilityModel.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt49
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStore.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/supervision/shared/DeprecateDpmSupervisionApis.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/panel/shared/flag/VolumePanelFlag.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/EditModeTest.kt13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/ResizingTest.kt21
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/recents/LauncherProxyServiceTest.kt22
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt33
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java17
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/development/domain/interactor/BuildNumberInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayRepository.kt23
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/PerDisplayStoreKosmos.kt29
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyevent/domain/interactor/SysUIKeyEventHandlerKosmos.kt23
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt6
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/model/SceneContainerPluginKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt34
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/FooterActionsTestUtils.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/scene/ui/view/WindowRootViewKeyEventHandlerKosmos.kt29
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarOrchestratorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayStoreKosmos.kt55
-rw-r--r--services/core/java/com/android/server/am/BroadcastController.java4
-rw-r--r--services/core/java/com/android/server/am/BroadcastProcessedEventRecord.java142
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueueImpl.java6
-rw-r--r--services/core/java/com/android/server/am/BroadcastRecord.java61
-rw-r--r--services/core/java/com/android/server/am/SettingsToPropertiesMapper.java1
-rw-r--r--services/core/java/com/android/server/am/broadcasts_flags.aconfig13
-rw-r--r--services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java10
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceBroker.java177
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceInventory.java29
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java3
-rw-r--r--services/core/java/com/android/server/compat/overrides/AppCompatOverridesService.java24
-rw-r--r--services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java8
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java6
-rw-r--r--services/core/java/com/android/server/policy/WindowManagerPolicy.java14
-rw-r--r--services/core/java/com/android/server/updates/CertPinInstallReceiver.java20
-rw-r--r--services/core/java/com/android/server/vibrator/VendorVibrationSession.java4
-rw-r--r--services/core/java/com/android/server/vibrator/VibrationThread.java4
-rw-r--r--services/core/java/com/android/server/vibrator/VibratorDebugUtils.java37
-rw-r--r--services/core/java/com/android/server/vibrator/VibratorManagerService.java4
-rw-r--r--services/core/java/com/android/server/wm/ActivityClientController.java16
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java222
-rw-r--r--services/core/java/com/android/server/wm/ActivityRefresher.java13
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java18
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskSupervisor.java10
-rw-r--r--services/core/java/com/android/server/wm/AppCompatSizeCompatModePolicy.java6
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java61
-rw-r--r--services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java4
-rw-r--r--services/core/java/com/android/server/wm/InsetsSourceProvider.java19
-rw-r--r--services/core/java/com/android/server/wm/KeyguardController.java13
-rw-r--r--services/core/java/com/android/server/wm/TaskFragment.java161
-rw-r--r--services/core/java/com/android/server/wm/WallpaperController.java45
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java46
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java11
-rw-r--r--services/core/java/com/android/server/wm/WindowProcessController.java10
-rw-r--r--services/core/java/com/android/server/wm/WindowProcessControllerMap.java3
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/BroadcastProcessedEventRecordTest.java141
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueImplTest.java50
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/BroadcastRecordTest.java156
-rw-r--r--services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/TestApp/src/com/android/coretests/apps/testapp/Android.bp1
-rw-r--r--services/tests/servicestests/src/com/android/server/locales/LocaleManagerBackupRestoreTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/OWNERS1
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java1
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java46
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java37
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl25
539 files changed, 8268 insertions, 3225 deletions
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 05d6e886b01a..e862cd9e0a95 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -6,6 +6,7 @@ ktfmt = true
[Builtin Hooks Options]
# Only turn on clang-format check for the following subfolders.
clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
+ apct-tests/
cmds/hid/
cmds/input/
cmds/uinput/
@@ -18,7 +19,7 @@ clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
tests/
tools/
bpfmt = -d
-ktfmt = --kotlinlang-style --include-dirs=services/permission,packages/SystemUI,libs/WindowManager/Shell/src/com/android/wm/shell/freeform,libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode,libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode
+ktfmt = --kotlinlang-style --include-dirs=services/permission,packages/SystemUI,libs/WindowManager/Shell/src/com/android/wm/shell/freeform,libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode,libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode,apct-tests
[Hook Scripts]
checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT}
diff --git a/Ravenwood.bp b/Ravenwood.bp
index 2e038e00bb35..a16b4406f217 100644
--- a/Ravenwood.bp
+++ b/Ravenwood.bp
@@ -19,6 +19,7 @@ java_library {
name: "framework-minus-apex-for-host",
installable: false,
static_libs: ["framework-minus-apex"],
+ srcs: [":framework-ravenwood-sources"],
visibility: ["//frameworks/base/ravenwood"],
}
diff --git a/apct-tests/perftests/core/src/android/input/MotionPredictorBenchmark.kt b/apct-tests/perftests/core/src/android/input/MotionPredictorBenchmark.kt
index add0a086201b..cf93331d87c2 100644
--- a/apct-tests/perftests/core/src/android/input/MotionPredictorBenchmark.kt
+++ b/apct-tests/perftests/core/src/android/input/MotionPredictorBenchmark.kt
@@ -25,11 +25,10 @@ import android.view.MotionEvent.ACTION_MOVE
import android.view.MotionEvent.PointerCoords
import android.view.MotionEvent.PointerProperties
import android.view.MotionPredictor
-
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.filters.LargeTest
import androidx.test.ext.junit.runners.AndroidJUnit4
-
+import androidx.test.filters.LargeTest
+import androidx.test.platform.app.InstrumentationRegistry
+import java.time.Duration
import org.junit.After
import org.junit.Assert.assertTrue
import org.junit.Before
@@ -37,14 +36,12 @@ import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.time.Duration
-
private fun getStylusMotionEvent(
- eventTime: Duration,
- action: Int,
- x: Float,
- y: Float,
- ): MotionEvent{
+ eventTime: Duration,
+ action: Int,
+ x: Float,
+ y: Float,
+): MotionEvent {
val pointerCount = 1
val properties = arrayOfNulls<MotionEvent.PointerProperties>(pointerCount)
val coords = arrayOfNulls<MotionEvent.PointerCoords>(pointerCount)
@@ -58,37 +55,49 @@ private fun getStylusMotionEvent(
coords[i]!!.y = y
}
- return MotionEvent.obtain(/*downTime=*/0, eventTime.toMillis(), action, properties.size,
- properties, coords, /*metaState=*/0, /*buttonState=*/0,
- /*xPrecision=*/0f, /*yPrecision=*/0f, /*deviceId=*/0, /*edgeFlags=*/0,
- InputDevice.SOURCE_STYLUS, /*flags=*/0)
+ return MotionEvent.obtain(
+ /*downTime=*/ 0,
+ eventTime.toMillis(),
+ action,
+ properties.size,
+ properties,
+ coords,
+ /*metaState=*/ 0,
+ /*buttonState=*/ 0,
+ /*xPrecision=*/ 0f,
+ /*yPrecision=*/ 0f,
+ /*deviceId=*/ 0,
+ /*edgeFlags=*/ 0,
+ InputDevice.SOURCE_STYLUS,
+ /*flags=*/ 0,
+ )
}
@RunWith(AndroidJUnit4::class)
@LargeTest
class MotionPredictorBenchmark {
private val instrumentation = InstrumentationRegistry.getInstrumentation()
- @get:Rule
- val perfStatusReporter = PerfStatusReporter()
+ @get:Rule val perfStatusReporter = PerfStatusReporter()
private val initialPropertyValue =
- SystemProperties.get("persist.input.enable_motion_prediction")
-
+ SystemProperties.get("persist.input.enable_motion_prediction")
@Before
fun setUp() {
instrumentation.uiAutomation.executeShellCommand(
- "setprop persist.input.enable_motion_prediction true")
+ "setprop persist.input.enable_motion_prediction true"
+ )
}
@After
fun tearDown() {
instrumentation.uiAutomation.executeShellCommand(
- "setprop persist.input.enable_motion_prediction $initialPropertyValue")
+ "setprop persist.input.enable_motion_prediction $initialPropertyValue"
+ )
}
/**
- * In a typical usage, app will send the event to the predictor and then call .predict to draw
- * a prediction. In a loop, we keep sending MOVE and then calling .predict to simulate this.
+ * In a typical usage, app will send the event to the predictor and then call .predict to draw a
+ * prediction. In a loop, we keep sending MOVE and then calling .predict to simulate this.
*/
@Test
fun timeRecordAndPredict() {
@@ -99,10 +108,16 @@ class MotionPredictorBenchmark {
var eventPosition = 0f
val positionInterval = 10f
- val predictor = MotionPredictor(/*isPredictionEnabled=*/true, offset.toNanos().toInt())
+ val predictor = MotionPredictor(/* isPredictionEnabled= */ true, offset.toNanos().toInt())
// ACTION_DOWN t=0 x=0 y=0
- predictor.record(getStylusMotionEvent(
- eventTime, ACTION_DOWN, /*x=*/eventPosition, /*y=*/eventPosition))
+ predictor.record(
+ getStylusMotionEvent(
+ eventTime,
+ ACTION_DOWN,
+ /*x=*/ eventPosition,
+ /*y=*/ eventPosition,
+ )
+ )
val state = perfStatusReporter.getBenchmarkState()
while (state.keepRunning()) {
@@ -110,8 +125,13 @@ class MotionPredictorBenchmark {
eventPosition += positionInterval
// Send MOVE event and then call .predict
- val moveEvent = getStylusMotionEvent(
- eventTime, ACTION_MOVE, /*x=*/eventPosition, /*y=*/eventPosition)
+ val moveEvent =
+ getStylusMotionEvent(
+ eventTime,
+ ACTION_MOVE,
+ /*x=*/ eventPosition,
+ /*y=*/ eventPosition,
+ )
predictor.record(moveEvent)
val predictionTime = eventTime + eventInterval
val predicted = checkNotNull(predictor.predict(predictionTime.toNanos()))
@@ -129,7 +149,7 @@ class MotionPredictorBenchmark {
val state = perfStatusReporter.getBenchmarkState()
while (state.keepRunning()) {
- MotionPredictor(/*isPredictionEnabled=*/true, offsetNanos)
+ MotionPredictor(/* isPredictionEnabled= */ true, offsetNanos)
}
}
}
diff --git a/apct-tests/perftests/core/src/android/input/VelocityTrackerBenchmarkTest.kt b/apct-tests/perftests/core/src/android/input/VelocityTrackerBenchmarkTest.kt
index 530ca7b7e5a0..c6fe32467099 100644
--- a/apct-tests/perftests/core/src/android/input/VelocityTrackerBenchmarkTest.kt
+++ b/apct-tests/perftests/core/src/android/input/VelocityTrackerBenchmarkTest.kt
@@ -19,12 +19,9 @@ import android.perftests.utils.PerfStatusReporter
import android.view.InputDevice
import android.view.MotionEvent
import android.view.VelocityTracker
-
import androidx.test.filters.LargeTest
import androidx.test.runner.AndroidJUnit4
-
import java.time.Duration
-
import org.junit.Assert
import org.junit.Before
import org.junit.Rule
@@ -74,22 +71,23 @@ private class ScrollMotionState : MotionState() {
props.id = 0
val coords = MotionEvent.PointerCoords()
coords.setAxisValue(MotionEvent.AXIS_SCROLL, DEFAULT_SCROLL_AMOUNT)
- val motionEvent = MotionEvent.obtain(
- /*downTime=*/0,
- currentTime.toMillis(),
- MotionEvent.ACTION_SCROLL,
- /*pointerCount=*/1,
- arrayOf(props),
- arrayOf(coords),
- /*metaState=*/0,
- /*buttonState=*/0,
- /*xPrecision=*/0f,
- /*yPrecision=*/0f,
- /*deviceId=*/1,
- /*edgeFlags=*/0,
- InputDevice.SOURCE_ROTARY_ENCODER,
- /*flags=*/0
- )
+ val motionEvent =
+ MotionEvent.obtain(
+ /*downTime=*/ 0,
+ currentTime.toMillis(),
+ MotionEvent.ACTION_SCROLL,
+ /*pointerCount=*/ 1,
+ arrayOf(props),
+ arrayOf(coords),
+ /*metaState=*/ 0,
+ /*buttonState=*/ 0,
+ /*xPrecision=*/ 0f,
+ /*yPrecision=*/ 0f,
+ /*deviceId=*/ 1,
+ /*edgeFlags=*/ 0,
+ InputDevice.SOURCE_ROTARY_ENCODER,
+ /*flags=*/ 0,
+ )
currentTime = currentTime.plus(DEFAULT_TIME_JUMP)
@@ -113,13 +111,15 @@ private class PlanarMotionState : MotionState() {
override fun createMotionEvent(): MotionEvent {
val action: Int = if (downEventCreated) MotionEvent.ACTION_MOVE else MotionEvent.ACTION_DOWN
- val motionEvent = MotionEvent.obtain(
- /*downTime=*/START_TIME.toMillis(),
- currentTime.toMillis(),
- action,
- x,
- y,
- /*metaState=*/0)
+ val motionEvent =
+ MotionEvent.obtain(
+ /*downTime=*/ START_TIME.toMillis(),
+ currentTime.toMillis(),
+ action,
+ x,
+ y,
+ /*metaState=*/ 0,
+ )
if (downEventCreated) {
x += INCREMENT
@@ -155,16 +155,15 @@ private class PlanarMotionState : MotionState() {
/**
* Benchmark tests for [VelocityTracker]
*
- * Build/Install/Run:
- * atest VelocityTrackerBenchmarkTest
+ * Build/Install/Run: atest VelocityTrackerBenchmarkTest
*/
@LargeTest
@RunWith(AndroidJUnit4::class)
class VelocityTrackerBenchmarkTest {
- @get:Rule
- val perfStatusReporter: PerfStatusReporter = PerfStatusReporter()
+ @get:Rule val perfStatusReporter: PerfStatusReporter = PerfStatusReporter()
private val velocityTracker = VelocityTracker.obtain()
+
@Before
fun setup() {
velocityTracker.clear()
@@ -255,4 +254,4 @@ class VelocityTrackerBenchmarkTest {
companion object {
private const val TEST_NUM_DATAPOINTS = 100
}
-} \ No newline at end of file
+}
diff --git a/apct-tests/perftests/core/src/android/view/ViewConfigurationPerfTest.java b/apct-tests/perftests/core/src/android/view/ViewConfigurationPerfTest.java
index 7a7250b9e910..8e3ed6d9931c 100644
--- a/apct-tests/perftests/core/src/android/view/ViewConfigurationPerfTest.java
+++ b/apct-tests/perftests/core/src/android/view/ViewConfigurationPerfTest.java
@@ -19,24 +19,27 @@ package android.view;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import android.content.Context;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
-import androidx.benchmark.BenchmarkState;
-import androidx.benchmark.junit4.BenchmarkRule;
-import androidx.test.filters.SmallTest;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.runner.RunWith;
-@SmallTest
+@LargeTest
+@RunWith(AndroidJUnit4.class)
public class ViewConfigurationPerfTest {
@Rule
- public final BenchmarkRule mBenchmarkRule = new BenchmarkRule();
+ public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
private final Context mContext = getInstrumentation().getTargetContext();
@Test
public void testGet_newViewConfiguration() {
- final BenchmarkState state = mBenchmarkRule.getState();
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
state.pauseTiming();
@@ -50,7 +53,7 @@ public class ViewConfigurationPerfTest {
@Test
public void testGet_cachedViewConfiguration() {
- final BenchmarkState state = mBenchmarkRule.getState();
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
// Do `get` once to make sure there's something cached.
ViewConfiguration.get(mContext);
@@ -58,4 +61,265 @@ public class ViewConfigurationPerfTest {
ViewConfiguration.get(mContext);
}
}
+
+ @Test
+ public void testGetPressedStateDuration_unCached() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+
+ while (state.keepRunning()) {
+ state.pauseTiming();
+ // Reset any caches.
+ ViewConfiguration.resetCacheForTesting();
+ state.resumeTiming();
+
+ ViewConfiguration.getPressedStateDuration();
+ }
+ }
+
+ @Test
+ public void testGetPressedStateDuration_cached() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ // Do `get` once to make sure the value gets cached.
+ ViewConfiguration.getPressedStateDuration();
+
+ while (state.keepRunning()) {
+ ViewConfiguration.getPressedStateDuration();
+ }
+ }
+
+ @Test
+ public void testGetTapTimeout_unCached() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+
+ while (state.keepRunning()) {
+ state.pauseTiming();
+ // Reset any caches.
+ ViewConfiguration.resetCacheForTesting();
+ state.resumeTiming();
+
+ ViewConfiguration.getTapTimeout();
+ }
+ }
+
+ @Test
+ public void testGetTapTimeout_cached() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ // Do `get` once to make sure the value gets cached.
+ ViewConfiguration.getTapTimeout();
+
+ while (state.keepRunning()) {
+ ViewConfiguration.getTapTimeout();
+ }
+ }
+
+ @Test
+ public void testGetJumpTapTimeout_unCached() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+
+ while (state.keepRunning()) {
+ state.pauseTiming();
+ // Reset any caches.
+ ViewConfiguration.resetCacheForTesting();
+ state.resumeTiming();
+
+ ViewConfiguration.getJumpTapTimeout();
+ }
+ }
+
+ @Test
+ public void testGetJumpTapTimeout_cached() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ // Do `get` once to make sure the value gets cached.
+ ViewConfiguration.getJumpTapTimeout();
+
+ while (state.keepRunning()) {
+ ViewConfiguration.getJumpTapTimeout();
+ }
+ }
+
+ @Test
+ public void testGetDoubleTapTimeout_unCached() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+
+ while (state.keepRunning()) {
+ state.pauseTiming();
+ // Reset any caches.
+ ViewConfiguration.resetCacheForTesting();
+ state.resumeTiming();
+
+ ViewConfiguration.getDoubleTapTimeout();
+ }
+ }
+
+ @Test
+ public void testGetDoubleTapTimeout_cached() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ // Do `get` once to make sure the value gets cached.
+ ViewConfiguration.getDoubleTapTimeout();
+
+ while (state.keepRunning()) {
+ ViewConfiguration.getDoubleTapTimeout();
+ }
+ }
+
+ @Test
+ public void testGetDoubleTapMinTime_unCached() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+
+ while (state.keepRunning()) {
+ state.pauseTiming();
+ // Reset any caches.
+ ViewConfiguration.resetCacheForTesting();
+ state.resumeTiming();
+
+ ViewConfiguration.getDoubleTapMinTime();
+ }
+ }
+
+ @Test
+ public void testGetDoubleTapMinTime_cached() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ // Do `get` once to make sure the value gets cached.
+ ViewConfiguration.getDoubleTapMinTime();
+
+ while (state.keepRunning()) {
+ ViewConfiguration.getDoubleTapMinTime();
+ }
+ }
+
+ @Test
+ public void testGetZoomControlsTimeout_unCached() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+
+ while (state.keepRunning()) {
+ state.pauseTiming();
+ // Reset any caches.
+ ViewConfiguration.resetCacheForTesting();
+ state.resumeTiming();
+
+ ViewConfiguration.getZoomControlsTimeout();
+ }
+ }
+
+ @Test
+ public void testGetZoomControlsTimeout_cached() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ // Do `get` once to make sure the value gets cached.
+ ViewConfiguration.getZoomControlsTimeout();
+
+ while (state.keepRunning()) {
+ ViewConfiguration.getZoomControlsTimeout();
+ }
+ }
+
+ @Test
+ public void testGetLongPressTimeout() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+
+ while (state.keepRunning()) {
+ ViewConfiguration.getLongPressTimeout();
+ }
+ }
+
+ @Test
+ public void testGetMultiPressTimeout() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+
+ while (state.keepRunning()) {
+ ViewConfiguration.getMultiPressTimeout();
+ }
+ }
+
+ @Test
+ public void testGetKeyRepeatTimeout() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+
+ while (state.keepRunning()) {
+ ViewConfiguration.getKeyRepeatTimeout();
+ }
+ }
+
+ @Test
+ public void testGetKeyRepeatDelay() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+
+ while (state.keepRunning()) {
+ ViewConfiguration.getKeyRepeatDelay();
+ }
+ }
+
+ @Test
+ public void testGetHoverTapSlop_unCached() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+
+ while (state.keepRunning()) {
+ state.pauseTiming();
+ // Reset any caches.
+ ViewConfiguration.resetCacheForTesting();
+ state.resumeTiming();
+
+ ViewConfiguration.getHoverTapSlop();
+ }
+ }
+
+ @Test
+ public void testGetHoverTapSlop_cached() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ // Do `get` once to make sure the value gets cached.
+ ViewConfiguration.getHoverTapSlop();
+
+ while (state.keepRunning()) {
+ ViewConfiguration.getHoverTapSlop();
+ }
+ }
+
+ @Test
+ public void testGetScrollFriction_unCached() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+
+ while (state.keepRunning()) {
+ state.pauseTiming();
+ // Reset any caches.
+ ViewConfiguration.resetCacheForTesting();
+ state.resumeTiming();
+
+ ViewConfiguration.getScrollFriction();
+ }
+ }
+
+ @Test
+ public void testGetScrollFriction_cached() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ // Do `get` once to make sure the value gets cached.
+ ViewConfiguration.getScrollFriction();
+
+ while (state.keepRunning()) {
+ ViewConfiguration.getScrollFriction();
+ }
+ }
+
+ @Test
+ public void testGetDefaultActionModeHideDuration_unCached() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+
+ while (state.keepRunning()) {
+ state.pauseTiming();
+ // Reset any caches.
+ ViewConfiguration.resetCacheForTesting();
+ state.resumeTiming();
+
+ ViewConfiguration.getDefaultActionModeHideDuration();
+ }
+ }
+
+ @Test
+ public void testGetDefaultActionModeHideDuration_cached() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ // Do `get` once to make sure the value gets cached.
+ ViewConfiguration.getDefaultActionModeHideDuration();
+
+ while (state.keepRunning()) {
+ ViewConfiguration.getDefaultActionModeHideDuration();
+ }
+ }
}
diff --git a/apct-tests/perftests/core/src/android/view/ViewPerfTest.java b/apct-tests/perftests/core/src/android/view/ViewPerfTest.java
index 67b33e5d157b..d2321ec7934f 100644
--- a/apct-tests/perftests/core/src/android/view/ViewPerfTest.java
+++ b/apct-tests/perftests/core/src/android/view/ViewPerfTest.java
@@ -84,12 +84,10 @@ public class ViewPerfTest {
final BenchmarkState state = mBenchmarkRule.getState();
mActivityRule.runOnUiThread(() -> {
- state.pauseTiming();
View view = new View(mContext);
mActivityRule.getActivity().setContentView(view);
assertTrue("View needs to be attached to Window to perform haptic feedback",
view.isAttachedToWindow());
- state.resumeTiming();
// Disable settings so perform will never be ignored.
int flags = HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING
diff --git a/apct-tests/perftests/healthconnect/src/com/android/perftests/healthconnect/HealthConnectReadWritePerfTest.kt b/apct-tests/perftests/healthconnect/src/com/android/perftests/healthconnect/HealthConnectReadWritePerfTest.kt
index 21a4ca048f62..bdb54c9dc0ac 100644
--- a/apct-tests/perftests/healthconnect/src/com/android/perftests/healthconnect/HealthConnectReadWritePerfTest.kt
+++ b/apct-tests/perftests/healthconnect/src/com/android/perftests/healthconnect/HealthConnectReadWritePerfTest.kt
@@ -32,8 +32,7 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class HealthConnectReadWritePerfTest {
- @get:Rule
- val perfStatusReporter = PerfStatusReporter()
+ @get:Rule val perfStatusReporter = PerfStatusReporter()
private val context by lazy { InstrumentationRegistry.getInstrumentation().context }
@@ -41,9 +40,7 @@ class HealthConnectReadWritePerfTest {
requireNotNull(context.getSystemService(HealthConnectManager::class.java))
}
- /**
- * A first empty test just to setup the test package and make sure it runs properly.
- */
+ /** A first empty test just to setup the test package and make sure it runs properly. */
@Test
fun placeholder() {
val state = perfStatusReporter.benchmarkState
@@ -51,4 +48,4 @@ class HealthConnectReadWritePerfTest {
SystemClock.sleep(100)
}
}
-} \ No newline at end of file
+}
diff --git a/apct-tests/perftests/packagemanager/src/android/os/PackageParsingPerfTest.kt b/apct-tests/perftests/packagemanager/src/android/os/PackageParsingPerfTest.kt
index ea10690bd672..48f2c1554c30 100644
--- a/apct-tests/perftests/packagemanager/src/android/os/PackageParsingPerfTest.kt
+++ b/apct-tests/perftests/packagemanager/src/android/os/PackageParsingPerfTest.kt
@@ -51,51 +51,52 @@ public class PackageParsingPerfTest {
private const val QUEUE_POLL_TIMEOUT_SECONDS = 5L
// TODO: Replace this with core version of SYSTEM_PARTITIONS
- val FOLDERS_TO_TEST = listOf(
- Environment.getRootDirectory(),
- Environment.getVendorDirectory(),
- Environment.getOdmDirectory(),
- Environment.getOemDirectory(),
- Environment.getOemDirectory(),
- Environment.getSystemExtDirectory()
- )
+ val FOLDERS_TO_TEST =
+ listOf(
+ Environment.getRootDirectory(),
+ Environment.getVendorDirectory(),
+ Environment.getOdmDirectory(),
+ Environment.getOemDirectory(),
+ Environment.getOemDirectory(),
+ Environment.getSystemExtDirectory(),
+ )
@JvmStatic
@Parameterized.Parameters(name = "{0}")
fun parameters(): Array<Params> {
- val apks = FOLDERS_TO_TEST
- .filter(File::exists)
- .map(File::walkTopDown)
- .flatMap(Sequence<File>::asIterable)
- .filter { it.name.endsWith(".apk") }
+ val apks =
+ FOLDERS_TO_TEST.filter(File::exists)
+ .map(File::walkTopDown)
+ .flatMap(Sequence<File>::asIterable)
+ .filter { it.name.endsWith(".apk") }
return arrayOf(
Params(1, apks) { ParallelParser1(it?.let(::PackageCacher1)) },
- Params(2, apks) { ParallelParser2(it?.let(::PackageCacher2)) }
+ Params(2, apks) { ParallelParser2(it?.let(::PackageCacher2)) },
)
}
data class Params(
val version: Int,
val apks: List<File>,
- val cacheDirToParser: (File?) -> ParallelParser<*>
+ val cacheDirToParser: (File?) -> ParallelParser<*>,
) {
// For test name formatting
override fun toString() = "v$version"
}
}
- @get:Rule
- var perfStatusReporter = PerfStatusReporter()
+ @get:Rule var perfStatusReporter = PerfStatusReporter()
+
+ @get:Rule var testFolder = TemporaryFolder()
- @get:Rule
- var testFolder = TemporaryFolder()
+ @Parameterized.Parameter(0) lateinit var params: Params
- @Parameterized.Parameter(0)
- lateinit var params: Params
+ private val state: BenchmarkState
+ get() = perfStatusReporter.benchmarkState
- private val state: BenchmarkState get() = perfStatusReporter.benchmarkState
- private val apks: List<File> get() = params.apks
+ private val apks: List<File>
+ get() = params.apks
private fun safeParse(parser: ParallelParser<*>, file: File) {
try {
@@ -109,9 +110,7 @@ public class PackageParsingPerfTest {
fun sequentialNoCache() {
params.cacheDirToParser(null).use { parser ->
while (state.keepRunning()) {
- apks.forEach {
- safeParse(parser, it)
- }
+ apks.forEach { safeParse(parser, it) }
}
}
}
@@ -155,18 +154,21 @@ public class PackageParsingPerfTest {
private val cacher: PackageCacher<PackageType>? = null
) : AutoCloseable {
private val queue = ArrayBlockingQueue<Any>(PARALLEL_QUEUE_CAPACITY)
- private val service = ConcurrentUtils.newFixedThreadPool(
- PARALLEL_MAX_THREADS, "package-parsing-test",
- Process.THREAD_PRIORITY_FOREGROUND)
+ private val service =
+ ConcurrentUtils.newFixedThreadPool(
+ PARALLEL_MAX_THREADS,
+ "package-parsing-test",
+ Process.THREAD_PRIORITY_FOREGROUND,
+ )
fun submit(file: File) {
- service.submit {
- try {
- queue.put(parse(file))
- } catch (e: Exception) {
- queue.put(e)
- }
+ service.submit {
+ try {
+ queue.put(parse(file))
+ } catch (e: Exception) {
+ queue.put(e)
}
+ }
}
fun take() = queue.poll(QUEUE_POLL_TIMEOUT_SECONDS, TimeUnit.SECONDS)
@@ -175,57 +177,51 @@ public class PackageParsingPerfTest {
service.shutdownNow()
}
- fun parse(file: File) = cacher?.getCachedResult(file)
- ?: parseImpl(file).also { cacher?.cacheResult(file, it) }
+ fun parse(file: File) =
+ cacher?.getCachedResult(file) ?: parseImpl(file).also { cacher?.cacheResult(file, it) }
protected abstract fun parseImpl(file: File): PackageType
}
class ParallelParser1(private val cacher: PackageCacher1? = null) :
ParallelParser<PackageParser.Package>(cacher) {
- val parser = PackageParser().apply {
- setCallback { true }
- }
+ val parser = PackageParser().apply { setCallback { true } }
override fun parseImpl(file: File) = parser.parsePackage(file, 0, cacher != null)
}
- class ParallelParser2(cacher: PackageCacher2? = null) :
- ParallelParser<PackageImpl>(cacher) {
- val input = ThreadLocal.withInitial {
- // For testing, just disable enforcement to avoid hooking up to compat framework
- ParseTypeImpl(ParseInput.Callback { _, _, _ -> false })
- }
- val parser = ParsingPackageUtils(null,
- null,
- emptyList(),
- object :
- ParsingPackageUtils.Callback {
- override fun hasFeature(feature: String) = true
-
- override fun startParsingPackage(
- packageName: String,
- baseApkPath: String,
- path: String,
- manifestArray: TypedArray,
- isCoreApp: Boolean
- ) = PackageImpl(
- packageName,
- baseApkPath,
- path,
- manifestArray,
- isCoreApp,
- this,
- )
- override fun getHiddenApiWhitelistedApps() =
+ class ParallelParser2(cacher: PackageCacher2? = null) : ParallelParser<PackageImpl>(cacher) {
+ val input =
+ ThreadLocal.withInitial {
+ // For testing, just disable enforcement to avoid hooking up to compat framework
+ ParseTypeImpl(ParseInput.Callback { _, _, _ -> false })
+ }
+ val parser =
+ ParsingPackageUtils(
+ null,
+ null,
+ emptyList(),
+ object : ParsingPackageUtils.Callback {
+ override fun hasFeature(feature: String) = true
+
+ override fun startParsingPackage(
+ packageName: String,
+ baseApkPath: String,
+ path: String,
+ manifestArray: TypedArray,
+ isCoreApp: Boolean,
+ ) = PackageImpl(packageName, baseApkPath, path, manifestArray, isCoreApp, this)
+
+ override fun getHiddenApiWhitelistedApps() =
SystemConfig.getInstance().hiddenApiWhitelistedApps
- override fun getInstallConstraintsAllowlist() =
+
+ override fun getInstallConstraintsAllowlist() =
SystemConfig.getInstance().installConstraintsAllowlist
- })
+ },
+ )
override fun parseImpl(file: File) =
- parser.parsePackage(input.get()!!.reset(), file, 0).result
- as PackageImpl
+ parser.parsePackage(input.get()!!.reset(), file, 0).result as PackageImpl
}
abstract class PackageCacher<PackageType : Parcelable>(private val cacheDir: File) {
@@ -237,14 +233,13 @@ public class PackageParsingPerfTest {
}
val bytes = IoUtils.readFileAsByteArray(cacheFile.absolutePath)
- val parcel = Parcel.obtain().apply {
- unmarshall(bytes, 0, bytes.size)
- setDataPosition(0)
- }
+ val parcel =
+ Parcel.obtain().apply {
+ unmarshall(bytes, 0, bytes.size)
+ setDataPosition(0)
+ }
ReadHelper(parcel).apply { startAndInstall() }
- return fromParcel(parcel).also {
- parcel.recycle()
- }
+ return fromParcel(parcel).also { parcel.recycle() }
}
fun cacheResult(file: File, parsed: Parcelable) {
@@ -263,26 +258,19 @@ public class PackageParsingPerfTest {
val helper = WriteHelper(parcel)
pkg.writeToParcel(parcel, 0 /* flags */)
helper.finishAndUninstall()
- return parcel.marshall().also {
- parcel.recycle()
- }
+ return parcel.marshall().also { parcel.recycle() }
}
protected abstract fun fromParcel(parcel: Parcel): PackageType
}
- /**
- * Re-implementation of v1's cache, since that's gone in R+.
- */
+ /** Re-implementation of v1's cache, since that's gone in R+. */
class PackageCacher1(cacheDir: File) : PackageCacher<PackageParser.Package>(cacheDir) {
override fun fromParcel(parcel: Parcel) = PackageParser.Package(parcel)
}
- /**
- * Re-implementation of the server side PackageCacher, as it's inaccessible here.
- */
+ /** Re-implementation of the server side PackageCacher, as it's inaccessible here. */
class PackageCacher2(cacheDir: File) : PackageCacher<PackageImpl>(cacheDir) {
- override fun fromParcel(parcel: Parcel) =
- PackageImpl(parcel)
+ override fun fromParcel(parcel: Parcel) = PackageImpl(parcel)
}
}
diff --git a/apct-tests/perftests/permission/src/android/perftests/permission/AppOpsPerfTest.kt b/apct-tests/perftests/permission/src/android/perftests/permission/AppOpsPerfTest.kt
index b6a53bf8226a..7d4061a10b37 100644
--- a/apct-tests/perftests/permission/src/android/perftests/permission/AppOpsPerfTest.kt
+++ b/apct-tests/perftests/permission/src/android/perftests/permission/AppOpsPerfTest.kt
@@ -50,7 +50,7 @@ class AppOpsPerfTest {
opPackageUid,
opPackageName,
null,
- null
+ null,
)
}
}
@@ -62,7 +62,7 @@ class AppOpsPerfTest {
appOpsManager.unsafeCheckOp(
AppOpsManager.OPSTR_FINE_LOCATION,
opPackageUid,
- opPackageName
+ opPackageName,
)
}
}
diff --git a/apct-tests/perftests/permission/src/android/perftests/permission/PermissionServicePerfTest.kt b/apct-tests/perftests/permission/src/android/perftests/permission/PermissionServicePerfTest.kt
index 1139835d3e7b..b64d5d92c46e 100644
--- a/apct-tests/perftests/permission/src/android/perftests/permission/PermissionServicePerfTest.kt
+++ b/apct-tests/perftests/permission/src/android/perftests/permission/PermissionServicePerfTest.kt
@@ -28,24 +28,26 @@ import com.android.compatibility.common.util.AdoptShellPermissionsRule
import com.android.compatibility.common.util.SystemUtil.eventually
import com.android.compatibility.common.util.SystemUtil.runShellCommand
import com.google.common.truth.Truth.assertThat
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import java.util.concurrent.TimeUnit
import java.util.function.BiConsumer
import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class PermissionServicePerfTest {
@get:Rule val mPerfManualStatusReporter = PerfManualStatusReporter()
- @get:Rule val mAdoptShellPermissionsRule = AdoptShellPermissionsRule(
- InstrumentationRegistry.getInstrumentation().getUiAutomation(),
- Manifest.permission.INSTALL_PACKAGES,
- Manifest.permission.DELETE_PACKAGES
- )
+ @get:Rule
+ val mAdoptShellPermissionsRule =
+ AdoptShellPermissionsRule(
+ InstrumentationRegistry.getInstrumentation().getUiAutomation(),
+ Manifest.permission.INSTALL_PACKAGES,
+ Manifest.permission.DELETE_PACKAGES,
+ )
val mUiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation()
@Test
@@ -95,13 +97,14 @@ class PermissionServicePerfTest {
private fun dumpResult(
parser: TraceMarkParser,
- handler: BiConsumer<String, List<TraceMarkParser.TraceMarkSlice>>
+ handler: BiConsumer<String, List<TraceMarkParser.TraceMarkSlice>>,
) {
parser.reset()
try {
- val inputStream = ParcelFileDescriptor.AutoCloseInputStream(
- mUiAutomation.executeShellCommand(COMMAND_TRACE_DUMP)
- )
+ val inputStream =
+ ParcelFileDescriptor.AutoCloseInputStream(
+ mUiAutomation.executeShellCommand(COMMAND_TRACE_DUMP)
+ )
val reader = BufferedReader(InputStreamReader(inputStream))
var line = reader.readLine()
while (line != null) {
diff --git a/core/java/Android.bp b/core/java/Android.bp
index 1ad247e24bc0..980d9737aba7 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -29,6 +29,15 @@ filegroup {
"android/os/*MessageQueue/**/*.java",
"android/ranging/**/*.java",
":dynamic_instrumentation_manager_aidl_sources",
+ "**/*_ravenwood.java",
+ ],
+ visibility: ["//frameworks/base"],
+}
+
+filegroup {
+ name: "framework-ravenwood-sources",
+ srcs: [
+ "**/*_ravenwood.java",
],
visibility: ["//frameworks/base"],
}
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index f9ec214390f9..b38f5da6b638 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -4975,6 +4975,25 @@ public class ActivityManager {
}
/**
+ * Fully stop the given app's processes without restoring service starts or
+ * bindings, but without the other durable effects of the full-scale
+ * "force stop" intervention.
+ *
+ * @param packageName The name of the package to be stopped.
+ *
+ * @hide This is not available to third party applications due to
+ * it allowing them to break other applications by stopping their
+ * services.
+ */
+ public void stopPackageForUser(String packageName) {
+ try {
+ getService().stopAppForUser(packageName, mContext.getUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Sets the current locales of the device. Calling app must have the permission
* {@code android.permission.CHANGE_CONFIGURATION} and
* {@code android.permission.WRITE_SETTINGS}.
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index dc5974fde0b0..7e5c0fbe1ee1 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2944,7 +2944,11 @@ class ContextImpl extends Context {
private void updateResourceOverlayConstraints() {
if (mResources != null) {
- mResources.getAssets().setOverlayConstraints(getDisplayId(), getDeviceId());
+ // Avoid calling getDisplay() here, as it makes a binder call into
+ // DisplayManagerService if the relevant DisplayInfo is not cached in
+ // DisplayManagerGlobal.
+ int displayId = mDisplay != null ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY;
+ mResources.getAssets().setOverlayConstraints(displayId, getDeviceId());
}
}
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index 75c7e267d477..e43a5fce6cb7 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -138,7 +138,7 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
private static native long nativeOpen(String path, int openFlags, String label,
boolean enableTrace, boolean enableProfile, int lookasideSlotSize,
int lookasideSlotCount);
- private static native void nativeClose(long connectionPtr);
+ private static native void nativeClose(long connectionPtr, boolean fast);
private static native void nativeRegisterCustomScalarFunction(long connectionPtr,
String name, UnaryOperator<String> function);
private static native void nativeRegisterCustomAggregateFunction(long connectionPtr,
@@ -183,6 +183,11 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
private static native long nativeChanges(long connectionPtr);
private static native long nativeTotalChanges(long connectionPtr);
+ // This method is deprecated and should be removed when it is no longer needed by the
+ // robolectric tests. It should not be called from any frameworks java code.
+ @Deprecated
+ private static native void nativeClose(long connectionPtr);
+
private SQLiteConnection(SQLiteConnectionPool pool,
SQLiteDatabaseConfiguration configuration,
int connectionId, boolean primaryConnection) {
@@ -300,7 +305,7 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
final int cookie = mRecentOperations.beginOperation("close", null, null);
try {
mPreparedStatementCache.evictAll();
- nativeClose(mConnectionPtr);
+ nativeClose(mConnectionPtr, finalized && Flags.noCheckpointOnFinalize());
mConnectionPtr = 0;
} finally {
mRecentOperations.endOperation(cookie);
diff --git a/core/java/android/database/sqlite/flags.aconfig b/core/java/android/database/sqlite/flags.aconfig
index 1d17a51f3653..9f4f1a16178b 100644
--- a/core/java/android/database/sqlite/flags.aconfig
+++ b/core/java/android/database/sqlite/flags.aconfig
@@ -5,7 +5,7 @@ flag {
name: "oneway_finalizer_close_fixed"
namespace: "system_performance"
is_fixed_read_only: true
- description: "Make BuildCursorNative.close oneway if in the the finalizer"
+ description: "Make BuildCursorNative.close oneway if in the finalizer"
bug: "368221351"
}
@@ -26,3 +26,10 @@ flag {
description: "Make SQLiteOpenHelper thread-safe"
bug: "335904370"
}
+
+flag {
+ name: "no_checkpoint_on_finalize"
+ namespace: "system_performance"
+ description: "Do not checkpoint WAL if closing in the finalizer"
+ bug: "397982577"
+}
diff --git a/core/java/android/os/CombinedMessageQueue/MessageQueue.java b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
index ce1717b60bfd..0964cde5a1f4 100644
--- a/core/java/android/os/CombinedMessageQueue/MessageQueue.java
+++ b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
@@ -76,8 +76,13 @@ public final class MessageQueue {
@SuppressWarnings("unused")
private long mPtr; // used by native code
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(
+ maxTargetSdk = Build.VERSION_CODES.BAKLAVA,
+ publicAlternatives =
+ "To manipulate the queue in Instrumentation tests, use {@link"
+ + " android.os.TestLooperManager}")
Message mMessages;
+
private Message mLast;
@UnsupportedAppUsage
private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>();
@@ -139,8 +144,8 @@ public final class MessageQueue {
return;
}
- if (RavenwoodEnvironment.getInstance().isRunningOnRavenwood()) {
- sIsProcessAllowedToUseConcurrent = false;
+ if (Flags.forceConcurrentMessageQueue()) {
+ sIsProcessAllowedToUseConcurrent = true;
return;
}
@@ -995,7 +1000,11 @@ public final class MessageQueue {
}
}
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(
+ maxTargetSdk = Build.VERSION_CODES.BAKLAVA,
+ publicAlternatives =
+ "To manipulate the queue in Instrumentation tests, use {@link"
+ + " android.os.TestLooperManager}")
Message next() {
if (mUseConcurrent) {
return nextConcurrent();
diff --git a/core/java/android/os/PerfettoTrackEventExtra.java b/core/java/android/os/PerfettoTrackEventExtra.java
index 8a3a5be9c934..07b44a87ef88 100644
--- a/core/java/android/os/PerfettoTrackEventExtra.java
+++ b/core/java/android/os/PerfettoTrackEventExtra.java
@@ -674,6 +674,7 @@ public final class PerfettoTrackEventExtra {
/**
* Resets the track event extra.
*/
+ @android.ravenwood.annotation.RavenwoodReplace
public void reset() {
native_clear_args(mPtr);
mPendingPointers.clear();
@@ -1303,4 +1304,8 @@ public final class PerfettoTrackEventExtra {
// Tracing currently completely disabled under Ravenwood
return null;
}
+
+ private void reset$ravenwood() {
+ // Tracing currently completely disabled under Ravenwood
+ }
}
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 0c5d9e97a77d..b68b9a7af5e2 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -1347,6 +1347,7 @@ public class Process {
* Return the name of this process. By default, the process name is the same as the app's
* package name, but this can be changed using {@code android:process}.
*/
+ @RavenwoodReplace
@NonNull
public static String myProcessName() {
// Note this could be different from the actual process name if someone changes the
@@ -1355,6 +1356,12 @@ public class Process {
return sArgV0;
}
+ /** @hide */
+ @NonNull
+ public static String myProcessName$ravenwood() {
+ return "ravenwood";
+ }
+
/**
* Kill the process with the given PID.
* Note that, though this API allows us to request to
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index d3c677bf8af2..86acb2b21cfa 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -211,6 +211,14 @@ flag {
}
flag {
+ name: "force_concurrent_message_queue"
+ namespace: "system_performance"
+ is_exported: true
+ description: "Whether MessageQueue uses the new concurrent implementation"
+ bug: "336880969"
+}
+
+flag {
name: "get_private_space_settings"
namespace: "profile_experiences"
description: "Guards a new Private Profile API in LauncherApps"
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index ca24c0c6c376..0476f62ec263 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -358,7 +358,16 @@ flag {
is_fixed_read_only: true
is_exported: true
namespace: "permissions"
- description: "Enables SQlite for recording discrete and historical AppOp accesses"
+ description: "Enables SQlite for recording individual/discrete AppOp accesses"
+ bug: "377584611"
+}
+
+flag {
+ name: "enable_all_sqlite_appops_accesses"
+ is_fixed_read_only: true
+ is_exported: true
+ namespace: "permissions"
+ description: "Enables SQlite for storing aggregated & individual/discrete AppOp accesses"
bug: "377584611"
}
diff --git a/core/java/android/preference/PreferenceScreen.java b/core/java/android/preference/PreferenceScreen.java
index 6b813b0c04f6..96548513bf37 100644
--- a/core/java/android/preference/PreferenceScreen.java
+++ b/core/java/android/preference/PreferenceScreen.java
@@ -109,6 +109,7 @@ public final class PreferenceScreen extends PreferenceGroup implements AdapterVi
private int mLayoutResId = com.android.internal.R.layout.preference_list_fragment;
private Drawable mDividerDrawable;
private boolean mDividerSpecified;
+ private boolean mDialogFitsSystemWindows = false;
/**
* Do NOT use this constructor, use {@link PreferenceManager#createPreferenceScreen(Context)}.
@@ -136,6 +137,18 @@ public final class PreferenceScreen extends PreferenceGroup implements AdapterVi
}
/**
+ * Used in {@link #onClick()} to override the {@link View#setFitsSystemWindows(boolean)} for
+ * the dialog that shows. This is set separately to limit the scope of this change to just
+ * the {@link PreferenceScreen} instances which have demonstrated an issue with edge to edge.
+ *
+ * @param dialogFitsSystemWindows value passed to {@link View#setFitsSystemWindows(boolean)}.
+ * @hide
+ */
+ public void setDialogFitsSystemWindows(boolean dialogFitsSystemWindows) {
+ mDialogFitsSystemWindows = dialogFitsSystemWindows;
+ }
+
+ /**
* Returns an adapter that can be attached to a {@link PreferenceActivity}
* or {@link PreferenceFragment} to show the preferences contained in this
* {@link PreferenceScreen}.
@@ -201,6 +214,11 @@ public final class PreferenceScreen extends PreferenceGroup implements AdapterVi
View childPrefScreen = inflater.inflate(mLayoutResId, null);
View titleView = childPrefScreen.findViewById(android.R.id.title);
mListView = (ListView) childPrefScreen.findViewById(android.R.id.list);
+ // Don't override any potential state that may exist on mListView. If it was already marked
+ // as "setFitsSystemWindows(true)" somewhere else don't change to "false" here.
+ if (mDialogFitsSystemWindows) {
+ mListView.setFitsSystemWindows(true);
+ }
if (mDividerSpecified) {
mListView.setDivider(mDividerDrawable);
}
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 9e97a8eb58aa..2895bf3f846a 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -21,7 +21,9 @@ import android.annotation.NonNull;
import android.annotation.TestApi;
import android.annotation.UiContext;
import android.app.Activity;
+import android.app.ActivityThread;
import android.app.AppGlobals;
+import android.app.Application;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Configuration;
@@ -39,14 +41,13 @@ import android.util.SparseArray;
import android.util.TypedValue;
import android.view.flags.Flags;
+import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
/**
* Contains methods to standard constants used in the UI for timeouts, sizes, and distances.
*/
public class ViewConfiguration {
- private static final String TAG = "ViewConfiguration";
-
/**
* Defines the width of the horizontal scrollbar and the height of the vertical scrollbar in
* dips
@@ -349,6 +350,8 @@ public class ViewConfiguration {
*/
private static final int SMART_SELECTION_INITIALIZING_TIMEOUT_IN_MILLISECOND = 500;
+ private static ResourceCache sResourceCache = new ResourceCache();
+
private final boolean mConstructedWithContext;
private final int mEdgeSlop;
private final int mFadingEdgeLength;
@@ -374,7 +377,6 @@ public class ViewConfiguration {
private final int mOverscrollDistance;
private final int mOverflingDistance;
private final boolean mViewTouchScreenHapticScrollFeedbackEnabled;
- @UnsupportedAppUsage
private final boolean mFadingMarqueeEnabled;
private final long mGlobalActionsKeyTimeout;
private final float mVerticalScrollFactor;
@@ -468,14 +470,12 @@ public class ViewConfiguration {
mEdgeSlop = (int) (sizeAndDensity * EDGE_SLOP + 0.5f);
mFadingEdgeLength = (int) (sizeAndDensity * FADING_EDGE_LENGTH + 0.5f);
- mScrollbarSize = res.getDimensionPixelSize(
- com.android.internal.R.dimen.config_scrollbarSize);
+ mScrollbarSize = res.getDimensionPixelSize(R.dimen.config_scrollbarSize);
mDoubleTapSlop = (int) (sizeAndDensity * DOUBLE_TAP_SLOP + 0.5f);
mWindowTouchSlop = (int) (sizeAndDensity * WINDOW_TOUCH_SLOP + 0.5f);
final TypedValue multiplierValue = new TypedValue();
- res.getValue(
- com.android.internal.R.dimen.config_ambiguousGestureMultiplier,
+ res.getValue(R.dimen.config_ambiguousGestureMultiplier,
multiplierValue,
true /*resolveRefs*/);
mAmbiguousGestureMultiplier = Math.max(1.0f, multiplierValue.getFloat());
@@ -488,8 +488,7 @@ public class ViewConfiguration {
mOverflingDistance = (int) (sizeAndDensity * OVERFLING_DISTANCE + 0.5f);
if (!sHasPermanentMenuKeySet) {
- final int configVal = res.getInteger(
- com.android.internal.R.integer.config_overrideHasPermanentMenuKey);
+ final int configVal = res.getInteger(R.integer.config_overrideHasPermanentMenuKey);
switch (configVal) {
default:
@@ -516,32 +515,27 @@ public class ViewConfiguration {
}
}
- mFadingMarqueeEnabled = res.getBoolean(
- com.android.internal.R.bool.config_ui_enableFadingMarquee);
- mTouchSlop = res.getDimensionPixelSize(
- com.android.internal.R.dimen.config_viewConfigurationTouchSlop);
+ mFadingMarqueeEnabled = res.getBoolean(R.bool.config_ui_enableFadingMarquee);
+ mTouchSlop = res.getDimensionPixelSize(R.dimen.config_viewConfigurationTouchSlop);
mHandwritingSlop = res.getDimensionPixelSize(
- com.android.internal.R.dimen.config_viewConfigurationHandwritingSlop);
- mHoverSlop = res.getDimensionPixelSize(
- com.android.internal.R.dimen.config_viewConfigurationHoverSlop);
+ R.dimen.config_viewConfigurationHandwritingSlop);
+ mHoverSlop = res.getDimensionPixelSize(R.dimen.config_viewConfigurationHoverSlop);
mMinScrollbarTouchTarget = res.getDimensionPixelSize(
- com.android.internal.R.dimen.config_minScrollbarTouchTarget);
+ R.dimen.config_minScrollbarTouchTarget);
mPagingTouchSlop = mTouchSlop * 2;
mDoubleTapTouchSlop = mTouchSlop;
mHandwritingGestureLineMargin = res.getDimensionPixelSize(
- com.android.internal.R.dimen.config_viewConfigurationHandwritingGestureLineMargin);
+ R.dimen.config_viewConfigurationHandwritingGestureLineMargin);
- mMinimumFlingVelocity = res.getDimensionPixelSize(
- com.android.internal.R.dimen.config_viewMinFlingVelocity);
- mMaximumFlingVelocity = res.getDimensionPixelSize(
- com.android.internal.R.dimen.config_viewMaxFlingVelocity);
+ mMinimumFlingVelocity = res.getDimensionPixelSize(R.dimen.config_viewMinFlingVelocity);
+ mMaximumFlingVelocity = res.getDimensionPixelSize(R.dimen.config_viewMaxFlingVelocity);
int configMinRotaryEncoderFlingVelocity = res.getDimensionPixelSize(
- com.android.internal.R.dimen.config_viewMinRotaryEncoderFlingVelocity);
+ R.dimen.config_viewMinRotaryEncoderFlingVelocity);
int configMaxRotaryEncoderFlingVelocity = res.getDimensionPixelSize(
- com.android.internal.R.dimen.config_viewMaxRotaryEncoderFlingVelocity);
+ R.dimen.config_viewMaxRotaryEncoderFlingVelocity);
if (configMinRotaryEncoderFlingVelocity < 0 || configMaxRotaryEncoderFlingVelocity < 0) {
mMinimumRotaryEncoderFlingVelocity = NO_FLING_MIN_VELOCITY;
mMaximumRotaryEncoderFlingVelocity = NO_FLING_MAX_VELOCITY;
@@ -551,8 +545,7 @@ public class ViewConfiguration {
}
int configRotaryEncoderHapticScrollFeedbackTickIntervalPixels =
- res.getDimensionPixelSize(
- com.android.internal.R.dimen
+ res.getDimensionPixelSize(R.dimen
.config_rotaryEncoderAxisScrollTickInterval);
mRotaryEncoderHapticScrollFeedbackTickIntervalPixels =
configRotaryEncoderHapticScrollFeedbackTickIntervalPixels > 0
@@ -560,41 +553,31 @@ public class ViewConfiguration {
: NO_HAPTIC_SCROLL_TICK_INTERVAL;
mRotaryEncoderHapticScrollFeedbackEnabled =
- res.getBoolean(
- com.android.internal.R.bool
+ res.getBoolean(R.bool
.config_viewRotaryEncoderHapticScrollFedbackEnabled);
- mGlobalActionsKeyTimeout = res.getInteger(
- com.android.internal.R.integer.config_globalActionsKeyTimeout);
+ mGlobalActionsKeyTimeout = res.getInteger(R.integer.config_globalActionsKeyTimeout);
- mHorizontalScrollFactor = res.getDimensionPixelSize(
- com.android.internal.R.dimen.config_horizontalScrollFactor);
- mVerticalScrollFactor = res.getDimensionPixelSize(
- com.android.internal.R.dimen.config_verticalScrollFactor);
+ mHorizontalScrollFactor = res.getDimensionPixelSize(R.dimen.config_horizontalScrollFactor);
+ mVerticalScrollFactor = res.getDimensionPixelSize(R.dimen.config_verticalScrollFactor);
mShowMenuShortcutsWhenKeyboardPresent = res.getBoolean(
- com.android.internal.R.bool.config_showMenuShortcutsWhenKeyboardPresent);
+ R.bool.config_showMenuShortcutsWhenKeyboardPresent);
- mMinScalingSpan = res.getDimensionPixelSize(
- com.android.internal.R.dimen.config_minScalingSpan);
+ mMinScalingSpan = res.getDimensionPixelSize(R.dimen.config_minScalingSpan);
- mScreenshotChordKeyTimeout = res.getInteger(
- com.android.internal.R.integer.config_screenshotChordKeyTimeout);
+ mScreenshotChordKeyTimeout = res.getInteger(R.integer.config_screenshotChordKeyTimeout);
mSmartSelectionInitializedTimeout = res.getInteger(
- com.android.internal.R.integer.config_smartSelectionInitializedTimeoutMillis);
+ R.integer.config_smartSelectionInitializedTimeoutMillis);
mSmartSelectionInitializingTimeout = res.getInteger(
- com.android.internal.R.integer.config_smartSelectionInitializingTimeoutMillis);
- mPreferKeepClearForFocusEnabled = res.getBoolean(
- com.android.internal.R.bool.config_preferKeepClearForFocus);
+ R.integer.config_smartSelectionInitializingTimeoutMillis);
+ mPreferKeepClearForFocusEnabled = res.getBoolean(R.bool.config_preferKeepClearForFocus);
mViewBasedRotaryEncoderScrollHapticsEnabledConfig =
- res.getBoolean(
- com.android.internal.R.bool.config_viewBasedRotaryEncoderHapticsEnabled);
+ res.getBoolean(R.bool.config_viewBasedRotaryEncoderHapticsEnabled);
mViewTouchScreenHapticScrollFeedbackEnabled =
Flags.enableScrollFeedbackForTouch()
- ? res.getBoolean(
- com.android.internal.R.bool
- .config_viewTouchScreenHapticScrollFeedbackEnabled)
+ ? res.getBoolean(R.bool.config_viewTouchScreenHapticScrollFeedbackEnabled)
: false;
}
@@ -632,6 +615,7 @@ public class ViewConfiguration {
@VisibleForTesting
public static void resetCacheForTesting() {
sConfigurations.clear();
+ sResourceCache = new ResourceCache();
}
/**
@@ -707,7 +691,7 @@ public class ViewConfiguration {
* components.
*/
public static int getPressedStateDuration() {
- return PRESSED_STATE_DURATION;
+ return sResourceCache.getPressedStateDuration();
}
/**
@@ -752,7 +736,7 @@ public class ViewConfiguration {
* considered to be a tap.
*/
public static int getTapTimeout() {
- return TAP_TIMEOUT;
+ return sResourceCache.getTapTimeout();
}
/**
@@ -761,7 +745,7 @@ public class ViewConfiguration {
* considered to be a tap.
*/
public static int getJumpTapTimeout() {
- return JUMP_TAP_TIMEOUT;
+ return sResourceCache.getJumpTapTimeout();
}
/**
@@ -770,7 +754,7 @@ public class ViewConfiguration {
* double-tap.
*/
public static int getDoubleTapTimeout() {
- return DOUBLE_TAP_TIMEOUT;
+ return sResourceCache.getDoubleTapTimeout();
}
/**
@@ -782,7 +766,7 @@ public class ViewConfiguration {
*/
@UnsupportedAppUsage
public static int getDoubleTapMinTime() {
- return DOUBLE_TAP_MIN_TIME;
+ return sResourceCache.getDoubleTapMinTime();
}
/**
@@ -792,7 +776,7 @@ public class ViewConfiguration {
* @hide
*/
public static int getHoverTapTimeout() {
- return HOVER_TAP_TIMEOUT;
+ return sResourceCache.getHoverTapTimeout();
}
/**
@@ -803,7 +787,7 @@ public class ViewConfiguration {
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public static int getHoverTapSlop() {
- return HOVER_TAP_SLOP;
+ return sResourceCache.getHoverTapSlop();
}
/**
@@ -1044,7 +1028,7 @@ public class ViewConfiguration {
* in milliseconds.
*/
public static long getZoomControlsTimeout() {
- return ZOOM_CONTROLS_TIMEOUT;
+ return sResourceCache.getZoomControlsTimeout();
}
/**
@@ -1113,14 +1097,14 @@ public class ViewConfiguration {
* friction.
*/
public static float getScrollFriction() {
- return SCROLL_FRICTION;
+ return sResourceCache.getScrollFriction();
}
/**
* @return the default duration in milliseconds for {@link ActionMode#hide(long)}.
*/
public static long getDefaultActionModeHideDuration() {
- return ACTION_MODE_HIDE_DURATION_DEFAULT;
+ return sResourceCache.getDefaultActionModeHideDuration();
}
/**
@@ -1471,8 +1455,137 @@ public class ViewConfiguration {
return HOVER_TOOLTIP_HIDE_SHORT_TIMEOUT;
}
- private static final int getDisplayDensity(Context context) {
+ private static int getDisplayDensity(Context context) {
final DisplayMetrics metrics = context.getResources().getDisplayMetrics();
return (int) (100.0f * metrics.density);
}
+
+ /**
+ * Fetches resource values statically and caches them locally for fast lookup. Note that these
+ * values will not be updated during the lifetime of a process, even if resource overlays are
+ * applied.
+ */
+ private static final class ResourceCache {
+
+ private int mPressedStateDuration = -1;
+ private int mTapTimeout = -1;
+ private int mJumpTapTimeout = -1;
+ private int mDoubleTapTimeout = -1;
+ private int mDoubleTapMinTime = -1;
+ private int mHoverTapTimeout = -1;
+ private int mHoverTapSlop = -1;
+ private long mZoomControlsTimeout = -1L;
+ private float mScrollFriction = -1f;
+ private long mDefaultActionModeHideDuration = -1L;
+
+ public int getPressedStateDuration() {
+ if (mPressedStateDuration < 0) {
+ Resources resources = getCurrentResources();
+ mPressedStateDuration = resources != null
+ ? resources.getInteger(R.integer.config_pressedStateDurationMillis)
+ : PRESSED_STATE_DURATION;
+ }
+ return mPressedStateDuration;
+ }
+
+ public int getTapTimeout() {
+ if (mTapTimeout < 0) {
+ Resources resources = getCurrentResources();
+ mTapTimeout = resources != null
+ ? resources.getInteger(R.integer.config_tapTimeoutMillis)
+ : TAP_TIMEOUT;
+ }
+ return mTapTimeout;
+ }
+
+ public int getJumpTapTimeout() {
+ if (mJumpTapTimeout < 0) {
+ Resources resources = getCurrentResources();
+ mJumpTapTimeout = resources != null
+ ? resources.getInteger(R.integer.config_jumpTapTimeoutMillis)
+ : JUMP_TAP_TIMEOUT;
+ }
+ return mJumpTapTimeout;
+ }
+
+ public int getDoubleTapTimeout() {
+ if (mDoubleTapTimeout < 0) {
+ Resources resources = getCurrentResources();
+ mDoubleTapTimeout = resources != null
+ ? resources.getInteger(R.integer.config_doubleTapTimeoutMillis)
+ : DOUBLE_TAP_TIMEOUT;
+ }
+ return mDoubleTapTimeout;
+ }
+
+ public int getDoubleTapMinTime() {
+ if (mDoubleTapMinTime < 0) {
+ Resources resources = getCurrentResources();
+ mDoubleTapMinTime = resources != null
+ ? resources.getInteger(R.integer.config_doubleTapMinTimeMillis)
+ : DOUBLE_TAP_MIN_TIME;
+ }
+ return mDoubleTapMinTime;
+ }
+
+ public int getHoverTapTimeout() {
+ if (mHoverTapTimeout < 0) {
+ Resources resources = getCurrentResources();
+ mHoverTapTimeout = resources != null
+ ? resources.getInteger(R.integer.config_hoverTapTimeoutMillis)
+ : HOVER_TAP_TIMEOUT;
+ }
+ return mHoverTapTimeout;
+ }
+
+ public int getHoverTapSlop() {
+ if (mHoverTapSlop < 0) {
+ Resources resources = getCurrentResources();
+ mHoverTapSlop = resources != null
+ ? resources.getDimensionPixelSize(R.dimen.config_hoverTapSlop)
+ : HOVER_TAP_SLOP;
+ }
+ return mHoverTapSlop;
+ }
+
+ public long getZoomControlsTimeout() {
+ if (mZoomControlsTimeout < 0) {
+ Resources resources = getCurrentResources();
+ mZoomControlsTimeout = resources != null
+ ? resources.getInteger(R.integer.config_zoomControlsTimeoutMillis)
+ : ZOOM_CONTROLS_TIMEOUT;
+ }
+ return mZoomControlsTimeout;
+ }
+
+ public float getScrollFriction() {
+ if (mScrollFriction < 0) {
+ Resources resources = getCurrentResources();
+ mScrollFriction = resources != null
+ ? resources.getFloat(R.dimen.config_scrollFriction)
+ : SCROLL_FRICTION;
+ }
+ return mScrollFriction;
+ }
+
+ public long getDefaultActionModeHideDuration() {
+ if (mDefaultActionModeHideDuration < 0) {
+ Resources resources = getCurrentResources();
+ mDefaultActionModeHideDuration = resources != null
+ ? resources.getInteger(R.integer.config_defaultActionModeHideDurationMillis)
+ : ACTION_MODE_HIDE_DURATION_DEFAULT;
+ }
+ return mDefaultActionModeHideDuration;
+ }
+
+ private static Resources getCurrentResources() {
+ if (!android.companion.virtualdevice.flags.Flags
+ .migrateViewconfigurationConstantsToResources()) {
+ return null;
+ }
+ Application application = ActivityThread.currentApplication();
+ Context context = application != null ? application.getApplicationContext() : null;
+ return context != null ? context.getResources() : null;
+ }
+ }
}
diff --git a/core/java/android/webkit/LegacyErrorStrings.java b/core/java/android/webkit/LegacyErrorStrings.java
index 60a6ee1a045f..f52214ca23ae 100644
--- a/core/java/android/webkit/LegacyErrorStrings.java
+++ b/core/java/android/webkit/LegacyErrorStrings.java
@@ -22,7 +22,7 @@ import android.util.Log;
/**
* Localized strings for the error codes defined in EventHandler.
*
- * {@hide}
+ * @hide
*/
class LegacyErrorStrings {
private LegacyErrorStrings() { /* Utility class, don't instantiate. */ }
diff --git a/core/java/android/webkit/WebIconDatabase.java b/core/java/android/webkit/WebIconDatabase.java
index b70565816037..76d2e4c632f6 100644
--- a/core/java/android/webkit/WebIconDatabase.java
+++ b/core/java/android/webkit/WebIconDatabase.java
@@ -73,7 +73,7 @@ public abstract class WebIconDatabase {
*/
public abstract void requestIconForPageUrl(String url, IconListener listener);
- /** {@hide}
+ /** @hide
*/
@SuppressWarnings("HiddenAbstractMethod")
@SystemApi
diff --git a/core/java/android/window/DesktopExperienceFlags.java b/core/java/android/window/DesktopExperienceFlags.java
index e0c48b03dad8..cf582176a9f7 100644
--- a/core/java/android/window/DesktopExperienceFlags.java
+++ b/core/java/android/window/DesktopExperienceFlags.java
@@ -60,6 +60,8 @@ public enum DesktopExperienceFlags {
ENABLE_MOVE_TO_NEXT_DISPLAY_SHORTCUT(Flags::enableMoveToNextDisplayShortcut, false),
ENABLE_MULTIPLE_DESKTOPS_BACKEND(Flags::enableMultipleDesktopsBackend, false),
ENABLE_MULTIPLE_DESKTOPS_FRONTEND(Flags::enableMultipleDesktopsFrontend, false),
+ ENABLE_PERSISTING_DISPLAY_SIZE_FOR_CONNECTED_DISPLAYS(
+ Flags::enablePersistingDisplaySizeForConnectedDisplays, false),
ENABLE_PER_DISPLAY_DESKTOP_WALLPAPER_ACTIVITY(Flags::enablePerDisplayDesktopWallpaperActivity,
false),
ENABLE_PER_DISPLAY_PACKAGE_CONTEXT_CACHE_IN_STATUSBAR_NOTIF(
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index 2f2a09a9fac3..9c77371c47eb 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -816,7 +816,7 @@ flag {
name: "enable_taskbar_overflow"
namespace: "lse_desktop_experience"
description: "Show recent apps in the taskbar overflow."
- bug: "368119679"
+ bug: "375627272"
}
flag {
@@ -827,13 +827,10 @@ flag {
}
flag {
- name: "enable_persisting_density_scale_for_connected_displays"
+ name: "enable_persisting_display_size_for_connected_displays"
namespace: "lse_desktop_experience"
- description: "Enables persisting density scale on resolution change for connected displays."
+ description: "Enables persisting display size on resolution change for connected displays."
bug: "392855657"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
}
flag {
@@ -875,3 +872,17 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "enable_size_compat_mode_improvements_for_connected_displays"
+ namespace: "lse_desktop_experience"
+ description: "Enable some improvements in size compat mode for connected displays."
+ bug: "399752440"
+}
+
+flag {
+ name: "form_factor_based_desktop_first_switch"
+ namespace: "lse_desktop_experience"
+ description: "Enables the desktop-first mode switching logic based on its form factor."
+ bug: "394736817"
+}
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index 0e19eb2d3219..f2ba16cf43d6 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -482,4 +482,15 @@ flag {
metadata {
purpose: PURPOSE_BUGFIX
}
+}
+
+flag {
+ name: "early_launch_hint"
+ namespace: "windowing_frontend"
+ description: "Sets Launch powermode for activity launches earlier"
+ bug: "399380676"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
} \ No newline at end of file
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 1f907602cb9b..dd31c388c973 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -634,7 +634,6 @@ public class LockPatternView extends View {
}
private void notifyPatternStarted() {
- sendAccessEvent(R.string.lockscreen_access_pattern_start);
if (mOnPatternListener != null) {
mOnPatternListener.onPatternStart();
}
@@ -642,14 +641,12 @@ public class LockPatternView extends View {
@UnsupportedAppUsage
private void notifyPatternDetected() {
- sendAccessEvent(R.string.lockscreen_access_pattern_detected);
if (mOnPatternListener != null) {
mOnPatternListener.onPatternDetected(mPattern);
}
}
private void notifyPatternCleared() {
- sendAccessEvent(R.string.lockscreen_access_pattern_cleared);
if (mOnPatternListener != null) {
mOnPatternListener.onPatternCleared();
}
@@ -1240,10 +1237,6 @@ public class LockPatternView extends View {
}
}
- private void sendAccessEvent(int resId) {
- announceForAccessibility(mContext.getString(resId));
- }
-
private void handleActionUp() {
// report pattern detected
if (!mPattern.isEmpty()) {
diff --git a/core/jni/android_database_SQLiteConnection.cpp b/core/jni/android_database_SQLiteConnection.cpp
index ba7e70564143..36c08a51c66a 100644
--- a/core/jni/android_database_SQLiteConnection.cpp
+++ b/core/jni/android_database_SQLiteConnection.cpp
@@ -204,7 +204,7 @@ static jlong nativeOpen(JNIEnv* env, jclass clazz, jstring pathStr, jint openFla
return reinterpret_cast<jlong>(connection);
}
-static void nativeClose(JNIEnv* env, jclass clazz, jlong connectionPtr) {
+static void nativeClose(JNIEnv* env, jclass clazz, jlong connectionPtr, jboolean fast) {
SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
if (connection) {
@@ -212,6 +212,13 @@ static void nativeClose(JNIEnv* env, jclass clazz, jlong connectionPtr) {
if (connection->tableQuery != nullptr) {
sqlite3_finalize(connection->tableQuery);
}
+ if (fast) {
+ // The caller requested a fast close, so do not checkpoint even if this is the last
+ // connection to the database. Note that the change is only to this connection.
+ // Any other connections to the same database are unaffected.
+ int _unused = 0;
+ sqlite3_db_config(connection->db, SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, 1, &_unused);
+ }
int err = sqlite3_close(connection->db);
if (err != SQLITE_OK) {
// This can happen if sub-objects aren't closed first. Make sure the caller knows.
@@ -224,6 +231,12 @@ static void nativeClose(JNIEnv* env, jclass clazz, jlong connectionPtr) {
}
}
+// This method is deprecated and should be removed when it is no longer needed by the
+// robolectric tests.
+static void nativeClose(JNIEnv* env, jclass clazz, jlong connectionPtr) {
+ nativeClose(env, clazz, connectionPtr, false);
+}
+
static void sqliteCustomScalarFunctionCallback(sqlite3_context *context,
int argc, sqlite3_value **argv) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
@@ -959,8 +972,10 @@ static const JNINativeMethod sMethods[] =
/* name, signature, funcPtr */
{ "nativeOpen", "(Ljava/lang/String;ILjava/lang/String;ZZII)J",
(void*)nativeOpen },
+ { "nativeClose", "(JZ)V",
+ (void*) static_cast<void(*)(JNIEnv*,jclass,jlong,jboolean)>(nativeClose) },
{ "nativeClose", "(J)V",
- (void*)nativeClose },
+ (void*) static_cast<void(*)(JNIEnv*,jclass,jlong)>(nativeClose) },
{ "nativeRegisterCustomScalarFunction", "(JLjava/lang/String;Ljava/util/function/UnaryOperator;)V",
(void*)nativeRegisterCustomScalarFunction },
{ "nativeRegisterCustomAggregateFunction", "(JLjava/lang/String;Ljava/util/function/BinaryOperator;)V",
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 8c7b335e6e86..42f444419765 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -1833,6 +1833,15 @@ static void BindMountSyspropOverride(fail_fn_t fail_fn, JNIEnv* env) {
ReloadBuildJavaConstants(env);
}
+static void MountInitOverride(fail_fn_t fail_fn, JNIEnv* env) {
+ const char* init_etc_dir = "/system/etc/init";
+
+ if (TEMP_FAILURE_RETRY(mount("tmpfs", init_etc_dir, "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC,
+ "uid=0,gid=0,mode=0751")) == -1) {
+ fail_fn(CREATE_ERROR("Failed to mount tmpfs %s: %s", init_etc_dir, strerror(errno)));
+ }
+}
+
static void BindMountStorageToLowerFs(const userid_t user_id, const uid_t uid,
const char* dir_name, const char* package, fail_fn_t fail_fn) {
bool hasSdcardFs = IsSdcardfsUsed();
@@ -1954,6 +1963,7 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids,
if (mount_sysprop_overrides) {
BindMountSyspropOverride(fail_fn, env);
+ MountInitOverride(fail_fn, env);
}
// If this zygote isn't root, it won't be able to create a process group,
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index a673ad7dfb34..5820c8e947c2 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -216,10 +216,10 @@ message DisplayContentProto {
optional .com.android.server.wm.IdentifierProto resumed_activity = 24;
repeated TaskProto tasks = 25 [deprecated=true];
optional bool display_ready = 26;
- optional WindowStateProto input_method_target = 27;
- optional WindowStateProto input_method_input_target = 28;
- optional WindowStateProto input_method_control_target = 29;
- optional WindowStateProto current_focus = 30;
+ optional WindowStateProto input_method_target = 27 [deprecated = true];
+ optional WindowStateProto input_method_input_target = 28 [deprecated = true];
+ optional WindowStateProto input_method_control_target = 29 [deprecated = true];
+ optional WindowStateProto current_focus = 30 [deprecated = true];
optional ImeInsetsSourceProviderProto ime_insets_source_provider = 31;
optional bool can_show_ime = 32 [deprecated=true];
@@ -231,6 +231,10 @@ message DisplayContentProto {
repeated string sleep_tokens = 37;
repeated .android.graphics.RectProto keep_clear_areas = 38;
optional int32 min_size_of_resizeable_task_dp = 39;
+ optional IdentifierProto input_method_layering_target_identifier = 40;
+ optional IdentifierProto input_method_input_target_identifier = 41;
+ optional IdentifierProto input_method_control_target_identifier = 42;
+ optional IdentifierProto current_focus_identifier = 43;
}
/* represents DisplayArea object */
@@ -590,9 +594,9 @@ message InsetsSourceProviderProto {
optional .android.graphics.RectProto frame = 2;
optional .android.view.InsetsSourceControlProto fake_control = 3;
optional .android.view.InsetsSourceControlProto control = 4;
- optional WindowStateProto control_target = 5;
- optional WindowStateProto pending_control_target = 6;
- optional WindowStateProto fake_control_target = 7;
+ optional WindowStateProto control_target = 5 [deprecated = true];
+ optional WindowStateProto pending_control_target = 6 [deprecated = true];
+ optional WindowStateProto fake_control_target = 7 [deprecated = true];
optional .android.view.SurfaceControlProto captured_leash = 8;
optional .android.graphics.RectProto ime_overridden_frame = 9 [deprecated=true];
optional bool is_leash_ready_for_dispatching = 10;
@@ -601,15 +605,21 @@ message InsetsSourceProviderProto {
optional bool seamless_rotating = 13;
optional int64 finish_seamless_rotate_frame_number = 14;
optional bool controllable = 15;
- optional WindowStateProto source_window_state = 16;
+ optional WindowStateProto source_window_state = 16 [deprecated = true];
+
+ optional IdentifierProto control_target_identifier = 17;
+ optional IdentifierProto pending_control_target_identifier = 18;
+ optional IdentifierProto fake_control_target_identifier = 19;
+ optional IdentifierProto source_window_state_identifier = 20;
}
message ImeInsetsSourceProviderProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
optional InsetsSourceProviderProto insets_source_provider = 1;
- optional WindowStateProto ime_target_from_ime = 2;
+ optional WindowStateProto ime_target_from_ime = 2 [deprecated = true];
optional bool is_ime_layout_drawn = 3 [deprecated=true];
+ optional IdentifierProto ime_target_from_ime_identifier = 4;
}
message BackNavigationProto {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index e16ce9849ff2..36b65ba43162 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -9292,6 +9292,9 @@
<action android:name="android.intent.action.UPDATE_PINS" />
<data android:scheme="content" android:host="*" android:mimeType="*/*" />
</intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.BOOT_COMPLETED" />
+ </intent-filter>
</receiver>
<receiver android:name="com.android.server.updates.IntentFirewallInstallReceiver"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index b6b5d8ba2d2f..ae05666bc2a2 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Jy kan jou gehoortoestel en mikrofoon vir handvrye oproepe gebruik. Dit skakel net jou mikrofoon tydens die oproep oor."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Skakel oor"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Instellings"</string>
- <string name="user_switched" msgid="7249833311585228097">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g> ."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Skakel tans oor na <xliff:g id="NAME">%1$s</xliff:g> …"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Meld <xliff:g id="NAME">%1$s</xliff:g> tans af …"</string>
<string name="owner_name" msgid="8713560351570795743">"Eienaar"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 29b153b23d3d..19be04eabfbf 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"የእርስዎን መስሚያ አጋዥ መሣሪያ ማይክሮፎን ለነጻ እጅ መደወል መጠቀም ይችላሉ። ይህ በጥሪው ወቅት ማይክሮፎንዎን ብቻ ይቀይራል።"</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"ቀይር"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"ቅንብሮች"</string>
- <string name="user_switched" msgid="7249833311585228097">"የአሁኑ ተጠቃሚ <xliff:g id="NAME">%1$s</xliff:g>።"</string>
<string name="user_switching_message" msgid="1912993630661332336">"ወደ <xliff:g id="NAME">%1$s</xliff:g> በመቀየር ላይ…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> በማውጣት ላይ…"</string>
<string name="owner_name" msgid="8713560351570795743">"ባለቤት"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 08d0af5f3a6f..66192cb01ebf 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1829,7 +1829,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"يمكنك استخدام ميكروفون سماعة الأذن الطبية لإجراء مكالمات بدون لمس الجهاز. يؤدي هذا الإجراء إلى تبديل الميكروفون فقط أثناء المكالمة."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"تبديل"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"الإعدادات"</string>
- <string name="user_switched" msgid="7249833311585228097">"المستخدم الحالي <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"جارٍ التبديل إلى <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"جارٍ الخروج <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"المالك"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 9eab313b1b94..b85be47b4a38 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"আপুনি হেণ্ডছ্‌-ফ্ৰী কলিঙৰ বাবে আপোনাৰ শ্ৰৱণ যন্ত্ৰৰ মাইক্ৰ’ফ’ন ব্যৱহাৰ কৰিব পাৰে। এইটোৱে কল চলি থাকোঁতে কেৱল আপোনাৰ মাইকটো সলনি কৰে।"</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"সলনি কৰক"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"ছেটিং"</string>
- <string name="user_switched" msgid="7249833311585228097">"বৰ্তমানৰ ব্যৱহাৰকাৰী <xliff:g id="NAME">%1$s</xliff:g>।"</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>লৈ সলনি কৰি থকা হৈছে…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g>ৰ পৰা লগ আউট কৰি থকা হৈছে…"</string>
<string name="owner_name" msgid="8713560351570795743">"গৰাকী"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 3aec62a8b8d5..b9bd5437c7b0 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Səsli idarəetmə ilə zəng etmək üçün eşitmə aparatı mikrofonunuzdan istifadə edə bilərsiniz. Bu, yalnız zəng zamanı mikrofonu dəyişdirir."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Dəyişin"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Ayarlar"</string>
- <string name="user_switched" msgid="7249833311585228097">"Cari istifadəçi <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> adına keçirilir…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> çıxır..."</string>
<string name="owner_name" msgid="8713560351570795743">"Sahib"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 47203a992934..a558de3d755a 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1804,8 +1804,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Režim jednom rukom"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Dodatno zatamni"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Slušni aparati"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Automatski klik"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Veza je prekinuta"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Povezano"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktivno"</string>
@@ -1826,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Možete da koristite mikrofon slušnog aparata za hendsfri pozivanje. Time se mikrofon menja samo tokom poziva."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Promeni"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Podešavanja"</string>
- <string name="user_switched" msgid="7249833311585228097">"Aktuelni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Prebacivanje na <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Odjavljuje se <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Vlasnik"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 8230f0c7739c..113be9de3185 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -159,7 +159,7 @@
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> праз <xliff:g id="TIME_DELAY">{2}</xliff:g> с."</string>
<string name="cfTemplateRegistered" msgid="5619930473441550596">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: не пераадрасоўваецца"</string>
<string name="cfTemplateRegisteredTime" msgid="5222794399642525045">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: не пераадрасоўваецца"</string>
- <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"Сеткавая бяспека"</string>
+ <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"Бяспека мабільнай сеткі"</string>
<string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"Шыфраванне, апавяшчэнні для незашыфраваных сетак"</string>
<string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"Атрыманы доступ да ідэнтыфікатара прылады"</string>
<string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"У <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> у сетцы паблізу быў запісаны ўнікальны ідэнтыфікатар вашай прылады (IMSI або IMEI) пры выкарыстанні SIM-карты <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>"</string>
@@ -1827,7 +1827,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Вы можаце выкарыстоўваць мікрафон слыхавога апарата, каб размаўляць падчас званка без дапамогі рук. Будзе пераключаны толькі ваш мікрафон."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Пераключыцца"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Налады"</string>
- <string name="user_switched" msgid="7249833311585228097">"Бягучы карыстальнік <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Пераключэнне на карыстальніка \"<xliff:g id="NAME">%1$s</xliff:g>\"…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> выходзіць з сістэмы…"</string>
<string name="owner_name" msgid="8713560351570795743">"Уладальнік"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index d9471e68c8e1..c36940f47371 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Можете да използвате микрофона на слуховия си апарат за обаждания в режим „свободни ръце“. Микрофонът ще бъде включен само по време на обаждането."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Превключване"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Настройки"</string>
- <string name="user_switched" msgid="7249833311585228097">"Текущ потребител <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Превключва се към: <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> излиза…"</string>
<string name="owner_name" msgid="8713560351570795743">"Собственик"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index cc05d28ca630..b79c1d703eb9 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -327,7 +327,7 @@
<string name="permgroupdesc_contacts" msgid="9163927941244182567">"আপনার পরিচিতিগুলিতে অ্যাক্সেস"</string>
<string name="permgrouplab_location" msgid="1858277002233964394">"লোকেশন"</string>
<string name="permgroupdesc_location" msgid="1995955142118450685">"এই ডিভাইসের লোকেশন অ্যাক্সেস"</string>
- <string name="permgrouplab_calendar" msgid="6426860926123033230">"ক্যালেন্ডার"</string>
+ <string name="permgrouplab_calendar" msgid="6426860926123033230">"Calendar"</string>
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"আপনার ক্যালেন্ডারে অ্যাক্সেস"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"এসএমএসগুলি পাঠাতে এবং দেখতে"</string>
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"হ্যান্ডস-ফ্রি কলিংয়ের জন্য আপনার হিয়ারিং এডের মাইক্রোফোন ব্যবহার করতে পারবেন। এটি শুধুমাত্র কল চলাকালীন আপনার মাইক পরিবর্তন করে।"</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"পরিবর্তন করুন"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"সেটিংস"</string>
- <string name="user_switched" msgid="7249833311585228097">"বর্তমান ব্যবহারকারী <xliff:g id="NAME">%1$s</xliff:g>৷"</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> প্রোফাইলে পাল্টানো হচ্ছে…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g>কে লগ-আউট করা হচ্ছে..."</string>
<string name="owner_name" msgid="8713560351570795743">"মালিক"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 9c553cedadc5..a995746a28e3 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -1826,7 +1826,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Možete koristiti mikrofon slušnog aparata za pozivanje bez dodira. Ovo mijenja mikrofon samo tokom poziva."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Promijeni"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Postavke"</string>
- <string name="user_switched" msgid="7249833311585228097">"Trenutni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Prebacivanje na korisnika <xliff:g id="NAME">%1$s</xliff:g>..."</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Odjava korisnika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Vlasnik"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 3fa177ef2116..62f59f2570f9 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1826,7 +1826,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Pots fer servir el micròfon del teu audiòfon per fer trucades amb mans lliures. Aquesta opció només canvia el micròfon durant la trucada."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Canvia"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Configuració"</string>
- <string name="user_switched" msgid="7249833311585228097">"Usuari actual: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"S\'està canviant a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"S\'està tancant la sessió de l\'usuari <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Propietari"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 670ca33f0e1d..5e7a8aa7ee2a 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1827,7 +1827,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"K handsfree telefonování můžete použít mikrofon naslouchátka. Mikrofon se přepne jen během hovoru."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Přepnout"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Nastavení"</string>
- <string name="user_switched" msgid="7249833311585228097">"Aktuální uživatel je <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Přepínání na uživatele <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Odhlašování uživatele <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Vlastník"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 47eb357b4087..ab7339491042 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Du kan bruge mikrofonen i dit høreapparat til at foretage håndfrie opkald. Der skiftes kun mikrofon under opkaldet."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Skift"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Indstillinger"</string>
- <string name="user_switched" msgid="7249833311585228097">"Nuværende bruger <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Skifter til <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> logges ud…"</string>
<string name="owner_name" msgid="8713560351570795743">"Ejer"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 06a35e628d27..8bff3505e78b 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Du kannst das Mikrofon deines Hörgeräts für Anrufe per Sprachbefehl verwenden. Das Mikrofon wird nur für die Dauer des Anrufs gewechselt."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Wechseln"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Einstellungen"</string>
- <string name="user_switched" msgid="7249833311585228097">"Aktueller Nutzer <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_switching_message" msgid="1912993630661332336">"Wechseln zu <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> wird abgemeldet…"</string>
<string name="owner_name" msgid="8713560351570795743">"Eigentümer"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 8a12e0e907b1..0e968bd4da04 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Μπορείτε να χρησιμοποιήσετε το μικρόφωνο του βοηθήματος ακοής σας για κλήσεις handsfree. Με αυτή την ενέργεια, το μικρόφωνό σας αλλάζει μόνο κατά τη διάρκεια της κλήσης."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Εναλλαγή"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Ρυθμίσεις"</string>
- <string name="user_switched" msgid="7249833311585228097">"Τρέχων χρήστης <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Εναλλαγή σε <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Αποσύνδεση <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Κάτοχος"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 3881f1de0002..6c43f9a51dbd 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"You can use your hearing aid microphone for hands-free calling. This only switches your mic during the call."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Switch"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Settings"</string>
- <string name="user_switched" msgid="7249833311585228097">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Logging out <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Owner"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index e6c4047cbda8..99abe8bfeb27 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -1824,7 +1824,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"You can use your hearing aid microphone for hands-free calling. This only switches your mic during the call."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Switch"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Settings"</string>
- <string name="user_switched" msgid="7249833311585228097">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Logging out <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Owner"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 9680b83af481..99040f3f56b9 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"You can use your hearing aid microphone for hands-free calling. This only switches your mic during the call."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Switch"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Settings"</string>
- <string name="user_switched" msgid="7249833311585228097">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Logging out <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Owner"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index fbe1c0a09a1c..cb1e92ed638f 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"You can use your hearing aid microphone for hands-free calling. This only switches your mic during the call."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Switch"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Settings"</string>
- <string name="user_switched" msgid="7249833311585228097">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Logging out <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Owner"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 54297a568091..18cbfaa5b1dd 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1826,7 +1826,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Puedes usar el micrófono de tu audífono para realizar llamadas sin usar las manos. Esto solo cambia el micrófono durante la llamada."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Cambiar"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Configuración"</string>
- <string name="user_switched" msgid="7249833311585228097">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_switching_message" msgid="1912993630661332336">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Saliendo de <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Propietario"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 5bd2bf5941c3..852347388819 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1826,7 +1826,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Puedes usar el micrófono de tu audífono para hacer llamadas en manos libres. Esta opción solo cambia el micrófono durante la llamada."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Cambiar"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Ajustes"</string>
- <string name="user_switched" msgid="7249833311585228097">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_switching_message" msgid="1912993630661332336">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Cerrando la sesión de <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Propietario"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 0c928a6c601d..a1ddf81c72a5 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -652,7 +652,7 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Võimaldab rakendusel muuta teie fotokogu."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"Lugeda teie meediakogus olevaid asukohti"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Võimaldab rakendusel lugeda teie meediakogus olevaid asukohti."</string>
- <string name="permlab_eye_tracking_coarse" msgid="7989596289790269059">"ligikaudse pilgu jälgimine"</string>
+ <string name="permlab_eye_tracking_coarse" msgid="7989596289790269059">"pilgu ligikaudne jälgimine"</string>
<string name="permdesc_eye_tracking_coarse" msgid="870510233930553355">"Võimaldab rakendusel teie pilku ligikaudselt jälgida."</string>
<string name="permlab_eye_tracking_fine" msgid="6914457357027049512">"pilgu suuna jälgimine"</string>
<string name="permdesc_eye_tracking_fine" msgid="5788889152304524730">"Võimaldab rakendusel juurde pääseda täpsetele pilguandmetele."</string>
@@ -665,9 +665,9 @@
<string name="permlab_scene_understanding_coarse" msgid="6518646430502858641">"vahetu keskkonna mõistmine"</string>
<string name="permdesc_scene_understanding_coarse" msgid="4508880777646198656">"Võimaldab rakendusel juurde pääseda teie vahetu keskkonna jälgimisandmetele."</string>
<string name="permlab_scene_understanding_fine" msgid="409126403264393251">"vahetu keskkonna väga üksikasjalik mõistmine"</string>
- <string name="permdesc_scene_understanding_fine" msgid="6223368011593524179">"Võimaldab rakendusel pääseda väga üksikasjalikult juurde teie vahetu keskkonna jälgimisandmetele."</string>
- <string name="permlab_xr_tracking_in_background" msgid="7117098718465619023">"juurdepääs XR-i andmetele, kui see pole esiplaanil"</string>
- <string name="permdesc_xr_tracking_in_background" msgid="939504041387836853">"Võimaldab rakendusel pääseda juurde XR-i andmetele, kui see pole esiplaanil."</string>
+ <string name="permdesc_scene_understanding_fine" msgid="6223368011593524179">"Võimaldab rakendusel pääseda juurde teie ümbruskonna üksikasjalikele jälgimisandmetele."</string>
+ <string name="permlab_xr_tracking_in_background" msgid="7117098718465619023">"juurdepääs XR-i andmetele, kui rakendus pole esiplaanil"</string>
+ <string name="permdesc_xr_tracking_in_background" msgid="939504041387836853">"Võimaldab rakendusel pääseda juurde XR-i andmetele, kui rakendus pole esiplaanil."</string>
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Biomeetria kasutamine"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biomeetria või ekraaniluku kasutamine"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Kinnitage oma isik"</string>
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Saate kasutada oma kuuldeaparaadi mikrofon vabakäerežiimis helistamiseks. See vahetab teie mikrofoni ainult kõne ajal."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Vaheta"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Seaded"</string>
- <string name="user_switched" msgid="7249833311585228097">"Praegune kasutaja <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Üleminek kasutajale <xliff:g id="NAME">%1$s</xliff:g> ..."</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Kasutaja <xliff:g id="NAME">%1$s</xliff:g> väljalogimine …"</string>
<string name="owner_name" msgid="8713560351570795743">"Omanik"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 13f0452b2f3a..c63cfe666afe 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Audifonoaren mikrofonoa erabil dezakezu esku libreko deiak egiteko. Deirako soilik aldatzen da mikrofonoa."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Aldatu"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Ezarpenak"</string>
- <string name="user_switched" msgid="7249833311585228097">"Erabiltzailea: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"\"<xliff:g id="NAME">%1$s</xliff:g>\" erabiltzailera aldatzen…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> erabiltzailearen saioa amaitzen…"</string>
<string name="owner_name" msgid="8713560351570795743">"Jabea"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 2eaf4c033d52..5e1caad2cf2b 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"برای تماس دست‌آزاد می‌توانید از میکروفون سمعک خود استفاده کنید. این کار فقط درطول تماس میکروفون شما را عوض می‌کند."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"عوض کردن"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"تنظیمات"</string>
- <string name="user_switched" msgid="7249833311585228097">"کاربر کنونی <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"در حالت تغییر به <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"در حال خروج از سیستم <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"مالک"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 280658c26735..f7115ebbffa3 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Voit soittaa ääniohjatusti kuulolaitteen mikrofonin avulla. Tämä vaihtaa mikrofonia vain puhelun ajaksi."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Vaihda"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Asetukset"</string>
- <string name="user_switched" msgid="7249833311585228097">"Nykyinen käyttäjä: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Vaihdetaan käyttäjään <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> kirjautuu ulos…"</string>
<string name="owner_name" msgid="8713560351570795743">"Omistaja"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 1740ce536ea5..56623a296c1c 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1826,7 +1826,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Vous pouvez utiliser votre microphone pour prothèse auditive pour faire des appels en mode mains libres. Cette option ne change votre micro que pendant l\'appel."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Changer"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Paramètres"</string>
- <string name="user_switched" msgid="7249833311585228097">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_switching_message" msgid="1912993630661332336">"Passage au profil : <xliff:g id="NAME">%1$s</xliff:g> en cours…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Déconnexion de <xliff:g id="NAME">%1$s</xliff:g> en cours..."</string>
<string name="owner_name" msgid="8713560351570795743">"Propriétaire"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 0564661de80d..90a0f441d0c9 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1826,7 +1826,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Vous pouvez utiliser le micro de votre appareil auditif pour passer des appels en mode mains-libres. Cette option change uniquement le micro pendant l\'appel."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Changer"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Paramètres"</string>
- <string name="user_switched" msgid="7249833311585228097">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_switching_message" msgid="1912993630661332336">"Passage à <xliff:g id="NAME">%1$s</xliff:g>..."</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Déconnexion de <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Propriétaire"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 73bed7fa72da..a2b53818dec6 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Podes usar o micrófono do audiófono para facer chamadas coas mans libres. Esta acción só cambia o micrófono durante a chamada."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Cambiar"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Configuración"</string>
- <string name="user_switched" msgid="7249833311585228097">"Usuario actual <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Pechando sesión de <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Propietario"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 0c99096ff4fc..9d57bde4ab4b 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"તમે હાથના ઉપયોગ વિના કૉલ કરવા માટે સાંભળવામાં મદદ આપતા તમારા યંત્રના માઇક્રોફોનનો ઉપયોગ કરી શકો છો. કૉલ દરમિયાન આ ફક્ત તમારા માઇકને સ્વિચ કરે છે."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"સ્વિચ કરો"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"સેટિંગ"</string>
- <string name="user_switched" msgid="7249833311585228097">"વર્તમાન વપરાશકર્તા <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> પર સ્વિચ કરી રહ્યાં છીએ…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> લોગ આઉટ થઈ રહ્યાં છે…"</string>
<string name="owner_name" msgid="8713560351570795743">"માલિક"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index df211dc458a7..563b724292f4 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"बोलकर कॉल का जवाब देने के लिए, \'कान की मशीन का माइक्रोफ़ोन\' इस्तेमाल किया जा सकता है. इससे, कॉल के दौरान सिर्फ़ आपका माइक चालू या बंद होता है."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"स्विच करें"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"सेटिंग"</string>
- <string name="user_switched" msgid="7249833311585228097">"मौजूदा उपयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> पर स्विच किया जा रहा है…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> द्वारा प्रस्‍थान किया जा रहा है…"</string>
<string name="owner_name" msgid="8713560351570795743">"मालिक"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index f701483453aa..fec624d94edc 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -354,9 +354,9 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"pristupiti podacima senzora o vašim vitalnim znakovima"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Obavijesti"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"prikazati obavijesti"</string>
- <string name="permgrouplab_xr_tracking" msgid="7418994009794287471">"XR podaci o praćenju"</string>
- <string name="permgroupdesc_xr_tracking" msgid="6777198859446500821">"pristup XR podacima o vama i vašem okruženju"</string>
- <string name="permgrouplab_xr_tracking_sensitive" msgid="1194833982988144536">"osjetljivi XR podaci o praćenju"</string>
+ <string name="permgrouplab_xr_tracking" msgid="7418994009794287471">"podaci o praćenju za proširenu stvarnost"</string>
+ <string name="permgroupdesc_xr_tracking" msgid="6777198859446500821">"pristup podacima proširene stvarnosti o vama i vašem okruženju"</string>
+ <string name="permgrouplab_xr_tracking_sensitive" msgid="1194833982988144536">"osjetljivi podaci o praćenju za XR"</string>
<string name="permgroupdesc_xr_tracking_sensitive" msgid="9178027369004805829">"pristup osjetljivim podacima o praćenju, kao što je pogled"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Dohvaćati sadržaj prozora"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Pregledat će sadržaj prozora koji upotrebljavate."</string>
@@ -655,7 +655,7 @@
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Omogućuje aplikaciji čitanje lokacija iz vaše medijske zbirke."</string>
<string name="permlab_eye_tracking_coarse" msgid="7989596289790269059">"praćenje približnog pogleda"</string>
<string name="permdesc_eye_tracking_coarse" msgid="870510233930553355">"Aplikaciji omogućuje praćenje približnih podataka o pogledu."</string>
- <string name="permlab_eye_tracking_fine" msgid="6914457357027049512">"praćenje toga gdje gledate"</string>
+ <string name="permlab_eye_tracking_fine" msgid="6914457357027049512">"praćenje mjesta u koje gledate"</string>
<string name="permdesc_eye_tracking_fine" msgid="5788889152304524730">"Aplikaciji omogućuje pristup preciznim podacima o pogledu."</string>
<string name="permlab_face_tracking" msgid="2272048395128283324">"praćenje lica"</string>
<string name="permdesc_face_tracking" msgid="2622783922311211866">"Aplikaciji omogućuje pristup podacima o praćenju lica."</string>
@@ -664,10 +664,10 @@
<string name="permlab_head_tracking" msgid="1309731456372087270">"praćenje pokreta glave"</string>
<string name="permdesc_head_tracking" msgid="231597390513699188">"Aplikaciji omogućuje pristup podacima o praćenju pokreta glave."</string>
<string name="permlab_scene_understanding_coarse" msgid="6518646430502858641">"stjecanje uvida u neposredno okruženje"</string>
- <string name="permdesc_scene_understanding_coarse" msgid="4508880777646198656">"Aplikaciji omogućuje pristup podacima o praćenju o vašem neposrednom okruženju."</string>
+ <string name="permdesc_scene_understanding_coarse" msgid="4508880777646198656">"Aplikaciji omogućuje pristup podacima o praćenju vašeg neposrednog okruženja."</string>
<string name="permlab_scene_understanding_fine" msgid="409126403264393251">"stjecanje detaljnih uvida u neposredno okruženje"</string>
- <string name="permdesc_scene_understanding_fine" msgid="6223368011593524179">"Aplikaciji omogućuje pristup detaljnim podacima o praćenju o vašem neposrednom okruženju."</string>
- <string name="permlab_xr_tracking_in_background" msgid="7117098718465619023">"pristup XR podacima dok nije u prednjem planu"</string>
+ <string name="permdesc_scene_understanding_fine" msgid="6223368011593524179">"Aplikaciji omogućuje pristup detaljnim podacima o praćenju vašeg neposrednog okruženja."</string>
+ <string name="permlab_xr_tracking_in_background" msgid="7117098718465619023">"pristup podacima proširene stvarnosti dok nije u prednjem planu"</string>
<string name="permdesc_xr_tracking_in_background" msgid="939504041387836853">"Aplikaciji omogućuje pristup XR podacima dok nije u prednjem planu."</string>
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Upotreba biometrije"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Upotreba biometrijske autentifikacije ili zaključavanja zaslona"</string>
@@ -1714,7 +1714,7 @@
<string name="wireless_display_route_description" msgid="8297563323032966831">"Bežični prikaz"</string>
<string name="media_route_button_content_description" msgid="2299223698196869956">"Emitiranje"</string>
<string name="media_route_chooser_title" msgid="6646594924991269208">"Povezivanje s uređajem"</string>
- <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Emitiranje zaslona na uređaj"</string>
+ <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Emitirajte zaslon na uređaj"</string>
<string name="media_route_chooser_searching" msgid="6119673534251329535">"Traženje uređaja…"</string>
<string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"Postavke"</string>
<string name="media_route_controller_disconnect" msgid="7362617572732576959">"Prekini vezu"</string>
@@ -1826,7 +1826,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Mikrofon slušnog pomagala možete koristiti za pozivanje bez upotrebe ruku. Time se mikrofon prebacuje samo tijekom poziva."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Prebaci"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Postavke"</string>
- <string name="user_switched" msgid="7249833311585228097">"Trenutačni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Prebacivanje na korisnika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Odjavljivanje korisnika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Vlasnik"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index e3d261e11da8..7871aba30258 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Használhatja hallókészüléke mikrofonját a szabadkezes hívásokhoz. Csak a mikrofont kapcsolja át hívás közben."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Váltás"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Beállítások"</string>
- <string name="user_switched" msgid="7249833311585228097">"<xliff:g id="NAME">%1$s</xliff:g> az aktuális felhasználó."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Átváltás erre: <xliff:g id="NAME">%1$s</xliff:g>..."</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> kijelentkeztetése folyamatban van…"</string>
<string name="owner_name" msgid="8713560351570795743">"Tulajdonos"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index de62af5376c7..01e51106ea3d 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Լսողական սարքի խոսափողը կարող եք օգտագործել ձայնային կառավարման համար։ Դուք կանցնեք խոսափողին միայն զանգի ընթացքում։"</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Անցնել"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Կարգավորումներ"</string>
- <string name="user_switched" msgid="7249833311585228097">"Ներկայիս օգտատերը <xliff:g id="NAME">%1$s</xliff:g>:"</string>
<string name="user_switching_message" msgid="1912993630661332336">"Անցում <xliff:g id="NAME">%1$s</xliff:g> պրոֆիլին..."</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Ելք <xliff:g id="NAME">%1$s</xliff:g>-ից…"</string>
<string name="owner_name" msgid="8713560351570795743">"Սեփականատեր"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 18ae5e9715f9..df42e47e7028 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Anda dapat menggunakan mikrofon alat bantu dengar untuk melakukan panggilan handsfree. Tindakan ini hanya akan mengalihkan mikrofon Anda selama panggilan."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Alihkan"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Setelan"</string>
- <string name="user_switched" msgid="7249833311585228097">"Pengguna saat ini <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Beralih ke <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Mengeluarkan <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Pemilik"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index a74ff1cadcb7..40d642d2fda4 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1713,7 +1713,7 @@
<string name="wireless_display_route_description" msgid="8297563323032966831">"Þráðlaus skjábirting"</string>
<string name="media_route_button_content_description" msgid="2299223698196869956">"Senda út"</string>
<string name="media_route_chooser_title" msgid="6646594924991269208">"Tengjast tæki"</string>
- <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Senda skjá út í tæki"</string>
+ <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Varpa skjá í tæki"</string>
<string name="media_route_chooser_searching" msgid="6119673534251329535">"Leitar að tækjum…"</string>
<string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"Stillingar"</string>
<string name="media_route_controller_disconnect" msgid="7362617572732576959">"Aftengja"</string>
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Þú getur notað hljóðnema heyrnartækisins þíns til að hringja eða svara símtölum handfrjálst. Aðeins verður skipt um hljóðnema á meðan á símtali stendur."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Skipta"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Stillingar"</string>
- <string name="user_switched" msgid="7249833311585228097">"Núverandi notandi <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Skiptir yfir á <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Skráir <xliff:g id="NAME">%1$s</xliff:g> út…"</string>
<string name="owner_name" msgid="8713560351570795743">"Eigandi"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index befd2b21776c..e501c572f94e 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -277,7 +277,7 @@
<string name="bugreport_option_full_title" msgid="7681035745950045690">"Report completo"</string>
<string name="bugreport_option_full_summary" msgid="1975130009258435885">"Utilizza questa opzione per ridurre al minimo l\'interferenza di sistema quando il dispositivo non risponde, è troppo lento oppure quando ti servono tutte le sezioni della segnalazione. Non puoi inserire altri dettagli o acquisire altri screenshot."</string>
<string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{Lo screenshot per la segnalazione di bug verrà acquisito tra # secondo.}many{Lo screenshot per la segnalazione di bug verrà acquisito tra # secondi.}other{Lo screenshot per la segnalazione di bug verrà acquisito tra # secondi.}}"</string>
- <string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"Screenshot con segnalazione di bug effettuato correttamente"</string>
+ <string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"Screenshot con segnalazione di bug effettuato"</string>
<string name="bugreport_screenshot_failure_toast" msgid="6736320861311294294">"Impossibile acquisire screenshot con segnalazione di bug"</string>
<string name="global_action_toggle_silent_mode" msgid="8464352592860372188">"Modalità silenziosa"</string>
<string name="global_action_silent_mode_on_status" msgid="2371892537738632013">"Audio non attivo"</string>
@@ -1804,8 +1804,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modalità a una mano"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Attenuazione extra"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Protesi uditive"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Clic automatico"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Disconnesso"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Connesso"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Attivo"</string>
@@ -1826,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Puoi usare il microfono dell\'apparecchio acustico per le chiamate in vivavoce. In questo modo, il microfono viene attivato solo durante la chiamata."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Cambia"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Impostazioni"</string>
- <string name="user_switched" msgid="7249833311585228097">"Utente corrente <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Passaggio a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Disconnessione di <xliff:g id="NAME">%1$s</xliff:g> in corso…"</string>
<string name="owner_name" msgid="8713560351570795743">"Proprietario"</string>
@@ -2282,7 +2280,7 @@
<string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Conversazione"</string>
<string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Conversazione di gruppo"</string>
<string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string>
- <string name="resolver_personal_tab" msgid="2051260504014442073">"Personale"</string>
+ <string name="resolver_personal_tab" msgid="2051260504014442073">"Personali"</string>
<string name="resolver_work_tab" msgid="2690019516263167035">"Lavoro"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Visualizzazione personale"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Visualizzazione di lavoro"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 0b6c80af7dcb..c9984e21c95e 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1826,7 +1826,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"אפשר לשוחח במצב דיבורית באמצעות המיקרופון של מכשיר השמיעה. במצב הזה המיקרופון מוחלף רק במהלך השיחה."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"החלפה"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"הגדרות"</string>
- <string name="user_switched" msgid="7249833311585228097">"המשתמש הנוכחי <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"מעבר אל <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"מתבצע ניתוק של <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"בעלים"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 2f8133a135a1..7ab896e6b247 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"片手モード"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"さらに輝度を下げる"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"補聴器"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"自動クリック"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"未接続"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"接続済み"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"有効"</string>
@@ -1825,7 +1824,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"補聴器のマイクを使ってハンズフリー通話を行えます。通話時のみマイクが切り替わります。"</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"切り替える"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"設定"</string>
- <string name="user_switched" msgid="7249833311585228097">"現在のユーザーは<xliff:g id="NAME">%1$s</xliff:g>です。"</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>に切り替えています…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> をログアウトしています…"</string>
<string name="owner_name" msgid="8713560351570795743">"所有者"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index ef154052843d..4d634d4fe752 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"შეგიძლიათ სმენის მოწყობილობის მიკროფონის გამოყენება უკონტაქტოდ დასარეკად. ეს გადართავს თქვენს მიკროფონს მხოლოდ ზარის დროს."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"გადართვა"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"პარამეტრები"</string>
- <string name="user_switched" msgid="7249833311585228097">"ამჟამინდელი მომხმარებელი <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>-ზე გადართვა…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g>-ის ანგარიშიდან გასვლა…"</string>
<string name="owner_name" msgid="8713560351570795743">"მფლობელი"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index b5756304e15f..8d54a32b625c 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Дауыспен басқару арқылы қоңырау шалу үшін есту аппаратының микрофонын пайдалана аласыз. Микрофонға тек қоңырау кезінде ауысады."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Ауысу"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Параметрлер"</string>
- <string name="user_switched" msgid="7249833311585228097">"Ағымдағы пайдаланушы <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> профиліне ауысу…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> ішінен шығу…"</string>
<string name="owner_name" msgid="8713560351570795743">"Құрылғы иесі"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index eeae49bf388a..d7e02997714b 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"អ្នកអាចប្រើមីក្រូហ្វូនឧបករណ៍​ជំនួយការ​ស្ដាប់របស់អ្នកសម្រាប់ការហៅទូរសព្ទដោយមិន​ប្រើ​ដៃ។ ការធ្វើបែបនេះប្ដូរមីក្រូហ្វូនរបស់អ្នក ក្នុងអំឡុងការហៅទូរសព្ទតែប៉ុណ្ណោះ។"</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"ប្ដូរ"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"ការកំណត់"</string>
- <string name="user_switched" msgid="7249833311585228097">"អ្នក​ប្រើ​បច្ចុប្បន្ន <xliff:g id="NAME">%1$s</xliff:g> ។"</string>
<string name="user_switching_message" msgid="1912993630661332336">"កំពុង​ប្ដូរ​ទៅ <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"កំពុងចេញ <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"ម្ចាស់"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index fd468b43fd33..9771def44b23 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"ಹ್ಯಾಂಡ್ಸ್-ಫ್ರೀ ಕರೆ ಮಾಡುವಿಕೆಗಾಗಿ ನಿಮ್ಮ ಶ್ರವಣ ಸಾಧನದ ಮೈಕ್ರೊಫೋನ್ ಅನ್ನು ನೀವು ಬಳಸಬಹುದು. ಇದು ಕರೆಯ ಸಮಯದಲ್ಲಿ ಮಾತ್ರ ನಿಮ್ಮ ಮೈಕ್ ಅನ್ನು ಬದಲಾಯಿಸುತ್ತದೆ."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"ಬದಲಿಸಿ"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
- <string name="user_switched" msgid="7249833311585228097">"ಪ್ರಸ್ತುತ ಬಳಕೆದಾರರು <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>ಗೆ ಬದಲಾಯಿಸಲಾಗುತ್ತಿದೆ…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> ಅವರನ್ನು ಲಾಗ್‌ ಔಟ್‌ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
<string name="owner_name" msgid="8713560351570795743">"ಮಾಲೀಕರು"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 0a8867088ecb..a39db4b07f3e 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"보청기 마이크로 핸즈프리 통화 기능을 이용할 수 있습니다. 통화 중에만 마이크가 전환됩니다."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"전환"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"설정"</string>
- <string name="user_switched" msgid="7249833311585228097">"현재 사용자는 <xliff:g id="NAME">%1$s</xliff:g>님입니다."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>로 전환하는 중…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g>님을 로그아웃하는 중…"</string>
<string name="owner_name" msgid="8713560351570795743">"소유자"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 83a1c69afa92..fbc3afdc573d 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Угуу аппаратыңыздын микрофонун үн режиминде чалуу үчүн колдоно аласыз. Микрофонуңуз чалуу учурунда гана которулат."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Которулуу"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Параметрлер"</string>
- <string name="user_switched" msgid="7249833311585228097">"Учурдагы колдонуучу <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> дегенге которулууда…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> чыгууда…"</string>
<string name="owner_name" msgid="8713560351570795743">"Ээси"</string>
@@ -2502,8 +2501,8 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Күйгүзүү"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Артка кайтуу"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Кезекте турат..."</string>
- <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Спутник SOS эми жеткиликтүү"</string>
- <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Мобилдик Интернет же Wi-Fi тармагы жок болсо, кырсыктаганда жардамга келчү кызматтарга билдирүү жөнөтө аласыз. Google Messages демейки жазышуу колдонмоңуз болушу керек."</string>
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Спутник SOS кызматы иштеп баштады"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Мобилдик Интернет же Wi-Fi жок болгон учурда, кырсыктаганда жардамга келчү кызматтарга билдирүү жөнөтө аласыз. Google Жазышуу демейки колдонмоңуз болушу керек."</string>
<string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Спутник SOS колдоого алынбайт"</string>
<string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Бул түзмөктө спутник SOS колдоого алынбайт"</string>
<string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Спутник SOS туураланган жок"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index f32ede63c67f..a0a6b38644ea 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"ທ່ານສາມາດໃຊ້ໄມໂຄຣໂຟນຂອງເຄື່ອງຊ່ວຍຟັງເພື່ອການໂທແບບແຮນຟຣີໄດ້. ການດຳເນີນການນີ້ພຽງແຕ່ປ່ຽນໄມໂຄຣໂຟນຂອງທ່ານໃນລະຫວ່າງການໂທເທົ່ານັ້ນ."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"ປ່ຽນ"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"ການຕັ້ງຄ່າ"</string>
- <string name="user_switched" msgid="7249833311585228097">"ຜູ່ໃຊ້ປັດຈຸບັນ <xliff:g id="NAME">%1$s</xliff:g> ."</string>
<string name="user_switching_message" msgid="1912993630661332336">"ກຳລັງສະຫຼັບໄປຫາ <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"ກຳລັງອອກຈາກລະບົບ <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"ເຈົ້າຂອງ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 51311b379649..0b4967a9ab92 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1827,7 +1827,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Galite naudoti klausos aparato mikrofoną skambučiams laisvų rankų režimu. Mikrofonas įjungiamas tik per skambutį."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Perjungti"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Nustatymai"</string>
- <string name="user_switched" msgid="7249833311585228097">"Dabartinis naudotojas: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Perjungiama į <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Atsijungiama (<xliff:g id="NAME">%1$s</xliff:g>)…"</string>
<string name="owner_name" msgid="8713560351570795743">"Savininkas"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 3b3609e0b07b..0d19dc26bb39 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1826,7 +1826,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Varat izmantot dzirdes aparāta mikrofonu zvaniem brīvroku režīmā. Mikrofons tiek pārslēgts tikai zvana laikā."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Pārslēgt"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Iestatījumi"</string>
- <string name="user_switched" msgid="7249833311585228097">"Pašreizējais lietotājs: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Notiek pāriešana uz: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Notiek lietotāja <xliff:g id="NAME">%1$s</xliff:g> atteikšanās…"</string>
<string name="owner_name" msgid="8713560351570795743">"Īpašnieks"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 0c92fd5cace6..9889ea9d622b 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Може да го користите вашиот микрофон на слушното помагало за повикување без користење раце. Ова го префрла вашиот микрофон само за време на повикот."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Префрли"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Поставки"</string>
- <string name="user_switched" msgid="7249833311585228097">"Тековен корисник <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Се префрла на <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> се одјавува…"</string>
<string name="owner_name" msgid="8713560351570795743">"Сопственик"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index cbdbd2d8108d..ff07aa08194b 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ഒറ്റക്കൈ മോഡ്"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"കൂടുതൽ ഡിം ചെയ്യൽ"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"ശ്രവണ ഉപകരണങ്ങൾ"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"ഓട്ടോക്ലിക്ക്"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"വിച്‌ഛേദിച്ചു"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"കണക്റ്റ് ചെയ്‌തു"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"സജീവം"</string>
@@ -1825,7 +1824,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"ഹാൻഡ്‌സ്‌-ഫ്രീ ആയി കോൾ ചെയ്യാൻ നിങ്ങളുടെ ശ്രവണ സഹായി മൈക്രോഫോൺ ഉപയോഗിക്കാം. ഇത് കോൾ സമയത്ത് മാത്രം നിങ്ങളുടെ മൈക്ക് മാറ്റുന്നു."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"മാറുക"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"ക്രമീകരണം"</string>
- <string name="user_switched" msgid="7249833311585228097">"നിലവിലെ ഉപയോക്താവ് <xliff:g id="NAME">%1$s</xliff:g> ആണ്."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> എന്ന ഉപയോക്താവിലേക്ക് മാറുന്നു…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> ലോഗൌട്ട് ചെയ്യുന്നു…"</string>
<string name="owner_name" msgid="8713560351570795743">"ഉടമ"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 4c72a86dcc75..3a1e0a621508 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Та гараас хамаарахгүй дуудлагад сонсголын төхөөрөмжийнхөө микрофоныг ашиглаж болно. Энэ нь зөвхөн дуудлагын үеэр таны микрофоныг сэлгэнэ."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Сэлгэх"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Тохиргоо"</string>
- <string name="user_switched" msgid="7249833311585228097">"Одоогийн хэрэглэгч <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> руу сэлгэж байна…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g>-с гарч байна…"</string>
<string name="owner_name" msgid="8713560351570795743">"Өмчлөгч"</string>
@@ -2502,7 +2501,7 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Асаах"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Буцах"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Хүлээгдэж буй..."</string>
- <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Хиймэл дагуул SOS одоо боломжтой боллоо"</string>
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Хиймэл дагуулын SOS одоо боломжтой боллоо"</string>
<string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Та хөдөлгөөнт холбооны эсвэл Wi-Fi сүлжээ байхгүй бол яаралтай тусламжийн үйлчилгээ рүү мессеж бичих боломжтой. Google Мессеж таны өгөгдмөл мессеж апп байх ёстой."</string>
<string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Хиймэл дагуул SOS-г дэмждэггүй"</string>
<string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Хиймэл дагуул SOS-г энэ төхөөрөмж дээр дэмждэггүй"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index ea1e92baf387..d79dc6d96a3b 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -115,8 +115,8 @@
<string name="roamingText2" msgid="2834048284153110598">"रोमिंग दर्शक फ्लॅशिंग"</string>
<string name="roamingText3" msgid="831690234035748988">"अतिपरिचित क्षेत्राबाहेर"</string>
<string name="roamingText4" msgid="2171252529065590728">"इमारती बाहेर"</string>
- <string name="roamingText5" msgid="4294671587635796641">"रोमिंग - प्राधान्यीकृत सिस्टम"</string>
- <string name="roamingText6" msgid="5536156746637992029">"रोमिंग - उपलब्ध सिस्टम"</string>
+ <string name="roamingText5" msgid="4294671587635796641">"रोमिंग - प्राधान्य दिलेली सिस्टीम"</string>
+ <string name="roamingText6" msgid="5536156746637992029">"रोमिंग - उपलब्ध सिस्टीम"</string>
<string name="roamingText7" msgid="1783303085512907706">"रोमिंग - युती भागीदार"</string>
<string name="roamingText8" msgid="7774800704373721973">"रोमिंग - प्रीमियम भागीदार"</string>
<string name="roamingText9" msgid="1933460020190244004">"रोमिंग - पूर्ण सेवा कार्यक्षमता"</string>
@@ -242,7 +242,7 @@
<string name="silent_mode_silent" msgid="5079789070221150912">"रिंगर बंद"</string>
<string name="silent_mode_vibrate" msgid="8821830448369552678">"रिंगर व्हायब्रेट"</string>
<string name="silent_mode_ring" msgid="6039011004781526678">"रिंगर सुरू"</string>
- <string name="reboot_to_update_title" msgid="2125818841916373708">"Android सिस्टम अपडेट"</string>
+ <string name="reboot_to_update_title" msgid="2125818841916373708">"Android सिस्टीम अपडेट"</string>
<string name="reboot_to_update_prepare" msgid="6978842143587422365">"अपडेट करण्याची तयारी करत आहे…"</string>
<string name="reboot_to_update_package" msgid="4644104795527534811">"अपडेट पॅकेज प्रक्रिया करत आहे…"</string>
<string name="reboot_to_update_reboot" msgid="4474726009984452312">"रीस्टार्ट करत आहे..."</string>
@@ -274,7 +274,7 @@
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"परस्परसंवादी अहवाल"</string>
<string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"बहुतांश प्रसंगांमध्ये याचा वापर करा. ते तुम्हाला अहवालाच्या प्रगतीचा मागोवा घेण्याची, समस्येविषयी आणखी तपाशील एंटर करण्याची आणि स्क्रीनशॉट घेण्याची अनुमती देते. ते कदाचित अहवाल देण्यासाठी बराच वेळ घेणारे कमी-वापरलेले विभाग वगळू शकते."</string>
<string name="bugreport_option_full_title" msgid="7681035745950045690">"संपूर्ण अहवाल"</string>
- <string name="bugreport_option_full_summary" msgid="1975130009258435885">"तुमचे डिव्हाइस प्रतिसाद देत नाही किंवा खूप धीमे असते अथवा तुम्हाला सर्व अहवाल विभागांची आवश्यकता असते तेव्हा कमीतकमी सिस्टम हस्तक्षेपासाठी या पर्यायाचा वापर करा. तुम्हाला आणखी तपशील एंटर करण्याची किंवा अतिरिक्त स्क्रीनशॉट घेण्याची अनुमती देत नाही."</string>
+ <string name="bugreport_option_full_summary" msgid="1975130009258435885">"तुमचे डिव्हाइस प्रतिसाद देत नाही किंवा खूप धीमे असते अथवा तुम्हाला सर्व अहवाल विभागांची आवश्यकता असते तेव्हा कमीतकमी सिस्टीम हस्तक्षेपासाठी या पर्यायाचा वापर करा. तुम्हाला आणखी तपशील एंटर करण्याची किंवा अतिरिक्त स्क्रीनशॉट घेण्याची अनुमती देत नाही."</string>
<string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{बग रिपोर्टसाठी # सेकंदामध्ये स्क्रीनशॉट घेत आहे.}other{बग रिपोर्टसाठी # सेकंदांमध्ये स्क्रीनशॉट घेत आहे.}}"</string>
<string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"बग रिपोर्टसह घेतलेला स्क्रीनशॉट"</string>
<string name="bugreport_screenshot_failure_toast" msgid="6736320861311294294">"बग रिपोर्टसह स्क्रीनशॉट घेता आला नाही"</string>
@@ -374,7 +374,7 @@
<string name="dream_preview_title" msgid="5570751491996100804">"पूर्वावलोकन, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
<string name="dream_accessibility_action_click" msgid="7392398629967797805">"डिसमिस करा"</string>
<string name="permlab_statusBar" msgid="8798267849526214017">"स्टेटस बार अक्षम करा किंवा सुधारित करा"</string>
- <string name="permdesc_statusBar" msgid="5809162768651019642">"स्टेटस बार अक्षम करण्यासाठी किंवा सिस्टम चिन्हे जोडण्यासाठी आणि काढण्यासाठी अ‍ॅप ला अनुमती देते."</string>
+ <string name="permdesc_statusBar" msgid="5809162768651019642">"स्टेटस बार बंद करण्यासाठी किंवा सिस्टीम आयकन जोडण्यासाठी आणि काढण्यासाठी ॲपला परवानगी देते."</string>
<string name="permlab_statusBarService" msgid="2523421018081437981">"स्टेटस बार होऊ द्या"</string>
<string name="permdesc_statusBarService" msgid="6652917399085712557">"स्टेटस बार होण्यासाठी अ‍ॅप ला अनुमती देते."</string>
<string name="permlab_expandStatusBar" msgid="1184232794782141698">"स्‍टेटस बार विस्तृत करा/संकुचित करा"</string>
@@ -472,9 +472,9 @@
<string name="permlab_writeSettings" msgid="8057285063719277394">"सिस्टीम सेटिंग्ज सुधारित करा"</string>
<string name="permdesc_writeSettings" msgid="8293047411196067188">"सिस्टीमचा सेटिंग्ज डेटा सुधारित करण्यासाठी अ‍ॅपला अनुमती देते. दुर्भावनापूर्ण अ‍ॅप्स तुमच्या सिस्टीमचे कॉन्फिगरेशन दूषित करू शकतात."</string>
<string name="permlab_receiveBootCompleted" msgid="6643339400247325379">"सुरूवातीस चालवा"</string>
- <string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"जसे सिस्टम बूट करणे समाप्त करते तसे अ‍ॅप ला स्वतः सुरू करण्यास अनुमती देते. यामुळे टॅबलेट सुरू करण्यास वेळ लागू शकतो आणि नेहमी सुरू राहून एकंदर टॅबलेटला धीमे करण्यास अ‍ॅप ला अनुमती देते."</string>
- <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"सिस्टम बूट होणे संपल्यावर ॲपला स्वतः सुरू होण्याची अनुमती देते. यामुळे तुमच्या Android TV डिव्हाइसला सुरू होण्यास वेळ लागू शकतो आणि नेहमी सुरू राहून एकंदर डिव्हाइसलाच धीमे करण्याची अनुमती ॲपला देते."</string>
- <string name="permdesc_receiveBootCompleted" product="default" msgid="7912677044558690092">"जसे सिस्टम बूट करणे समाप्त करते तसे अ‍ॅप ला स्वतः सुरू करण्यास अनुमती देते. यामुळे फोन सुरू करण्यास वेळ लागू शकतो आणि नेहमी सुरू राहून एकंदर फोनला धीमे करण्यास अ‍ॅप ला अनुमती देते."</string>
+ <string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"जसे सिस्टीम बूट करणे समाप्त करते तसे ॲपला स्वतः सुरू करण्यास अनुमती देते. यामुळे टॅबलेट सुरू करण्यास वेळ लागू शकतो आणि नेहमी सुरू राहून एकंदर टॅबलेटला धीमे करण्यास ॲपला अनुमती देते."</string>
+ <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"सिस्टीम बूट होणे संपल्यावर ॲपला स्वतः सुरू होण्याची अनुमती देते. यामुळे तुमच्या Android TV डिव्हाइसला सुरू होण्यास वेळ लागू शकतो आणि नेहमी सुरू राहून एकंदर डिव्हाइसलाच धीमे करण्याची अनुमती ॲपला देते."</string>
+ <string name="permdesc_receiveBootCompleted" product="default" msgid="7912677044558690092">"जसे सिस्टीम बूट करणे समाप्त करते तसे ॲपला स्वतः सुरू करण्यास अनुमती देते. यामुळे फोन सुरू करण्यास वेळ लागू शकतो आणि नेहमी सुरू राहून एकंदर फोनला धीमे करण्यास ॲपला अनुमती देते."</string>
<string name="permlab_broadcastSticky" msgid="4552241916400572230">"रोचक प्रसारण पाठवा"</string>
<string name="permdesc_broadcastSticky" product="tablet" msgid="5058486069846384013">"रोचक प्रसारणे पाठविण्यासाठी अ‍ॅप ला अनुमती देते, जे प्रसारण समाप्त झाल्यानंतर देखील तसेच राहते. अत्याधिक वापरामुळे बरीच मेमरी वापरली जाऊन तो टॅब्लेटला धीमा किंवा अस्थिर करू शकतो."</string>
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"रोचक प्रसारणे पाठविण्यासाठी अ‍ॅपला अनुमती देते, जे प्रसारण समाप्त झाल्यानंतर देखील तसेच राहते. अत्याधिक वापरामुळे बरीच मेमरी वापरली जाऊन तो तुमच्या Android TV डिव्हाइसला धिमा किंवा अस्थिर करू शकतो."</string>
@@ -529,8 +529,8 @@
<string name="permdesc_camera" msgid="5240801376168647151">"ॲप वापरात असताना, हे ॲप कॅमेरा वापरून फोटो काढू शकते आणि व्हिडिओ रेकॉर्ड करू शकते."</string>
<string name="permlab_backgroundCamera" msgid="7549917926079731681">"बॅकग्राउंडमध्ये फोटो काढा आणि व्हिडिओ रेकॉर्ड करा"</string>
<string name="permdesc_backgroundCamera" msgid="1615291686191138250">"हे ॲप कॅमेरा वापरून कधीही फोटो काढू शकते आणि व्हिडिओ रेकॉर्ड करू शकते."</string>
- <string name="permlab_systemCamera" msgid="3642917457796210580">"फोटो आणि व्हिडिओ काढण्यासाठी ॲप्लिकेशन किंवा सेवेला सिस्टम कॅमेरे ॲक्सेस करण्याची अनुमती द्या"</string>
- <string name="permdesc_systemCamera" msgid="5938360914419175986">"हे विशेषाधिकृत किंवा सिस्टम ॲप कधीही सिस्टम कॅमेरा वापरून फोटो आणि व्हिडिओ रेकॉर्ड करू शकते. ॲपकडे android.permission.CAMERA परवानगी असण्याचीदेखील आवश्यकता आहे"</string>
+ <string name="permlab_systemCamera" msgid="3642917457796210580">"फोटो आणि व्हिडिओ काढण्यासाठी ॲप्लिकेशन किंवा सेवेला सिस्टीम कॅमेरे ॲक्सेस करण्याची अनुमती द्या"</string>
+ <string name="permdesc_systemCamera" msgid="5938360914419175986">"हे विशेष महत्त्वाचे किंवा सिस्टीम ॲप कधीही सिस्टीम कॅमेरा वापरून फोटो आणि व्हिडिओ रेकॉर्ड करू शकते. ॲपकडे android.permission.CAMERA परवानगी असण्याचीदेखील आवश्यकता आहे"</string>
<string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"एखाद्या अ‍ॅप्लिकेशन किंवा सेवेला कॅमेरा डिव्हाइस सुरू किंवा बंद केल्याची कॉलबॅक मिळवण्याची अनुमती द्या."</string>
<string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"कोणतेही कॅमेरा डिव्हाइस (कोणत्या अ‍ॅप्लिकेशनने) सुरू किंवा बंद केले जाते तेव्हा हे ॲप कॉलबॅक मिळवू शकते."</string>
<string name="permlab_cameraHeadlessSystemUser" msgid="680194666834500050">"अ‍ॅप्लिकेशन किंवा सेवेला हेडलेस सिस्टीम वापरकर्ता म्हणून कॅमेरा अ‍ॅक्सेस करण्याची अनुमती द्या."</string>
@@ -548,7 +548,7 @@
<string name="permdesc_readBasicPhoneState" msgid="828185691675460520">"यामुळे ॲपला डिव्हाइसची मूलभूत टेलिफोनी वैशिष्ट्ये अ‍ॅक्सेस करण्याची अनुमती मिळते."</string>
<string name="permlab_manageOwnCalls" msgid="9033349060307561370">"प्रणालीच्या माध्यमातून कॉल रूट करा"</string>
<string name="permdesc_manageOwnCalls" msgid="4431178362202142574">"कॉल करण्याचा अनुभव सुधारण्यासाठी ॲपला त्याचे कॉल प्रणालीच्या माध्यमातून रूट करू देते."</string>
- <string name="permlab_callCompanionApp" msgid="3654373653014126884">"सिस्टम वापरून कॉल पहा आणि नियंत्रण ठेवा."</string>
+ <string name="permlab_callCompanionApp" msgid="3654373653014126884">"सिस्टीम वापरून कॉल पहा आणि नियंत्रण ठेवा."</string>
<string name="permdesc_callCompanionApp" msgid="8474168926184156261">"डिव्हाइसवर येणार कॉल पाहण्यासाठी आणि नियंत्रित करण्यासाठी ॲपला अनुमती देते. यामध्ये कॉल करण्यासाठी कॉलचा नंबर आणि कॉलची स्थिती यासारख्या माहितीचा समावेश असतो."</string>
<string name="permlab_exemptFromAudioRecordRestrictions" msgid="1164725468350759486">"ऑडिओ रेकॉर्ड प्रतिबंधांपासून मुक्त"</string>
<string name="permdesc_exemptFromAudioRecordRestrictions" msgid="2425117015896871976">"ऑडिओ रेकॉर्ड करण्यासाठी प्रतिबंधांपासून ॲपला मुक्त करा."</string>
@@ -569,11 +569,11 @@
<string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"ॲपला Android TV डिव्हाइसचा इन्‍फ्रारेड ट्रान्‍समीटर वापरण्‍याची अनुमती देते."</string>
<string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"अ‍ॅप ला फोनच्‍या इन्‍फ्रारेड ट्रान्‍समीटरचा वापर करण्‍याची अनुमती देते."</string>
<string name="permlab_setWallpaper" msgid="6959514622698794511">"वॉलपेपर सेट करा"</string>
- <string name="permdesc_setWallpaper" msgid="2973996714129021397">"सिस्टम वॉलपेपर सेट करण्यासाठी अ‍ॅप ला अनुमती देते."</string>
+ <string name="permdesc_setWallpaper" msgid="2973996714129021397">"सिस्टीम वॉलपेपर सेट करण्यासाठी ॲपला परवानगी देते."</string>
<string name="permlab_accessHiddenProfile" msgid="8607094418491556823">"लपवलेल्या प्रोफाइल अ‍ॅक्सेस करा"</string>
<string name="permdesc_accessHiddenProfile" msgid="1543153202481009676">"अ‍ॅपला लपवलेल्या प्रोफाइल अ‍ॅक्सेस करण्याची अनुमती देते."</string>
<string name="permlab_setWallpaperHints" msgid="1153485176642032714">"तुमचा वॉलपेपर आकार समायोजित करा"</string>
- <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"सिस्टम वॉलपेपर आकार सूचना सेट करण्यासाठी अ‍ॅप ला अनुमती देते."</string>
+ <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"सिस्टीम वॉलपेपर आकार सूचना सेट करण्याची ॲपला परवानगी देते."</string>
<string name="permlab_setTimeZone" msgid="7922618798611542432">"टाइम झोन सेट करा"</string>
<string name="permdesc_setTimeZone" product="tablet" msgid="1788868809638682503">"टॅब्लेटचा टाइम झोन बदलण्यासाठी अ‍ॅप ला अनुमती देते."</string>
<string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"तुमच्या Android TV डिव्हाइसचा टाइम झोन बदलण्यासाठी ॲपला अनुमती देते."</string>
@@ -1241,7 +1241,7 @@
<string name="input_method_ime_switch_long_click_action_desc" msgid="3161942124116646998">"इनपुट पद्धत पिकर उघडा"</string>
<string name="input_method_switcher_settings_button" msgid="5609835654697108485">"सेटिंग्ज"</string>
<string name="low_internal_storage_view_title" msgid="9024241779284783414">"संचयन स्थान संपत आहे"</string>
- <string name="low_internal_storage_view_text" msgid="8172166728369697835">"काही सिस्टम कार्ये कार्य करू शकत नाहीत"</string>
+ <string name="low_internal_storage_view_text" msgid="8172166728369697835">"काही सिस्टीम फंक्शन कार्य करू शकत नाहीत"</string>
<string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"सिस्टीमसाठी पुरेसे संचयन नाही. आपल्याकडे 250MB मोकळे स्थान असल्याचे सुनिश्चित करा आणि रीस्टार्ट करा."</string>
<string name="app_running_notification_title" msgid="8985999749231486569">"<xliff:g id="APP_NAME">%1$s</xliff:g> चालत आहे"</string>
<string name="app_running_notification_text" msgid="5120815883400228566">"अधिक माहितीसाठी किंवा अ‍ॅप थांबविण्यासाठी टॅप करा."</string>
@@ -1287,7 +1287,7 @@
<string name="whichImageCaptureApplicationLabel" msgid="6505433734824988277">"इमेज कॅप्चर करा"</string>
<string name="alwaysUse" msgid="3153558199076112903">"या क्रियेसाठी डीफॉल्‍टनुसार वापरा."</string>
<string name="use_a_different_app" msgid="4987790276170972776">"एक भिन्न अ‍ॅप वापरा"</string>
- <string name="clearDefaultHintMsg" msgid="1325866337702524936">"डाउनलोड केलेल्या सिस्टम सेटिंग्ज &gt; Apps &gt; मधील डीफॉल्ट साफ करा."</string>
+ <string name="clearDefaultHintMsg" msgid="1325866337702524936">"डाउनलोड केलेल्या सिस्टीम सेटिंग्ज &gt; Apps &gt; मधील डीफॉल्ट साफ करा."</string>
<string name="chooseActivity" msgid="8563390197659779956">"क्रिया निवडा"</string>
<string name="chooseUsbActivity" msgid="2096269989990986612">"USB डिव्हाइससाठी अ‍ॅप निवडा"</string>
<string name="noApplications" msgid="1186909265235544019">"कोणतेही अ‍ॅप्स ही क्रिया करू शकत नाहीत."</string>
@@ -1315,7 +1315,7 @@
<string name="launch_warning_original" msgid="3332206576800169626">"<xliff:g id="APP_NAME">%1$s</xliff:g> मूळतः लाँच केले."</string>
<string name="screen_compat_mode_scale" msgid="8627359598437527726">"स्केल"</string>
<string name="screen_compat_mode_show" msgid="5080361367584709857">"नेहमी दर्शवा"</string>
- <string name="screen_compat_mode_hint" msgid="4032272159093750908">"सिस्टम सेटिंग्ज &gt; Apps &gt; डाउनलोड केलेले मध्ये हे पुन्हा-सुरू करा."</string>
+ <string name="screen_compat_mode_hint" msgid="4032272159093750908">"सिस्टीम सेटिंग्ज &gt; Apps &gt; डाउनलोड केलेले मध्ये हे पुन्हा-सुरू करा."</string>
<string name="unsupported_display_size_message" msgid="7265211375269394699">"<xliff:g id="APP_NAME">%1$s</xliff:g> वर्तमान डिस्प्ले आकार सेटिंगला समर्थन देत नाही आणि अनपेक्षित वर्तन करू शकते."</string>
<string name="unsupported_display_size_show" msgid="980129850974919375">"नेहमी दर्शवा"</string>
<string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"<xliff:g id="APP_NAME">%1$s</xliff:g> हे Android OS च्या विसंगत आवृत्तीसाठी तयार केले होते आणि ते अनपेक्षित पद्धतीने काम करू शकते. ॲपची अपडेट केलेली आवृत्ती उपलब्ध असू शकते."</string>
@@ -1330,7 +1330,7 @@
<string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android सुरू करत आहे…"</string>
<string name="android_start_title" product="tablet" msgid="4429767260263190344">"टॅबलेट सुरू होत आहे…"</string>
<string name="android_start_title" product="device" msgid="6967413819673299309">"डिव्‍हाइस सुरू होत आहे…"</string>
- <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"सिस्‍टम अपडेट संपत आहे…"</string>
+ <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"सिस्टीम अपडेट संपत आहे…"</string>
<string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> श्रेणीसुधारित करत आहे…"</string>
<string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> तयार करत आहे."</string>
<string name="android_upgrading_starting_apps" msgid="6206161195076057075">"अ‍ॅप्स सुरू करत आहे."</string>
@@ -1708,7 +1708,7 @@
<string name="default_audio_route_name_external_device" msgid="8124229858618975">"बाह्य डिव्हाइस"</string>
<string name="default_audio_route_name_headphones" msgid="6954070994792640762">"हेडफोन"</string>
<string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
- <string name="default_audio_route_category_name" msgid="5241740395748134483">"सिस्टम"</string>
+ <string name="default_audio_route_category_name" msgid="5241740395748134483">"सिस्टीम"</string>
<string name="bluetooth_a2dp_audio_route_name" msgid="4214648773120426288">"ब्लूटूथ ऑडिओ"</string>
<string name="wireless_display_route_description" msgid="8297563323032966831">"वायरलेस डिस्प्ले"</string>
<string name="media_route_button_content_description" msgid="2299223698196869956">"कास्‍ट करा"</string>
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"हँड्स-फ्री कॉलिंगसाठी तुम्ही तुमच्या श्रवणयंत्राचा मायक्रोफोन वापरू शकता. यामुळे कॉलदरम्यान फक्त तुमचा माइक स्विच केला जातो."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"स्विच करा"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"सेटिंग्ज"</string>
- <string name="user_switched" msgid="7249833311585228097">"वर्तमान वापरकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> वर स्विच करत आहे…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> लॉग आउट करत आहे…"</string>
<string name="owner_name" msgid="8713560351570795743">"मालक"</string>
@@ -2192,12 +2191,12 @@
<string name="screenshot_edit" msgid="7408934887203689207">"संपादित करा"</string>
<string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"कॉल आणि सूचनांवर व्हायब्रेट होईल"</string>
<string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"कॉल आणि सूचना म्यूट केल्या जातील"</string>
- <string name="notification_channel_system_changes" msgid="2462010596920209678">"सिस्टम बदल"</string>
+ <string name="notification_channel_system_changes" msgid="2462010596920209678">"सिस्टीम बदल"</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"सूचना सेटिंग्जचे पुनरावलोकन करा"</string>
<string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13 पासून, तुम्ही त्यामध्ये इंस्टॉल केलेल्या अ‍ॅप्सना सूचना पाठवण्यासाठी तुमच्या परवानगीची आवश्यकता आहे. सध्याच्या अ‍ॅप्ससाठी ही परवानगी बदलण्याकरिता टॅप करा."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"मला आठवण करून द्या"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"डिसमिस करा"</string>
- <string name="notification_app_name_system" msgid="3045196791746735601">"सिस्टम"</string>
+ <string name="notification_app_name_system" msgid="3045196791746735601">"सिस्टीम"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"सेटिंग्ज"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"कॅमेरा"</string>
<string name="notification_appops_microphone_active" msgid="581333393214739332">"मायक्रोफोन"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 43acbac72819..76d402796e6f 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Mod sebelah tangan"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Amat malap"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Peranti pendengaran"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Autoklik"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Diputuskan sambungan"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Disambungkan"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Aktif"</string>
@@ -1825,7 +1824,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Anda boleh menggunakan mikrofon alat bantu pendengaran anda untuk membuat panggilan bebas tangan. Tindakan ini hanya menukar mikrofon anda semasa panggilan."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Tukar"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Tetapan"</string>
- <string name="user_switched" msgid="7249833311585228097">"Pengguna semasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Beralih kepada <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Log keluar daripada <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Pemilik"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 2333539d415c..fc6df7ac899c 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"လက်လွတ်ခေါ်ဆိုခြင်းအတွက် နားကြားကိရိယာ၏ မိုက်ခရိုဖုန်းကို သုံးနိုင်သည်။ ခေါ်ဆိုနေစဉ်သာ သင့်မိုက်ကို ပြောင်းပေးသည်။"</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"ပြောင်းရန်"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"ဆက်တင်များ"</string>
- <string name="user_switched" msgid="7249833311585228097">"လက်ရှိအသုံးပြုနေသူ <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>သို့ ပြောင်းနေသည်…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g>ကို ထွက်ပစ်ပါတော့မည်..."</string>
<string name="owner_name" msgid="8713560351570795743">"ပိုင်ရှင်"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 3a337f603348..b8cc711fcf46 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Du kan bruke mikrofonen i høreapparatet til å ringe håndfritt. Dette fører bare til at mikrofonen byttes under samtalen."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Bytt"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Innstillinger"</string>
- <string name="user_switched" msgid="7249833311585228097">"Gjeldende bruker: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Bytter til <xliff:g id="NAME">%1$s</xliff:g> …"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Logger av <xliff:g id="NAME">%1$s</xliff:g> …"</string>
<string name="owner_name" msgid="8713560351570795743">"Eier"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index ce64589a4870..59071826720d 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"तपाईं ह्यान्ड्सफ्री तरिकाले कल गर्न आफ्नो श्रवण यन्त्रको माइक्रोफोन प्रयोग गर्न सक्नुहुन्छ। यसले कल भइरहेका बेला मात्र तपाईंको माइक बदल्छ।"</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"बदल्नुहोस्"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"सेटिङ"</string>
- <string name="user_switched" msgid="7249833311585228097">"अहिलेको प्रयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>।"</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> मा स्विच गरिँदै छ…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"लग आउट गर्दै <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"मालिक"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index f7b6cc87249b..98ce463186ba 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Je kunt de microfoon van je hoortoestel gebruiken om handsfree te bellen. Hiermee wordt de microfoon alleen gewisseld tijdens het gesprek."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Wisselen"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Instellingen"</string>
- <string name="user_switched" msgid="7249833311585228097">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Overschakelen naar <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> uitloggen…"</string>
<string name="owner_name" msgid="8713560351570795743">"Eigenaar"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index ef567e504e70..4931bd2e90bf 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ଏକ-ହାତ ମୋଡ୍"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ଅତ୍ୟଧିକ ଡିମ"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"ଶ୍ରବଣ ଡିଭାଇସଗୁଡ଼ିକ"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"ଅଟୋକ୍ଲିକ"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"ଡିସକନେକ୍ଟ କରାଯାଇଛି"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"କନେକ୍ଟ କରାଯାଇଛି"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"ସକ୍ରିୟ"</string>
@@ -1825,7 +1824,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"ହେଣ୍ଡସ-ଫ୍ରି କଲିଂ ପାଇଁ ଆପଣ ଆପଣଙ୍କର ଶ୍ରବଣ ଯନ୍ତ୍ର ମାଇକ୍ରୋଫୋନ ବ୍ୟବହାର କରିପାରିବେ। କଲ ସମୟରେ ଏହା କେବଳ ଆପଣଙ୍କର ମାଇକକୁ ସୁଇଚ କରିଥାଏ।"</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"ସୁଇଚ କରନ୍ତୁ"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"ସେଟିଂସ"</string>
- <string name="user_switched" msgid="7249833311585228097">"ବର୍ତ୍ତମାନର ୟୁଜର୍‌ ହେଉଛନ୍ତି <xliff:g id="NAME">%1$s</xliff:g>।"</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>ରେ ସୁଇଚ ହେଉଛି…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g>ଙ୍କୁ ଲଗଆଉଟ୍‍ କରାଯାଉଛି…"</string>
<string name="owner_name" msgid="8713560351570795743">"ମାଲିକ"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 7f06227ba147..80ed484e2523 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ਇੱਕ ਹੱਥ ਮੋਡ"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ਜ਼ਿਆਦਾ ਘੱਟ ਚਮਕ"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"ਸੁਣਨ ਵਾਲੇ ਡੀਵਾਈਸ"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"ਸਵੈ-ਕਲਿੱਕ"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"ਡਿਸਕਨੈਕਟ ਹੋ ਗਿਆ"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"ਕਨੈਕਟ ਹੈ"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"ਕਿਰਿਆਸ਼ੀਲ"</string>
@@ -1825,7 +1824,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"ਤੁਸੀਂ ਹੱਥ-ਰਹਿਤ ਕਾਲਿੰਗ ਲਈ ਆਪਣੇ ਸੁਣਨ ਦੇ ਸਾਧਨ ਦੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਦੀ ਵਰਤੋਂ ਕਰ ਸਕਦੇ ਹੋ। ਇਹ ਸਿਰਫ਼ ਕਾਲ ਦੌਰਾਨ ਹੀ ਤੁਹਾਡੇ ਮਾਈਕ ਨੂੰ ਸਵਿੱਚ ਕਰਦਾ ਹੈ।"</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"ਸਵਿੱਚ ਕਰੋ"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"ਸੈਟਿੰਗਾਂ"</string>
- <string name="user_switched" msgid="7249833311585228097">"ਮੌਜੂਦਾ ਉਪਭੋਗਤਾ <xliff:g id="NAME">%1$s</xliff:g>।"</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> \'ਤੇ ਸਵਿੱਚ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> ਨੂੰ ਲਾਗ-ਆਉਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ …"</string>
<string name="owner_name" msgid="8713560351570795743">"ਮਾਲਕ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 73e4d24ac241..efae947b3793 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1715,7 +1715,7 @@
<string name="wireless_display_route_description" msgid="8297563323032966831">"Wyświetlacz bezprzewodowy"</string>
<string name="media_route_button_content_description" msgid="2299223698196869956">"Przesyłaj"</string>
<string name="media_route_chooser_title" msgid="6646594924991269208">"Połącz z urządzeniem"</string>
- <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Prześlij ekran na urządzenie"</string>
+ <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Prześlij treści z ekranu na urządzenie"</string>
<string name="media_route_chooser_searching" msgid="6119673534251329535">"Szukam urządzeń…"</string>
<string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"Ustawienia"</string>
<string name="media_route_controller_disconnect" msgid="7362617572732576959">"Rozłącz"</string>
@@ -1827,7 +1827,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Możesz używać mikrofonu w aparacie słuchowym, aby dzwonić bez użycia rąk. Mikrofon zostanie przełączony tylko na czas połączenia."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Przełącz"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Ustawienia"</string>
- <string name="user_switched" msgid="7249833311585228097">"Bieżący użytkownik: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Przełączam na użytkownika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Wylogowuję użytkownika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Właściciel"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index f15ab35d54f0..4036d636ae5c 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1826,7 +1826,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Você pode usar o microfone do aparelho auditivo para fazer ligações sem usar as mãos. A troca do microfone só será feita durante a ligação."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Trocar"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Configurações"</string>
- <string name="user_switched" msgid="7249833311585228097">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Mudando para <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Desconectando <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Proprietário"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index e80b780c34cc..df3f9c6e2b63 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1714,7 +1714,7 @@
<string name="wireless_display_route_description" msgid="8297563323032966831">"Visualização sem fios"</string>
<string name="media_route_button_content_description" msgid="2299223698196869956">"Transmitir"</string>
<string name="media_route_chooser_title" msgid="6646594924991269208">"Ligar ao dispositivo"</string>
- <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Transmitir ecrã para dispositivo"</string>
+ <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Transmita o ecrã para o dispositivo"</string>
<string name="media_route_chooser_searching" msgid="6119673534251329535">"A pesquisar dispositivos…"</string>
<string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"Definições"</string>
<string name="media_route_controller_disconnect" msgid="7362617572732576959">"Desligar"</string>
@@ -1826,7 +1826,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Pode usar o microfone do aparelho auditivo para chamadas mãos-livres. Esta ação apenas muda o microfone durante a chamada."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Mudar"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Definições"</string>
- <string name="user_switched" msgid="7249833311585228097">"<xliff:g id="NAME">%1$s</xliff:g> do utilizador atual."</string>
<string name="user_switching_message" msgid="1912993630661332336">"A mudar para <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"A terminar a sessão de <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Proprietário"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index f15ab35d54f0..4036d636ae5c 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1826,7 +1826,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Você pode usar o microfone do aparelho auditivo para fazer ligações sem usar as mãos. A troca do microfone só será feita durante a ligação."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Trocar"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Configurações"</string>
- <string name="user_switched" msgid="7249833311585228097">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Mudando para <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Desconectando <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Proprietário"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index f02923b611d0..b12af3960d65 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1826,8 +1826,7 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Poți folosi microfonul aparatului auditiv pentru apelarea hands-free. Astfel, microfonul pornește numai în timpul apelului."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Schimbă"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Setări"</string>
- <string name="user_switched" msgid="7249833311585228097">"Utilizator curent: <xliff:g id="NAME">%1$s</xliff:g>."</string>
- <string name="user_switching_message" msgid="1912993630661332336">"Se comută la <xliff:g id="NAME">%1$s</xliff:g>…"</string>
+ <string name="user_switching_message" msgid="1912993630661332336">"Se trece la <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Se deconectează utilizatorul <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Proprietar"</string>
<string name="guest_name" msgid="8502103277839834324">"Invitat"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index e32ec412c4fd..4911fc60d23e 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1827,7 +1827,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Вы можете использовать микрофон слухового аппарата, когда разговариваете по телефону. Микрофон будет переключен только на время звонка."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Переключиться"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Настройки"</string>
- <string name="user_switched" msgid="7249833311585228097">"Выбран аккаунт пользователя <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Смена профиля на \"<xliff:g id="NAME">%1$s</xliff:g>\"…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Выход из аккаунта <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Владелец"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 35251bcd2536..b11e442bfeb8 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1713,7 +1713,7 @@
<string name="wireless_display_route_description" msgid="8297563323032966831">"නොරැහැන් සංදර්ශකය"</string>
<string name="media_route_button_content_description" msgid="2299223698196869956">"Cast"</string>
<string name="media_route_chooser_title" msgid="6646594924991269208">"උපාංගයට සම්බන්ධ වන්න"</string>
- <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"තිරය උපාංගයට යොමු කරන්න"</string>
+ <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"තිරය උපාංගයට විකාශය කරන්න"</string>
<string name="media_route_chooser_searching" msgid="6119673534251329535">"උපාංග සඳහා සොයමින්…"</string>
<string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"සැකසීම්"</string>
<string name="media_route_controller_disconnect" msgid="7362617572732576959">"විසන්ධි කරන්න"</string>
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"දෑත් නොයොදන ඇමතුම් සඳහා ඔබට ඔබේ ශ්‍රවණාධාර මයික්‍රෆෝනය භාවිතා කළ හැක. මෙය ඇමතුම අතරතුර පමණක් ඔබේ මයික්‍රෆෝනය මාරු කරයි."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"මාරු කරන්න"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"සැකසීම්"</string>
- <string name="user_switched" msgid="7249833311585228097">"දැනට සිටින පරිශීලකයා <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> වෙත මාරු කරමින්…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> වරමින්…"</string>
<string name="owner_name" msgid="8713560351570795743">"හිමිකරු"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 391b0d76a104..47bee0ad1bc9 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1827,7 +1827,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Volať handsfree môžete pomocou mikrofónu načúvadla. Týmto iba prepnete mikrofón počas hovoru."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Prepnúť"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Nastavenia"</string>
- <string name="user_switched" msgid="7249833311585228097">"Aktuálny používateľ je <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Prepína sa na účet <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Prebieha odhlásenie používateľa <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Vlastník"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index c84fd1762e6f..208c17463ce4 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1827,7 +1827,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Mikrofon za slušni aparat lahko uporabljate za prostoročno klicanje. S tem preklopite mikrofon samo med klicem."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Preklopi"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Nastavitve"</string>
- <string name="user_switched" msgid="7249833311585228097">"Trenutni uporabnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Preklapljanje na uporabnika <xliff:g id="NAME">%1$s</xliff:g> …"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Odjavljanje uporabnika <xliff:g id="NAME">%1$s</xliff:g> …"</string>
<string name="owner_name" msgid="8713560351570795743">"Lastnik"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 25d51a358278..5f8490882bec 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -653,18 +653,18 @@
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lexo vendndodhjet nga koleksioni yt i medias"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Lejon aplikacionin të lexojë vendndodhjet nga koleksioni yt i medias."</string>
<string name="permlab_eye_tracking_coarse" msgid="7989596289790269059">"të gjurmojë vështrimin e përafërt të syve"</string>
- <string name="permdesc_eye_tracking_coarse" msgid="870510233930553355">"Lejon që aplikacioni të gjurmojë vështrimin e përafërt të syve"</string>
+ <string name="permdesc_eye_tracking_coarse" msgid="870510233930553355">"Lejon që aplikacioni të gjurmojë vështrimin e përafërt të syve."</string>
<string name="permlab_eye_tracking_fine" msgid="6914457357027049512">"të gjurmojë se ku po shikon ti"</string>
<string name="permdesc_eye_tracking_fine" msgid="5788889152304524730">"Lejon që aplikacioni të qaset në të dhënat e vështrimit të saktë të syve."</string>
<string name="permlab_face_tracking" msgid="2272048395128283324">"të gjurmojë fytyrën tënde"</string>
- <string name="permdesc_face_tracking" msgid="2622783922311211866">"Lejo që aplikacioni të qaset në të dhënat e gjurmimit të fytyrës."</string>
+ <string name="permdesc_face_tracking" msgid="2622783922311211866">"Lejon që aplikacioni të qaset në të dhënat e gjurmimit të fytyrës."</string>
<string name="permlab_hand_tracking" msgid="6478233866595566940">"të gjurmojë duart e tua"</string>
<string name="permdesc_hand_tracking" msgid="8639715900104966456">"Lejon që aplikacioni të qaset në të dhënat e gjurmimit të duarve."</string>
<string name="permlab_head_tracking" msgid="1309731456372087270">"të gjurmojë kokën tënde"</string>
- <string name="permdesc_head_tracking" msgid="231597390513699188">"Lejo që aplikacioni të qaset në të dhënat e gjurmimit të kokës."</string>
+ <string name="permdesc_head_tracking" msgid="231597390513699188">"Lejon që aplikacioni të qaset në të dhënat e gjurmimit të kokës."</string>
<string name="permlab_scene_understanding_coarse" msgid="6518646430502858641">"të kuptojë mjedisin tënd"</string>
<string name="permdesc_scene_understanding_coarse" msgid="4508880777646198656">"Lejon që aplikacioni të qaset në të dhënat e gjurmimit për mjedisin drejtpërdrejt rreth teje."</string>
- <string name="permlab_scene_understanding_fine" msgid="409126403264393251">"të kuptojë mjedisin tënd të drejtpërdrejtë me nivel të lartë të detajeve"</string>
+ <string name="permlab_scene_understanding_fine" msgid="409126403264393251">"të kuptojë mjedisin drejtpërdrejtë rreth teje me nivel të lartë të detajeve"</string>
<string name="permdesc_scene_understanding_fine" msgid="6223368011593524179">"Lejon që aplikacioni të qaset në të dhënat e gjurmimit për mjedisin drejtpërdrejt rreth teje me nivel shumë të lartë të detajeve."</string>
<string name="permlab_xr_tracking_in_background" msgid="7117098718465619023">"të qaset në të dhënat për XR kur nuk është në plan të parë"</string>
<string name="permdesc_xr_tracking_in_background" msgid="939504041387836853">"Lejon që aplikacioni të qaset në të dhënat për XR kur nuk është në plan të parë."</string>
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Mund ta përdorësh mikrofonin e aparatit të dëgjimit për telefonata pa përdorur duart. Kjo vetëm ndërron mikrofonin gjatë telefonatës."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Ndërro"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Cilësimet"</string>
- <string name="user_switched" msgid="7249833311585228097">"Emri i përdoruesit aktual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_switching_message" msgid="1912993630661332336">"Po kalon në \"<xliff:g id="NAME">%1$s</xliff:g>\"…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> po del…"</string>
<string name="owner_name" msgid="8713560351570795743">"Zotëruesi"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 77ceff214d60..61102d3bb076 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1804,8 +1804,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Режим једном руком"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Додатно затамни"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Слушни апарати"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"Аутоматски клик"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"Веза је прекинута"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"Повезано"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"Активно"</string>
@@ -1826,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Можете да користите микрофон слушног апарата за хендсфри позивање. Тиме се микрофон мења само током позива."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Промени"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Подешавања"</string>
- <string name="user_switched" msgid="7249833311585228097">"Актуелни корисник <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Пребацивање на <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Одјављује се <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Власник"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 1ee2564ea4f6..d5fc6948aa6f 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -661,7 +661,7 @@
<string name="permlab_hand_tracking" msgid="6478233866595566940">"spåra dina händer"</string>
<string name="permdesc_hand_tracking" msgid="8639715900104966456">"Tillåter att appen får åtkomst till data om handspårning."</string>
<string name="permlab_head_tracking" msgid="1309731456372087270">"spåra ditt huvud"</string>
- <string name="permdesc_head_tracking" msgid="231597390513699188">"Tillåter att appen får åtkomst till data om huvudföljning."</string>
+ <string name="permdesc_head_tracking" msgid="231597390513699188">"Tillåter att appen får åtkomst till data om huvudspårning."</string>
<string name="permlab_scene_understanding_coarse" msgid="6518646430502858641">"förstå din omgivning"</string>
<string name="permdesc_scene_understanding_coarse" msgid="4508880777646198656">"Tillåter att appen får åtkomst till spårningsdata om omgivningen runtomkring dig."</string>
<string name="permlab_scene_understanding_fine" msgid="409126403264393251">"förstå din omgivning i detalj"</string>
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Du kan använda hörapparatens mikrofon för handsfree-samtal. Detta byter bara mikrofon under samtalet."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Byt"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Inställningar"</string>
- <string name="user_switched" msgid="7249833311585228097">"Nuvarande användare: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Byter till <xliff:g id="NAME">%1$s</xliff:g> …"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Loggar ut <xliff:g id="NAME">%1$s</xliff:g> …"</string>
<string name="owner_name" msgid="8713560351570795743">"Ägare"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 36bf76dc7eb6..49e9f1cd64d5 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Unaweza kutumia maikrofoni ya visaidizi vyako vya kusikia ili kupiga simu bila kugusa. Hali hii hubadilisha maikrofoni yako tu wakati unapiga simu."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Badilisha"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Mipangilio"</string>
- <string name="user_switched" msgid="7249833311585228097">"Mtumiaji wa sasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Inaenda kwa <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Inamwondoa <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Mmiliki"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 3fa382783be1..dad40dc8f4c9 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"கைகளைப் பயன்படுத்தாமல் அழைக்க உங்கள் செவித்துணைக் கருவியின் மைக்ரோஃபோனைப் பயன்படுத்தலாம். அழைப்பின்போது உங்கள் மைக்கை மட்டுமே இது மாற்றுகிறது."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"மாற்று"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"அமைப்புகள்"</string>
- <string name="user_switched" msgid="7249833311585228097">"நடப்பு பயனர் <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>க்கு மாறுகிறது…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> வெளியேறுகிறார்…"</string>
<string name="owner_name" msgid="8713560351570795743">"உரிமையாளர்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 027161e986fc..322a703ccdbe 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"హ్యాండ్స్-ఫ్రీ కాలింగ్ కోసం మీరు మీ వినికిడి పరికరాన్ని ఉపయోగించవచ్చు. ఇది కాల్ సమయంలో మాత్రమే మీ మైక్‌ను మారుస్తుంది."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"మారండి"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"సెట్టింగ్‌లు"</string>
- <string name="user_switched" msgid="7249833311585228097">"ప్రస్తుత వినియోగదారు <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> యూజర్‌కు స్విచ్ అవుతోంది…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g>ని లాగ్ అవుట్ చేస్తోంది…"</string>
<string name="owner_name" msgid="8713560351570795743">"ఓనర్"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index f82adc6a4f64..107a59fb2829 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"โหมดมือเดียว"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"หรี่แสงเพิ่มเติม"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"เครื่องช่วยฟัง"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"การคลิกอัตโนมัติ"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"เลิกเชื่อมต่อแล้ว"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"เชื่อมต่อแล้ว"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"ใช้งานอยู่"</string>
@@ -1825,7 +1824,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"คุณใช้ไมโครโฟนของเครื่องช่วยฟังเพื่อโทรแบบแฮนด์ฟรีได้ การดำเนินการนี้เพียงแค่เปลี่ยนไมโครโฟนระหว่างการโทรเท่านั้น"</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"เปลี่ยน"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"การตั้งค่า"</string>
- <string name="user_switched" msgid="7249833311585228097">"ผู้ใช้ปัจจุบัน <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_switching_message" msgid="1912993630661332336">"กำลังเปลี่ยนเป็น<xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"กำลังออกจากระบบ <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"เจ้าของ"</string>
@@ -2281,7 +2279,7 @@
<string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"การสนทนา"</string>
<string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"บทสนทนากลุ่ม"</string>
<string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string>
- <string name="resolver_personal_tab" msgid="2051260504014442073">"ส่วนบุคคล"</string>
+ <string name="resolver_personal_tab" msgid="2051260504014442073">"ส่วนตัว"</string>
<string name="resolver_work_tab" msgid="2690019516263167035">"งาน"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"มุมมองส่วนตัว"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"ดูงาน"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 328997d33382..97883270cda7 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Puwede mong gamitin ang mikropono ng iyong hearing aid para sa hands-free na pagtawag. Inililipat lang nito ang iyong mikropono habang nasa tawag ka."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Lumipat"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Mga Setting"</string>
- <string name="user_switched" msgid="7249833311585228097">"Kasalukuyang user <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Lumilipat kay <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Nila-log out si <xliff:g id="NAME">%1$s</xliff:g>..."</string>
<string name="owner_name" msgid="8713560351570795743">"May-ari"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 5106e1a6545d..095a3da72ae1 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Eller serbest modunda arama yapmak için işitme cihazı mikrofonunu kullanabilirsiniz. Bu işlem yalnızca görüşme sırasında mikrofonunuzu değiştirir."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Geçiş yap"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Ayarlar"</string>
- <string name="user_switched" msgid="7249833311585228097">"Geçerli kullanıcı: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> adlı kullanıcıya geçiliyor…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> hesabından çıkış yapılıyor…"</string>
<string name="owner_name" msgid="8713560351570795743">"Sahip"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 203cdfac5c1d..bc05f49e0e6f 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1827,7 +1827,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Ви можете використовувати мікрофон слухового апарата для голосового керування викликами. Мікрофон перемикатиметься лише на час дзвінка."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Перемкнути"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Налаштування"</string>
- <string name="user_switched" msgid="7249833311585228097">"Поточний користувач: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Перехід в обліковий запис \"<xliff:g id="NAME">%1$s</xliff:g>\"…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Вихід з облікового запису користувача <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Власник"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 376efd1f0bd6..7794c9af1f1f 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"آپ ہینڈز فری کالنگ کے لیے اپنا سماعتی آلہ مائیکروفون استعمال کر سکتے ہیں۔ یہ صرف کال کے دوران آپ کا مائیک سوئچ کرتا ہے۔"</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"سوئچ کریں"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"ترتیبات"</string>
- <string name="user_switched" msgid="7249833311585228097">"موجودہ صارف <xliff:g id="NAME">%1$s</xliff:g>۔"</string>
<string name="user_switching_message" msgid="1912993630661332336">"‫<xliff:g id="NAME">%1$s</xliff:g> پر سوئچ کیا جا رہا ہے…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> لاگ آؤٹ ہو رہا ہے…"</string>
<string name="owner_name" msgid="8713560351570795743">"مالک"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index a1b9e5d0a754..95a44bbd5c3d 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Garniturali chaqiruv uchun eshitish moslamasi mikrofonidan foydalanish mumkin. Bu faqat chaqiruv paytida mikrofonni almashtiradi."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Almashtirish"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Sozlamalar"</string>
- <string name="user_switched" msgid="7249833311585228097">"Joriy foydalanuvchi <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Bunga almashilmoqda: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> hisobidan chiqilmoqda…"</string>
<string name="owner_name" msgid="8713560351570795743">"Egasi"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 473568de3e31..bb9b797e9ec2 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Bạn có thể sử dụng micrô của thiết bị trợ thính để gọi điện mà không cần dùng tay. Thao tác này chỉ chuyển micrô của bạn trong cuộc gọi."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Chuyển"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Cài đặt"</string>
- <string name="user_switched" msgid="7249833311585228097">"Người dùng hiện tại <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Đang chuyển sang <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Đang đăng xuất <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Chủ sở hữu"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index f91f457b85cc..108d62eb072c 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"您可以使用助听器麦克风进行免提通话。此操作只会切换通话期间的麦克风。"</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"切换"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"设置"</string>
- <string name="user_switched" msgid="7249833311585228097">"当前用户是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
<string name="user_switching_message" msgid="1912993630661332336">"正在切换为<xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"正在将<xliff:g id="NAME">%1$s</xliff:g>退出账号…"</string>
<string name="owner_name" msgid="8713560351570795743">"机主"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 9bcb1730d63f..fc9e6e8e506d 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"你可使用助聽器麥克風進行免提通話。此操作只會切換通話期間的麥克風。"</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"切換"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"設定"</string>
- <string name="user_switched" msgid="7249833311585228097">"目前的使用者是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
<string name="user_switching_message" msgid="1912993630661332336">"正在切換至<xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"正在登出 <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"擁有者"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 9f8fd6713097..d2ca941d7dd2 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"免持通話時,可以使用助聽器麥克風。麥克風只會在通話期間切換。"</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"切換"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"設定"</string>
- <string name="user_switched" msgid="7249833311585228097">"目前的使用者是 <xliff:g id="NAME">%1$s</xliff:g>。"</string>
<string name="user_switching_message" msgid="1912993630661332336">"正在切換至<xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"正在將<xliff:g id="NAME">%1$s</xliff:g>登出帳戶…"</string>
<string name="owner_name" msgid="8713560351570795743">"擁有者"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index a0df4a1cbc0b..e11683200d30 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1825,7 +1825,6 @@
<string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Ungasebenzisa imakrofoni yakho yomshini wendlebe ekufoneni ngehands-free. Lokhu kushintsha kuphela imakrofoni yakho ngesikhathi sekholi."</string>
<string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Shintsha"</string>
<string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Amasethingi"</string>
- <string name="user_switched" msgid="7249833311585228097">"Umsebenzisi wamanje <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Ishintshela ku-<xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Iyaphuma <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Umnikazi"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 1cb38bed1388..fbb8e25eeced 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3072,6 +3072,43 @@
{@link MotionEvent#ACTION_SCROLL} event. -->
<dimen name="config_scrollFactor">64dp</dimen>
+ <!-- Duration in milliseconds of the pressed state in child components. -->
+ <integer name="config_pressedStateDurationMillis">64</integer>
+
+ <!-- Duration in milliseconds we will wait to see if a touch event is a tap or a scroll.
+ If the user does not move within this interval, it is considered to be a tap. -->
+ <integer name="config_tapTimeoutMillis">100</integer>
+
+ <!-- Duration in milliseconds we will wait to see if a touch event is a jump tap.
+ If the user does not move within this interval, it is considered to be a tap. -->
+ <integer name="config_jumpTapTimeoutMillis">500</integer>
+
+ <!-- Duration in milliseconds between the first tap's up event and the second tap's down
+ event for an interaction to be considered a double-tap. -->
+ <integer name="config_doubleTapTimeoutMillis">300</integer>
+
+ <!-- Minimum duration in milliseconds between the first tap's up event and the second tap's
+ down event for an interaction to be considered a double-tap. -->
+ <integer name="config_doubleTapMinTimeMillis">40</integer>
+
+ <!-- Maximum duration in milliseconds between a touch pad touch and release for a given touch
+ to be considered a tap (click) as opposed to a hover movement gesture. -->
+ <integer name="config_hoverTapTimeoutMillis">150</integer>
+
+ <!-- The amount of time in milliseconds that the zoom controls should be displayed on the
+ screen. -->
+ <integer name="config_zoomControlsTimeoutMillis">3000</integer>
+
+ <!-- Default duration in milliseconds for {@link ActionMode#hide(long)}. -->
+ <integer name="config_defaultActionModeHideDurationMillis">2000</integer>
+
+ <!-- Maximum distance in pixels that a touch pad touch can move before being released
+ for it to be considered a tap (click) as opposed to a hover movement gesture. -->
+ <dimen name="config_hoverTapSlop">20px</dimen>
+
+ <!-- The amount of friction applied to scrolls and flings. -->
+ <item name="config_scrollFriction" format="float" type="dimen">0.015</item>
+
<!-- Maximum number of grid columns permitted in the ResolverActivity
used for picking activities to handle an intent. -->
<integer name="config_maxResolverActivityColumns">3</integer>
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index 59ed25a1865f..6245a53b02f5 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -524,4 +524,9 @@
capabilities. -->
<string-array name="config_unsupported_network_capabilities" translatable="false"></string-array>
<java-symbol type="array" name="config_unsupported_network_capabilities" />
+
+ <!-- Whether to enable APDU sender optimization i.e. a logical channel is opened and
+ kept open for multiple APDU commands within one session.-->
+ <bool name="euicc_optimize_apdu_sender">false</bool>
+ <java-symbol type="bool" name="euicc_optimize_apdu_sender" />
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index cb3dfc70d135..b3cc8837e0bf 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -5412,7 +5412,7 @@
<!-- Notification shown when device owner silently installs a package [CHAR LIMIT=NONE] -->
<string name="package_installed_device_owner">Installed by your admin.\nGo to settings to view granted permissions</string>
<!-- Notification shown when device owner silently updates a package [CHAR LIMIT=NONE] -->
- <string name="package_updated_device_owner">Updated by your admin</string>
+ <string name="package_updated_device_owner">Updated by your admin.\nGo to settings to view granted permissions</string>
<!-- Notification shown when device owner silently deletes a package [CHAR LIMIT=NONE] -->
<string name="package_deleted_device_owner">Deleted by your admin</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index a18c1d4df98b..f5424dbed21a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4159,6 +4159,17 @@
<java-symbol type="string" name="config_headlineFontFamily" />
<java-symbol type="string" name="config_headlineFontFamilyMedium" />
+ <java-symbol type="integer" name="config_pressedStateDurationMillis" />
+ <java-symbol type="integer" name="config_tapTimeoutMillis" />
+ <java-symbol type="integer" name="config_jumpTapTimeoutMillis" />
+ <java-symbol type="integer" name="config_doubleTapTimeoutMillis" />
+ <java-symbol type="integer" name="config_doubleTapMinTimeMillis" />
+ <java-symbol type="integer" name="config_hoverTapTimeoutMillis" />
+ <java-symbol type="integer" name="config_zoomControlsTimeoutMillis" />
+ <java-symbol type="integer" name="config_defaultActionModeHideDurationMillis" />
+ <java-symbol type="dimen" name="config_hoverTapSlop" />
+ <java-symbol type="dimen" name="config_scrollFriction" />
+
<java-symbol type="drawable" name="stat_sys_vitals" />
<java-symbol type="color" name="text_color_primary" />
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
index 7cb6f87dc97f..4ee7d7ee92bb 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Levi ekran 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Levi ekran 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Režim celog ekrana za donji ekran"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Zamenite gornju aplikaciju donjom"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Zamenite levu aplikaciju desnom"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Režim celog ekrana za gornji ekran"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Gornji ekran 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Gornji ekran 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Restartuj"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ne prikazuj ponovo"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Dvaput dodirnite da biste\npremestili ovu aplikaciju"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Uvećajte: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Vratite: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Umanjite: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Zatvorite: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Nazad"</string>
<string name="handle_text" msgid="4419667835599523257">"Identifikator aplikacije"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Promenite veličinu prozora nalevo"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Promenite veličinu prozora nadesno"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Uvećajte ili vratite veličinu prozora"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Uvećajte veličinu prozora aplikacije"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Vratite veličinu prozora"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Umanjite prozor aplikacije"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Zatvorite prozor aplikacije"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Podešavanje Podrazumevano otvaraj"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Odaberite način otvaranja veb-linkova za ovu aplikaciju"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"U aplikaciji"</string>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index ebfdc6d0a780..1d5d3855bd23 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -142,7 +142,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Cerrar menú"</string>
<string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (vista para computadoras de escritorio)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar pantalla"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Cambiar el tamaño"</string>
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Dividir pantalla"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"No se puede mover la app aquí"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Inmersivo"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restablecer"</string>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index 85f0f8c2c4d2..a2787a7e7b91 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Schermata sinistra al 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Schermata sinistra al 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Schermata destra a schermo intero"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Scambia l\'app in alto con quella in basso"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Scambia l\'app di sinistra con quella di destra"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Schermata superiore a schermo intero"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Schermata superiore al 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Schermata superiore al 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Riavvia"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Non mostrare più"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Tocca due volte per\nspostare questa app"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Ingrandisci <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Ripristina <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Riduci a icona <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Chiudi <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Indietro"</string>
<string name="handle_text" msgid="4419667835599523257">"Punto di manipolazione app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icona dell\'app"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Ridimensiona la finestra a sinistra"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Ridimensiona la finestra a destra"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Ingrandisci o ripristina le dimensioni della finestra"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Ingrandisci le dimensioni della finestra dell\'app"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Ripristina le dimensioni della finestra"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Riduci a icona la finestra dell\'app"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Chiudi finestra dell\'app"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Apri in base alle impostazioni predefinite"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Scegli come aprire i link web per questa app"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"All\'interno dell\'app"</string>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index 3a12680395c6..d68581bda1ff 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"左 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"左 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"右全画面"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"上下のアプリを入れ替える"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"左右のアプリを入れ替える"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"上部全画面"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"上 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"上 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"再起動"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"次回から表示しない"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"ダブルタップすると\nこのアプリを移動できます"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」を最大化する"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」を元に戻す"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」を最小化する"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」を閉じる"</string>
<string name="back_button_text" msgid="1469718707134137085">"戻る"</string>
<string name="handle_text" msgid="4419667835599523257">"アプリハンドル"</string>
<string name="app_icon_text" msgid="2823268023931811747">"アプリのアイコン"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ウィンドウを左側にサイズ変更する"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"ウィンドウを右側にサイズ変更する"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"ウィンドウを最大化する、またはウィンドウを元のサイズに戻す"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"アプリ ウィンドウを最大化する"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"ウィンドウを元のサイズに戻す"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"アプリ ウィンドウを最小化する"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"アプリ ウィンドウを閉じる"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"デフォルトの設定で開く"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"このアプリのウェブリンクを開く方法を選択"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"アプリ内"</string>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index c48cbce331c4..cb84dec8a254 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ഇടത് 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ഇടത് 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"വലത് പൂർണ്ണ സ്ക്രീൻ"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"മുകളിലെയും താഴത്തെയും ആപ്പ് സ്വാപ്പ് ചെയ്യുക"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"ഇടതുവശത്തെയും വലതുവശത്തെയും ആപ്പ് സ്വാപ്പ് ചെയ്യുക"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"മുകളിൽ പൂർണ്ണ സ്ക്രീൻ"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"മുകളിൽ 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"മുകളിൽ 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"റീസ്റ്റാർട്ട് ചെയ്യൂ"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"വീണ്ടും കാണിക്കരുത്"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"ഈ ആപ്പ് നീക്കാൻ\nഡബിൾ ടാപ്പ് ചെയ്യുക"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g> പരമാവധിയാക്കുക"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g> പുനഃസ്ഥാപിക്കുക"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g> ചുരുക്കുക"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g> അടയ്ക്കുക"</string>
<string name="back_button_text" msgid="1469718707134137085">"മടങ്ങുക"</string>
<string name="handle_text" msgid="4419667835599523257">"ആപ്പ് ഹാൻഡിൽ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ആപ്പ് ഐക്കൺ"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ഇടത്തേക്ക് ആപ്പ് വിൻഡോ വലുപ്പം മാറ്റുക"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"വലത്തേക്ക് ആപ്പ് വിൻഡോ വലുപ്പം മാറ്റുക"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"വിന്‍ഡോ വലുപ്പം വലുതാക്കുക അല്ലെങ്കിൽ പഴയത് പുനഃസ്ഥാപിക്കുക"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"ആപ്പ് വിൻഡോ വലുപ്പം പരമാവധിയാക്കുക"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"വിൻഡോ വലുപ്പം പുനഃസ്ഥാപിക്കുക"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"ആപ്പ് വിൻഡോ ചുരുക്കുക"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"ആപ്പ് വിൻഡോ അടയ്ക്കുക"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"ഡിഫോൾട്ട് ക്രമീകരണം ഉപയോഗിച്ച് തുറക്കുക"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"ഈ ആപ്പിനായി വെബ് ലിങ്കുകൾ എങ്ങനെ തുറക്കണമെന്ന് തിരഞ്ഞെടുക്കൂ"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ആപ്പിൽ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index f0cd560b1f48..e954b0f8937e 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kiri 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Kiri 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Skrin penuh kanan"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Tukar apl bahagian atas dengan apl bahagian bawah"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Tukar apl sebelah kiri dengan apl sebelah kanan"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Skrin penuh atas"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Atas 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Atas 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Mulakan semula"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Jangan tunjukkan lagi"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Ketik dua kali untuk\nalih apl ini"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Maksimumkan <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Pulihkan <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Minimumkan <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Tutup <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Kembali"</string>
<string name="handle_text" msgid="4419667835599523257">"Pengendalian apl"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikon Apl"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Ubah saiz tetingkap ke sebelah kiri"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Ubah saiz tetingkap ke sebelah kanan"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maksimumkan atau pulihkan saiz tetingkap"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Maksimumkan saiz tetingkap apl"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Pulihkan saiz tetingkap"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Minimumkan tetingkap apl"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Tutup tetingkap apl"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Buka tetapan secara lalai"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Pilih cara membuka pautan web untuk apl ini"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Pada apl"</string>
diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml
index 6390d37a3f57..62ee4a049a1d 100644
--- a/libs/WindowManager/Shell/res/values-or/strings.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ବାମ ପଟକୁ 50% କରନ୍ତୁ"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ବାମ ପଟେ 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"ଡାହାଣ ପଟକୁ ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନ୍‍ କରନ୍ତୁ"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"ବଟମ ସହ ଟପକୁ ଆପ ସ୍ବାପ କରନ୍ତୁ"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"ଡାହାଣ ସହ ବାମକୁ ଆପ ସ୍ବାପ କରନ୍ତୁ"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"ଉପର ଆଡ଼କୁ ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନ୍‍ କରନ୍ତୁ"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ଉପର ଆଡ଼କୁ 70% କରନ୍ତୁ"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ଉପର ଆଡ଼କୁ 50% କରନ୍ତୁ"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"ପୁଣି ଦେଖାନ୍ତୁ ନାହିଁ"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"ଏହି ଆପକୁ ମୁଭ\nକରିବା ପାଇଁ ଦୁଇଥର-ଟାପ କରନ୍ତୁ"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବଡ଼ କରନ୍ତୁ"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g> ରିଷ୍ଟୋର କରନ୍ତୁ"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଛୋଟ କରନ୍ତୁ"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="back_button_text" msgid="1469718707134137085">"ପଛକୁ ଫେରନ୍ତୁ"</string>
<string name="handle_text" msgid="4419667835599523257">"ଆପର ହେଣ୍ଡେଲ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ଆପ ଆଇକନ"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ବାମପଟକୁ ୱିଣ୍ଡୋ ରିସାଇଜ କରନ୍ତୁ"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"ଡାହାଣପଟକୁ ୱିଣ୍ଡୋ ରିସାଇଜ କରନ୍ତୁ"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"ୱିଣ୍ଡୋ ସାଇଜକୁ ମେକ୍ସିମାଇଜ କିମ୍ବା ରିଷ୍ଟୋର କରନ୍ତୁ"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"ଆପ ଇଣ୍ଡୋ ଆକାର ବଡ଼ କରନ୍ତୁ"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"ୱିଣ୍ଡୋ ଆକାର ରିଷ୍ଟୋର କରନ୍ତୁ"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"ଆପ ୱିଣ୍ଡୋକୁ ମିନିମାଇଜ କରନ୍ତୁ"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"ଆପ ୱିଣ୍ଡୋ ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"ଡିଫଲ୍ଟ ସେଟିଂସକୁ ଖୋଲନ୍ତୁ"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"ଏହି ଆପ ପାଇଁ ୱେବ ଲିଙ୍କଗୁଡ଼ିକୁ କିପରି ଖୋଲିବେ, ତାହା ବାଛନ୍ତୁ"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ଆପରେ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index d2b837c5df3a..4dde6d292148 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ਖੱਬੇ 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ਖੱਬੇ 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"ਸੱਜੇ ਪੂਰੀ ਸਕ੍ਰੀਨ"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"ਸਿਖਰਲੀ ਐਪ ਨੂੰ ਹੇਠਲੀ ਨਾਲ ਬਦਲੋ"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"ਖੱਬੀ ਐਪ ਨੂੰ ਸੱਜੀ ਨਾਲ ਬਦਲੋ"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"ਉੱਪਰ ਪੂਰੀ ਸਕ੍ਰੀਨ"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ਉੱਪਰ 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ਉੱਪਰ 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"ਦੁਬਾਰਾ ਨਾ ਦਿਖਾਓ"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"ਇਸ ਐਪ ਦਾ ਟਿਕਾਣਾ ਬਦਲਣ ਲਈ\nਡਬਲ ਟੈਪ ਕਰੋ"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਵੱਡਾ ਕਰੋ"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਮੁੜ-ਬਹਾਲ ਕਰੋ"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਛੋਟਾ ਕਰੋ"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਬੰਦ ਕਰੋ"</string>
<string name="back_button_text" msgid="1469718707134137085">"ਪਿੱਛੇ"</string>
<string name="handle_text" msgid="4419667835599523257">"ਐਪ ਹੈਂਡਲ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ਐਪ ਪ੍ਰਤੀਕ"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ਵਿੰਡੋ ਦਾ ਆਕਾਰ ਬਦਲ ਕੇ ਖੱਬੇ ਪਾਸੇ ਕਰੋ"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"ਵਿੰਡੋ ਦਾ ਆਕਾਰ ਬਦਲ ਕੇ ਸੱਜੇ ਪਾਸੇ ਕਰੋ"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"ਵਿੰਡੋ ਦਾ ਆਕਾਰ ਵਧਾਓ ਜਾਂ ਮੁੜ-ਬਹਾਲ ਕਰੋ"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"ਐਪ ਵਿੰਡੋ ਦਾ ਆਕਾਰ ਵਧਾਓ"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"ਵਿੰਡੋ ਦੇ ਆਕਾਰ ਨੂੰ ਮੁੜ-ਬਹਾਲ ਕਰੋ"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"ਐਪ ਵਿੰਡੋ ਨੂੰ ਛੋਟਾ ਕਰੋ"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"ਐਪ ਵਿੰਡੋ ਬੰਦ ਕਰੋ"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਸੈਟਿੰਗਾਂ ਮੁਤਾਬਕ ਖੋਲ੍ਹੋ"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"ਇਸ ਐਪ ਲਈ ਵੈੱਬ ਲਿੰਕਾਂ ਨੂੰ ਖੋਲ੍ਹਣ ਦਾ ਤਰੀਕਾ ਚੁਣੋ"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ਐਪ ਵਿੱਚ"</string>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index c64df85dad65..3e88ed15aff1 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -127,7 +127,7 @@
<string name="handle_text" msgid="4419667835599523257">"Emërtimi i aplikacionit"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona e aplikacionit"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Ekrani i plotë"</string>
- <string name="desktop_text" msgid="1582173066857454541">"Pamja për desktop"</string>
+ <string name="desktop_text" msgid="1582173066857454541">"Pamja e desktopit"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Ekrani i ndarë"</string>
<string name="more_button_text" msgid="3655388105592893530">"Më shumë"</string>
<string name="float_button_text" msgid="9221657008391364581">"Pluskuese"</string>
@@ -140,7 +140,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Ndrysho raportin e pamjes"</string>
<string name="close_text" msgid="4986518933445178928">"Mbyll"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Mbyll menynë"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Pamja për desktop)"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="8300164817452574565">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Pamja e desktopit)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimizo ekranin"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Ndrysho përmasat"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacioni nuk mund të zhvendoset këtu"</string>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index d2462a7282c2..287d34fc1de8 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Леви екран 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Леви екран 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Режим целог екрана за доњи екран"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"Замените горњу апликацију доњом"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"Замените леву апликацију десном"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Режим целог екрана за горњи екран"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Горњи екран 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Горњи екран 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"Рестартуј"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Не приказуј поново"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Двапут додирните да бисте\nпреместили ову апликацију"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"Увећајте: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"Вратите: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"Умањите: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"Затворите: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
<string name="handle_text" msgid="4419667835599523257">"Идентификатор апликације"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Икона апликације"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Промените величину прозора налево"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Промените величину прозора надесно"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Увећајте или вратите величину прозора"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"Увећајте величину прозора апликације"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"Вратите величину прозора"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"Умањите прозор апликације"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"Затворите прозор апликације"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"Подешавање Подразумевано отварај"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Одаберите начин отварања веб-линкова за ову апликацију"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"У апликацији"</string>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index 16372d26977c..594ee6c97689 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ซ้าย 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ซ้าย 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"เต็มหน้าจอทางขวา"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"สลับแอปด้านบนกับด้านล่าง"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"สลับแอปด้านซ้ายกับด้านขวา"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"เต็มหน้าจอด้านบน"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ด้านบน 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ด้านบน 50%"</string>
@@ -115,14 +113,10 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"รีสตาร์ท"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"ไม่ต้องแสดงข้อความนี้อีก"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"แตะสองครั้ง\nเพื่อย้ายแอปนี้"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"ขยาย <xliff:g id="APP_NAME">%1$s</xliff:g> ให้ใหญ่สุด"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"คืนค่า <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"ย่อ <xliff:g id="APP_NAME">%1$s</xliff:g> ให้เล็กสุด"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"ปิด <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="back_button_text" msgid="1469718707134137085">"กลับ"</string>
<string name="handle_text" msgid="4419667835599523257">"แฮนเดิลแอป"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ไอคอนแอป"</string>
@@ -158,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ปรับขนาดหน้าต่างไปทางซ้าย"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"ปรับขนาดหน้าต่างไปทางขวา"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"ขยายหรือคืนค่าขนาดหน้าต่าง"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"ขยายขนาดหน้าต่างแอปให้ใหญ่สุด"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"คืนค่าขนาดหน้าต่าง"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"ย่อหน้าต่างแอปให้เล็กสุด"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"ปิดหน้าต่างแอป"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"เปิดตามการตั้งค่าเริ่มต้น"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"เลือกวิธีเปิดเว็บลิงก์สำหรับแอปนี้"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ในแอป"</string>
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DeviceConfig.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DeviceConfig.kt
index f479da051e06..1b7c9c282304 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DeviceConfig.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DeviceConfig.kt
@@ -49,19 +49,29 @@ data class DeviceConfig(
or WindowInsets.Type.displayCutout())
val windowBounds = windowMetrics.bounds
val config: Configuration = context.resources.configuration
- val isLargeScreen = config.smallestScreenWidthDp >= LARGE_SCREEN_MIN_EDGE_DP
- val largestEdgeDp = max(config.screenWidthDp, config.screenHeightDp)
- val isSmallTablet = isLargeScreen && largestEdgeDp < SMALL_TABLET_MAX_EDGE_DP
val isLandscape = context.resources.configuration.orientation == ORIENTATION_LANDSCAPE
val isRtl = context.resources.configuration.layoutDirection == LAYOUT_DIRECTION_RTL
return DeviceConfig(
- isLargeScreen = isLargeScreen,
- isSmallTablet = isSmallTablet,
+ isLargeScreen = isLargeScreen(config),
+ isSmallTablet = isSmallTablet(context),
isLandscape = isLandscape,
isRtl = isRtl,
windowBounds = windowBounds,
insets = insets
)
}
+
+ @JvmStatic
+ fun isSmallTablet(context: Context): Boolean {
+ val config: Configuration = context.resources.configuration
+ if (!isLargeScreen(config)) {
+ return false
+ }
+ val largestEdgeDp = max(config.screenWidthDp, config.screenHeightDp)
+ return largestEdgeDp < SMALL_TABLET_MAX_EDGE_DP
+ }
+
+ private fun isLargeScreen(config: Configuration) =
+ config.smallestScreenWidthDp >= LARGE_SCREEN_MIN_EDGE_DP
}
}
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DropTargetManager.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DropTargetManager.kt
index 5c2590849dd2..2dbbeaebd3c0 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DropTargetManager.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DropTargetManager.kt
@@ -33,7 +33,6 @@ import com.android.wm.shell.shared.R
class DropTargetManager(
private val context: Context,
private val container: FrameLayout,
- private val isLayoutRtl: Boolean,
private val dragZoneChangedListener: DragZoneChangedListener,
) {
@@ -41,6 +40,7 @@ class DropTargetManager(
private val dropTargetView = DropTargetView(context)
private var animator: ValueAnimator? = null
private var morphRect: RectF = RectF(0f, 0f, 0f, 0f)
+ private val isLayoutRtl = container.isLayoutRtl
private companion object {
const val MORPH_ANIM_DURATION = 250L
@@ -80,9 +80,11 @@ class DropTargetManager(
/** Called when the drag ended. */
fun onDragEnded() {
+ val dropState = state ?: return
startFadeAnimation(from = dropTargetView.alpha, to = 0f) {
container.removeView(dropTargetView)
}
+ dragZoneChangedListener.onDragEnded(dropState.currentDragZone)
state = null
}
@@ -156,6 +158,9 @@ class DropTargetManager(
/** Called when the object was dragged to a different drag zone. */
fun onDragZoneChanged(from: DragZone, to: DragZone)
+
+ /** Called when the drag has ended with the zone it ended in. */
+ fun onDragEnded(zone: DragZone)
}
private fun Animator.doOnEnd(onEnd: () -> Unit) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
index 33f1b94bac73..70340d7032b4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
@@ -136,6 +136,11 @@ public class BubblePositioner implements BubbleDropTargetBoundsProvider {
updateInternal(mRotation, deviceConfig.getInsets(), deviceConfig.getWindowBounds());
}
+ /** Returns the device config being used. */
+ public DeviceConfig getCurrentConfig() {
+ return mDeviceConfig;
+ }
+
@VisibleForTesting
public void updateInternal(int rotation, Insets insets, Rect bounds) {
BubbleStackView.RelativeStackPosition prevStackPosition = null;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt
index 34259bfb7aaa..9d4f904e55d0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt
@@ -21,7 +21,11 @@ import android.view.MotionEvent
import android.view.View
import androidx.annotation.VisibleForTesting
import com.android.wm.shell.bubbles.BubblePositioner
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation
import com.android.wm.shell.shared.bubbles.DismissView
+import com.android.wm.shell.shared.bubbles.DragZoneFactory
+import com.android.wm.shell.shared.bubbles.DraggedObject
+import com.android.wm.shell.shared.bubbles.DropTargetManager
import com.android.wm.shell.shared.bubbles.RelativeTouchListener
import com.android.wm.shell.shared.magnetictarget.MagnetizedObject
@@ -33,6 +37,8 @@ class BubbleBarExpandedViewDragController(
private val animationHelper: BubbleBarAnimationHelper,
private val bubblePositioner: BubblePositioner,
private val pinController: BubbleExpandedViewPinController,
+ private val dropTargetManager: DropTargetManager?,
+ private val dragZoneFactory: DragZoneFactory?,
@get:VisibleForTesting val dragListener: DragListener,
) {
@@ -97,7 +103,21 @@ class BubbleBarExpandedViewDragController(
override fun onDown(v: View, ev: MotionEvent): Boolean {
// While animating, don't allow new touch events
if (expandedView.isAnimating) return false
- pinController.onDragStart(bubblePositioner.isBubbleBarOnLeft)
+ if (dropTargetManager != null && dragZoneFactory != null) {
+ val draggedObject = DraggedObject.ExpandedView(
+ if (bubblePositioner.isBubbleBarOnLeft) {
+ BubbleBarLocation.LEFT
+ } else {
+ BubbleBarLocation.RIGHT
+ }
+ )
+ dropTargetManager.onDragStarted(
+ draggedObject,
+ dragZoneFactory.createSortedDragZones(draggedObject)
+ )
+ } else {
+ pinController.onDragStart(bubblePositioner.isBubbleBarOnLeft)
+ }
isDragged = true
return true
}
@@ -117,7 +137,11 @@ class BubbleBarExpandedViewDragController(
expandedView.translationX = expandedViewInitialTranslationX + dx
expandedView.translationY = expandedViewInitialTranslationY + dy
dismissView.show()
- pinController.onDragUpdate(ev.rawX, ev.rawY)
+ if (dropTargetManager != null) {
+ dropTargetManager.onDragUpdated(ev.rawX.toInt(), ev.rawY.toInt())
+ } else {
+ pinController.onDragUpdate(ev.rawX, ev.rawY)
+ }
}
override fun onUp(
@@ -140,7 +164,11 @@ class BubbleBarExpandedViewDragController(
private fun finishDrag() {
if (!isStuckToDismiss) {
- pinController.onDragEnd()
+ if (dropTargetManager != null) {
+ dropTargetManager.onDragEnded()
+ } else {
+ pinController.onDragEnd()
+ }
dragListener.onReleased(inDismiss = false)
animationHelper.animateToRestPosition()
dismissView.hide()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
index 677c21c96f4b..99082f18492c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
@@ -27,6 +27,7 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.drawable.ColorDrawable;
+import android.util.Log;
import android.view.Gravity;
import android.view.SurfaceControl;
import android.view.TouchDelegate;
@@ -48,9 +49,13 @@ import com.android.wm.shell.bubbles.BubbleViewProvider;
import com.android.wm.shell.bubbles.DismissViewUtils;
import com.android.wm.shell.bubbles.bar.BubbleBarExpandedViewDragController.DragListener;
import com.android.wm.shell.shared.bubbles.BaseBubblePinController;
+import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
import com.android.wm.shell.shared.bubbles.DeviceConfig;
import com.android.wm.shell.shared.bubbles.DismissView;
+import com.android.wm.shell.shared.bubbles.DragZone;
+import com.android.wm.shell.shared.bubbles.DragZoneFactory;
+import com.android.wm.shell.shared.bubbles.DropTargetManager;
import kotlin.Unit;
@@ -76,6 +81,10 @@ public class BubbleBarLayerView extends FrameLayout
private final BubbleEducationViewController mEducationViewController;
private final View mScrimView;
private final BubbleExpandedViewPinController mBubbleExpandedViewPinController;
+ @Nullable
+ private DropTargetManager mDropTargetManager = null;
+ @Nullable
+ private DragZoneFactory mDragZoneFactory = null;
@Nullable
private BubbleViewProvider mExpandedBubble;
@@ -123,8 +132,72 @@ public class BubbleBarLayerView extends FrameLayout
mBubbleExpandedViewPinController = new BubbleExpandedViewPinController(
context, this, mPositioner);
- mBubbleExpandedViewPinController.setListener(new LocationChangeListener());
-
+ LocationChangeListener locationChangeListener = new LocationChangeListener();
+ mBubbleExpandedViewPinController.setListener(locationChangeListener);
+
+ if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
+ mDropTargetManager = new DropTargetManager(context, this,
+ new DropTargetManager.DragZoneChangedListener() {
+ private DragZone mLastBubbleLocationDragZone = null;
+ private BubbleBarLocation mInitialLocation = null;
+ @Override
+ public void onDragEnded(@NonNull DragZone zone) {
+ if (mExpandedBubble == null || !(mExpandedBubble instanceof Bubble)) {
+ Log.w(TAG, "dropped invalid bubble: " + mExpandedBubble);
+ return;
+ }
+ if (zone instanceof DragZone.FullScreen) {
+ ((Bubble) mExpandedBubble).getTaskView().moveToFullscreen();
+ // Make sure location change listener is updated with the initial
+ // location -- even if we "switched sides" during the drag, since
+ // we've ended up in fullscreen, the location shouldn't change.
+ locationChangeListener.onRelease(mInitialLocation);
+ } else if (zone instanceof DragZone.Bubble.Left) {
+ locationChangeListener.onRelease(BubbleBarLocation.LEFT);
+ } else if (zone instanceof DragZone.Bubble.Right) {
+ locationChangeListener.onRelease(BubbleBarLocation.RIGHT);
+ }
+ }
+
+ @Override
+ public void onInitialDragZoneSet(@NonNull DragZone dragZone) {
+ mInitialLocation = dragZone instanceof DragZone.Bubble.Left
+ ? BubbleBarLocation.LEFT
+ : BubbleBarLocation.RIGHT;
+ locationChangeListener.onStart(mInitialLocation);
+ }
+
+ @Override
+ public void onDragZoneChanged(@NonNull DragZone from,
+ @NonNull DragZone to) {
+ final boolean isBubbleLeft = to instanceof DragZone.Bubble.Left;
+ final boolean isBubbleRight = to instanceof DragZone.Bubble.Right;
+ if ((isBubbleLeft || isBubbleRight)
+ && to != mLastBubbleLocationDragZone) {
+ mLastBubbleLocationDragZone = to;
+ locationChangeListener.onChange(isBubbleLeft
+ ? BubbleBarLocation.LEFT
+ : BubbleBarLocation.RIGHT);
+
+ }
+ }
+ });
+ // TODO - currently only fullscreen is supported, should enable for split & desktop
+ mDragZoneFactory = new DragZoneFactory(context, mPositioner.getCurrentConfig(),
+ new DragZoneFactory.SplitScreenModeChecker() {
+ @NonNull
+ @Override
+ public SplitScreenMode getSplitScreenMode() {
+ return SplitScreenMode.NONE;
+ }
+ },
+ new DragZoneFactory.DesktopWindowModeChecker() {
+ @Override
+ public boolean isSupported() {
+ return false;
+ }
+ });
+ }
setOnClickListener(view -> hideModalOrCollapse());
}
@@ -272,6 +345,8 @@ public class BubbleBarLayerView extends FrameLayout
mAnimationHelper,
mPositioner,
mBubbleExpandedViewPinController,
+ mDropTargetManager,
+ mDragZoneFactory,
dragListener);
addView(mExpandedView, new LayoutParams(width, height, Gravity.LEFT));
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDesktopState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDesktopState.java
index 3f21e74a7d03..01fd3442f604 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDesktopState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDesktopState.java
@@ -19,18 +19,13 @@ package com.android.wm.shell.common.pip;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-import android.app.ActivityManager;
import android.window.DesktopExperienceFlags;
import android.window.DisplayAreaInfo;
-import android.window.WindowContainerToken;
-import android.window.WindowContainerTransaction;
import com.android.window.flags.Flags;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
-import com.android.wm.shell.desktopmode.DesktopRepository;
import com.android.wm.shell.desktopmode.DesktopUserRepositories;
-import com.android.wm.shell.desktopmode.desktopwallpaperactivity.DesktopWallpaperActivityTokenProvider;
-import com.android.wm.shell.pip2.phone.PipTransition;
+import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler;
import java.util.Optional;
@@ -38,32 +33,28 @@ import java.util.Optional;
public class PipDesktopState {
private final PipDisplayLayoutState mPipDisplayLayoutState;
private final Optional<DesktopUserRepositories> mDesktopUserRepositoriesOptional;
- private final Optional<DesktopWallpaperActivityTokenProvider>
- mDesktopWallpaperActivityTokenProviderOptional;
+ private final Optional<DragToDesktopTransitionHandler> mDragToDesktopTransitionHandlerOptional;
private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
public PipDesktopState(PipDisplayLayoutState pipDisplayLayoutState,
Optional<DesktopUserRepositories> desktopUserRepositoriesOptional,
- Optional<DesktopWallpaperActivityTokenProvider>
- desktopWallpaperActivityTokenProviderOptional,
+ Optional<DragToDesktopTransitionHandler> dragToDesktopTransitionHandlerOptional,
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) {
mPipDisplayLayoutState = pipDisplayLayoutState;
mDesktopUserRepositoriesOptional = desktopUserRepositoriesOptional;
- mDesktopWallpaperActivityTokenProviderOptional =
- desktopWallpaperActivityTokenProviderOptional;
+ mDragToDesktopTransitionHandlerOptional = dragToDesktopTransitionHandlerOptional;
mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
}
/**
* Returns whether PiP in Desktop Windowing is enabled by checking the following:
* - Desktop Windowing in PiP flag is enabled
- * - DesktopWallpaperActivityTokenProvider is injected
* - DesktopUserRepositories is injected
+ * - DragToDesktopTransitionHandler is injected
*/
public boolean isDesktopWindowingPipEnabled() {
- return Flags.enableDesktopWindowingPip()
- && mDesktopWallpaperActivityTokenProviderOptional.isPresent()
- && mDesktopUserRepositoriesOptional.isPresent();
+ return Flags.enableDesktopWindowingPip() && mDesktopUserRepositoriesOptional.isPresent()
+ && mDragToDesktopTransitionHandlerOptional.isPresent();
}
/** Returns whether PiP in Connected Displays is enabled by checking the flag. */
@@ -89,45 +80,10 @@ public class PipDesktopState {
return false;
}
final int displayId = mPipDisplayLayoutState.getDisplayId();
- return getDesktopRepository().isAnyDeskActive(displayId)
- || getDesktopWallpaperActivityTokenProvider().isWallpaperActivityVisible(displayId)
+ return mDesktopUserRepositoriesOptional.get().getCurrent().isAnyDeskActive(displayId)
|| isDisplayInFreeform();
}
- /** Returns whether {@param pipTask} would be entering in a Desktop Mode session. */
- public boolean isPipEnteringInDesktopMode(ActivityManager.RunningTaskInfo pipTask) {
- // Early return if PiP in Desktop Windowing is not supported.
- if (!isDesktopWindowingPipEnabled()) {
- return false;
- }
- final DesktopRepository desktopRepository = getDesktopRepository();
- return desktopRepository.isAnyDeskActive(pipTask.getDisplayId())
- || desktopRepository.isMinimizedPipPresentInDisplay(pipTask.getDisplayId());
- }
-
- /**
- * Invoked when an EXIT_PiP transition is detected in {@link PipTransition}.
- * Returns whether the PiP exiting should also trigger the active Desktop Mode session to exit.
- */
- public boolean shouldExitPipExitDesktopMode() {
- // Early return if PiP in Desktop Windowing is not supported.
- if (!isDesktopWindowingPipEnabled()) {
- return false;
- }
- final int displayId = mPipDisplayLayoutState.getDisplayId();
- return !getDesktopRepository().isAnyDeskActive(displayId)
- && getDesktopWallpaperActivityTokenProvider().isWallpaperActivityVisible(displayId);
- }
-
- /**
- * Returns a {@link WindowContainerTransaction} that reorders the {@link WindowContainerToken}
- * of the DesktopWallpaperActivity for the display with the given {@param displayId}.
- */
- public WindowContainerTransaction getWallpaperActivityTokenWct(int displayId) {
- return new WindowContainerTransaction().reorder(
- getDesktopWallpaperActivityTokenProvider().getToken(displayId), /* onTop= */ false);
- }
-
/**
* The windowing mode to restore to when resizing out of PIP direction.
* Defaults to undefined and can be overridden to restore to an alternate windowing mode.
@@ -150,11 +106,12 @@ public class PipDesktopState {
return WINDOWING_MODE_UNDEFINED;
}
- private DesktopRepository getDesktopRepository() {
- return mDesktopUserRepositoriesOptional.get().getCurrent();
- }
-
- private DesktopWallpaperActivityTokenProvider getDesktopWallpaperActivityTokenProvider() {
- return mDesktopWallpaperActivityTokenProviderOptional.get();
+ /** Returns whether there is a drag-to-desktop transition in progress. */
+ public boolean isDragToDesktopInProgress() {
+ // Early return if PiP in Desktop Windowing is not supported.
+ if (!isDesktopWindowingPipEnabled()) {
+ return false;
+ }
+ return mDragToDesktopTransitionHandlerOptional.get().getInProgress();
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java
index 5b2dd97a338f..bc0a8573f977 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java
@@ -39,6 +39,7 @@ import com.android.wm.shell.Flags;
import com.android.wm.shell.shared.split.SplitScreenConstants.PersistentSnapPosition;
import java.util.ArrayList;
+import java.util.stream.IntStream;
/**
* Calculates the snap targets and the snap position given a position and a velocity. All positions
@@ -354,10 +355,20 @@ public class DividerSnapAlgorithm {
float ratio = areOffscreenRatiosSupported()
? SplitSpec.OFFSCREEN_ASYMMETRIC_RATIO
: SplitSpec.ONSCREEN_ONLY_ASYMMETRIC_RATIO;
+
+ // The intended size of the smaller app, in pixels
int size = (int) (ratio * (end - start)) - mDividerSize / 2;
- int leftTopPosition = start + pinnedTaskbarShiftStart + size;
- int rightBottomPosition = end - pinnedTaskbarShiftEnd - size - mDividerSize;
+ // If there are insets that interfere with the smaller app (visually or blocking touch
+ // targets), make the smaller app bigger by that amount to compensate. This applies to
+ // pinned taskbar, 3-button nav (both create an opaque bar at bottom) and status bar (blocks
+ // touch targets at top).
+ int extraSpace = IntStream.of(
+ getStartInset(), getEndInset(), pinnedTaskbarShiftStart, pinnedTaskbarShiftEnd
+ ).max().getAsInt();
+
+ int leftTopPosition = start + extraSpace + size;
+ int rightBottomPosition = end - extraSpace - size - mDividerSize;
addNonDismissingTargets(isLeftRightSplit, leftTopPosition, rightBottomPosition, dividerMax);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index 720e8e53b218..b7867d0b81b5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -1543,11 +1543,28 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
}
}
+ /**
+ * When IME is triggered on the bottom app in split screen, we want to translate the bottom
+ * app up by a certain amount so that it's not covered too much by the IME. But there's also
+ * an upper limit to the amount we want to translate (since we still need some of the top
+ * app to be visible too). So this function essentially says "try to translate the bottom
+ * app up, but stop before you make the top app too small."
+ */
private int getTargetYOffset() {
- final int desireOffset = Math.abs(mEndImeTop - mStartImeTop);
- // Make sure to keep at least 30% visible for the top split.
- final int maxOffset = (int) (getTopLeftBounds().height() * ADJUSTED_SPLIT_FRACTION_MAX);
- return -Math.min(desireOffset, maxOffset);
+ // We want to translate up the bottom app by this amount.
+ final int desiredOffset = Math.abs(mEndImeTop - mStartImeTop);
+
+ // But we also want to keep this much of the top app visible.
+ final float amountOfTopAppToKeepVisible =
+ getTopLeftBounds().height() * (1 - ADJUSTED_SPLIT_FRACTION_MAX);
+
+ // So the current onscreen size of the top app, minus the minimum size, is the max
+ // translation we will allow.
+ final float currentOnScreenSizeOfTopApp = getTopLeftBounds().bottom;
+ final int maxOffset =
+ (int) Math.max(currentOnScreenSizeOfTopApp - amountOfTopAppToKeepVisible, 0);
+
+ return -Math.min(desiredOffset, maxOffset);
}
@SplitPosition
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index 0e6481b1c0ac..318cdeec5bc1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -1052,23 +1052,8 @@ public abstract class WMShellBaseModule {
});
}
- @WMSingleton
- @Provides
- static DesktopWallpaperActivityTokenProvider provideDesktopWallpaperActivityTokenProvider() {
- return new DesktopWallpaperActivityTokenProvider();
- }
-
- @WMSingleton
- @Provides
- static Optional<DesktopWallpaperActivityTokenProvider>
- provideOptionalDesktopWallpaperActivityTokenProvider(
- Context context,
- DesktopWallpaperActivityTokenProvider desktopWallpaperActivityTokenProvider) {
- if (DesktopModeStatus.canEnterDesktopMode(context)) {
- return Optional.of(desktopWallpaperActivityTokenProvider);
- }
- return Optional.empty();
- }
+ @BindsOptionalOf
+ abstract DesktopWallpaperActivityTokenProvider optionalDesktopWallpaperActivityTokenProvider();
//
// App zoom out (optional feature)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index 79fbd32dafe6..6b7f311daa7c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -938,6 +938,12 @@ public abstract class WMShellModule {
@WMSingleton
@Provides
+ static DesktopWallpaperActivityTokenProvider provideDesktopWallpaperActivityTokenProvider() {
+ return new DesktopWallpaperActivityTokenProvider();
+ }
+
+ @WMSingleton
+ @Provides
static DragToDisplayTransitionHandler provideDragToDisplayTransitionHandler() {
return new DragToDisplayTransitionHandler();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
index f8b18f29c797..6f0919e1d045 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.content.Context;
import android.os.Handler;
+import com.android.internal.jank.InteractionJankMonitor;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
@@ -42,9 +43,10 @@ import com.android.wm.shell.common.pip.SizeSpecSource;
import com.android.wm.shell.dagger.WMShellBaseModule;
import com.android.wm.shell.dagger.WMSingleton;
import com.android.wm.shell.desktopmode.DesktopUserRepositories;
-import com.android.wm.shell.desktopmode.desktopwallpaperactivity.DesktopWallpaperActivityTokenProvider;
+import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler;
import com.android.wm.shell.pip2.phone.PhonePipMenuController;
import com.android.wm.shell.pip2.phone.PipController;
+import com.android.wm.shell.pip2.phone.PipInteractionHandler;
import com.android.wm.shell.pip2.phone.PipMotionHelper;
import com.android.wm.shell.pip2.phone.PipScheduler;
import com.android.wm.shell.pip2.phone.PipTaskListener;
@@ -59,6 +61,7 @@ import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.Transitions;
+import dagger.BindsOptionalOf;
import dagger.Module;
import dagger.Provides;
@@ -87,12 +90,13 @@ public abstract class Pip2Module {
@NonNull PipUiStateChangeController pipUiStateChangeController,
DisplayController displayController,
Optional<SplitScreenController> splitScreenControllerOptional,
- PipDesktopState pipDesktopState) {
+ PipDesktopState pipDesktopState,
+ PipInteractionHandler pipInteractionHandler) {
return new PipTransition(context, shellInit, shellTaskOrganizer, transitions,
pipBoundsState, null, pipBoundsAlgorithm, pipTaskListener,
pipScheduler, pipStackListenerController, pipDisplayLayoutState,
pipUiStateChangeController, displayController, splitScreenControllerOptional,
- pipDesktopState);
+ pipDesktopState, pipInteractionHandler);
}
@WMSingleton
@@ -209,8 +213,9 @@ public abstract class Pip2Module {
@WMSingleton
@Provides
- static PipTransitionState providePipTransitionState(@ShellMainThread Handler handler) {
- return new PipTransitionState(handler);
+ static PipTransitionState providePipTransitionState(@ShellMainThread Handler handler,
+ PipDesktopState pipDesktopState) {
+ return new PipTransitionState(handler, pipDesktopState);
}
@WMSingleton
@@ -238,11 +243,23 @@ public abstract class Pip2Module {
static PipDesktopState providePipDesktopState(
PipDisplayLayoutState pipDisplayLayoutState,
Optional<DesktopUserRepositories> desktopUserRepositoriesOptional,
- Optional<DesktopWallpaperActivityTokenProvider>
- desktopWallpaperActivityTokenProviderOptional,
+ Optional<DragToDesktopTransitionHandler> dragToDesktopTransitionHandlerOptional,
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer
) {
return new PipDesktopState(pipDisplayLayoutState, desktopUserRepositoriesOptional,
- desktopWallpaperActivityTokenProviderOptional, rootTaskDisplayAreaOrganizer);
+ dragToDesktopTransitionHandlerOptional, rootTaskDisplayAreaOrganizer);
+ }
+
+ @BindsOptionalOf
+ abstract DragToDesktopTransitionHandler optionalDragToDesktopTransitionHandler();
+
+ @WMSingleton
+ @Provides
+ static PipInteractionHandler providePipInteractionHandler(
+ Context context,
+ @ShellMainThread Handler mainHandler
+ ) {
+ return new PipInteractionHandler(context, mainHandler,
+ InteractionJankMonitor.getInstance());
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
index 73df9767ee50..8c2748742595 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
@@ -28,7 +28,6 @@ import androidx.core.util.forEach
import androidx.core.util.valueIterator
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.protolog.ProtoLog
-import com.android.window.flags.Flags
import com.android.wm.shell.desktopmode.persistence.DesktopPersistentRepository
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
import com.android.wm.shell.shared.annotations.ShellMainThread
@@ -70,9 +69,6 @@ class DesktopRepository(
* fullscreen task launched on top of the desk. Cleared when the transparent task is closed or
* sent to back. (top is at index 0).
* @property pipTaskId the task id of PiP task entered while in Desktop Mode.
- * @property pipShouldKeepDesktopActive whether an active PiP window should keep the desk
- * active. Only false when we are explicitly exiting Desktop Mode (via user action) while
- * there is an active PiP window.
*/
private data class Desk(
val deskId: Int,
@@ -86,8 +82,6 @@ class DesktopRepository(
var fullImmersiveTaskId: Int? = null,
var topTransparentFullscreenTaskId: Int? = null,
var pipTaskId: Int? = null,
- // TODO: b/389960283 - consolidate this with [DesktopDisplay#activeDeskId].
- var pipShouldKeepDesktopActive: Boolean = true,
) {
fun deepCopy(): Desk =
Desk(
@@ -101,7 +95,6 @@ class DesktopRepository(
fullImmersiveTaskId = fullImmersiveTaskId,
topTransparentFullscreenTaskId = topTransparentFullscreenTaskId,
pipTaskId = pipTaskId,
- pipShouldKeepDesktopActive = pipShouldKeepDesktopActive,
)
// TODO: b/362720497 - remove when multi-desktops is enabled where instances aren't
@@ -115,7 +108,6 @@ class DesktopRepository(
fullImmersiveTaskId = null
topTransparentFullscreenTaskId = null
pipTaskId = null
- pipShouldKeepDesktopActive = true
}
}
@@ -625,7 +617,6 @@ class DesktopRepository(
?: error("Expected active desk in display: $displayId")
if (enterPip) {
activeDesk.pipTaskId = taskId
- activeDesk.pipShouldKeepDesktopActive = true
} else {
activeDesk.pipTaskId =
if (activeDesk.pipTaskId == taskId) null
@@ -638,19 +629,9 @@ class DesktopRepository(
activeDesk.pipTaskId
}
}
- notifyVisibleTaskListeners(displayId, getVisibleTaskCount(displayId))
}
/**
- * Returns whether there is a PiP that was entered/minimized from Desktop in this display's
- * active desk.
- *
- * TODO: b/389960283 - add explicit [deskId] argument.
- */
- fun isMinimizedPipPresentInDisplay(displayId: Int): Boolean =
- desktopData.getActiveDesk(displayId)?.pipTaskId != null
-
- /**
* Returns whether the given task is the Desktop-entered PiP task in this display's active desk.
*
* TODO: b/389960283 - add explicit [deskId] argument.
@@ -659,25 +640,6 @@ class DesktopRepository(
desktopData.getActiveDesk(displayId)?.pipTaskId == taskId
/**
- * Returns whether a desk should be active in this display due to active PiP.
- *
- * TODO: b/389960283 - add explicit [deskId] argument.
- */
- fun shouldDesktopBeActiveForPip(displayId: Int): Boolean =
- Flags.enableDesktopWindowingPip() &&
- isMinimizedPipPresentInDisplay(displayId) &&
- (desktopData.getActiveDesk(displayId)?.pipShouldKeepDesktopActive ?: false)
-
- /**
- * Saves whether a PiP window should keep Desktop session active in this display.
- *
- * TODO: b/389960283 - add explicit [deskId] argument.
- */
- fun setPipShouldKeepDesktopActive(displayId: Int, keepActive: Boolean) {
- desktopData.getActiveDesk(displayId)?.pipShouldKeepDesktopActive = keepActive
- }
-
- /**
* Saves callback to handle a pending PiP transition being aborted.
*
* TODO: b/389960283 - add explicit [deskId] argument.
@@ -772,12 +734,8 @@ class DesktopRepository(
}
private fun notifyVisibleTaskListeners(displayId: Int, visibleTasksCount: Int) {
- val visibleAndPipTasksCount =
- if (shouldDesktopBeActiveForPip(displayId)) visibleTasksCount + 1 else visibleTasksCount
visibleTasksListeners.forEach { (listener, executor) ->
- executor.execute {
- listener.onTasksVisibilityChanged(displayId, visibleAndPipTasksCount)
- }
+ executor.execute { listener.onTasksVisibilityChanged(displayId, visibleTasksCount) }
}
}
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 8f7e52ea2108..e1dcf0f1c049 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
@@ -343,45 +343,28 @@ class DesktopTasksController(
fun isAnyDeskActive(displayId: Int): Boolean = taskRepository.isAnyDeskActive(displayId)
/**
- * Returns true if any of the following is true:
- * - Any freeform tasks are visible
- * - A transparent fullscreen task exists on top in Desktop Mode
- * - PiP on Desktop Windowing is enabled, there is an active PiP window and the desktop
- * wallpaper is visible.
+ * Returns true if any freeform tasks are visible or if a transparent fullscreen task exists on
+ * top in Desktop Mode.
*
* TODO: b/362720497 - consolidate with [isAnyDeskActive].
* - top-transparent-fullscreen case: should not be needed if we allow it to launch inside
* the desk in fullscreen instead of force-exiting desktop and having to trick this method
* into thinking it is in desktop mode when a task in this state exists.
- * - PIP case: a PIP presence should influence desk activation, so
- * [DesktopRepository#isAnyDeskActive] should be sufficient.
*/
fun isDesktopModeShowing(displayId: Int): Boolean {
val hasVisibleTasks = taskRepository.isAnyDeskActive(displayId)
val hasTopTransparentFullscreenTask =
taskRepository.getTopTransparentFullscreenTaskId(displayId) != null
- val hasMinimizedPip =
- Flags.enableDesktopWindowingPip() &&
- taskRepository.isMinimizedPipPresentInDisplay(displayId) &&
- desktopWallpaperActivityTokenProvider.isWallpaperActivityVisible(displayId)
if (
DesktopModeFlags.INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC
.isTrue() && DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_MODALS_POLICY.isTrue()
) {
logV(
- "isDesktopModeShowing: hasVisibleTasks=%s hasTopTransparentFullscreenTask=%s hasMinimizedPip=%s",
+ "isDesktopModeShowing: hasVisibleTasks=%s hasTopTransparentFullscreenTask=%s",
hasVisibleTasks,
hasTopTransparentFullscreenTask,
- hasMinimizedPip,
)
- return hasVisibleTasks || hasTopTransparentFullscreenTask || hasMinimizedPip
- } else if (Flags.enableDesktopWindowingPip()) {
- logV(
- "isDesktopModeShowing: hasVisibleTasks=%s hasMinimizedPip=%s",
- hasVisibleTasks,
- hasMinimizedPip,
- )
- return hasVisibleTasks || hasMinimizedPip
+ return hasVisibleTasks || hasTopTransparentFullscreenTask
}
logV("isDesktopModeShowing: hasVisibleTasks=%s", hasVisibleTasks)
return hasVisibleTasks
@@ -537,8 +520,7 @@ class DesktopTasksController(
return false
}
logV("moveBackgroundTaskToDesktop with taskId=%d", taskId)
- val taskIdToMinimize =
- bringDesktopAppsToFrontBeforeShowingNewTask(task.displayId, wct, taskId)
+ val taskIdToMinimize = bringDesktopAppsToFront(task.displayId, wct, taskId)
val exitResult =
desktopImmersiveController.exitImmersiveIfApplicable(
wct = wct,
@@ -603,13 +585,7 @@ class DesktopTasksController(
reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH,
)
- val taskIdToMinimize =
- prepareMoveTaskToDeskAndActivate(
- wct = wct,
- displayId = displayId,
- deskId = deskId,
- task = task,
- )
+ val taskIdToMinimize = addDeskActivationWithMovingTaskChanges(deskId, wct, task)
val transition: IBinder
if (remoteTransition != null) {
@@ -643,44 +619,6 @@ class DesktopTasksController(
return true
}
- /**
- * Applies the necessary changes and operations to [wct] to move a task into a desk and
- * activating that desk. This includes showing pre-existing tasks of that desk behind the new
- * task (but minimizing one of them if needed) and showing Home and the desktop wallpaper.
- *
- * @return the id of the task that is being minimized, if any.
- */
- private fun prepareMoveTaskToDeskAndActivate(
- wct: WindowContainerTransaction,
- displayId: Int,
- deskId: Int,
- task: RunningTaskInfo,
- ): Int? {
- val taskIdToMinimize =
- if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
- // Activate the desk first.
- prepareForDeskActivation(displayId, wct)
- desksOrganizer.activateDesk(wct, deskId)
- if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) {
- // TODO: b/362720497 - do non-running tasks need to be restarted with
- // |wct#startTask|?
- }
- taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate(
- doesAnyTaskRequireTaskbarRounding(displayId)
- )
- // TODO: b/362720497 - activating a desk with the intention to move a new task to
- // it means we may need to minimize something in the activating desk. Do so here
- // similar to how it's done in #bringDesktopAppsToFrontBeforeShowingNewTask
- // instead of returning null.
- null
- } else {
- // Bring other apps to front first.
- bringDesktopAppsToFrontBeforeShowingNewTask(displayId, wct, task.taskId)
- }
- addMoveToDeskTaskChanges(wct = wct, task = task, deskId = deskId)
- return taskIdToMinimize
- }
-
private fun invokeCallbackToOverview(transition: IBinder, callback: IMoveToDesktopCallback?) {
// TODO: b/333524374 - Remove this later.
// This is a temporary implementation for adding CUJ end and
@@ -738,13 +676,7 @@ class DesktopTasksController(
moveHomeTask(context.displayId, wct)
}
}
- val taskIdToMinimize =
- prepareMoveTaskToDeskAndActivate(
- wct = wct,
- displayId = taskInfo.displayId,
- deskId = deskId,
- task = taskInfo,
- )
+ val taskIdToMinimize = addDeskActivationWithMovingTaskChanges(deskId, wct, taskInfo)
val exitResult =
desktopImmersiveController.exitImmersiveIfApplicable(
wct = wct,
@@ -818,7 +750,6 @@ class DesktopTasksController(
displayId = displayId,
forceExitDesktop = false,
)
- taskRepository.setPipShouldKeepDesktopActive(displayId, keepActive = true)
val desktopExitRunnable =
performDesktopExitCleanUp(
wct = wct,
@@ -888,7 +819,6 @@ class DesktopTasksController(
val wct = WindowContainerTransaction()
snapEventHandler.removeTaskIfTiled(displayId, taskId)
- taskRepository.setPipShouldKeepDesktopActive(displayId, keepActive = true)
val willExitDesktop = willExitDesktop(taskId, displayId, forceExitDesktop = false)
val desktopExitRunnable =
performDesktopExitCleanUp(
@@ -1003,11 +933,9 @@ class DesktopTasksController(
// handles case where we are moving to full screen without closing all DW tasks.
if (
!taskRepository.isOnlyVisibleNonClosingTask(task.taskId)
- // This callback is already invoked by |addMoveToFullscreenChanges| when one of these
- // flags is enabled.
- &&
- !DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue &&
- !Flags.enableDesktopWindowingPip()
+ // This callback is already invoked by |addMoveToFullscreenChanges| when this flag is
+ // enabled.
+ && !DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue
) {
desktopModeEnterExitTransitionListener?.onExitDesktopModeTransitionStarted(
FULLSCREEN_ANIMATION_DURATION
@@ -1733,12 +1661,6 @@ class DesktopTasksController(
}
}
- private fun bringDesktopAppsToFrontBeforeShowingNewTask(
- displayId: Int,
- wct: WindowContainerTransaction,
- newTaskIdInFront: Int,
- ): Int? = bringDesktopAppsToFront(displayId, wct, newTaskIdInFront)
-
@Deprecated("Use activeDesk() instead.", ReplaceWith("activateDesk()"))
private fun bringDesktopAppsToFront(
displayId: Int,
@@ -1911,11 +1833,7 @@ class DesktopTasksController(
displayId: Int,
forceExitDesktop: Boolean,
): Boolean {
- if (
- forceExitDesktop &&
- (Flags.enableDesktopWindowingPip() ||
- DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue)
- ) {
+ if (forceExitDesktop && DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
// |forceExitDesktop| is true when the callers knows we'll exit desktop, such as when
// explicitly going fullscreen, so there's no point in checking the desktop state.
return true
@@ -1924,11 +1842,6 @@ class DesktopTasksController(
if (!taskRepository.isOnlyVisibleNonClosingTask(triggerTaskId, displayId)) {
return false
}
- } else if (
- Flags.enableDesktopWindowingPip() &&
- taskRepository.isMinimizedPipPresentInDisplay(displayId)
- ) {
- return false
} else {
if (!taskRepository.isOnlyVisibleNonClosingTask(triggerTaskId)) {
return false
@@ -1945,7 +1858,6 @@ class DesktopTasksController(
forceToFullscreen: Boolean,
shouldEndUpAtHome: Boolean = true,
): RunOnTransitStart? {
- taskRepository.setPipShouldKeepDesktopActive(displayId, keepActive = !forceToFullscreen)
if (!willExitDesktop(taskId, displayId, forceToFullscreen)) {
return null
}
@@ -2363,7 +2275,7 @@ class DesktopTasksController(
runOnTransitStart?.invoke(transition)
return wct
}
- bringDesktopAppsToFrontBeforeShowingNewTask(task.displayId, wct, task.taskId)
+ bringDesktopAppsToFront(task.displayId, wct, task.taskId)
wct.reorder(task.token, true)
return wct
}
@@ -2434,7 +2346,7 @@ class DesktopTasksController(
task.baseIntent.flags.and(Intent.FLAG_ACTIVITY_TASK_ON_HOME) != 0 ||
!isDesktopModeShowing(task.displayId)
) {
- bringDesktopAppsToFrontBeforeShowingNewTask(task.displayId, wct, task.taskId)
+ bringDesktopAppsToFront(task.displayId, wct, task.taskId)
wct.reorder(task.token, true)
}
@@ -2559,6 +2471,20 @@ class DesktopTasksController(
}
/**
+ * Applies the [wct] changes need when a task is first moving to a desk and the desk needs to be
+ * activated.
+ */
+ private fun addDeskActivationWithMovingTaskChanges(
+ deskId: Int,
+ wct: WindowContainerTransaction,
+ task: RunningTaskInfo,
+ ): Int? {
+ val taskIdToMinimize = addDeskActivationChanges(deskId, wct, task)
+ addMoveToDeskTaskChanges(wct = wct, task = task, deskId = deskId)
+ return taskIdToMinimize
+ }
+
+ /**
* Applies the [wct] changes needed when a task is first moving to a desk.
*
* Note that this recalculates the initial bounds of the task, so it should not be used when
@@ -2697,7 +2623,6 @@ class DesktopTasksController(
if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
wct.reparent(taskInfo.token, tdaInfo.token, /* onTop= */ true)
}
- taskRepository.setPipShouldKeepDesktopActive(taskInfo.displayId, keepActive = false)
val deskId = taskRepository.getDeskIdForTask(taskInfo.taskId)
return performDesktopExitCleanUp(
wct = wct,
@@ -2827,9 +2752,13 @@ class DesktopTasksController(
}
/** Activates the given desk but without starting a transition. */
- fun addDeskActivationChanges(deskId: Int, wct: WindowContainerTransaction) {
+ fun addDeskActivationChanges(
+ deskId: Int,
+ wct: WindowContainerTransaction,
+ newTask: RunningTaskInfo? = null,
+ ): Int? {
val displayId = taskRepository.getDisplayForDesk(deskId)
- if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
+ return if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
prepareForDeskActivation(displayId, wct)
desksOrganizer.activateDesk(wct, deskId)
if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) {
@@ -2838,8 +2767,12 @@ class DesktopTasksController(
taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate(
doesAnyTaskRequireTaskbarRounding(displayId)
)
+ // TODO: b/362720497 - activating a desk with the intention to move a new task to
+ // it means we may need to minimize something in the activating desk. Do so here
+ // similar to how it's done in #bringDesktopAppsToFront instead of returning null.
+ null
} else {
- bringDesktopAppsToFront(displayId, wct)
+ bringDesktopAppsToFront(displayId, wct, newTask?.taskId)
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt
index df2cf67fced2..26a5d5b52358 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt
@@ -25,7 +25,6 @@ import android.view.WindowManager.TRANSIT_CLOSE
import android.view.WindowManager.TRANSIT_OPEN
import android.view.WindowManager.TRANSIT_PIP
import android.view.WindowManager.TRANSIT_TO_BACK
-import android.view.WindowManager.TRANSIT_TO_FRONT
import android.window.DesktopExperienceFlags
import android.window.DesktopModeFlags
import android.window.DesktopModeFlags.ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER
@@ -332,10 +331,6 @@ class DesktopTasksTransitionObserver(
taskInfo.token,
taskInfo.displayId,
)
- desktopWallpaperActivityTokenProvider.setWallpaperActivityIsVisible(
- isVisible = true,
- taskInfo.displayId,
- )
// After the task for the wallpaper is created, set it non-trimmable.
// This is important to prevent recents from trimming and removing the
// task.
@@ -346,16 +341,6 @@ class DesktopTasksTransitionObserver(
}
TRANSIT_CLOSE ->
desktopWallpaperActivityTokenProvider.removeToken(taskInfo.displayId)
- TRANSIT_TO_FRONT ->
- desktopWallpaperActivityTokenProvider.setWallpaperActivityIsVisible(
- isVisible = true,
- taskInfo.displayId,
- )
- TRANSIT_TO_BACK ->
- desktopWallpaperActivityTokenProvider.setWallpaperActivityIsVisible(
- isVisible = false,
- taskInfo.displayId,
- )
else -> {}
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/desktopwallpaperactivity/DesktopWallpaperActivityTokenProvider.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/desktopwallpaperactivity/DesktopWallpaperActivityTokenProvider.kt
index b5490cb4b595..d185ed53f78a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/desktopwallpaperactivity/DesktopWallpaperActivityTokenProvider.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/desktopwallpaperactivity/DesktopWallpaperActivityTokenProvider.kt
@@ -17,7 +17,6 @@
package com.android.wm.shell.desktopmode.desktopwallpaperactivity
import android.util.SparseArray
-import android.util.SparseBooleanArray
import android.view.Display.DEFAULT_DISPLAY
import android.window.WindowContainerToken
import androidx.core.util.keyIterator
@@ -28,7 +27,6 @@ import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
class DesktopWallpaperActivityTokenProvider {
private val wallpaperActivityTokenByDisplayId = SparseArray<WindowContainerToken>()
- private val wallpaperActivityVisByDisplayId = SparseBooleanArray()
fun setToken(token: WindowContainerToken, displayId: Int = DEFAULT_DISPLAY) {
logV("Setting desktop wallpaper activity token for display %s", displayId)
@@ -55,18 +53,6 @@ class DesktopWallpaperActivityTokenProvider {
}
}
- fun setWallpaperActivityIsVisible(
- isVisible: Boolean = false,
- displayId: Int = DEFAULT_DISPLAY,
- ) {
- wallpaperActivityVisByDisplayId.put(displayId, isVisible)
- }
-
- fun isWallpaperActivityVisible(displayId: Int = DEFAULT_DISPLAY): Boolean {
- return wallpaperActivityTokenByDisplayId[displayId] != null &&
- wallpaperActivityVisByDisplayId.get(displayId, false)
- }
-
private fun logV(msg: String, vararg arguments: Any?) {
ProtoLog.v(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/dagger.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/dagger.md
index 9b09904527bf..84525a741480 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/dagger.md
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/dagger.md
@@ -1,4 +1,5 @@
# Usage of Dagger in the Shell library
+
[Back to home](README.md)
---
@@ -16,36 +17,69 @@ As such, the Shell also tries to provide some reasonable out-of-the-box modules
## Modules
All the Dagger related code in the Shell can be found in the `com.android.wm.shell.dagger` package,
-this is intentional as it keeps the "magic" in a single location. The explicit nature of how
+this is intentional as it keeps the "magic" in a single location. The explicit nature of how
components in the shell are provided is as a result a bit more verbose, but it makes it easy for
developers to jump into a few select files and understand how different components are provided
(especially as products override components).
The module dependency tree looks a bit like:
+
- [WMShellConcurrencyModule](/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java)
(provides threading-related components)
- - [WMShellBaseModule](/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java)
- (provides components that are likely common to all products, ie. DisplayController,
- Transactions, etc.)
- - [WMShellModule](/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java)
- (phone/tablet specific components only)
- - [TvPipModule](/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java)
- (PIP specific components for TV)
- - [TvWMShellModule](/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java)
- (TV specific components only)
- - etc.
+ - [WMShellBaseModule](/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java)
+ (provides components that are common to many products, ie. DisplayController, Transactions,
+ etc.)
+ - [WMShellModule](/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java)
+ (phone/tablet specific components only)
+ - [TvPipModule](/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java)
+ (PIP specific components for TV)
+ - [TvWMShellModule](/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java)
+ (TV specific components only)
+ - etc.
Ideally features could be abstracted out into their own modules and included as needed by each
product.
+## Changing WMShellBaseModule
+
+Because all products will include WMShellBaseModule, we don't want it to provide instances for
+features that aren't used across multiple products (ie. Handheld, TV, Auto, Wear). This module
+should generally only provide:
+
+- Concrete implementations that are needed for startup
+ (see `provideIndependentShellComponentsToCreate()`)
+- Things used directly/indirectly by interfaces
+ exposed to SysUI
+ in [WMComponent.java](/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMComponent.java).
+
+For the latter, not every feature will be enabled on the SysUI form factor including the base
+module, so the recommendation is to have an `@BindsOptionalOf` for the interface, and have the
+actual implementation provided in the form-factor specific module (ie. `WMShellModule`).
+
## Overriding base components
In some rare cases, there are base components that can change behavior depending on which
-product it runs on. If there are hooks that can be added to the component, that is the
+product it runs on. If there are hooks that can be added to the component, that is the
preferable approach.
-The alternative is to use the [@DynamicOverride](/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/DynamicOverride.java)
+The alternative is to use
+the [@DynamicOverride](/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/DynamicOverride.java)
annotation to allow the product module to provide an implementation that the base module can
-reference. This is most useful if the existence of the entire component is controlled by the
-product and the override implementation is optional (there is a default implementation). More
-details can be found in the class's javadoc. \ No newline at end of file
+reference. This is most useful if the existence of the entire component is controlled by the
+product and the override implementation is optional (there is a default implementation). More
+details can be found in the class's javadoc.
+
+## Starting up Shell components aren't dependencies for other components
+
+With Dagger, objects are created in dependency order and individual components can register with
+`ShellInit` (see [Component initialization](changes.md#component-initialization)) to initialize in
+dependency order as well. However, if there is code that needs to run on startup but has nothing
+dependent on it (imagine a background error detector for example), then
+`provideIndependentShellComponentsToCreate()` can serve as the artificial dependent object (itself
+a dependency for `ShellInterface`) to trigger creation of such a component.
+
+This can be declared within each module, so if a product includes `WMShellModule`, all the
+components in `provideIndependentShellComponentsToCreate()` for both it and `WMShellBaseModule` will
+be created.
+
+Note that long term we are looking to move to a `CoreStartable` like infrastructure. \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
index 6012fe66188d..119763ff2022 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
@@ -238,7 +238,10 @@ public class PipController implements ConfigurationChangeListener,
@Override
public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) {
- if (task.getWindowingMode() != WINDOWING_MODE_PINNED) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "onActivityRestartAttempt: topActivity=%s, wasVisible=%b",
+ task.topActivity, wasVisible);
+ if (task.getWindowingMode() != WINDOWING_MODE_PINNED || !wasVisible) {
return;
}
mPipScheduler.scheduleExitPipViaExpand();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipInteractionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipInteractionHandler.java
new file mode 100644
index 000000000000..321952480094
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipInteractionHandler.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.pip2.phone;
+
+import static com.android.internal.jank.Cuj.CUJ_PIP_TRANSITION;
+
+import android.annotation.IntDef;
+import android.content.Context;
+import android.os.Handler;
+import android.view.SurfaceControl;
+
+import com.android.internal.jank.InteractionJankMonitor;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Helps track PIP CUJ interactions
+ */
+public class PipInteractionHandler {
+ @IntDef(prefix = {"INTERACTION_"}, value = {
+ INTERACTION_EXIT_PIP,
+ INTERACTION_EXIT_PIP_TO_SPLIT
+ })
+
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Interaction {}
+
+ public static final int INTERACTION_EXIT_PIP = 0;
+ public static final int INTERACTION_EXIT_PIP_TO_SPLIT = 1;
+
+ private final Context mContext;
+ private final Handler mHandler;
+ private final InteractionJankMonitor mInteractionJankMonitor;
+
+ public PipInteractionHandler(Context context, Handler handler,
+ InteractionJankMonitor interactionJankMonitor) {
+ mContext = context;
+ mHandler = handler;
+ mInteractionJankMonitor = interactionJankMonitor;
+ }
+
+ /**
+ * Begin tracking PIP CUJ.
+ *
+ * @param leash PIP leash.
+ * @param interaction Tag for interaction.
+ */
+ public void begin(SurfaceControl leash, @Interaction int interaction) {
+ mInteractionJankMonitor.begin(leash, mContext, mHandler, CUJ_PIP_TRANSITION,
+ pipInteractionToString(interaction));
+ }
+
+ /**
+ * End tracking CUJ.
+ */
+ public void end() {
+ mInteractionJankMonitor.end(CUJ_PIP_TRANSITION);
+ }
+
+ /**
+ * Converts an interaction to a string representation used for tagging.
+ *
+ * @param interaction Interaction to track.
+ * @return String representation of the interaction.
+ */
+ public static String pipInteractionToString(@Interaction int interaction) {
+ return switch (interaction) {
+ case INTERACTION_EXIT_PIP -> "EXIT_PIP";
+ case INTERACTION_EXIT_PIP_TO_SPLIT -> "EXIT_PIP_TO_SPLIT";
+ default -> "";
+ };
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
index 91fbd456eb63..9bb2e38e1526 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
@@ -113,6 +113,7 @@ public class PipTransition extends PipTransitionController implements
private final DisplayController mDisplayController;
private final PipSurfaceTransactionHelper mPipSurfaceTransactionHelper;
private final PipDesktopState mPipDesktopState;
+ private final PipInteractionHandler mPipInteractionHandler;
//
// Transition caches
@@ -154,7 +155,8 @@ public class PipTransition extends PipTransitionController implements
PipUiStateChangeController pipUiStateChangeController,
DisplayController displayController,
Optional<SplitScreenController> splitScreenControllerOptional,
- PipDesktopState pipDesktopState) {
+ PipDesktopState pipDesktopState,
+ PipInteractionHandler pipInteractionHandler) {
super(shellInit, shellTaskOrganizer, transitions, pipBoundsState, pipMenuController,
pipBoundsAlgorithm);
@@ -168,9 +170,11 @@ public class PipTransition extends PipTransitionController implements
mDisplayController = displayController;
mPipSurfaceTransactionHelper = new PipSurfaceTransactionHelper(mContext);
mPipDesktopState = pipDesktopState;
+ mPipInteractionHandler = pipInteractionHandler;
mExpandHandler = new PipExpandHandler(mContext, pipBoundsState, pipBoundsAlgorithm,
- pipTransitionState, pipDisplayLayoutState, splitScreenControllerOptional);
+ pipTransitionState, pipDisplayLayoutState, pipInteractionHandler,
+ splitScreenControllerOptional);
}
@Override
@@ -770,7 +774,7 @@ public class PipTransition extends PipTransitionController implements
// Since opening a new task while in Desktop Mode always first open in Fullscreen
// until DesktopMode Shell code resolves it to Freeform, PipTransition will get a
// possibility to handle it also. In this case return false to not have it enter PiP.
- if (mPipDesktopState.isPipEnteringInDesktopMode(pipTask)) {
+ if (mPipDesktopState.isPipInDesktopMode()) {
return false;
}
@@ -794,9 +798,26 @@ public class PipTransition extends PipTransitionController implements
setEnterAnimationType(ANIM_TYPE_BOUNDS);
return true;
}
- // If the only change in the changes list is a opening type PiP task,
+
+ // Sometimes root PiP task can have TF children. These child containers can be collected
+ // even if they can promote to their parents: e.g. if they are marked as "organized".
+ // So we count the chain of containers under PiP task as one "real" changing target;
+ // iterate through changes bottom-to-top to properly identify parents.
+ int expectedTargetCount = 1;
+ WindowContainerToken lastPipChildToken = pipChange.getContainer();
+ for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+ TransitionInfo.Change change = info.getChanges().get(i);
+ if (change == pipChange || change.getContainer() == null) continue;
+ if (change.getParent() != null && change.getParent().equals(lastPipChildToken)) {
+ // Allow an extra change since our pinned root task has a child.
+ ++expectedTargetCount;
+ lastPipChildToken = change.getContainer();
+ }
+ }
+
+ // If the only root task change in the changes list is a opening type PiP task,
// then this is legacy-enter PiP.
- return info.getChanges().size() == 1
+ return info.getChanges().size() == expectedTargetCount
&& TransitionUtil.isOpeningMode(pipChange.getMode());
}
return false;
@@ -930,14 +951,6 @@ public class PipTransition extends PipTransitionController implements
"Unexpected bundle for " + mPipTransitionState);
break;
case PipTransitionState.EXITED_PIP:
- if (mPipDesktopState.shouldExitPipExitDesktopMode()) {
- mTransitions.startTransition(
- TRANSIT_TO_BACK,
- mPipDesktopState.getWallpaperActivityTokenWct(
- mPipTransitionState.getPipTaskInfo().getDisplayId()),
- null /* firstHandler */
- );
- }
mPipTransitionState.setPinnedTaskLeash(null);
mPipTransitionState.setPipTaskInfo(null);
mPendingRemoveWithFadeout = false;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
index 18c9a705dcf7..9e2fbfe2e282 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
@@ -26,9 +26,11 @@ import android.window.WindowContainerToken;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.Preconditions;
+import com.android.wm.shell.common.pip.PipDesktopState;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.shared.annotations.ShellMainThread;
@@ -123,6 +125,8 @@ public class PipTransitionState {
@ShellMainThread
private final Handler mMainHandler;
+ private final PipDesktopState mPipDesktopState;
+
//
// Swipe up to enter PiP related state
//
@@ -172,8 +176,9 @@ public class PipTransitionState {
private final List<PipTransitionStateChangedListener> mCallbacks = new ArrayList<>();
- public PipTransitionState(@ShellMainThread Handler handler) {
+ public PipTransitionState(@ShellMainThread Handler handler, PipDesktopState pipDesktopState) {
mMainHandler = handler;
+ mPipDesktopState = pipDesktopState;
}
/**
@@ -384,12 +389,16 @@ public class PipTransitionState {
return ++mPrevCustomState;
}
- private boolean shouldTransitionToState(@TransitionState int newState) {
+ @VisibleForTesting
+ boolean shouldTransitionToState(@TransitionState int newState) {
switch (newState) {
case SCHEDULED_BOUNDS_CHANGE:
- // Allow scheduling bounds change only while in PiP, except for if another bounds
- // change was scheduled but hasn't started playing yet.
- return isInPip();
+ // Allow scheduling bounds change only when both of these are true:
+ // - while in PiP, except for if another bounds change was scheduled but hasn't
+ // started playing yet
+ // - there is no drag-to-desktop gesture in progress; otherwise the PiP resize
+ // transition will block the drag-to-desktop transitions from finishing
+ return isInPip() && !mPipDesktopState.isDragToDesktopInProgress();
default:
return true;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/transition/PipExpandHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/transition/PipExpandHandler.java
index db4942b2fb95..3274f4ae354a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/transition/PipExpandHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/transition/PipExpandHandler.java
@@ -45,6 +45,7 @@ import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
import com.android.wm.shell.common.pip.PipBoundsState;
import com.android.wm.shell.common.pip.PipDisplayLayoutState;
import com.android.wm.shell.pip2.animation.PipExpandAnimator;
+import com.android.wm.shell.pip2.phone.PipInteractionHandler;
import com.android.wm.shell.pip2.phone.PipTransitionState;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.splitscreen.SplitScreenController;
@@ -58,6 +59,7 @@ public class PipExpandHandler implements Transitions.TransitionHandler {
private final PipBoundsAlgorithm mPipBoundsAlgorithm;
private final PipTransitionState mPipTransitionState;
private final PipDisplayLayoutState mPipDisplayLayoutState;
+ private final PipInteractionHandler mPipInteractionHandler;
private final Optional<SplitScreenController> mSplitScreenControllerOptional;
@Nullable
@@ -72,12 +74,14 @@ public class PipExpandHandler implements Transitions.TransitionHandler {
PipBoundsAlgorithm pipBoundsAlgorithm,
PipTransitionState pipTransitionState,
PipDisplayLayoutState pipDisplayLayoutState,
+ PipInteractionHandler pipInteractionHandler,
Optional<SplitScreenController> splitScreenControllerOptional) {
mContext = context;
mPipBoundsState = pipBoundsState;
mPipBoundsAlgorithm = pipBoundsAlgorithm;
mPipTransitionState = pipTransitionState;
mPipDisplayLayoutState = pipDisplayLayoutState;
+ mPipInteractionHandler = pipInteractionHandler;
mSplitScreenControllerOptional = splitScreenControllerOptional;
mPipExpandAnimatorSupplier = PipExpandAnimator::new;
@@ -183,6 +187,8 @@ public class PipExpandHandler implements Transitions.TransitionHandler {
PipExpandAnimator animator = mPipExpandAnimatorSupplier.get(mContext, pipLeash,
startTransaction, finishTransaction, endBounds, startBounds, endBounds,
sourceRectHint, delta);
+ animator.setAnimationStartCallback(() -> mPipInteractionHandler.begin(pipLeash,
+ PipInteractionHandler.INTERACTION_EXIT_PIP));
animator.setAnimationEndCallback(() -> {
if (parentBeforePip != null) {
// TODO b/377362511: Animate local leash instead to also handle letterbox case.
@@ -190,6 +196,7 @@ public class PipExpandHandler implements Transitions.TransitionHandler {
finishTransaction.setCrop(pipLeash, null);
}
finishTransition();
+ mPipInteractionHandler.end();
});
cacheAndStartTransitionAnimator(animator);
saveReentryState();
@@ -248,6 +255,8 @@ public class PipExpandHandler implements Transitions.TransitionHandler {
splitController.finishEnterSplitScreen(finishTransaction);
});
+ animator.setAnimationStartCallback(() -> mPipInteractionHandler.begin(pipLeash,
+ PipInteractionHandler.INTERACTION_EXIT_PIP_TO_SPLIT));
animator.setAnimationEndCallback(() -> {
if (parentBeforePip == null) {
// After PipExpandAnimator is done modifying finishTransaction, we need to make
@@ -256,6 +265,7 @@ public class PipExpandHandler implements Transitions.TransitionHandler {
finishTransaction.setPosition(pipLeash, 0, 0);
}
finishTransition();
+ mPipInteractionHandler.end();
});
cacheAndStartTransitionAnimator(animator);
saveReentryState();
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 30e5c2ae0914..2a5315739396 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
@@ -1702,6 +1702,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
mExclusionRegionListener.onExclusionRegionDismissed(mTaskInfo.taskId);
disposeResizeVeil();
disposeStatusBarInputLayer();
+ mWindowDecorViewHolder.close();
mWindowDecorViewHolder = null;
if (canEnterDesktopMode(mContext) && isEducationEnabled()) {
notifyNoCaptionHandle();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
index 2948fdaf16af..d9df899f8b40 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
@@ -274,4 +274,6 @@ internal class AppHandleViewHolder(
}
animator.start()
}
+
+ override fun close() {}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
index eb8b617df4ce..8b054335d11c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
@@ -725,6 +725,11 @@ class AppHeaderViewHolder(
Configuration.UI_MODE_NIGHT_YES
}
+ override fun close() {
+ // Should not fire long press events after closing the window decoration.
+ maximizeWindowButton.cancelLongPress()
+ }
+
companion object {
private const val TAG = "DesktopModeAppControlsWindowDecorationViewHolder"
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/WindowDecorationViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/WindowDecorationViewHolder.kt
index 1fe743da966a..cd202bfbd29e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/WindowDecorationViewHolder.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/WindowDecorationViewHolder.kt
@@ -24,7 +24,7 @@ import com.android.wm.shell.windowdecor.viewholder.WindowDecorationViewHolder.Da
* Encapsulates the root [View] of a window decoration and its children to facilitate looking up
* children (via findViewById) and updating to the latest data from [RunningTaskInfo].
*/
-abstract class WindowDecorationViewHolder<T : Data>(rootView: View) {
+abstract class WindowDecorationViewHolder<T : Data>(rootView: View) : AutoCloseable {
val context: Context = rootView.context
/**
@@ -39,6 +39,9 @@ abstract class WindowDecorationViewHolder<T : Data>(rootView: View) {
/** Callback when the handle menu is closed. */
abstract fun onHandleMenuClosed()
+ /** Callback when the window decoration is destroyed. */
+ abstract override fun close()
+
/** Data clas that contains the information needed to update the view holder. */
abstract class Data
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipDesktopStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipDesktopStateTest.java
index e85d30fbaebd..4cdb1e5b5d10 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipDesktopStateTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipDesktopStateTest.java
@@ -41,7 +41,7 @@ import androidx.test.filters.SmallTest;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.desktopmode.DesktopRepository;
import com.android.wm.shell.desktopmode.DesktopUserRepositories;
-import com.android.wm.shell.desktopmode.desktopwallpaperactivity.DesktopWallpaperActivityTokenProvider;
+import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler;
import org.junit.Before;
import org.junit.Test;
@@ -62,11 +62,12 @@ import java.util.Optional;
public class PipDesktopStateTest {
@Mock private PipDisplayLayoutState mMockPipDisplayLayoutState;
@Mock private Optional<DesktopUserRepositories> mMockDesktopUserRepositoriesOptional;
- @Mock private Optional<DesktopWallpaperActivityTokenProvider>
- mMockDesktopWallpaperActivityTokenProviderOptional;
@Mock private DesktopUserRepositories mMockDesktopUserRepositories;
- @Mock private DesktopWallpaperActivityTokenProvider mMockDesktopWallpaperActivityTokenProvider;
@Mock private DesktopRepository mMockDesktopRepository;
+ @Mock
+ private Optional<DragToDesktopTransitionHandler> mMockDragToDesktopTransitionHandlerOptional;
+ @Mock private DragToDesktopTransitionHandler mMockDragToDesktopTransitionHandler;
+
@Mock private RootTaskDisplayAreaOrganizer mMockRootTaskDisplayAreaOrganizer;
@Mock private ActivityManager.RunningTaskInfo mMockTaskInfo;
@@ -78,11 +79,12 @@ public class PipDesktopStateTest {
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mMockDesktopUserRepositoriesOptional.get()).thenReturn(mMockDesktopUserRepositories);
- when(mMockDesktopWallpaperActivityTokenProviderOptional.get()).thenReturn(
- mMockDesktopWallpaperActivityTokenProvider);
when(mMockDesktopUserRepositories.getCurrent()).thenReturn(mMockDesktopRepository);
when(mMockDesktopUserRepositoriesOptional.isPresent()).thenReturn(true);
- when(mMockDesktopWallpaperActivityTokenProviderOptional.isPresent()).thenReturn(true);
+
+ when(mMockDragToDesktopTransitionHandlerOptional.get()).thenReturn(
+ mMockDragToDesktopTransitionHandler);
+ when(mMockDragToDesktopTransitionHandlerOptional.isPresent()).thenReturn(true);
when(mMockTaskInfo.getDisplayId()).thenReturn(DISPLAY_ID);
when(mMockPipDisplayLayoutState.getDisplayId()).thenReturn(DISPLAY_ID);
@@ -93,7 +95,7 @@ public class PipDesktopStateTest {
mPipDesktopState = new PipDesktopState(mMockPipDisplayLayoutState,
mMockDesktopUserRepositoriesOptional,
- mMockDesktopWallpaperActivityTokenProviderOptional,
+ mMockDragToDesktopTransitionHandlerOptional,
mMockRootTaskDisplayAreaOrganizer);
}
@@ -110,8 +112,8 @@ public class PipDesktopStateTest {
}
@Test
- public void isDesktopWindowingPipEnabled_desktopWallpaperEmpty_returnsFalse() {
- when(mMockDesktopWallpaperActivityTokenProviderOptional.isPresent()).thenReturn(false);
+ public void isDesktopWindowingPipEnabled_dragToDesktopTransitionHandlerEmpty_returnsFalse() {
+ when(mMockDragToDesktopTransitionHandlerOptional.isPresent()).thenReturn(false);
assertFalse(mPipDesktopState.isDesktopWindowingPipEnabled());
}
@@ -123,59 +125,7 @@ public class PipDesktopStateTest {
}
@Test
- public void isPipEnteringInDesktopMode_visibleCountZero_minimizedPipPresent_returnsTrue() {
- when(mMockDesktopRepository.isAnyDeskActive(DISPLAY_ID)).thenReturn(false);
- when(mMockDesktopRepository.isMinimizedPipPresentInDisplay(DISPLAY_ID)).thenReturn(true);
-
- assertTrue(mPipDesktopState.isPipEnteringInDesktopMode(mMockTaskInfo));
- }
-
- @Test
- public void isPipEnteringInDesktopMode_visibleCountNonzero_minimizedPipAbsent_returnsTrue() {
- when(mMockDesktopRepository.isAnyDeskActive(DISPLAY_ID)).thenReturn(true);
- when(mMockDesktopRepository.isMinimizedPipPresentInDisplay(DISPLAY_ID)).thenReturn(false);
-
- assertTrue(mPipDesktopState.isPipEnteringInDesktopMode(mMockTaskInfo));
- }
-
- @Test
- public void isPipEnteringInDesktopMode_visibleCountZero_minimizedPipAbsent_returnsFalse() {
- when(mMockDesktopRepository.isAnyDeskActive(DISPLAY_ID)).thenReturn(false);
- when(mMockDesktopRepository.isMinimizedPipPresentInDisplay(DISPLAY_ID)).thenReturn(false);
-
- assertFalse(mPipDesktopState.isPipEnteringInDesktopMode(mMockTaskInfo));
- }
-
- @Test
- public void shouldExitPipExitDesktopMode_visibleCountZero_wallpaperInvisible_returnsFalse() {
- when(mMockDesktopRepository.isAnyDeskActive(DISPLAY_ID)).thenReturn(false);
- when(mMockDesktopWallpaperActivityTokenProvider.isWallpaperActivityVisible(
- DISPLAY_ID)).thenReturn(false);
-
- assertFalse(mPipDesktopState.shouldExitPipExitDesktopMode());
- }
-
- @Test
- public void shouldExitPipExitDesktopMode_visibleCountNonzero_wallpaperVisible_returnsFalse() {
- when(mMockDesktopRepository.isAnyDeskActive(DISPLAY_ID)).thenReturn(true);
- when(mMockDesktopWallpaperActivityTokenProvider.isWallpaperActivityVisible(
- DISPLAY_ID)).thenReturn(true);
-
- assertFalse(mPipDesktopState.shouldExitPipExitDesktopMode());
- }
-
- @Test
- public void shouldExitPipExitDesktopMode_visibleCountZero_wallpaperVisible_returnsTrue() {
- when(mMockDesktopRepository.isAnyDeskActive(DISPLAY_ID)).thenReturn(false);
- when(mMockDesktopWallpaperActivityTokenProvider.isWallpaperActivityVisible(
- DISPLAY_ID)).thenReturn(true);
-
- assertTrue(mPipDesktopState.shouldExitPipExitDesktopMode());
- }
-
- @Test
public void getOutPipWindowingMode_exitToDesktop_displayFreeform_returnsUndefined() {
- // Set visible task count to 1 so isPipExitingToDesktopMode returns true
when(mMockDesktopRepository.isAnyDeskActive(DISPLAY_ID)).thenReturn(true);
setDisplayWindowingMode(WINDOWING_MODE_FREEFORM);
@@ -184,7 +134,6 @@ public class PipDesktopStateTest {
@Test
public void getOutPipWindowingMode_exitToDesktop_displayFullscreen_returnsFreeform() {
- // Set visible task count to 1 so isPipExitingToDesktopMode returns true
when(mMockDesktopRepository.isAnyDeskActive(DISPLAY_ID)).thenReturn(true);
setDisplayWindowingMode(WINDOWING_MODE_FULLSCREEN);
@@ -198,6 +147,20 @@ public class PipDesktopStateTest {
assertEquals(WINDOWING_MODE_UNDEFINED, mPipDesktopState.getOutPipWindowingMode());
}
+ @Test
+ public void isDragToDesktopInProgress_inProgress_returnsTrue() {
+ when(mMockDragToDesktopTransitionHandler.getInProgress()).thenReturn(true);
+
+ assertTrue(mPipDesktopState.isDragToDesktopInProgress());
+ }
+
+ @Test
+ public void isDragToDesktopInProgress_notInProgress_returnsFalse() {
+ when(mMockDragToDesktopTransitionHandler.getInProgress()).thenReturn(false);
+
+ assertFalse(mPipDesktopState.isDragToDesktopInProgress());
+ }
+
private void setDisplayWindowingMode(int windowingMode) {
mDefaultTda.configuration.windowConfiguration.setWindowingMode(windowingMode);
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt
index a43b4dd00911..2e74d4391c63 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt
@@ -26,7 +26,6 @@ import android.view.Display.INVALID_DISPLAY
import androidx.test.filters.SmallTest
import com.android.window.flags.Flags
import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PERSISTENCE
-import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP
import com.android.window.flags.Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.TestShellExecutor
@@ -1242,39 +1241,6 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() {
}
@Test
- @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
- fun setPipShouldKeepDesktopActive_shouldKeepDesktopActive() {
- assertThat(repo.shouldDesktopBeActiveForPip(DEFAULT_DESKTOP_ID)).isFalse()
-
- repo.setTaskInPip(DEFAULT_DESKTOP_ID, taskId = 1, enterPip = true)
- repo.setPipShouldKeepDesktopActive(DEFAULT_DESKTOP_ID, keepActive = true)
-
- assertThat(repo.shouldDesktopBeActiveForPip(DEFAULT_DESKTOP_ID)).isTrue()
- }
-
- @Test
- @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
- fun setPipShouldNotKeepDesktopActive_shouldNotKeepDesktopActive() {
- repo.setTaskInPip(DEFAULT_DESKTOP_ID, taskId = 1, enterPip = true)
- assertThat(repo.shouldDesktopBeActiveForPip(DEFAULT_DESKTOP_ID)).isTrue()
-
- repo.setPipShouldKeepDesktopActive(DEFAULT_DESKTOP_ID, keepActive = false)
-
- assertThat(repo.shouldDesktopBeActiveForPip(DEFAULT_DESKTOP_ID)).isFalse()
- }
-
- @Test
- @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
- fun removeTaskInPip_shouldNotKeepDesktopActive() {
- repo.setTaskInPip(DEFAULT_DESKTOP_ID, taskId = 1, enterPip = true)
- assertThat(repo.shouldDesktopBeActiveForPip(DEFAULT_DESKTOP_ID)).isTrue()
-
- repo.setTaskInPip(DEFAULT_DESKTOP_ID, taskId = 1, enterPip = false)
-
- assertThat(repo.shouldDesktopBeActiveForPip(DEFAULT_DESKTOP_ID)).isFalse()
- }
-
- @Test
@DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
fun addTask_deskDoesNotExists_createsDesk() {
repo.addTask(displayId = 999, taskId = 6, isVisible = true)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index 63bf6841dba4..0bccde13cabd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -87,7 +87,6 @@ import com.android.dx.mockito.inline.extended.StaticMockitoSession
import com.android.internal.jank.InteractionJankMonitor
import com.android.window.flags.Flags
import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE
-import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP
import com.android.window.flags.Flags.FLAG_ENABLE_DISPLAY_FOCUS_IN_SHELL_TRANSITIONS
import com.android.window.flags.Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP
import com.android.window.flags.Flags.FLAG_ENABLE_MOVE_TO_NEXT_DISPLAY_SHORTCUT
@@ -656,38 +655,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
}
@Test
- @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
- fun isDesktopModeShowing_minimizedPipTask_wallpaperVisible_returnsTrue() {
- val pipTask = setUpPipTask(autoEnterEnabled = true)
- whenever(desktopWallpaperActivityTokenProvider.isWallpaperActivityVisible())
- .thenReturn(true)
-
- taskRepository.setTaskInPip(DEFAULT_DISPLAY, pipTask.taskId, enterPip = true)
-
- assertThat(controller.isDesktopModeShowing(displayId = DEFAULT_DISPLAY)).isTrue()
- }
-
- @Test
- @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
- fun isDesktopModeShowing_minimizedPipTask_wallpaperNotVisible_returnsFalse() {
- val pipTask = setUpPipTask(autoEnterEnabled = true)
- whenever(desktopWallpaperActivityTokenProvider.isWallpaperActivityVisible())
- .thenReturn(false)
-
- taskRepository.setTaskInPip(DEFAULT_DISPLAY, pipTask.taskId, enterPip = true)
-
- assertThat(controller.isDesktopModeShowing(displayId = DEFAULT_DISPLAY)).isFalse()
- }
-
- @Test
- @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
- fun isDesktopModeShowing_pipTaskNotMinimizedNorVisible_returnsFalse() {
- setUpPipTask(autoEnterEnabled = true)
-
- assertThat(controller.isDesktopModeShowing(displayId = DEFAULT_DISPLAY)).isFalse()
- }
-
- @Test
@EnableFlags(
Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
Flags.FLAG_ENABLE_PER_DISPLAY_DESKTOP_WALLPAPER_ACTIVITY,
@@ -3103,42 +3070,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
}
@Test
- @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
- fun onDesktopWindowClose_minimizedPipPresent_doesNotExitDesktop() {
- val freeformTask = setUpFreeformTask().apply { isFocused = true }
- val pipTask = setUpPipTask(autoEnterEnabled = true)
-
- taskRepository.setTaskInPip(DEFAULT_DISPLAY, pipTask.taskId, enterPip = true)
- val wct = WindowContainerTransaction()
- controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, freeformTask)
-
- verifyExitDesktopWCTNotExecuted()
- }
-
- @Test
- @EnableFlags(
- FLAG_ENABLE_DESKTOP_WINDOWING_PIP,
- Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER,
- )
- fun onDesktopWindowClose_minimizedPipNotPresent_exitDesktop() {
- val freeformTask = setUpFreeformTask()
- val pipTask = setUpPipTask(autoEnterEnabled = true)
- val handler = mock(TransitionHandler::class.java)
- whenever(transitions.dispatchRequest(any(), any(), anyOrNull()))
- .thenReturn(android.util.Pair(handler, WindowContainerTransaction()))
-
- controller.minimizeTask(pipTask, MinimizeReason.MINIMIZE_BUTTON)
- verifyExitDesktopWCTNotExecuted()
-
- taskRepository.setTaskInPip(DEFAULT_DISPLAY, pipTask.taskId, enterPip = false)
- val wct = WindowContainerTransaction()
- controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, freeformTask)
-
- // Moves wallpaper activity to back when leaving desktop
- wct.assertReorder(wallpaperToken, toTop = false)
- }
-
- @Test
@EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
fun onDesktopWindowClose_lastWindow_deactivatesDesk() {
val task = setUpFreeformTask()
@@ -3267,26 +3198,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
}
@Test
- fun onPipTaskMinimize_doesntRemoveWallpaper() {
- val task = setUpPipTask(autoEnterEnabled = true)
- val handler = mock(TransitionHandler::class.java)
- whenever(transitions.dispatchRequest(any(), any(), anyOrNull()))
- .thenReturn(android.util.Pair(handler, WindowContainerTransaction()))
-
- controller.minimizeTask(task, MinimizeReason.MINIMIZE_BUTTON)
-
- val captor = argumentCaptor<WindowContainerTransaction>()
- verify(freeformTaskTransitionStarter).startPipTransition(captor.capture())
- assertThat(
- captor.firstValue.hierarchyOps.none { hop ->
- hop.type == HIERARCHY_OP_TYPE_REMOVE_TASK &&
- hop.container == wallpaperToken.asBinder()
- }
- )
- .isTrue()
- }
-
- @Test
fun onDesktopWindowMinimize_singleActiveTask_noWallpaperActivityToken_doesntRemoveWallpaper() {
val task = setUpFreeformTask(active = true)
val transition = Binder()
@@ -4735,32 +4646,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
}
@Test
- @EnableFlags(
- FLAG_ENABLE_DESKTOP_WINDOWING_PIP,
- Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER,
- )
- fun moveFocusedTaskToFullscreen_minimizedPipPresent_removeWallpaperActivity() {
- val freeformTask = setUpFreeformTask()
- val pipTask = setUpPipTask(autoEnterEnabled = true)
- val handler = mock(TransitionHandler::class.java)
- whenever(transitions.dispatchRequest(any(), any(), anyOrNull()))
- .thenReturn(android.util.Pair(handler, WindowContainerTransaction()))
-
- controller.minimizeTask(pipTask, MinimizeReason.MINIMIZE_BUTTON)
- verifyExitDesktopWCTNotExecuted()
-
- freeformTask.isFocused = true
- controller.enterFullscreen(DEFAULT_DISPLAY, transitionSource = UNKNOWN)
-
- val wct = getLatestExitDesktopWct()
- val taskChange = assertNotNull(wct.changes[freeformTask.token.asBinder()])
- assertThat(taskChange.windowingMode)
- .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN
- // Moves wallpaper activity to back when leaving desktop
- wct.assertReorder(wallpaperToken, toTop = false)
- }
-
- @Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION)
@DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
fun removeDesk_multipleTasks_removesAll() {
@@ -6877,8 +6762,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
}
private fun setUpPipTask(autoEnterEnabled: Boolean): RunningTaskInfo =
- // active = false marks the task as non-visible; PiP window doesn't count as visible tasks
- setUpFreeformTask(active = false).apply {
+ setUpFreeformTask().apply {
pictureInPictureParams =
PictureInPictureParams.Builder().setAutoEnterEnabled(autoEnterEnabled).build()
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt
index 5b0f94f91a13..fd8842b6d99b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt
@@ -340,51 +340,6 @@ class DesktopTasksTransitionObserverTest {
}
@Test
- fun transitOpenWallpaper_wallpaperActivityVisibilitySaved() {
- val wallpaperTask = createWallpaperTaskInfo()
-
- transitionObserver.onTransitionReady(
- transition = mock(),
- info = createOpenChangeTransition(wallpaperTask),
- startTransaction = mock(),
- finishTransaction = mock(),
- )
-
- verify(desktopWallpaperActivityTokenProvider)
- .setWallpaperActivityIsVisible(isVisible = true, wallpaperTask.displayId)
- }
-
- @Test
- fun transitToFrontWallpaper_wallpaperActivityVisibilitySaved() {
- val wallpaperTask = createWallpaperTaskInfo()
-
- transitionObserver.onTransitionReady(
- transition = mock(),
- info = createToFrontTransition(wallpaperTask),
- startTransaction = mock(),
- finishTransaction = mock(),
- )
-
- verify(desktopWallpaperActivityTokenProvider)
- .setWallpaperActivityIsVisible(isVisible = true, wallpaperTask.displayId)
- }
-
- @Test
- fun transitToBackWallpaper_wallpaperActivityVisibilitySaved() {
- val wallpaperTask = createWallpaperTaskInfo()
-
- transitionObserver.onTransitionReady(
- transition = mock(),
- info = createToBackTransition(wallpaperTask),
- startTransaction = mock(),
- finishTransaction = mock(),
- )
-
- verify(desktopWallpaperActivityTokenProvider)
- .setWallpaperActivityIsVisible(isVisible = false, wallpaperTask.displayId)
- }
-
- @Test
fun transitCloseWallpaper_wallpaperActivityVisibilitySaved() {
val wallpaperTask = createWallpaperTaskInfo()
@@ -407,7 +362,7 @@ class DesktopTasksTransitionObserverTest {
transitionObserver.onTransitionReady(
transition = pipTransition,
- info = createOpenChangeTransition(task, TRANSIT_PIP),
+ info = createOpenChangeTransition(task, type = TRANSIT_PIP),
startTransaction = mock(),
finishTransaction = mock(),
)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipInteractionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipInteractionHandlerTest.java
new file mode 100644
index 000000000000..9c0127ea2414
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipInteractionHandlerTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.pip2.phone;
+
+import static com.android.internal.jank.Cuj.CUJ_PIP_TRANSITION;
+import static com.android.wm.shell.pip2.phone.PipInteractionHandler.INTERACTION_EXIT_PIP;
+import static com.android.wm.shell.pip2.phone.PipInteractionHandler.INTERACTION_EXIT_PIP_TO_SPLIT;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.kotlin.VerificationKt.times;
+
+import android.content.Context;
+import android.os.Handler;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.SurfaceControl;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.jank.InteractionJankMonitor;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Unit test against {@link PipInteractionHandler}.
+ */
+@SmallTest
+@TestableLooper.RunWithLooper
+@RunWith(AndroidTestingRunner.class)
+public class PipInteractionHandlerTest {
+ @Mock private Context mMockContext;
+ @Mock private Handler mMockHandler;
+ @Mock private InteractionJankMonitor mMockInteractionJankMonitor;
+
+ private SurfaceControl mTestLeash;
+
+ private PipInteractionHandler mPipInteractionHandler;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mPipInteractionHandler = new PipInteractionHandler(mMockContext, mMockHandler,
+ mMockInteractionJankMonitor);
+ mTestLeash = new SurfaceControl.Builder()
+ .setContainerLayer()
+ .setName("PipInteractionHandlerTest")
+ .setCallsite("PipInteractionHandlerTest")
+ .build();
+ }
+
+ @Test
+ public void begin_expand_startsTracking() {
+ mPipInteractionHandler.begin(mTestLeash, INTERACTION_EXIT_PIP);
+
+ verify(mMockInteractionJankMonitor, times(1)).begin(eq(mTestLeash),
+ eq(mMockContext), eq(mMockHandler), eq(CUJ_PIP_TRANSITION),
+ eq(PipInteractionHandler.pipInteractionToString(INTERACTION_EXIT_PIP)));
+ }
+
+ @Test
+ public void begin_expandToSplit_startsTracking() {
+ mPipInteractionHandler.begin(mTestLeash, INTERACTION_EXIT_PIP_TO_SPLIT);
+
+ verify(mMockInteractionJankMonitor, times(1)).begin(eq(mTestLeash),
+ eq(mMockContext), eq(mMockHandler), eq(CUJ_PIP_TRANSITION),
+ eq(PipInteractionHandler.pipInteractionToString(INTERACTION_EXIT_PIP_TO_SPLIT)));
+ }
+
+ @Test
+ public void end_stopsTracking() {
+ mPipInteractionHandler.end();
+
+ verify(mMockInteractionJankMonitor, times(1)).end(CUJ_PIP_TRANSITION);
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTransitionStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTransitionStateTest.java
index fa9b5903bc3c..66b8ef1ac130 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTransitionStateTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTransitionStateTest.java
@@ -16,12 +16,15 @@
package com.android.wm.shell.pip2.phone;
+import static org.mockito.Mockito.when;
+
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import android.testing.AndroidTestingRunner;
import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.common.pip.PipDesktopState;
import junit.framework.Assert;
@@ -45,9 +48,12 @@ public class PipTransitionStateTest extends ShellTestCase {
@Mock
private Handler mMainHandler;
+ @Mock
+ private PipDesktopState mMockPipDesktopState;
+
@Before
public void setUp() {
- mPipTransitionState = new PipTransitionState(mMainHandler);
+ mPipTransitionState = new PipTransitionState(mMainHandler, mMockPipDesktopState);
mPipTransitionState.setState(PipTransitionState.UNDEFINED);
mEmptyParcelable = new Bundle();
}
@@ -128,4 +134,29 @@ public class PipTransitionStateTest extends ShellTestCase {
mPipTransitionState.setState(PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extra);
Assert.assertEquals(PipTransitionState.EXITING_PIP, mPipTransitionState.getState());
}
+
+ @Test
+ public void testShouldTransitionToState_scheduledBoundsChange_inPip_returnsTrue() {
+ mPipTransitionState.setState(PipTransitionState.ENTERED_PIP);
+
+ Assert.assertTrue(mPipTransitionState.shouldTransitionToState(
+ PipTransitionState.SCHEDULED_BOUNDS_CHANGE));
+ }
+
+ @Test
+ public void testShouldTransitionToState_scheduledBoundsChange_notInPip_returnsFalse() {
+ mPipTransitionState.setState(PipTransitionState.EXITED_PIP);
+
+ Assert.assertFalse(mPipTransitionState.shouldTransitionToState(
+ PipTransitionState.SCHEDULED_BOUNDS_CHANGE));
+ }
+
+ @Test
+ public void testShouldTransitionToState_scheduledBoundsChange_dragToDesktop_returnsFalse() {
+ mPipTransitionState.setState(PipTransitionState.ENTERED_PIP);
+ when(mMockPipDesktopState.isDragToDesktopInProgress()).thenReturn(true);
+
+ Assert.assertFalse(mPipTransitionState.shouldTransitionToState(
+ PipTransitionState.SCHEDULED_BOUNDS_CHANGE));
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/transition/PipExpandHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/transition/PipExpandHandlerTest.java
index 2a22842eda1a..cc66f00525b5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/transition/PipExpandHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/transition/PipExpandHandlerTest.java
@@ -23,6 +23,7 @@ import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP;
import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP_TO_SPLIT;
import static org.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -48,11 +49,13 @@ import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
import com.android.wm.shell.common.pip.PipBoundsState;
import com.android.wm.shell.common.pip.PipDisplayLayoutState;
import com.android.wm.shell.pip2.animation.PipExpandAnimator;
+import com.android.wm.shell.pip2.phone.PipInteractionHandler;
import com.android.wm.shell.pip2.phone.PipTransitionState;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.transition.TransitionInfoBuilder;
@@ -61,6 +64,8 @@ import com.android.wm.shell.util.StubTransaction;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -79,6 +84,7 @@ public class PipExpandHandlerTest {
@Mock private PipBoundsAlgorithm mMockPipBoundsAlgorithm;
@Mock private PipTransitionState mMockPipTransitionState;
@Mock private PipDisplayLayoutState mMockPipDisplayLayoutState;
+ @Mock private PipInteractionHandler mMockPipInteractionHandler;
@Mock private SplitScreenController mMockSplitScreenController;
@Mock private IBinder mMockTransitionToken;
@@ -89,6 +95,8 @@ public class PipExpandHandlerTest {
@Mock private PipExpandAnimator mMockPipExpandAnimator;
+ @Captor private ArgumentCaptor<Runnable> mAnimatorCallbackArgumentCaptor;
+
@Surface.Rotation
private static final int DISPLAY_ROTATION = Surface.ROTATION_0;
@@ -108,7 +116,7 @@ public class PipExpandHandlerTest {
mPipExpandHandler = new PipExpandHandler(mMockContext, mMockPipBoundsState,
mMockPipBoundsAlgorithm, mMockPipTransitionState, mMockPipDisplayLayoutState,
- Optional.of(mMockSplitScreenController));
+ mMockPipInteractionHandler, Optional.of(mMockSplitScreenController));
mPipExpandHandler.setPipExpandAnimatorSupplier((context, leash, startTransaction,
finishTransaction, baseBounds, startBounds, endBounds,
sourceRectHint, rotation) -> mMockPipExpandAnimator);
@@ -138,6 +146,13 @@ public class PipExpandHandlerTest {
verify(mMockPipExpandAnimator, times(1)).start();
verify(mMockPipBoundsState, times(1)).saveReentryState(SNAP_FRACTION);
+
+ verify(mMockPipExpandAnimator, times(1))
+ .setAnimationStartCallback(mAnimatorCallbackArgumentCaptor.capture());
+ InstrumentationRegistry.getInstrumentation()
+ .runOnMainSync(mAnimatorCallbackArgumentCaptor.getValue());
+ verify(mMockPipInteractionHandler, times(1)).begin(any(),
+ eq(PipInteractionHandler.INTERACTION_EXIT_PIP));
}
@Test
@@ -158,6 +173,13 @@ public class PipExpandHandlerTest {
verify(mMockSplitScreenController, times(1)).finishEnterSplitScreen(eq(mFinishT));
verify(mMockPipExpandAnimator, times(1)).start();
verify(mMockPipBoundsState, times(1)).saveReentryState(SNAP_FRACTION);
+
+ verify(mMockPipExpandAnimator, times(1))
+ .setAnimationStartCallback(mAnimatorCallbackArgumentCaptor.capture());
+ InstrumentationRegistry.getInstrumentation()
+ .runOnMainSync(mAnimatorCallbackArgumentCaptor.getValue());
+ verify(mMockPipInteractionHandler, times(1)).begin(any(),
+ eq(PipInteractionHandler.INTERACTION_EXIT_PIP_TO_SPLIT));
}
private TransitionInfo getExpandFromPipTransitionInfo(@WindowManager.TransitionType int type,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/bubbles/DropTargetManagerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/bubbles/DropTargetManagerTest.kt
index 3f7f21ef2074..95498cbbe53c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/bubbles/DropTargetManagerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/bubbles/DropTargetManagerTest.kt
@@ -65,7 +65,7 @@ class DropTargetManagerTest {
container = FrameLayout(context)
dragZoneChangedListener = FakeDragZoneChangedListener()
dropTargetManager =
- DropTargetManager(context, container, isLayoutRtl = false, dragZoneChangedListener)
+ DropTargetManager(context, container, dragZoneChangedListener)
}
@Test
@@ -228,6 +228,22 @@ class DropTargetManagerTest {
}
@Test
+ fun onDragEnded_dropTargetNotifies() {
+ dropTargetManager.onDragStarted(
+ DraggedObject.Bubble(BubbleBarLocation.LEFT),
+ listOf(bubbleLeftDragZone, bubbleRightDragZone, dismissDragZone)
+ )
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ dropTargetManager.onDragUpdated(
+ bubbleRightDragZone.bounds.centerX(),
+ bubbleRightDragZone.bounds.centerY()
+ )
+ dropTargetManager.onDragEnded()
+ }
+ assertThat(dragZoneChangedListener.endedDragZone).isEqualTo(bubbleRightDragZone)
+ }
+
+ @Test
fun startNewDrag_beforeDropTargetRemoved() {
dropTargetManager.onDragStarted(
DraggedObject.Bubble(BubbleBarLocation.LEFT),
@@ -330,6 +346,7 @@ class DropTargetManagerTest {
var initialDragZone: DragZone? = null
var fromDragZone: DragZone? = null
var toDragZone: DragZone? = null
+ var endedDragZone: DragZone? = null
override fun onInitialDragZoneSet(dragZone: DragZone) {
initialDragZone = dragZone
@@ -339,5 +356,9 @@ class DropTargetManagerTest {
fromDragZone = from
toDragZone = to
}
+
+ override fun onDragEnded(zone: DragZone) {
+ endedDragZone = zone
+ }
}
}
diff --git a/media/java/android/media/MediaRoute2ProviderService.java b/media/java/android/media/MediaRoute2ProviderService.java
index 4ae8daa63e1d..6a33b374b21c 100644
--- a/media/java/android/media/MediaRoute2ProviderService.java
+++ b/media/java/android/media/MediaRoute2ProviderService.java
@@ -759,12 +759,29 @@ public abstract class MediaRoute2ProviderService extends Service {
/**
* Updates routes of the provider and notifies the system media router service.
+ *
+ * @throws IllegalArgumentException If {@code routes} contains a route that {@link
+ * MediaRoute2Info#getSupportedRoutingTypes() supports} both system media routing and remote
+ * routing but doesn't contain any {@link MediaRoute2Info#getDeduplicationIds()
+ * deduplication ids}.
*/
public final void notifyRoutes(@NonNull Collection<MediaRoute2Info> routes) {
requireNonNull(routes, "routes must not be null");
List<MediaRoute2Info> sanitizedRoutes = new ArrayList<>(routes.size());
for (MediaRoute2Info route : routes) {
+ if (Flags.enableMirroringInMediaRouter2()
+ && route.supportsRemoteRouting()
+ && route.supportsSystemMediaRouting()
+ && route.getDeduplicationIds().isEmpty()) {
+ String errorMessage =
+ TextUtils.formatSimple(
+ "Route with id='%s' name='%s' supports both system media and remote"
+ + " type routing, but doesn't contain a deduplication id, which"
+ + " it needs. You can add the route id as a deduplication id.",
+ route.getOriginalId(), route.getName());
+ throw new IllegalArgumentException(errorMessage);
+ }
if (route.isSystemRouteType()) {
Log.w(
TAG,
diff --git a/native/android/thermal.cpp b/native/android/thermal.cpp
index cefcaf7766bb..93e6ed814c34 100644
--- a/native/android/thermal.cpp
+++ b/native/android/thermal.cpp
@@ -139,7 +139,12 @@ AThermalManager::~AThermalManager() {
mStatusListeners.clear();
if (mServiceStatusListener != nullptr) {
bool success = false;
- mThermalSvc->unregisterThermalStatusListener(mServiceStatusListener, &success);
+ auto ret =
+ mThermalSvc->unregisterThermalStatusListener(mServiceStatusListener, &success);
+ if (!success || !ret.isOk()) {
+ ALOGE("Failed in unregisterThermalStatusListener when AThermalManager is being "
+ "destroyed %d", success);
+ }
mServiceStatusListener = nullptr;
}
}
@@ -148,7 +153,12 @@ AThermalManager::~AThermalManager() {
mHeadroomListeners.clear();
if (mServiceHeadroomListener != nullptr) {
bool success = false;
- mThermalSvc->unregisterThermalHeadroomListener(mServiceHeadroomListener, &success);
+ auto ret = mThermalSvc->unregisterThermalHeadroomListener(mServiceHeadroomListener,
+ &success);
+ if (!success || !ret.isOk()) {
+ ALOGE("Failed in unregisterThermalHeadroomListener when AThermalManager is being "
+ "destroyed %d", success);
+ }
mServiceHeadroomListener = nullptr;
}
}
diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml
index f4e17213fd2d..40c7dd16812b 100644
--- a/packages/CompanionDeviceManager/res/values-ar/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"عدم السماح"</string>
<string name="consent_cancel" msgid="5655005528379285841">"إلغاء"</string>
<string name="consent_back" msgid="2560683030046918882">"رجوع"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"الانتقال لأسفل القائمة"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"سهم متّجه للأسفل"</string>
<string name="permission_expand" msgid="893185038020887411">"توسيع <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"تصغير <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"‏هل تريد منح التطبيقات على &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; نفس الأذونات على &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;؟"</string>
diff --git a/packages/CompanionDeviceManager/res/values-be/strings.xml b/packages/CompanionDeviceManager/res/values-be/strings.xml
index 14878c11c5db..8ef80d34e37d 100644
--- a/packages/CompanionDeviceManager/res/values-be/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-be/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Не дазваляць"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Скасаваць"</string>
<string name="consent_back" msgid="2560683030046918882">"Назад"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Прагартаць спіс уніз"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Стрэлка ўніз"</string>
<string name="permission_expand" msgid="893185038020887411">"Разгарнуць <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Згарнуць <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Даць праграмам на прыладзе &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; такія самыя дазволы, што і на прыладзе &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml
index 6e5b3234b992..ebc2cf5dc9f9 100644
--- a/packages/CompanionDeviceManager/res/values-bg/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bg/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Забраняване"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Отказ"</string>
<string name="consent_back" msgid="2560683030046918882">"Назад"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Превъртете списъка надолу"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Стрелка за надолу"</string>
<string name="permission_expand" msgid="893185038020887411">"Разгъване на <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Свиване на <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Искате ли да дадете на приложенията на &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; същите разрешения както на &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-el/strings.xml b/packages/CompanionDeviceManager/res/values-el/strings.xml
index 1dc00dc4085b..9ede68477cfa 100644
--- a/packages/CompanionDeviceManager/res/values-el/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-el/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Να μην επιτρέπεται"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Ακύρωση"</string>
<string name="consent_back" msgid="2560683030046918882">"Πίσω"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Κύλιση προς τα κάτω στη λίστα"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Βέλος που δείχνει προς τα κάτω"</string>
<string name="permission_expand" msgid="893185038020887411">"Ανάπτυξη <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Σύμπτυξη <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Παραχώρηση των ίδιων αδειών στις εφαρμογές στη συσκευή &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; όπως στη συσκευή &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;;"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
index 8d7338024107..15d30429c25f 100644
--- a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Don\'t allow"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Cancel"</string>
<string name="consent_back" msgid="2560683030046918882">"Back"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Scroll down the list"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Downward arrow"</string>
<string name="permission_expand" msgid="893185038020887411">"Expand <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Collapse <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Give apps on &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; the same permissions as on &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
index 50f76549d807..edcc4bd465d3 100644
--- a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"No permitir"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Cancelar"</string>
<string name="consent_back" msgid="2560683030046918882">"Atrás"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Bajar por la lista"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Flecha hacia abajo"</string>
<string name="permission_expand" msgid="893185038020887411">"Expandir <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Contraer <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"¿Dar a las apps de &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; los mismos permisos que tienen en &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-et/strings.xml b/packages/CompanionDeviceManager/res/values-et/strings.xml
index 0f390e1fea89..3c837582027a 100644
--- a/packages/CompanionDeviceManager/res/values-et/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-et/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Ära luba"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Tühista"</string>
<string name="consent_back" msgid="2560683030046918882">"Tagasi"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Kerige loendis alla"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Allapoole suunatud nool"</string>
<string name="permission_expand" msgid="893185038020887411">"Laienda: <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Ahenda: <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Kas anda rakendustele seadmes &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; samad load, mis seadmes &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml
index f7086c650e2e..f204e9450568 100644
--- a/packages/CompanionDeviceManager/res/values-hi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hi/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"अनुमति न दें"</string>
<string name="consent_cancel" msgid="5655005528379285841">"रद्द करें"</string>
<string name="consent_back" msgid="2560683030046918882">"वापस जाएं"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"सूची को नीचे की ओर स्क्रोल करें"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"डाउनवर्ड ऐरो"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> को बड़ा करें"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> को छोटा करें"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"क्या &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; पर ऐप्लिकेशन को वही अनुमतियां देनी हैं जो &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; पर दी हैं?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hu/strings.xml b/packages/CompanionDeviceManager/res/values-hu/strings.xml
index 5d3b31329198..42702ca00f1c 100644
--- a/packages/CompanionDeviceManager/res/values-hu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Tiltás"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Mégse"</string>
<string name="consent_back" msgid="2560683030046918882">"Vissza"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Görgetés a listában lefelé"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Lefelé mutató nyíl"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> kibontása"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> összecsukása"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Ugyanolyan engedélyeket ad a(z) &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; eszközön található alkalmazásoknak, mint a(z) &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; eszköz esetén?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-it/strings.xml b/packages/CompanionDeviceManager/res/values-it/strings.xml
index 34967181eea7..b744542f2f89 100644
--- a/packages/CompanionDeviceManager/res/values-it/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-it/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Non consentire"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Annulla"</string>
<string name="consent_back" msgid="2560683030046918882">"Indietro"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Scorri l\'elenco verso il basso"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Freccia verso il basso"</string>
<string name="permission_expand" msgid="893185038020887411">"Espandi <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Comprimi <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Vuoi dare alle app su &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; le stesse autorizzazioni che hai dato su &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ja/strings.xml b/packages/CompanionDeviceManager/res/values-ja/strings.xml
index a8dc756fee76..664d53630cc9 100644
--- a/packages/CompanionDeviceManager/res/values-ja/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ja/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"許可しない"</string>
<string name="consent_cancel" msgid="5655005528379285841">"キャンセル"</string>
<string name="consent_back" msgid="2560683030046918882">"戻る"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"リストを下にスクロール"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"下矢印"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>を開く"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>を閉じる"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; のアプリに &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; の場合と同じ権限を付与しますか?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml
index 9047b05eb373..ddd414422199 100644
--- a/packages/CompanionDeviceManager/res/values-km/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-km/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"មិនអនុញ្ញាត"</string>
<string name="consent_cancel" msgid="5655005528379285841">"បោះបង់"</string>
<string name="consent_back" msgid="2560683030046918882">"ថយក្រោយ"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"រំកិលបញ្ជីចុះក្រោម"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"ព្រួញ​ចុះ​ក្រោម"</string>
<string name="permission_expand" msgid="893185038020887411">"ពង្រីក <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"បង្រួម <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"ផ្ដល់​ការអនុញ្ញាតឱ្យ​កម្មវិធីនៅលើ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ដូចនៅលើ &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ឬ?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lt/strings.xml b/packages/CompanionDeviceManager/res/values-lt/strings.xml
index a3ac47b9642f..09183bbd9756 100644
--- a/packages/CompanionDeviceManager/res/values-lt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lt/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Neleisti"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Atšaukti"</string>
<string name="consent_back" msgid="2560683030046918882">"Atgal"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Slinkti sąrašu žemyn"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Rodyklė žemyn"</string>
<string name="permission_expand" msgid="893185038020887411">"Išskleisti „<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>“"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Sutraukti „<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>“"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Suteikti &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; esančioms programoms tuos pačius leidimus kaip &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; esančioms programoms?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-nl/strings.xml b/packages/CompanionDeviceManager/res/values-nl/strings.xml
index 2f0fc9a7997a..2bb4b9abce2a 100644
--- a/packages/CompanionDeviceManager/res/values-nl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nl/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Niet toestaan"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Annuleren"</string>
<string name="consent_back" msgid="2560683030046918882">"Terug"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Omlaag scrollen in de lijst"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Pijl-omlaag"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> uitvouwen"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> samenvouwen"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Apps op de &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; dezelfde rechten geven als op de &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
index bee8e916349d..ec9beeb2c7ce 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Não permitir"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Cancelar"</string>
<string name="consent_back" msgid="2560683030046918882">"Voltar"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Deslocar para baixo na lista"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Seta para baixo"</string>
<string name="permission_expand" msgid="893185038020887411">"Expandir <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Reduzir <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Dar às apps no dispositivo &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; as mesmas autorizações de &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-tl/strings.xml b/packages/CompanionDeviceManager/res/values-tl/strings.xml
index 90e5eb7583e0..fbc12f2a5f06 100644
--- a/packages/CompanionDeviceManager/res/values-tl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tl/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"Huwag payagan"</string>
<string name="consent_cancel" msgid="5655005528379285841">"Kanselahin"</string>
<string name="consent_back" msgid="2560683030046918882">"Bumalik"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"Mag-scroll pababa sa listahan"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"Pababang arrow"</string>
<string name="permission_expand" msgid="893185038020887411">"I-expand ang <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"I-collapse ang <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Bigyan ang mga app sa &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ng mga pahintulot na mayroon din sa &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ur/strings.xml b/packages/CompanionDeviceManager/res/values-ur/strings.xml
index 690e439857d1..895dfb05d264 100644
--- a/packages/CompanionDeviceManager/res/values-ur/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ur/strings.xml
@@ -51,10 +51,8 @@
<string name="consent_no" msgid="2640796915611404382">"اجازت نہ دیں"</string>
<string name="consent_cancel" msgid="5655005528379285841">"منسوخ کریں"</string>
<string name="consent_back" msgid="2560683030046918882">"پیچھے"</string>
- <!-- no translation found for downward_arrow_action (2327165938832076333) -->
- <skip />
- <!-- no translation found for downward_arrow (2292427714411156088) -->
- <skip />
+ <string name="downward_arrow_action" msgid="2327165938832076333">"فہرست نیچے سکرول کریں"</string>
+ <string name="downward_arrow" msgid="2292427714411156088">"نیچے کی طرف تیر کا نشان"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> کو پھیلائیں"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> کو سکیڑیں"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"‏ایپس کو &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; پر وہی اجازتیں دیں جو &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; پر دی گئی ہیں؟"</string>
diff --git a/packages/DynamicSystemInstallationService/res/values-mr/strings.xml b/packages/DynamicSystemInstallationService/res/values-mr/strings.xml
index 3b6741d6c5a8..b18ce0e1db32 100644
--- a/packages/DynamicSystemInstallationService/res/values-mr/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-mr/strings.xml
@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="keyguard_description" msgid="8582605799129954556">"कृपया तुमचा पासवर्ड एंटर करा आणि डायनॅमिक सिस्टम अपडेट वर जा"</string>
- <string name="notification_install_completed" msgid="6252047868415172643">"डायनॅमिक सिस्टम तयार आहे. ती वापरणे सुरू करण्यासाठी, तुमचे डिव्हाइस रीस्टार्ट करा."</string>
+ <string name="keyguard_description" msgid="8582605799129954556">"कृपया तुमचा पासवर्ड एंटर करा आणि डायनॅमिक सिस्टीम अपडेट वर जा"</string>
+ <string name="notification_install_completed" msgid="6252047868415172643">"डायनॅमिक सिस्टीम तयार आहे. ती वापरणे सुरू करण्यासाठी, तुमचे डिव्हाइस रीस्टार्ट करा."</string>
<string name="notification_install_inprogress" msgid="7383334330065065017">"इंस्टॉल प्रगतीपथावर आहे"</string>
<string name="notification_install_failed" msgid="4066039210317521404">"इंस्टॉल करता आली नाही"</string>
<string name="notification_image_validation_failed" msgid="2720357826403917016">"इमेज प्रमाणित करता आली नाही. इंस्टॉलेशन रद्द करा."</string>
- <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"सध्या डायनॅमिक सिस्टम रन करत आहे. मूळ Android आवृत्ती वापरण्यासाठी रीस्टार्ट करा."</string>
+ <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"सध्या डायनॅमिक सिस्टीम रन करत आहे. मूळ Android आवृत्ती वापरण्यासाठी रीस्टार्ट करा."</string>
<string name="notification_action_cancel" msgid="5929299408545961077">"रद्द करा"</string>
<string name="notification_action_discard" msgid="1817481003134947493">"काढून टाका"</string>
<string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"रीस्टार्ट करा"</string>
<string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"रीस्टार्ट करा"</string>
- <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"डायनॅमिक सिस्टम काढून टाकली"</string>
- <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"डायनॅमिक सिस्टम रीस्टार्ट किंवा लोड करू शकत नाही"</string>
- <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"डायनॅमिक सिस्टम बंद करता आली नाही"</string>
+ <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"डायनॅमिक सिस्टीम काढून टाकली"</string>
+ <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"डायनॅमिक सिस्टीम रीस्टार्ट किंवा लोड करू शकत नाही"</string>
+ <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"डायनॅमिक सिस्टीम बंद करता आली नाही"</string>
</resources>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout-v36/settingslib_expressive_main_switch_layout.xml b/packages/SettingsLib/MainSwitchPreference/res/layout-v36/settingslib_expressive_main_switch_layout.xml
index 94c6924a02f2..7adbfbfb1ffd 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/layout-v36/settingslib_expressive_main_switch_layout.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/layout-v36/settingslib_expressive_main_switch_layout.xml
@@ -19,14 +19,14 @@
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
- android:importantForAccessibility="no">
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
<com.android.settingslib.widget.MainSwitchBar
android:id="@+id/settingslib_main_switch_bar"
android:visibility="gone"
android:layout_height="wrap_content"
- android:layout_width="match_parent" />
+ android:layout_width="match_parent"
+ android:importantForAccessibility="no" />
</FrameLayout>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_layout.xml b/packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_layout.xml
index bef6e352d854..c5dd24cc4d2e 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_layout.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_layout.xml
@@ -17,14 +17,14 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:importantForAccessibility="no">
+ android:layout_width="match_parent">
<com.android.settingslib.widget.MainSwitchBar
android:id="@+id/settingslib_main_switch_bar"
android:visibility="gone"
android:layout_height="wrap_content"
- android:layout_width="match_parent" />
+ android:layout_width="match_parent"
+ android:importantForAccessibility="no" />
</FrameLayout>
diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
index d883fb0594e6..5170581aa382 100644
--- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
@@ -80,7 +80,14 @@ public class MainSwitchPreference extends TwoStatePreference implements OnChecke
mainSwitchBar.setIconSpaceReserved(isIconSpaceReserved());
// To support onPreferenceChange callback, it needs to call callChangeListener() when
// MainSwitchBar is clicked.
- mainSwitchBar.setOnClickListener(view -> callChangeListener(isChecked()));
+ mainSwitchBar.setOnClickListener(view -> {
+ boolean isChecked = isChecked();
+ if (!callChangeListener(isChecked)) {
+ // Change checked state back if listener doesn't like it.
+ // Note that CompoundButton maintains internal state to avoid infinite recursion.
+ mainSwitchBar.setChecked(!isChecked);
+ }
+ });
// Remove all listeners to 1. avoid triggering listener when update UI 2. prevent potential
// listener leaking when the view holder is reused by RecyclerView
@@ -88,7 +95,11 @@ public class MainSwitchPreference extends TwoStatePreference implements OnChecke
mainSwitchBar.setChecked(isChecked());
mainSwitchBar.addOnSwitchChangeListener(this);
- mainSwitchBar.show();
+ if (isVisible()) {
+ mainSwitchBar.show();
+ } else {
+ mainSwitchBar.hide();
+ }
}
@Override
@@ -101,7 +112,10 @@ public class MainSwitchPreference extends TwoStatePreference implements OnChecke
/**
* Adds a listener for switch changes
+ *
+ * @deprecated Use {@link #setOnPreferenceChangeListener(OnPreferenceChangeListener)}
*/
+ @Deprecated
public void addOnSwitchChangeListener(OnCheckedChangeListener listener) {
if (!mSwitchChangeListeners.contains(listener)) {
mSwitchChangeListeners.add(listener);
@@ -110,7 +124,10 @@ public class MainSwitchPreference extends TwoStatePreference implements OnChecke
/**
* Remove a listener for switch changes
+ *
+ * @deprecated Use {@link #setOnPreferenceChangeListener(OnPreferenceChangeListener)}
*/
+ @Deprecated
public void removeOnSwitchChangeListener(OnCheckedChangeListener listener) {
mSwitchChangeListeners.remove(listener);
}
diff --git a/packages/SettingsLib/SelectorWithWidgetPreference/res/layout-v36/preference_selector_with_widget.xml b/packages/SettingsLib/SelectorWithWidgetPreference/res/layout-v36/settingslib_expressive_preference_selector_with_widget.xml
index a79d69dbff8c..a79d69dbff8c 100644
--- a/packages/SettingsLib/SelectorWithWidgetPreference/res/layout-v36/preference_selector_with_widget.xml
+++ b/packages/SettingsLib/SelectorWithWidgetPreference/res/layout-v36/settingslib_expressive_preference_selector_with_widget.xml
diff --git a/packages/SettingsLib/SelectorWithWidgetPreference/src/com/android/settingslib/widget/SelectorWithWidgetPreference.java b/packages/SettingsLib/SelectorWithWidgetPreference/src/com/android/settingslib/widget/SelectorWithWidgetPreference.java
index cde8b332f2e7..465b6ccf4d9c 100644
--- a/packages/SettingsLib/SelectorWithWidgetPreference/src/com/android/settingslib/widget/SelectorWithWidgetPreference.java
+++ b/packages/SettingsLib/SelectorWithWidgetPreference/src/com/android/settingslib/widget/SelectorWithWidgetPreference.java
@@ -238,7 +238,10 @@ public class SelectorWithWidgetPreference extends CheckBoxPreference {
} else {
setWidgetLayoutResource(R.layout.settingslib_preference_widget_radiobutton);
}
- setLayoutResource(R.layout.preference_selector_with_widget);
+ int resID = SettingsThemeHelper.isExpressiveTheme(context)
+ ? R.layout.settingslib_expressive_preference_selector_with_widget
+ : R.layout.preference_selector_with_widget;
+ setLayoutResource(resID);
setIconSpaceReserved(false);
final TypedArray a =
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background.xml
index 0446873126b7..9aa0bc39c5d8 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background.xml
@@ -19,12 +19,16 @@
android:color="?android:colorControlHighlight">
<item
android:start="?android:attr/listPreferredItemPaddingStart"
- android:end="?android:attr/listPreferredItemPaddingEnd">
+ android:end="?android:attr/listPreferredItemPaddingEnd"
+ android:top="2dp"
+ android:bottom="16dp">
<shape android:shape="rectangle">
<solid
android:color="@color/settingslib_materialColorSurfaceBright" />
<corners
android:radius="@dimen/settingslib_preference_corner_radius" />
+ <padding
+ android:bottom="16dp"/>
</shape>
</item>
-</ripple>
+</ripple> \ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom.xml
index 25a936deade5..554cba565383 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom.xml
@@ -19,7 +19,9 @@
android:color="?android:colorControlHighlight">
<item
android:start="?android:attr/listPreferredItemPaddingStart"
- android:end="?android:attr/listPreferredItemPaddingEnd">
+ android:end="?android:attr/listPreferredItemPaddingEnd"
+ android:top="2dp"
+ android:bottom="16dp">
<shape android:shape="rectangle">
<solid
android:color="@color/settingslib_materialColorSurfaceBright" />
@@ -28,6 +30,8 @@
android:bottomLeftRadius="@dimen/settingslib_preference_corner_radius"
android:topRightRadius="4dp"
android:bottomRightRadius="@dimen/settingslib_preference_corner_radius" />
+ <padding
+ android:bottom="16dp"/>
</shape>
</item>
-</ripple>
+</ripple> \ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom_highlighted.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom_highlighted.xml
index db2800e0ec41..c0c08699cc2a 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom_highlighted.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom_highlighted.xml
@@ -19,7 +19,8 @@
<item
android:bottom="16dp"
android:end="?android:attr/listPreferredItemPaddingEnd"
- android:start="?android:attr/listPreferredItemPaddingStart">
+ android:start="?android:attr/listPreferredItemPaddingStart"
+ android:top="2dp">
<shape
android:shape="rectangle"
android:tint="?android:attr/colorAccent">
@@ -28,7 +29,8 @@
android:bottomRightRadius="@dimen/settingslib_preference_corner_radius"
android:topLeftRadius="4dp"
android:topRightRadius="4dp" />
+ <padding android:bottom="16dp" />
<solid android:color="#42000000" />
</shape>
</item>
-</ripple>
+</ripple> \ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom_selected.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom_selected.xml
index 98f95d927fa6..543b237373fb 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom_selected.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_bottom_selected.xml
@@ -19,7 +19,9 @@
android:color="?android:colorControlHighlight">
<item
android:start="?android:attr/listPreferredItemPaddingStart"
- android:end="?android:attr/listPreferredItemPaddingEnd">
+ android:end="?android:attr/listPreferredItemPaddingEnd"
+ android:top="2dp"
+ android:bottom="16dp">
<shape android:shape="rectangle">
<solid
android:color="@color/settingslib_materialColorSurfaceContainer" />
@@ -28,6 +30,8 @@
android:bottomLeftRadius="@dimen/settingslib_preference_corner_radius"
android:topRightRadius="4dp"
android:bottomRightRadius="@dimen/settingslib_preference_corner_radius" />
+ <padding
+ android:bottom="16dp"/>
</shape>
</item>
-</ripple>
+</ripple> \ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center.xml
index c4286fdf020c..b89a0ddcdec5 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center.xml
@@ -19,7 +19,8 @@
android:color="?android:colorControlHighlight">
<item
android:start="?android:attr/listPreferredItemPaddingStart"
- android:end="?android:attr/listPreferredItemPaddingEnd">
+ android:end="?android:attr/listPreferredItemPaddingEnd"
+ android:top="2dp">
<shape android:shape="rectangle">
<solid
android:color="@color/settingslib_materialColorSurfaceBright" />
@@ -27,4 +28,4 @@
android:radius="4dp" />
</shape>
</item>
-</ripple>
+</ripple> \ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center_highlighted.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center_highlighted.xml
index 194cdb00a337..8099d9b3d7f7 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center_highlighted.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center_highlighted.xml
@@ -18,7 +18,8 @@
android:color="?android:colorControlHighlight">
<item
android:end="?android:attr/listPreferredItemPaddingEnd"
- android:start="?android:attr/listPreferredItemPaddingStart">
+ android:start="?android:attr/listPreferredItemPaddingStart"
+ android:top="2dp">
<shape
android:shape="rectangle"
android:tint="?android:attr/colorAccent">
@@ -26,4 +27,4 @@
<solid android:color="#42000000" />
</shape>
</item>
-</ripple>
+</ripple> \ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center_selected.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center_selected.xml
index 8bc2f2f9ccd1..6d2cd1a51620 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center_selected.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_center_selected.xml
@@ -19,7 +19,8 @@
android:color="?android:colorControlHighlight">
<item
android:start="?android:attr/listPreferredItemPaddingStart"
- android:end="?android:attr/listPreferredItemPaddingEnd">
+ android:end="?android:attr/listPreferredItemPaddingEnd"
+ android:top="2dp">
<shape android:shape="rectangle">
<solid
android:color="@color/settingslib_materialColorSurfaceContainer" />
@@ -27,4 +28,4 @@
android:radius="4dp" />
</shape>
</item>
-</ripple>
+</ripple> \ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_highlighted.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_highlighted.xml
index 2341661528d9..a119a4ae083f 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_highlighted.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_highlighted.xml
@@ -19,12 +19,14 @@
<item
android:bottom="16dp"
android:end="?android:attr/listPreferredItemPaddingEnd"
- android:start="?android:attr/listPreferredItemPaddingStart">
+ android:start="?android:attr/listPreferredItemPaddingStart"
+ android:top="2dp">
<shape
android:shape="rectangle"
android:tint="?android:attr/colorAccent">
<corners android:radius="@dimen/settingslib_preference_corner_radius" />
+ <padding android:bottom="16dp" />
<solid android:color="#42000000" />
</shape>
</item>
-</ripple>
+</ripple> \ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_selected.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_selected.xml
index 99704f2df190..bcdbf1d19545 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_selected.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_selected.xml
@@ -19,12 +19,16 @@
android:color="?android:colorControlHighlight">
<item
android:start="?android:attr/listPreferredItemPaddingStart"
- android:end="?android:attr/listPreferredItemPaddingEnd">
+ android:end="?android:attr/listPreferredItemPaddingEnd"
+ android:top="2dp"
+ android:bottom="16dp">
<shape android:shape="rectangle">
<solid
android:color="@color/settingslib_materialColorSurfaceContainer" />
<corners
android:radius="@dimen/settingslib_preference_corner_radius" />
+ <padding
+ android:bottom="16dp"/>
</shape>
</item>
-</ripple>
+</ripple> \ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top.xml
index 3a5938688f34..7955e4418ae9 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top.xml
@@ -19,7 +19,8 @@
android:color="?android:colorControlHighlight">
<item
android:start="?android:attr/listPreferredItemPaddingStart"
- android:end="?android:attr/listPreferredItemPaddingEnd">
+ android:end="?android:attr/listPreferredItemPaddingEnd"
+ android:top="2dp">
<shape android:shape="rectangle">
<solid
android:color="@color/settingslib_materialColorSurfaceBright" />
@@ -30,4 +31,4 @@
android:bottomRightRadius="4dp" />
</shape>
</item>
-</ripple>
+</ripple> \ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top_highlighted.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top_highlighted.xml
index edace29df37a..052eb01cab8d 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top_highlighted.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top_highlighted.xml
@@ -19,7 +19,8 @@
<item
android:color="?android:attr/colorAccent"
android:end="?android:attr/listPreferredItemPaddingEnd"
- android:start="?android:attr/listPreferredItemPaddingStart">
+ android:start="?android:attr/listPreferredItemPaddingStart"
+ android:top="2dp">
<shape
android:shape="rectangle"
android:tint="?android:attr/colorAccent">
@@ -31,4 +32,4 @@
<solid android:color="#42000000" />
</shape>
</item>
-</ripple>
+</ripple> \ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top_selected.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top_selected.xml
index b2d6d9da6af8..d4b658c384e6 100644
--- a/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top_selected.xml
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v36/settingslib_round_background_top_selected.xml
@@ -19,7 +19,8 @@
android:color="?android:colorControlHighlight">
<item
android:start="?android:attr/listPreferredItemPaddingStart"
- android:end="?android:attr/listPreferredItemPaddingEnd">
+ android:end="?android:attr/listPreferredItemPaddingEnd"
+ android:top="2dp">
<shape android:shape="rectangle">
<solid
android:color="@color/settingslib_materialColorSurfaceContainer" />
@@ -30,4 +31,4 @@
android:bottomRightRadius="4dp" />
</shape>
</item>
-</ripple>
+</ripple> \ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/SettingsBasePreferenceFragment.kt b/packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/SettingsBasePreferenceFragment.kt
index 22cd87307a42..8d12f01e24ed 100644
--- a/packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/SettingsBasePreferenceFragment.kt
+++ b/packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/SettingsBasePreferenceFragment.kt
@@ -16,7 +16,6 @@
package com.android.settingslib.widget
-import android.graphics.Rect
import android.os.Bundle
import android.view.LayoutInflater;
import android.view.View
@@ -25,7 +24,6 @@ import androidx.annotation.CallSuper
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceScreen
import androidx.recyclerview.widget.RecyclerView
-import com.android.settingslib.widget.theme.R
/** Base class for Settings to use PreferenceFragmentCompat */
abstract class SettingsBasePreferenceFragment : PreferenceFragmentCompat() {
@@ -45,7 +43,6 @@ abstract class SettingsBasePreferenceFragment : PreferenceFragmentCompat() {
if (SettingsThemeHelper.isExpressiveTheme(requireContext())) {
// Don't allow any divider in between the preferences in expressive design.
setDivider(null)
- this.listView.addItemDecoration(MarginItemDecoration())
}
}
@@ -54,18 +51,4 @@ abstract class SettingsBasePreferenceFragment : PreferenceFragmentCompat() {
return SettingsPreferenceGroupAdapter(preferenceScreen)
return super.onCreateAdapter(preferenceScreen)
}
-
- internal class MarginItemDecoration() : RecyclerView.ItemDecoration() {
- override fun getItemOffsets(
- outRect: Rect,
- view: View,
- parent: RecyclerView,
- state: RecyclerView.State,
- ) {
- with(outRect) {
- bottom =
- view.resources.getDimensionPixelSize(R.dimen.settingslib_expressive_radius_extrasmall1)
- }
- }
- }
}
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 2fc946b9ed9f..07849e09ecc9 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -81,7 +81,7 @@
<string name="speed_label_fast" msgid="2677719134596044051">"Élevée"</string>
<string name="speed_label_very_fast" msgid="8215718029533182439">"Très rapide"</string>
<string name="wifi_passpoint_expired" msgid="6540867261754427561">"Arrivé à expiration"</string>
- <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
+ <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
<string name="bluetooth_disconnected" msgid="7739366554710388701">"Déconnecté"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Déconnexion…"</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"Connexion…"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 826d6015fc49..8c77b0897aed 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -561,7 +561,7 @@
<string name="retail_demo_reset_next" msgid="3688129033843885362">"पुढील"</string>
<string name="retail_demo_reset_title" msgid="1866911701095959800">"पासवर्ड आवश्यक"</string>
<string name="active_input_method_subtypes" msgid="4232680535471633046">"सक्रिय इनपुट पद्धती"</string>
- <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"सिस्टम भाषा वापरा"</string>
+ <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"सिस्टीम भाषा वापरा"</string>
<string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> साठी सेटिंग्ज उघडण्यात अयशस्वी"</string>
<string name="ime_security_warning" msgid="6547562217880551450">"ही इनपुट पद्धत पासवर्ड आणि क्रेडिट कार्ड नंबर यासह, तुम्ही टाइप करता तो सर्व मजकूर संकलित करण्यात सक्षम होऊ शकते. ही <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> ॲपवरून येते. ही इनपुट पद्धत वापरायची?"</string>
<string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"टीप: रीबूट केल्यानंतर, तुम्ही तुमचा फोन अनलॉक करेपर्यंत हे अ‍ॅप सुरू होऊ शकत नाही"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index e4381d6131e7..11f410f90497 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -530,7 +530,7 @@
<string name="battery_info_status_charging_dock" msgid="8573274094093364791">"A carregar"</string>
<string name="battery_info_status_discharging" msgid="6962689305413556485">"Não está a carregar"</string>
<string name="battery_info_status_not_charging" msgid="1103084691314264664">"Ligado, mas não está a carregar"</string>
- <string name="battery_info_status_full" msgid="1339002294876531312">"Carregada"</string>
+ <string name="battery_info_status_full" msgid="1339002294876531312">"Bateria carregada"</string>
<string name="battery_info_status_full_charged" msgid="3536054261505567948">"Totalmente carregada"</string>
<string name="battery_info_status_charging_on_hold" msgid="6364355145521694438">"Carregamento em espera"</string>
<string name="battery_info_status_charging_v2" msgid="6118522107222245505">"Carregamento"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 6095e8c2af4c..c2c035c15ce0 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -109,7 +109,7 @@
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Đã lưu"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Đang hoạt động (chỉ tai trái)"</string>
<string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Đang hoạt động (chỉ tai phải)"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Đang hoạt động (cả tai phải và tai trái)"</string>
+ <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Đang hoạt động (trái và phải)"</string>
<string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Không cập nhật được âm lượng xung quanh"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Đang hoạt động (chỉ phát nội dung đa phương tiện). Còn <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> pin."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Đang hoạt động (chỉ phát nội dung đa phương tiện). Bên trái: Còn <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> pin. Bên phải: Còn <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> pin."</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BatteryLevelsInfo.kt b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BatteryLevelsInfo.kt
new file mode 100644
index 000000000000..b52a9017fc16
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BatteryLevelsInfo.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.bluetooth
+
+/**
+ * BatteryLevelsInfo contains the battery levels of different components of a bluetooth device.
+ * The range of a valid battery level is [0-100], and -1 if the battery level is not applicable.
+ */
+data class BatteryLevelsInfo(
+ val leftBatteryLevel: Int,
+ val rightBatteryLevel: Int,
+ val caseBatteryLevel: Int,
+ val overallBatteryLevel: Int,
+) \ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index bb96041739eb..3646842d36ef 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -44,10 +44,12 @@ import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.util.LruCache;
import android.util.Pair;
+import android.view.InputDevice;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
+import androidx.annotation.WorkerThread;
import com.android.internal.util.ArrayUtils;
import com.android.settingslib.R;
@@ -62,6 +64,7 @@ import com.google.common.util.concurrent.ListenableFuture;
import java.sql.Timestamp;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
@@ -150,6 +153,9 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
private boolean mIsHearingAidProfileConnectedFail = false;
private boolean mIsLeAudioProfileConnectedFail = false;
private boolean mUnpairing;
+ @Nullable
+ private final InputDevice mInputDevice;
+ private final boolean mIsDeviceStylus;
// Group second device for Hearing Aid
private CachedBluetoothDevice mSubDevice;
@@ -193,6 +199,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
mGroupId = BluetoothCsipSetCoordinator.GROUP_ID_INVALID;
initDrawableCache();
mUnpairing = false;
+ mInputDevice = BluetoothUtils.getInputDevice(mContext, getAddress());
+ mIsDeviceStylus = BluetoothUtils.isDeviceStylus(mInputDevice, this);
}
/** Clears any pending messages in the message queue. */
@@ -1622,6 +1630,86 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
}
}
+ /**
+ * Returns the battery levels of all components of the bluetooth device. If no battery info is
+ * available then returns null.
+ */
+ @WorkerThread
+ @Nullable
+ public BatteryLevelsInfo getBatteryLevelsInfo() {
+ // Try getting the battery information from metadata.
+ BatteryLevelsInfo metadataSourceBattery = getBatteryFromMetadata();
+ if (metadataSourceBattery != null) {
+ return metadataSourceBattery;
+ }
+ // Get the battery information from Bluetooth service.
+ return getBatteryFromBluetoothService();
+ }
+
+ @Nullable
+ private BatteryLevelsInfo getBatteryFromMetadata() {
+ if (BluetoothUtils.getBooleanMetaData(mDevice,
+ BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)) {
+ // The device is untethered headset, containing both earbuds and case.
+ int leftBattery =
+ BluetoothUtils.getIntMetaData(
+ mDevice, BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY);
+ int rightBattery =
+ BluetoothUtils.getIntMetaData(
+ mDevice, BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY);
+ int caseBattery =
+ BluetoothUtils.getIntMetaData(
+ mDevice, BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY);
+
+ if (leftBattery <= BluetoothDevice.BATTERY_LEVEL_UNKNOWN
+ && rightBattery <= BluetoothDevice.BATTERY_LEVEL_UNKNOWN
+ && caseBattery <= BluetoothDevice.BATTERY_LEVEL_UNKNOWN) {
+ Log.d(TAG, "No battery info from metadata is available for untethered device "
+ + mDevice.getAnonymizedAddress());
+ return null;
+ } else {
+ int overallBattery =
+ Arrays.stream(new int[]{leftBattery, rightBattery, caseBattery})
+ .filter(battery -> battery > BluetoothDevice.BATTERY_LEVEL_UNKNOWN)
+ .min()
+ .orElse(BluetoothDevice.BATTERY_LEVEL_UNKNOWN);
+ Log.d(TAG, "Acquired battery info from metadata for untethered device "
+ + mDevice.getAnonymizedAddress()
+ + " left earbud battery: " + leftBattery
+ + " right earbud battery: " + rightBattery
+ + " case battery: " + caseBattery
+ + " overall battery: " + overallBattery);
+ return new BatteryLevelsInfo(
+ leftBattery, rightBattery, caseBattery, overallBattery);
+ }
+ } else if (mInputDevice != null || mIsDeviceStylus) {
+ // The device is input device, using METADATA_MAIN_BATTERY field to get battery info.
+ int overallBattery = BluetoothUtils.getIntMetaData(
+ mDevice, BluetoothDevice.METADATA_MAIN_BATTERY);
+ if (overallBattery <= BluetoothDevice.BATTERY_LEVEL_UNKNOWN) {
+ Log.d(TAG, "No battery info from metadata is available for input device "
+ + mDevice.getAnonymizedAddress());
+ return null;
+ } else {
+ Log.d(TAG, "Acquired battery info from metadata for input device "
+ + mDevice.getAnonymizedAddress()
+ + " overall battery: " + overallBattery);
+ return new BatteryLevelsInfo(
+ BluetoothDevice.BATTERY_LEVEL_UNKNOWN,
+ BluetoothDevice.BATTERY_LEVEL_UNKNOWN,
+ BluetoothDevice.BATTERY_LEVEL_UNKNOWN,
+ overallBattery);
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ private BatteryLevelsInfo getBatteryFromBluetoothService() {
+ // TODO(b/397847825): Implement the logic to get battery from Bluetooth service.
+ return null;
+ }
+
private CharSequence getTvBatterySummary(int mainBattery, int leftBattery, int rightBattery,
int lowBatteryColorRes) {
// Since there doesn't seem to be a way to use format strings to add the
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
index f6e26a7200ef..ed53d8d04988 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -40,12 +40,14 @@ import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothStatusCodes;
import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
+import android.hardware.input.InputManager;
import android.media.AudioManager;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import android.text.Spannable;
import android.text.style.ForegroundColorSpan;
import android.util.LruCache;
+import android.view.InputDevice;
import com.android.settingslib.R;
import com.android.settingslib.media.flags.Flags;
@@ -77,8 +79,10 @@ public class CachedBluetoothDeviceTest {
private static final String DEVICE_ALIAS_NEW = "TestAliasNew";
private static final String TWS_BATTERY_LEFT = "15";
private static final String TWS_BATTERY_RIGHT = "25";
+ private static final String TWS_BATTERY_CASE = "10";
private static final String TWS_LOW_BATTERY_THRESHOLD_LOW = "10";
private static final String TWS_LOW_BATTERY_THRESHOLD_HIGH = "25";
+ private static final String MAIN_BATTERY = "80";
private static final String TEMP_BOND_METADATA =
"<TEMP_BOND_TYPE>le_audio_sharing</TEMP_BOND_TYPE>";
private static final short RSSI_1 = 10;
@@ -87,6 +91,8 @@ public class CachedBluetoothDeviceTest {
private static final boolean JUSTDISCOVERED_2 = false;
private static final int LOW_BATTERY_COLOR = android.R.color.holo_red_dark;
private static final int METADATA_FAST_PAIR_CUSTOMIZED_FIELDS = 25;
+ private static final int TEST_DEVICE_ID = 123;
+ private final InputDevice mInputDevice = mock(InputDevice.class);
@Mock
private LocalBluetoothProfileManager mProfileManager;
@Mock
@@ -116,6 +122,8 @@ public class CachedBluetoothDeviceTest {
private LocalBluetoothLeBroadcastAssistant mAssistant;
@Mock
private BluetoothLeBroadcastReceiveState mLeBroadcastReceiveState;
+ @Mock
+ private InputManager mInputManager;
private CachedBluetoothDevice mCachedDevice;
private CachedBluetoothDevice mSubCachedDevice;
private AudioManager mAudioManager;
@@ -2175,6 +2183,74 @@ public class CachedBluetoothDeviceTest {
assertThat(mCachedDevice.isHearingDevice()).isFalse();
}
+ @Test
+ public void getBatteryLevelsInfo_untetheredHeadsetWithBattery_returnBatteryLevelsInfo() {
+ when(mDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn(
+ "true".getBytes());
+ when(mDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY)).thenReturn(
+ TWS_BATTERY_LEFT.getBytes());
+ when(mDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY)).thenReturn(
+ TWS_BATTERY_RIGHT.getBytes());
+ when(mDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY)).thenReturn(
+ TWS_BATTERY_CASE.getBytes());
+
+ BatteryLevelsInfo batteryLevelsInfo = mCachedDevice.getBatteryLevelsInfo();
+
+ assertThat(batteryLevelsInfo.getLeftBatteryLevel()).isEqualTo(
+ Integer.parseInt(TWS_BATTERY_LEFT));
+ assertThat(batteryLevelsInfo.getRightBatteryLevel()).isEqualTo(
+ Integer.parseInt(TWS_BATTERY_RIGHT));
+ assertThat(batteryLevelsInfo.getCaseBatteryLevel()).isEqualTo(
+ Integer.parseInt(TWS_BATTERY_CASE));
+ assertThat(batteryLevelsInfo.getOverallBatteryLevel()).isEqualTo(
+ Integer.parseInt(TWS_BATTERY_CASE));
+ }
+
+ @Test
+ public void getBatteryLevelsInfo_inputDeviceWithBattery_returnBatteryLevelsInfo() {
+ when(mDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn(
+ "false".getBytes());
+ when(mDevice.getMetadata(BluetoothDevice.METADATA_MAIN_BATTERY)).thenReturn(
+ MAIN_BATTERY.getBytes());
+ when(mContext.getSystemService(InputManager.class)).thenReturn(mInputManager);
+ when(mInputManager.getInputDeviceIds()).thenReturn(new int[]{TEST_DEVICE_ID});
+ when(mInputManager.getInputDeviceBluetoothAddress(TEST_DEVICE_ID)).thenReturn(
+ DEVICE_ADDRESS);
+ when(mInputManager.getInputDevice(TEST_DEVICE_ID)).thenReturn(mInputDevice);
+
+ BatteryLevelsInfo batteryLevelsInfo = mCachedDevice.getBatteryLevelsInfo();
+
+ assertThat(batteryLevelsInfo.getLeftBatteryLevel()).isEqualTo(
+ BluetoothDevice.BATTERY_LEVEL_UNKNOWN);
+ assertThat(batteryLevelsInfo.getRightBatteryLevel()).isEqualTo(
+ BluetoothDevice.BATTERY_LEVEL_UNKNOWN);
+ assertThat(batteryLevelsInfo.getCaseBatteryLevel()).isEqualTo(
+ BluetoothDevice.BATTERY_LEVEL_UNKNOWN);
+ assertThat(batteryLevelsInfo.getOverallBatteryLevel()).isEqualTo(
+ Integer.parseInt(MAIN_BATTERY));
+ }
+
+ @Test
+ public void getBatteryLevelsInfo_stylusDeviceWithBattery_returnBatteryLevelsInfo() {
+ when(mDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn(
+ "false".getBytes());
+ when(mDevice.getMetadata(BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn(
+ BluetoothDevice.DEVICE_TYPE_STYLUS.getBytes());
+ when(mDevice.getMetadata(BluetoothDevice.METADATA_MAIN_BATTERY)).thenReturn(
+ MAIN_BATTERY.getBytes());
+
+ BatteryLevelsInfo batteryLevelsInfo = mCachedDevice.getBatteryLevelsInfo();
+
+ assertThat(batteryLevelsInfo.getLeftBatteryLevel()).isEqualTo(
+ BluetoothDevice.BATTERY_LEVEL_UNKNOWN);
+ assertThat(batteryLevelsInfo.getRightBatteryLevel()).isEqualTo(
+ BluetoothDevice.BATTERY_LEVEL_UNKNOWN);
+ assertThat(batteryLevelsInfo.getCaseBatteryLevel()).isEqualTo(
+ BluetoothDevice.BATTERY_LEVEL_UNKNOWN);
+ assertThat(batteryLevelsInfo.getOverallBatteryLevel()).isEqualTo(
+ Integer.parseInt(MAIN_BATTERY));
+ }
+
private void updateProfileStatus(LocalBluetoothProfile profile, int status) {
doReturn(status).when(profile).getConnectionStatus(mDevice);
mCachedDevice.onProfileStateChanged(profile, status);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java
index a47b4d5c354f..093833ec41cf 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java
@@ -18,13 +18,22 @@ package com.android.settingslib.widget;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
import android.view.View;
import android.widget.TextView;
+import androidx.preference.PreferenceDataStore;
import androidx.preference.PreferenceViewHolder;
import androidx.test.core.app.ApplicationProvider;
+import com.android.settingslib.preference.PreferenceScreenFactory;
import com.android.settingslib.widget.mainswitch.R;
import org.junit.Before;
@@ -67,4 +76,31 @@ public class MainSwitchPreferenceTest {
assertThat(mRootView.<MainSwitchBar>requireViewById(
R.id.settingslib_main_switch_bar).isChecked()).isTrue();
}
+
+ @Test
+ public void setOnPreferenceChangeListener() {
+ // Attach preference to preference screen, otherwise `Preference.performClick` does not
+ // interact with underlying datastore
+ new PreferenceScreenFactory(mContext).getOrCreatePreferenceScreen().addPreference(
+ mPreference);
+
+ PreferenceDataStore preferenceDataStore = mock(PreferenceDataStore.class);
+ // always return the provided default value
+ when(preferenceDataStore.getBoolean(any(), anyBoolean())).thenAnswer(
+ invocation -> invocation.getArguments()[1]);
+ mPreference.setPreferenceDataStore(preferenceDataStore);
+
+ String key = "key";
+ mPreference.setKey(key);
+ mPreference.setOnPreferenceChangeListener((preference, newValue) -> false);
+ mPreference.onBindViewHolder(mHolder);
+
+ mPreference.performClick();
+ verify(preferenceDataStore, never()).putBoolean(any(), anyBoolean());
+
+ mPreference.setOnPreferenceChangeListener((preference, newValue) -> true);
+
+ mPreference.performClick();
+ verify(preferenceDataStore).putBoolean(any(), anyBoolean());
+ }
}
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 7e8d5496a390..a90081738062 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -1434,16 +1434,6 @@ flag {
}
flag {
- name: "notification_media_manager_background_execution"
- namespace: "systemui"
- description: "Decide whether to execute binder calls in background thread"
- bug: "336612071"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
name: "dozeui_scheduling_alarms_background_execution"
namespace: "systemui"
description: "Decide whether to execute binder calls to schedule alarms in background thread"
@@ -2103,3 +2093,13 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "always_compose_qs_ui_fragment"
+ namespace: "systemui"
+ description: "Have QQS and QS scenes in the Compose fragment always composed, not just when it should be visible."
+ bug: "389985793"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/Bounceable.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/Bounceable.kt
index 3f2f84b95977..827096996f0b 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/Bounceable.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/Bounceable.kt
@@ -17,13 +17,20 @@
package com.android.compose.animation
import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.runtime.Stable
import androidx.compose.ui.Modifier
+import androidx.compose.ui.layout.Measurable
+import androidx.compose.ui.layout.MeasureResult
+import androidx.compose.ui.layout.MeasureScope
import androidx.compose.ui.layout.layout
+import androidx.compose.ui.node.LayoutModifierNode
+import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Dp
import kotlin.math.roundToInt
/** A component that can bounce in one dimension, for instance when it is tapped. */
+@Stable
interface Bounceable {
val bounce: Dp
}
@@ -46,6 +53,7 @@ interface Bounceable {
* RTL layouts) side. This can be used for grids for which the last item does not align perfectly
* with the end of the grid.
*/
+@Stable
fun Modifier.bounceable(
bounceable: Bounceable,
previousBounceable: Bounceable?,
@@ -53,7 +61,47 @@ fun Modifier.bounceable(
orientation: Orientation,
bounceEnd: Boolean = nextBounceable != null,
): Modifier {
- return layout { measurable, constraints ->
+ return this then
+ BounceableElement(bounceable, previousBounceable, nextBounceable, orientation, bounceEnd)
+}
+
+private data class BounceableElement(
+ private val bounceable: Bounceable,
+ private val previousBounceable: Bounceable?,
+ private val nextBounceable: Bounceable?,
+ private val orientation: Orientation,
+ private val bounceEnd: Boolean,
+) : ModifierNodeElement<BounceableNode>() {
+ override fun create(): BounceableNode {
+ return BounceableNode(
+ bounceable,
+ previousBounceable,
+ nextBounceable,
+ orientation,
+ bounceEnd,
+ )
+ }
+
+ override fun update(node: BounceableNode) {
+ node.bounceable = bounceable
+ node.previousBounceable = previousBounceable
+ node.nextBounceable = nextBounceable
+ node.orientation = orientation
+ node.bounceEnd = bounceEnd
+ }
+}
+
+private class BounceableNode(
+ var bounceable: Bounceable,
+ var previousBounceable: Bounceable?,
+ var nextBounceable: Bounceable?,
+ var orientation: Orientation,
+ var bounceEnd: Boolean = nextBounceable != null,
+) : Modifier.Node(), LayoutModifierNode {
+ override fun MeasureScope.measure(
+ measurable: Measurable,
+ constraints: Constraints,
+ ): MeasureResult {
// The constraints in the orientation should be fixed, otherwise there is no way to know
// what the size of our child node will be without this animation code.
checkFixedSize(constraints, orientation)
@@ -61,10 +109,12 @@ fun Modifier.bounceable(
var sizePrevious = 0f
var sizeNext = 0f
+ val previousBounceable = previousBounceable
if (previousBounceable != null) {
sizePrevious += bounceable.bounce.toPx() - previousBounceable.bounce.toPx()
}
+ val nextBounceable = nextBounceable
if (nextBounceable != null) {
sizeNext += bounceable.bounce.toPx() - nextBounceable.bounce.toPx()
} else if (bounceEnd) {
@@ -84,7 +134,7 @@ fun Modifier.bounceable(
// constraints, otherwise the parent will automatically center this node given the
// size that it expects us to be. This allows us to then place the element where we
// want it to be.
- layout(idleWidth, placeable.height) {
+ return layout(idleWidth, placeable.height) {
placeable.placeRelative(-sizePrevious.roundToInt(), 0)
}
}
@@ -95,7 +145,7 @@ fun Modifier.bounceable(
constraints.copy(minHeight = animatedHeight, maxHeight = animatedHeight)
val placeable = measurable.measure(animatedConstraints)
- layout(placeable.width, idleHeight) {
+ return layout(placeable.width, idleHeight) {
placeable.placeRelative(0, -sizePrevious.roundToInt())
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/compose/modifiers/SysuiTestTag.kt b/packages/SystemUI/compose/features/src/com/android/systemui/compose/modifiers/SysuiTestTag.kt
index 9eb78e14ab4e..b1afb161f33d 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/compose/modifiers/SysuiTestTag.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/compose/modifiers/SysuiTestTag.kt
@@ -16,7 +16,7 @@
package com.android.systemui.compose.modifiers
-import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.runtime.Stable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.semantics
@@ -26,7 +26,11 @@ import androidx.compose.ui.semantics.testTagsAsResourceId
* Set a test tag on this node so that it is associated with [resId]. This node will then be
* accessible by integration tests using `sysuiResSelector(resId)`.
*/
-@OptIn(ExperimentalComposeUiApi::class)
+@Stable
fun Modifier.sysuiResTag(resId: String): Modifier {
- return this.semantics { testTagsAsResourceId = true }.testTag("com.android.systemui:id/$resId")
+ // TODO(b/372412931): Only compose the semantics modifier once, at the root of the SystemUI
+ // window.
+ return this.then(TestTagAsResourceIdModifier).testTag("com.android.systemui:id/$resId")
}
+
+private val TestTagAsResourceIdModifier = Modifier.semantics { testTagsAsResourceId = true }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt
index 60c017227334..216f0a74e1c7 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt
@@ -141,7 +141,7 @@ fun FooterActions(
mutableStateOf<FooterActionsForegroundServicesButtonViewModel?>(null)
}
var userSwitcher by remember { mutableStateOf<FooterActionsButtonViewModel?>(null) }
- var power by remember { mutableStateOf<FooterActionsButtonViewModel?>(null) }
+ var power by remember { mutableStateOf(viewModel.initialPower()) }
LaunchedEffect(
context,
@@ -218,23 +218,19 @@ fun FooterActions(
}
val useModifierBasedExpandable = remember { QSComposeFragment.isEnabled }
- security?.let { SecurityButton(it, useModifierBasedExpandable, Modifier.weight(1f)) }
- foregroundServices?.let { ForegroundServicesButton(it, useModifierBasedExpandable) }
- userSwitcher?.let {
- IconButton(
- it,
- useModifierBasedExpandable,
- Modifier.sysuiResTag("multi_user_switch"),
- )
- }
+ SecurityButton({ security }, useModifierBasedExpandable, Modifier.weight(1f))
+ ForegroundServicesButton({ foregroundServices }, useModifierBasedExpandable)
IconButton(
- viewModel.settings,
+ { userSwitcher },
+ useModifierBasedExpandable,
+ Modifier.sysuiResTag("multi_user_switch"),
+ )
+ IconButton(
+ { viewModel.settings },
useModifierBasedExpandable,
Modifier.sysuiResTag("settings_button_container"),
)
- power?.let {
- IconButton(it, useModifierBasedExpandable, Modifier.sysuiResTag("pm_lite"))
- }
+ IconButton({ power }, useModifierBasedExpandable, Modifier.sysuiResTag("pm_lite"))
}
}
}
@@ -242,10 +238,11 @@ fun FooterActions(
/** The security button. */
@Composable
private fun SecurityButton(
- model: FooterActionsSecurityButtonViewModel,
+ model: () -> FooterActionsSecurityButtonViewModel?,
useModifierBasedExpandable: Boolean,
modifier: Modifier = Modifier,
) {
+ val model = model() ?: return
val onClick: ((Expandable) -> Unit)? =
model.onClick?.let { onClick ->
val context = LocalContext.current
@@ -265,9 +262,10 @@ private fun SecurityButton(
/** The foreground services button. */
@Composable
private fun RowScope.ForegroundServicesButton(
- model: FooterActionsForegroundServicesButtonViewModel,
+ model: () -> FooterActionsForegroundServicesButtonViewModel?,
useModifierBasedExpandable: Boolean,
) {
+ val model = model() ?: return
if (model.displayText) {
TextButton(
Icon.Resource(R.drawable.ic_info_outline, contentDescription = null),
@@ -291,6 +289,17 @@ private fun RowScope.ForegroundServicesButton(
/** A button with an icon. */
@Composable
fun IconButton(
+ model: () -> FooterActionsButtonViewModel?,
+ useModifierBasedExpandable: Boolean,
+ modifier: Modifier = Modifier,
+) {
+ val model = model() ?: return
+ IconButton(model, useModifierBasedExpandable, modifier)
+}
+
+/** A button with an icon. */
+@Composable
+fun IconButton(
model: FooterActionsButtonViewModel,
useModifierBasedExpandable: Boolean,
modifier: Modifier = Modifier,
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
index 404f1b217026..22688d310b44 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
@@ -102,6 +102,7 @@ interface SceneTransitionLayoutScope<out CS : ContentScope> {
key: SceneKey,
userActions: Map<UserAction, UserActionResult> = emptyMap(),
effectFactory: OverscrollFactory? = null,
+ alwaysCompose: Boolean = false,
content: @Composable CS.() -> Unit,
)
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
index e3c4eb0f8bea..4da83c3a6fc9 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
@@ -207,6 +207,9 @@ internal class SceneTransitionLayoutImpl(
private val nestedScrollDispatcher = NestedScrollDispatcher()
private val nestedScrollConnection = object : NestedScrollConnection {}
+ // TODO(b/399825091): Remove this.
+ private var scenesToAlwaysCompose: MutableList<Scene>? = null
+
init {
updateContents(builder, layoutDirection, defaultEffectFactory)
@@ -312,6 +315,7 @@ internal class SceneTransitionLayoutImpl(
key: SceneKey,
userActions: Map<UserAction, UserActionResult>,
effectFactory: OverscrollFactory?,
+ alwaysCompose: Boolean,
content: @Composable InternalContentScope.() -> Unit,
) {
require(!overlaysDefined) { "all scenes must be defined before overlays" }
@@ -324,6 +328,10 @@ internal class SceneTransitionLayoutImpl(
Content.calculateGlobalZIndex(parentZIndex, ++zIndex, ancestors.size)
val factory = effectFactory ?: defaultEffectFactory
if (scene != null) {
+ check(alwaysCompose == scene.alwaysCompose) {
+ "scene.alwaysCompose can not change"
+ }
+
// Update an existing scene.
scene.content = content
scene.userActions = resolvedUserActions
@@ -332,7 +340,7 @@ internal class SceneTransitionLayoutImpl(
scene.maybeUpdateEffects(factory)
} else {
// New scene.
- scenes[key] =
+ val scene =
Scene(
key,
this@SceneTransitionLayoutImpl,
@@ -341,7 +349,16 @@ internal class SceneTransitionLayoutImpl(
zIndex.toFloat(),
globalZIndex,
factory,
+ alwaysCompose,
)
+
+ scenes[key] = scene
+
+ if (alwaysCompose) {
+ (scenesToAlwaysCompose
+ ?: mutableListOf<Scene>().also { scenesToAlwaysCompose = it })
+ .add(scene)
+ }
}
}
@@ -470,22 +487,24 @@ internal class SceneTransitionLayoutImpl(
@Composable
private fun Scenes() {
- scenesToCompose().fastForEach { scene -> key(scene.key) { scene.Content() } }
+ scenesToCompose().fastForEach { (scene, isInvisible) ->
+ key(scene.key) { scene.Content(isInvisible = isInvisible) }
+ }
}
- private fun scenesToCompose(): List<Scene> {
+ private fun scenesToCompose(): List<SceneToCompose> {
val transitions = state.currentTransitions
- return if (transitions.isEmpty()) {
- listOf(scene(state.transitionState.currentScene))
- } else {
- buildList {
- val visited = mutableSetOf<SceneKey>()
- fun maybeAdd(sceneKey: SceneKey) {
- if (visited.add(sceneKey)) {
- add(scene(sceneKey))
- }
+ return buildList {
+ val visited = mutableSetOf<SceneKey>()
+ fun maybeAdd(sceneKey: SceneKey, isInvisible: Boolean = false) {
+ if (visited.add(sceneKey)) {
+ add(SceneToCompose(scene(sceneKey), isInvisible))
}
+ }
+ if (transitions.isEmpty()) {
+ maybeAdd(state.transitionState.currentScene)
+ } else {
// Compose the new scene we are going to first.
transitions.fastForEachReversed { transition ->
when (transition) {
@@ -504,9 +523,13 @@ internal class SceneTransitionLayoutImpl(
// Make sure that the current scene is always composed.
maybeAdd(transitions.last().currentScene)
}
+
+ scenesToAlwaysCompose?.fastForEach { maybeAdd(it.key, isInvisible = true) }
}
}
+ private data class SceneToCompose(val scene: Scene, val isInvisible: Boolean)
+
@Composable
private fun BoxScope.Overlays() {
val overlaysOrderedByZIndex = overlaysToComposeOrderedByZIndex()
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt
index 149a9e7c4705..72ee75ad2d47 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt
@@ -34,6 +34,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.LookaheadScope
import androidx.compose.ui.layout.approachLayout
+import androidx.compose.ui.layout.layout
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.zIndex
@@ -154,11 +155,12 @@ internal sealed class Content(
@SuppressLint("NotConstructor")
@Composable
- fun Content(modifier: Modifier = Modifier) {
+ fun Content(modifier: Modifier = Modifier, isInvisible: Boolean = false) {
// If this content has a custom factory, provide it to the content so that the factory is
// automatically used when calling rememberOverscrollEffect().
Box(
modifier
+ .thenIf(isInvisible) { InvisibleModifier }
.zIndex(zIndex)
.approachLayout(
isMeasurementApproachInProgress = { layoutImpl.state.isTransitioning() }
@@ -305,3 +307,8 @@ internal class ContentScopeImpl(
)
}
}
+
+private val InvisibleModifier =
+ Modifier.layout { measurable, constraints ->
+ measurable.measure(constraints).run { layout(width, height) {} }
+ }
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Scene.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Scene.kt
index 7f57798fb1b3..38acd4be80ae 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Scene.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Scene.kt
@@ -35,6 +35,7 @@ internal class Scene(
zIndex: Float,
globalZIndex: Long,
effectFactory: OverscrollFactory,
+ val alwaysCompose: Boolean,
) : Content(key, layoutImpl, content, actions, zIndex, globalZIndex, effectFactory) {
override fun toString(): String {
return "Scene(key=$key)"
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/TransitionState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/TransitionState.kt
index e23e234b1cad..312dd77fd53f 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/TransitionState.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/TransitionState.kt
@@ -22,6 +22,8 @@ import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.runtime.Stable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
import com.android.compose.animation.scene.ContentKey
import com.android.compose.animation.scene.MutableSceneTransitionLayoutState
import com.android.compose.animation.scene.OverlayKey
@@ -241,6 +243,15 @@ sealed interface TransitionState {
/** Additional gesture context whenever the transition is driven by a user gesture. */
abstract val gestureContext: GestureContext?
+ /**
+ * True when the transition reached the end and the progress won't be updated anymore.
+ *
+ * [isProgressStable] will be `true` before this [Transition] is completed while there are
+ * still custom transition animations settling.
+ */
+ var isProgressStable: Boolean by mutableStateOf(false)
+ private set
+
/** The CUJ covered by this transition. */
@CujType
val cuj: Int?
@@ -372,7 +383,11 @@ sealed interface TransitionState {
check(_coroutineScope == null) { "A Transition can be started only once." }
coroutineScope {
_coroutineScope = this
- run()
+ try {
+ run()
+ } finally {
+ isProgressStable = true
+ }
}
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/mechanics/TransitionScopedMechanicsAdapter.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/mechanics/TransitionScopedMechanicsAdapter.kt
new file mode 100644
index 000000000000..ac8a8c014af4
--- /dev/null
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/mechanics/TransitionScopedMechanicsAdapter.kt
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compose.animation.scene.mechanics
+
+import androidx.annotation.VisibleForTesting
+import androidx.compose.runtime.mutableFloatStateOf
+import com.android.compose.animation.scene.ContentKey
+import com.android.compose.animation.scene.ElementKey
+import com.android.compose.animation.scene.ElementStateScope
+import com.android.compose.animation.scene.content.state.TransitionState
+import com.android.compose.animation.scene.transformation.CustomPropertyTransformation
+import com.android.compose.animation.scene.transformation.PropertyTransformationScope
+import com.android.mechanics.MotionValue
+import com.android.mechanics.ProvidedGestureContext
+import com.android.mechanics.spec.InputDirection
+import com.android.mechanics.spec.MotionSpec
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+
+/**
+ * Callback to create a [MotionSpec] on the first call to [CustomPropertyTransformation.transform]
+ */
+typealias SpecFactory =
+ PropertyTransformationScope.(content: ContentKey, element: ElementKey) -> MotionSpec
+
+/** Callback to compute the [MotionValue] per frame */
+typealias MotionValueInput =
+ PropertyTransformationScope.(progress: Float, content: ContentKey, element: ElementKey) -> Float
+
+/**
+ * Adapter to create a [MotionValue] and `keepRunning()` it temporarily while a
+ * [CustomPropertyTransformation] is in progress and until the animation settles.
+ *
+ * The [MotionValue]'s input is by default the transition progress.
+ */
+internal class TransitionScopedMechanicsAdapter(
+ private val computeInput: MotionValueInput = { progress, _, _ -> progress },
+ private val stableThreshold: Float = MotionValue.StableThresholdEffect,
+ private val label: String? = null,
+ private val createSpec: SpecFactory,
+) {
+
+ private val input = mutableFloatStateOf(0f)
+ private var motionValue: MotionValue? = null
+
+ fun PropertyTransformationScope.update(
+ content: ContentKey,
+ element: ElementKey,
+ transition: TransitionState.Transition,
+ transitionScope: CoroutineScope,
+ ): Float {
+ val progress = transition.progressTo(content)
+ input.floatValue = computeInput(progress, content, element)
+ var motionValue = motionValue
+
+ if (motionValue == null) {
+ motionValue =
+ MotionValue(
+ input::floatValue,
+ transition.gestureContext
+ ?: ProvidedGestureContext(
+ 0f,
+ appearDirection(content, element, transition),
+ ),
+ createSpec(content, element),
+ stableThreshold = stableThreshold,
+ label = label,
+ )
+ this@TransitionScopedMechanicsAdapter.motionValue = motionValue
+
+ transitionScope.launch {
+ motionValue.keepRunningWhile { !transition.isProgressStable || !isStable }
+ }
+ }
+
+ return motionValue.output
+ }
+
+ companion object {
+ /**
+ * Computes the InputDirection for a triggered transition of an element appearing /
+ * disappearing.
+ *
+ * Since [CustomPropertyTransformation] are only supported for non-shared elements, the
+ * [TransitionScopedMechanicsAdapter] is only used in the context of an element appearing /
+ * disappearing. This helper computes the direction to result in [InputDirection.Max] for an
+ * appear transition, and [InputDirection.Min] for a disappear transition.
+ */
+ @VisibleForTesting
+ internal fun ElementStateScope.appearDirection(
+ content: ContentKey,
+ element: ElementKey,
+ transition: TransitionState.Transition,
+ ): InputDirection {
+ check(!transition.isInitiatedByUserInput)
+
+ val inMaxDirection =
+ when (transition) {
+ is TransitionState.Transition.ChangeScene -> {
+ val transitionTowardsContent = content == transition.toContent
+ val elementInContent = element.targetSize(content) != null
+ val isReversed = transition.currentScene != transition.toScene
+ (transitionTowardsContent xor elementInContent) xor !isReversed
+ }
+
+ is TransitionState.Transition.ShowOrHideOverlay -> {
+ val transitioningTowardsOverlay = transition.overlay == transition.toContent
+ val isReversed =
+ transitioningTowardsOverlay xor transition.isEffectivelyShown
+ transitioningTowardsOverlay xor isReversed
+ }
+
+ is TransitionState.Transition.ReplaceOverlay -> {
+ transition.effectivelyShownOverlay == content
+ }
+ }
+
+ return if (inMaxDirection) InputDirection.Max else InputDirection.Min
+ }
+ }
+}
diff --git a/packages/SystemUI/compose/scene/tests/goldens/motionValue_interruptedAnimation_completes.json b/packages/SystemUI/compose/scene/tests/goldens/motionValue_interruptedAnimation_completes.json
new file mode 100644
index 000000000000..ce62ac3f4ee2
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/motionValue_interruptedAnimation_completes.json
@@ -0,0 +1,70 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144,
+ 160,
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ 272,
+ 288,
+ 304,
+ 320,
+ 336,
+ 352,
+ 368,
+ 384,
+ "after"
+ ],
+ "features": [
+ {
+ "name": "Foo_yOffset",
+ "type": "float",
+ "data_points": [
+ {
+ "type": "not_found"
+ },
+ {
+ "type": "not_found"
+ },
+ 175,
+ 175,
+ 174.00105,
+ 149.84001,
+ 114.73702,
+ 0,
+ 0,
+ 0,
+ 0,
+ 10.212692,
+ 42.525528,
+ 77.174965,
+ 106.322296,
+ 128.37651,
+ 144.09671,
+ 154.88022,
+ 162.08202,
+ 166.79778,
+ 169.83923,
+ 171.77742,
+ 173.00056,
+ 173.76627,
+ 174.24236,
+ {
+ "type": "not_found"
+ }
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/motionValue_withAnimation_prolongsTransition.json b/packages/SystemUI/compose/scene/tests/goldens/motionValue_withAnimation_prolongsTransition.json
new file mode 100644
index 000000000000..ac09ff3f359c
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/motionValue_withAnimation_prolongsTransition.json
@@ -0,0 +1,48 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144,
+ 160,
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ "after"
+ ],
+ "features": [
+ {
+ "name": "Foo_yOffset",
+ "type": "float",
+ "data_points": [
+ 175,
+ 175,
+ 175,
+ 175,
+ 156.26086,
+ 121.784874,
+ 88.35684,
+ 61.32686,
+ 41.302353,
+ 27.215454,
+ 17.638702,
+ 11.284393,
+ 7.144104,
+ 4.4841614,
+ 2.7943878,
+ 1.7307587,
+ 1.0663452,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/motionValue_withoutAnimation_terminatesImmediately.json b/packages/SystemUI/compose/scene/tests/goldens/motionValue_withoutAnimation_terminatesImmediately.json
new file mode 100644
index 000000000000..5cf66a4aa88c
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/motionValue_withoutAnimation_terminatesImmediately.json
@@ -0,0 +1,26 @@
+{
+ "frame_ids": [
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ "after"
+ ],
+ "features": [
+ {
+ "name": "Foo_yOffset",
+ "type": "float",
+ "data_points": [
+ 175,
+ 145.83333,
+ 116.666664,
+ 87.5,
+ 58.33333,
+ 29.166672,
+ 0
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
index fa7661b6d102..6538d4340cf3 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
@@ -45,6 +45,7 @@ import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.SemanticsNodeInteraction
import androidx.compose.ui.test.assertHeightIsEqualTo
import androidx.compose.ui.test.assertIsDisplayed
+import androidx.compose.ui.test.assertIsNotDisplayed
import androidx.compose.ui.test.assertPositionInRootIsEqualTo
import androidx.compose.ui.test.assertWidthIsEqualTo
import androidx.compose.ui.test.junit4.createComposeRule
@@ -64,10 +65,13 @@ import com.android.compose.animation.scene.TestScenes.SceneB
import com.android.compose.animation.scene.TestScenes.SceneC
import com.android.compose.animation.scene.subjects.assertThat
import com.android.compose.test.assertSizeIsEqualTo
+import com.android.compose.test.setContentAndCreateMainScope
import com.android.compose.test.subjects.DpOffsetSubject
import com.android.compose.test.subjects.assertThat
+import com.android.compose.test.transition
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
import org.junit.Assert.assertThrows
import org.junit.Rule
import org.junit.Test
@@ -582,4 +586,34 @@ class SceneTransitionLayoutTest {
assertThat((state2 as MutableSceneTransitionLayoutStateImpl).motionScheme)
.isEqualTo(motionScheme2)
}
+
+ @Test
+ fun alwaysCompose() {
+ val state = rule.runOnUiThread { MutableSceneTransitionLayoutStateForTests(SceneA) }
+ val scope =
+ rule.setContentAndCreateMainScope {
+ SceneTransitionLayoutForTesting(state) {
+ scene(SceneA) { Box(Modifier.element(TestElements.Foo).size(20.dp)) }
+ scene(SceneB, alwaysCompose = true) {
+ Box(Modifier.element(TestElements.Bar).size(40.dp))
+ }
+ }
+ }
+
+ // Idle(A): Foo is displayed and Bar exists given that SceneB is always composed but it is
+ // not displayed.
+ rule.onNode(isElement(TestElements.Foo)).assertIsDisplayed().assertSizeIsEqualTo(20.dp)
+ rule.onNode(isElement(TestElements.Bar)).assertExists().assertIsNotDisplayed()
+
+ // Transition(A => B): Foo and Bar are both displayed
+ val aToB = transition(SceneA, SceneB)
+ scope.launch { state.startTransition(aToB) }
+ rule.onNode(isElement(TestElements.Foo)).assertIsDisplayed().assertSizeIsEqualTo(20.dp)
+ rule.onNode(isElement(TestElements.Bar)).assertIsDisplayed().assertSizeIsEqualTo(40.dp)
+
+ // Idle(B): Foo does not exist and Bar is displayed.
+ aToB.finish()
+ rule.onNode(isElement(TestElements.Foo)).assertDoesNotExist()
+ rule.onNode(isElement(TestElements.Bar)).assertIsDisplayed().assertSizeIsEqualTo(40.dp)
+ }
}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/mechanics/TransitionScopedMechanicsAdapterTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/mechanics/TransitionScopedMechanicsAdapterTest.kt
new file mode 100644
index 000000000000..b9bd115782b7
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/mechanics/TransitionScopedMechanicsAdapterTest.kt
@@ -0,0 +1,519 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compose.animation.scene.mechanics
+
+import android.platform.test.annotations.MotionTest
+import androidx.compose.animation.core.LinearEasing
+import androidx.compose.animation.core.tween
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.size
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.semantics.SemanticsNode
+import androidx.compose.ui.test.junit4.ComposeContentTestRule
+import androidx.compose.ui.unit.IntSize
+import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.compose.animation.scene.ContentKey
+import com.android.compose.animation.scene.ContentScope
+import com.android.compose.animation.scene.ElementKey
+import com.android.compose.animation.scene.MutableSceneTransitionLayoutStateForTests
+import com.android.compose.animation.scene.MutableSceneTransitionLayoutStateImpl
+import com.android.compose.animation.scene.OverlayKey
+import com.android.compose.animation.scene.SceneKey
+import com.android.compose.animation.scene.SceneTransitionLayout
+import com.android.compose.animation.scene.SceneTransitionLayoutForTesting
+import com.android.compose.animation.scene.SceneTransitionsBuilder
+import com.android.compose.animation.scene.TestElements
+import com.android.compose.animation.scene.TestOverlays
+import com.android.compose.animation.scene.TestScenes
+import com.android.compose.animation.scene.TransitionBuilder
+import com.android.compose.animation.scene.TransitionRecordingSpec
+import com.android.compose.animation.scene.content.state.TransitionState
+import com.android.compose.animation.scene.featureOfElement
+import com.android.compose.animation.scene.mechanics.TransitionScopedMechanicsAdapter.Companion.appearDirection
+import com.android.compose.animation.scene.recordTransition
+import com.android.compose.animation.scene.testing.lastOffsetForTesting
+import com.android.compose.animation.scene.transformation.CustomPropertyTransformation
+import com.android.compose.animation.scene.transformation.PropertyTransformation
+import com.android.compose.animation.scene.transformation.PropertyTransformationScope
+import com.android.compose.animation.scene.transitions
+import com.android.mechanics.spec.InputDirection
+import com.android.mechanics.spec.Mapping
+import com.android.mechanics.spec.MotionSpec
+import com.android.mechanics.spec.buildDirectionalMotionSpec
+import com.android.mechanics.spring.SpringParameters
+import com.google.common.truth.Truth
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.test.TestScope
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import platform.test.motion.compose.ComposeRecordingSpec
+import platform.test.motion.compose.MotionControl
+import platform.test.motion.compose.createComposeMotionTestRule
+import platform.test.motion.compose.recordMotion
+import platform.test.motion.compose.runTest
+import platform.test.motion.golden.DataPoint
+import platform.test.motion.golden.DataPointTypes
+import platform.test.motion.golden.FeatureCapture
+import platform.test.motion.testing.createGoldenPathManager
+
+@RunWith(AndroidJUnit4::class)
+@MotionTest
+class TransitionScopedMechanicsAdapterTest {
+
+ private val goldenPaths =
+ createGoldenPathManager("frameworks/base/packages/SystemUI/compose/scene/tests/goldens")
+
+ private val testScope = TestScope()
+ @get:Rule val motionRule = createComposeMotionTestRule(goldenPaths, testScope)
+ private val composeRule = motionRule.toolkit.composeContentTestRule
+
+ @Test
+ fun motionValue_withoutAnimation_terminatesImmediately() =
+ motionRule.runTest {
+ val specFactory: SpecFactory = { _, _ ->
+ MotionSpec(
+ // Linearly animate from 10 down to 0
+ buildDirectionalMotionSpec(TestSpring, Mapping.Fixed(50.dp.toPx())) {
+ targetFromCurrent(breakpoint = 0f, to = 0f)
+ constantValueFromCurrent(breakpoint = 1f)
+ }
+ )
+ }
+
+ assertOffsetMatchesGolden(
+ transition = {
+ spec = tween(16 * 6, easing = LinearEasing)
+ transformation(TestElements.Foo) { TestTransformation(specFactory) }
+ }
+ )
+ }
+
+ @Test
+ fun motionValue_withAnimation_prolongsTransition() =
+ motionRule.runTest {
+ val specFactory: SpecFactory = { _, _ ->
+ MotionSpec(
+ // Use a spring to toggle 10f -> 0f at a progress of 0.5
+ buildDirectionalMotionSpec(TestSpring, Mapping.Fixed(50.dp.toPx())) {
+ constantValue(breakpoint = 0.5f, value = 0f)
+ }
+ )
+ }
+
+ assertOffsetMatchesGolden(
+ transition = {
+ spec = tween(16 * 6, easing = LinearEasing)
+ transformation(TestElements.Foo) { TestTransformation(specFactory) }
+ }
+ )
+ }
+
+ @Test
+ fun motionValue_interruptedAnimation_completes() =
+ motionRule.runTest {
+ val transitions = transitions {
+ from(TestScenes.SceneA, to = TestScenes.SceneB) {
+ spec = tween(16 * 6, easing = LinearEasing)
+
+ transformation(TestElements.Foo) {
+ TestTransformation { _, _ ->
+ MotionSpec(
+ buildDirectionalMotionSpec(
+ TestSpring,
+ Mapping.Fixed(50.dp.toPx()),
+ ) {
+ constantValue(breakpoint = 0.3f, value = 0f)
+ }
+ )
+ }
+ }
+ }
+ }
+
+ val state =
+ composeRule.runOnUiThread {
+ MutableSceneTransitionLayoutStateForTests(TestScenes.SceneA, transitions)
+ }
+ lateinit var coroutineScope: CoroutineScope
+
+ val motionControl =
+ MotionControl(delayRecording = { awaitFrames(4) }) {
+ awaitFrames(1)
+ val (transitionToB, firstTransitionJob) =
+ toolkit.composeContentTestRule.runOnUiThread {
+ checkNotNull(
+ state.setTargetScene(
+ TestScenes.SceneB,
+ animationScope = coroutineScope,
+ )
+ )
+ }
+
+ awaitCondition { transitionToB.progress > 0.5f }
+ val (transitionBackToA, secondTransitionJob) =
+ toolkit.composeContentTestRule.runOnUiThread {
+ checkNotNull(
+ state.setTargetScene(
+ TestScenes.SceneA,
+ animationScope = coroutineScope,
+ )
+ )
+ }
+
+ Truth.assertThat(transitionBackToA.replacedTransition)
+ .isSameInstanceAs(transitionToB)
+
+ awaitCondition { !state.isTransitioning() }
+
+ Truth.assertThat(firstTransitionJob.isCompleted).isTrue()
+ Truth.assertThat(secondTransitionJob.isCompleted).isTrue()
+ }
+
+ val motion =
+ recordMotion(
+ content = {
+ coroutineScope = rememberCoroutineScope()
+ SceneTransitionLayoutForTesting(state, modifier = Modifier.size(50.dp)) {
+ scene(TestScenes.SceneA) { SceneAContent() }
+ scene(TestScenes.SceneB) { SceneBContent() }
+ }
+ },
+ ComposeRecordingSpec(motionControl, recordBefore = false) {
+ featureOfElement(TestElements.Foo, yOffsetFeature)
+ },
+ )
+
+ assertThat(motion).timeSeriesMatchesGolden()
+ }
+
+ @Test
+ fun animationDirection_sceneTransition_forward() {
+ val transitionDirection =
+ composeRule.getAppearDirectionOnTransition(
+ initialScene = TestScenes.SceneA,
+ transitionBuilder = {
+ from(TestScenes.SceneA, to = TestScenes.SceneB) { it(TestElements.Foo) }
+ },
+ ) { state, animationScope, _ ->
+ state.setTargetScene(TestScenes.SceneB, animationScope)
+ false
+ }
+
+ Truth.assertThat(transitionDirection).isEqualTo(InputDirection.Max)
+ }
+
+ @Test
+ fun animationDirection_sceneTransition_backwards() {
+ val transitionDirection =
+ composeRule.getAppearDirectionOnTransition(
+ initialScene = TestScenes.SceneB,
+ transitionBuilder = {
+ from(TestScenes.SceneA, to = TestScenes.SceneB) { it(TestElements.Foo) }
+ },
+ ) { state, animationScope, _ ->
+ state.setTargetScene(TestScenes.SceneA, animationScope)
+ false
+ }
+
+ Truth.assertThat(transitionDirection).isEqualTo(InputDirection.Min)
+ }
+
+ @Test
+ fun animationDirection_interruptedTransition_flipsDirection() {
+ val transitionDirection =
+ composeRule.getAppearDirectionOnTransition(
+ initialScene = TestScenes.SceneA,
+ transitionBuilder = {
+ from(TestScenes.SceneA, to = TestScenes.SceneB) { it(TestElements.Foo) }
+ },
+ ) { state, animationScope, iteration ->
+ when (iteration) {
+ 0 -> {
+ state.setTargetScene(TestScenes.SceneB, animationScope)
+ true
+ }
+ 1 -> {
+ state.setTargetScene(TestScenes.SceneA, animationScope)
+ false
+ }
+ else -> throw AssertionError()
+ }
+ }
+
+ Truth.assertThat(transitionDirection).isEqualTo(InputDirection.Min)
+ }
+
+ @Test
+ fun animationDirection_showOverlay_animatesInMaxDirection() {
+ val transitionDirection =
+ composeRule.getAppearDirectionOnTransition(
+ initialScene = TestScenes.SceneA,
+ transitionBuilder = { this.to(TestOverlays.OverlayA) { it(TestElements.Bar) } },
+ ) { state, animationScope, _ ->
+ state.showOverlay(TestOverlays.OverlayA, animationScope)
+ false
+ }
+
+ Truth.assertThat(transitionDirection).isEqualTo(InputDirection.Max)
+ }
+
+ @Test
+ fun animationDirection_hideOverlay_animatesInMinDirection() {
+ val transitionDirection =
+ composeRule.getAppearDirectionOnTransition(
+ initialScene = TestScenes.SceneA,
+ initialOverlays = setOf(TestOverlays.OverlayA),
+ transitionBuilder = { this.to(TestOverlays.OverlayA) { it(TestElements.Bar) } },
+ ) { state, animationScope, _ ->
+ state.hideOverlay(TestOverlays.OverlayA, animationScope)
+ false
+ }
+
+ Truth.assertThat(transitionDirection).isEqualTo(InputDirection.Min)
+ }
+
+ @Test
+ fun animationDirection_hideOverlayMidTransition_animatesInMinDirection() {
+ val transitionDirection =
+ composeRule.getAppearDirectionOnTransition(
+ initialScene = TestScenes.SceneA,
+ transitionBuilder = { this.to(TestOverlays.OverlayA) { it(TestElements.Bar) } },
+ ) { state, animationScope, iteration ->
+ when (iteration) {
+ 0 -> {
+ state.showOverlay(TestOverlays.OverlayA, animationScope)
+ true
+ }
+ 1 -> {
+ state.hideOverlay(TestOverlays.OverlayA, animationScope)
+ false
+ }
+ else -> throw AssertionError()
+ }
+ }
+
+ Truth.assertThat(transitionDirection).isEqualTo(InputDirection.Min)
+ }
+
+ @Test
+ fun animationDirection_replaceOverlay_showingContent_animatesInMaxDirection() {
+ val transitionDirection =
+ composeRule.getAppearDirectionOnTransition(
+ initialScene = TestScenes.SceneA,
+ initialOverlays = setOf(TestOverlays.OverlayB),
+ transitionBuilder = { this.to(TestOverlays.OverlayA) { it(TestElements.Bar) } },
+ ) { state, animationScope, _ ->
+ state.replaceOverlay(TestOverlays.OverlayB, TestOverlays.OverlayA, animationScope)
+ false
+ }
+
+ Truth.assertThat(transitionDirection).isEqualTo(InputDirection.Max)
+ }
+
+ @Test
+ fun animationDirection_replaceOverlay_hidingContent_animatesInMinDirection() {
+ val transitionDirection =
+ composeRule.getAppearDirectionOnTransition(
+ initialScene = TestScenes.SceneA,
+ initialOverlays = setOf(TestOverlays.OverlayA),
+ transitionBuilder = { this.to(TestOverlays.OverlayA) { it(TestElements.Bar) } },
+ ) { state, animationScope, _ ->
+ state.replaceOverlay(TestOverlays.OverlayA, TestOverlays.OverlayB, animationScope)
+ false
+ }
+
+ Truth.assertThat(transitionDirection).isEqualTo(InputDirection.Min)
+ }
+
+ @Test
+ fun animationDirection_replaceOverlay_revertMidTransition_animatesInMinDirection() {
+ val transitionDirection =
+ composeRule.getAppearDirectionOnTransition(
+ initialScene = TestScenes.SceneA,
+ initialOverlays = setOf(TestOverlays.OverlayB),
+ transitionBuilder = { this.to(TestOverlays.OverlayA) { it(TestElements.Bar) } },
+ ) { state, animationScope, iteration ->
+ when (iteration) {
+ 0 -> {
+ state.replaceOverlay(
+ TestOverlays.OverlayB,
+ TestOverlays.OverlayA,
+ animationScope,
+ )
+ true
+ }
+ 1 -> {
+ state.replaceOverlay(
+ TestOverlays.OverlayA,
+ TestOverlays.OverlayB,
+ animationScope,
+ )
+ false
+ }
+ else -> throw AssertionError()
+ }
+ }
+
+ Truth.assertThat(transitionDirection).isEqualTo(InputDirection.Min)
+ }
+
+ private fun ComposeContentTestRule.getAppearDirectionOnTransition(
+ initialScene: SceneKey,
+ transitionBuilder: SceneTransitionsBuilder.(foo: DirectionAssertionTransition) -> Unit,
+ initialOverlays: Set<OverlayKey> = emptySet(),
+ runTransition:
+ (
+ state: MutableSceneTransitionLayoutStateImpl,
+ animationScope: CoroutineScope,
+ iteration: Int,
+ ) -> Boolean,
+ ): InputDirection {
+
+ lateinit var result: InputDirection
+
+ val x: DirectionAssertionTransition = {
+ transformation(it) {
+ object : CustomPropertyTransformation<IntSize> {
+ override val property = PropertyTransformation.Property.Size
+
+ override fun PropertyTransformationScope.transform(
+ content: ContentKey,
+ element: ElementKey,
+ transition: TransitionState.Transition,
+ transitionScope: CoroutineScope,
+ ): IntSize {
+ result = appearDirection(content, element, transition)
+ return IntSize.Zero
+ }
+ }
+ }
+ }
+
+ val state = runOnUiThread {
+ MutableSceneTransitionLayoutStateForTests(
+ initialScene,
+ transitions { transitionBuilder(x) },
+ initialOverlays,
+ )
+ }
+ lateinit var coroutineScope: CoroutineScope
+
+ setContent {
+ coroutineScope = rememberCoroutineScope()
+ SceneTransitionLayout(state) {
+ scene(TestScenes.SceneA) { SceneAContent() }
+ scene(TestScenes.SceneB) { SceneBContent() }
+ overlay(TestOverlays.OverlayA) { OverlayAContent() }
+ overlay(TestOverlays.OverlayB) {}
+ }
+ }
+
+ waitForIdle()
+ mainClock.autoAdvance = false
+ var keepOnAnimating = true
+ var iterationCount = 0
+ while (keepOnAnimating) {
+ runOnUiThread { keepOnAnimating = runTransition(state, coroutineScope, iterationCount) }
+ composeRule.mainClock.advanceTimeByFrame()
+ waitForIdle()
+ iterationCount++
+ }
+ waitForIdle()
+
+ return result
+ }
+
+ private class TestTransformation(specFactory: SpecFactory) :
+ CustomPropertyTransformation<Offset> {
+ override val property = PropertyTransformation.Property.Offset
+
+ val motionValue =
+ TransitionScopedMechanicsAdapter(createSpec = specFactory, stableThreshold = 1f)
+
+ override fun PropertyTransformationScope.transform(
+ content: ContentKey,
+ element: ElementKey,
+ transition: TransitionState.Transition,
+ transitionScope: CoroutineScope,
+ ): Offset {
+ val yOffset =
+ with(motionValue) { update(content, element, transition, transitionScope) }
+
+ return Offset(x = 0f, y = yOffset)
+ }
+ }
+
+ private fun assertOffsetMatchesGolden(transition: TransitionBuilder.() -> Unit) {
+ val recordingSpec =
+ TransitionRecordingSpec(recordBefore = false, recordAfter = true) {
+ featureOfElement(TestElements.Foo, yOffsetFeature)
+ }
+
+ val motion =
+ motionRule.recordTransition(
+ fromSceneContent = { SceneAContent() },
+ toSceneContent = { SceneBContent() },
+ transition = transition,
+ recordingSpec = recordingSpec,
+ layoutModifier = Modifier.size(50.dp),
+ )
+
+ motionRule.assertThat(motion).timeSeriesMatchesGolden()
+ }
+
+ companion object {
+
+ @Composable
+ fun ContentScope.SceneAContent() {
+ Box(modifier = Modifier.fillMaxSize())
+ }
+
+ @Composable
+ fun ContentScope.SceneBContent() {
+ Box(modifier = Modifier.fillMaxSize()) {
+ Box(Modifier.element(TestElements.Foo).size(50.dp).background(Color.Red))
+ }
+ }
+
+ @Composable
+ fun ContentScope.OverlayAContent() {
+ Box(Modifier.element(TestElements.Bar).size(50.dp).background(Color.Red))
+ }
+
+ @Composable
+ fun ContentScope.OverlayBContent() {
+ Box(modifier = Modifier.size(50.dp).background(Color.Green))
+ }
+
+ val TestSpring = SpringParameters(1200f, 1f)
+
+ val yOffsetFeature =
+ FeatureCapture<SemanticsNode, Float>("yOffset") {
+ DataPoint.of(it.lastOffsetForTesting?.y, DataPointTypes.float)
+ }
+ }
+}
+
+typealias DirectionAssertionTransition = TransitionBuilder.(container: ElementKey) -> Unit
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/FlexClockView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/FlexClockView.kt
index c765ea9cc84c..2dc3e2b7af73 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/FlexClockView.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/FlexClockView.kt
@@ -33,6 +33,7 @@ import com.android.systemui.shared.clocks.CanvasUtil.translate
import com.android.systemui.shared.clocks.CanvasUtil.use
import com.android.systemui.shared.clocks.ClockContext
import com.android.systemui.shared.clocks.DigitTranslateAnimator
+import com.android.systemui.shared.clocks.VPoint
import com.android.systemui.shared.clocks.VPointF
import com.android.systemui.shared.clocks.VPointF.Companion.max
import com.android.systemui.shared.clocks.VPointF.Companion.times
@@ -109,13 +110,11 @@ class FlexClockView(clockCtx: ClockContext) : ViewGroup(clockCtx.context) {
shouldMeasureChildren: Boolean,
): VPointF {
maxChildSize = VPointF(-1, -1)
- fun SimpleDigitalClockTextView.getSize() = VPointF(measuredWidth, measuredHeight)
-
childViews.forEach { textView ->
if (shouldMeasureChildren) {
textView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
}
- maxChildSize = max(maxChildSize, textView.getSize())
+ maxChildSize = max(maxChildSize, textView.measuredSize)
}
aodTranslate = VPointF.ZERO
// TODO(b/364680879): Cleanup
@@ -180,8 +179,8 @@ class FlexClockView(clockCtx: ClockContext) : ViewGroup(clockCtx.context) {
)
private fun updateMeasuredSize(
- widthMeasureSpec: Int = measuredWidthAndState,
- heightMeasureSpec: Int = measuredHeightAndState,
+ widthMeasureSpec: Int,
+ heightMeasureSpec: Int,
shouldMeasureChildren: Boolean,
) {
val size = calculateSize(widthMeasureSpec, heightMeasureSpec, shouldMeasureChildren)
@@ -357,7 +356,18 @@ class FlexClockView(clockCtx: ClockContext) : ViewGroup(clockCtx.context) {
}
fun animateFidget(x: Float, y: Float) {
- childViews.forEach { view -> view.animateFidget(x, y) }
+ val touchPt = VPointF(x, y)
+ val ints = intArrayOf(0, 0)
+ childViews
+ .sortedBy { view ->
+ view.getLocationInWindow(ints)
+ val loc = VPoint(ints[0], ints[1])
+ val center = loc + view.measuredSize / 2f
+ (center - touchPt).length()
+ }
+ .forEachIndexed { i, view ->
+ view.animateFidget(FIDGET_DELAYS[min(i, FIDGET_DELAYS.size - 1)])
+ }
}
private fun updateLocale(locale: Locale) {
@@ -441,6 +451,8 @@ class FlexClockView(clockCtx: ClockContext) : ViewGroup(clockCtx.context) {
val AOD_HORIZONTAL_TRANSLATE_RATIO = -0.15F
val AOD_VERTICAL_TRANSLATE_RATIO = 0.075F
+ val FIDGET_DELAYS = listOf(0L, 75L, 150L, 225L)
+
// Delays. Each digit's animation should have a slight delay, so we get a nice
// "stepping" effect. When moving right, the second digit of the hour should move first.
// When moving left, the first digit of the hour should move first. The lists encode
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
index abe5cc27f6d7..fae17a5321ff 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
@@ -372,7 +372,9 @@ open class SimpleDigitalClockTextView(
updateTextBoundsForTextAnimator()
}
- fun animateFidget(x: Float, y: Float) {
+ fun animateFidget(x: Float, y: Float) = animateFidget(0L)
+
+ fun animateFidget(delay: Long) {
if (!this::textAnimator.isInitialized || textAnimator.isRunning) {
// Skip fidget animation if other animation is already playing.
return
@@ -381,13 +383,13 @@ open class SimpleDigitalClockTextView(
logger.animateFidget(x, y)
clockCtx.vibrator?.vibrate(FIDGET_HAPTICS)
- // TODO(b/374306512): Delay each glyph's animation based on x/y position
textAnimator.setTextStyle(
TextAnimator.Style(fVar = fidgetFontVariation),
TextAnimator.Animation(
animate = isAnimationEnabled,
duration = FIDGET_ANIMATION_DURATION,
interpolator = FIDGET_INTERPOLATOR,
+ startDelay = delay,
onAnimationEnd = {
textAnimator.setTextStyle(
TextAnimator.Style(fVar = lsFontVariation),
@@ -430,8 +432,10 @@ open class SimpleDigitalClockTextView(
/** Returns the interpolated text bounding rect based on interpolation progress */
private fun getInterpolatedTextBounds(progress: Float = getInterpolatedProgress()): RectF {
- if (!textAnimator.isRunning || progress >= 1f) {
- return RectF(targetTextBounds)
+ if (progress <= 0f) {
+ return prevTextBounds
+ } else if (!textAnimator.isRunning || progress >= 1f) {
+ return targetTextBounds
}
return RectF().apply {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
index 0cfb36d58f89..446891a7873e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -531,20 +531,23 @@ open class AuthContainerViewTest : SysuiTestCase() {
@Test
fun testLayoutParams_hasSecureWindowFlag() {
- val layoutParams = AuthContainerView.getLayoutParams(windowToken, "")
+ val layoutParams =
+ AuthContainerView.getLayoutParams(windowToken, "", false /* isCredentialView */)
assertThat((layoutParams.flags and WindowManager.LayoutParams.FLAG_SECURE) != 0).isTrue()
}
@Test
fun testLayoutParams_hasShowWhenLockedFlag() {
- val layoutParams = AuthContainerView.getLayoutParams(windowToken, "")
+ val layoutParams =
+ AuthContainerView.getLayoutParams(windowToken, "", false /* isCredentialView */)
assertThat((layoutParams.flags and WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED) != 0)
.isTrue()
}
@Test
fun testLayoutParams_hasDimbehindWindowFlag() {
- val layoutParams = AuthContainerView.getLayoutParams(windowToken, "")
+ val layoutParams =
+ AuthContainerView.getLayoutParams(windowToken, "", false /* isCredentialView */)
val lpFlags = layoutParams.flags
val lpDimAmount = layoutParams.dimAmount
@@ -554,7 +557,8 @@ open class AuthContainerViewTest : SysuiTestCase() {
@Test
fun testLayoutParams_excludesImeInsets() {
- val layoutParams = AuthContainerView.getLayoutParams(windowToken, "")
+ val layoutParams =
+ AuthContainerView.getLayoutParams(windowToken, "", false /* isCredentialView */)
assertThat((layoutParams.fitInsetsTypes and WindowInsets.Type.ime()) == 0).isTrue()
}
@@ -706,7 +710,8 @@ open class AuthContainerViewTest : SysuiTestCase() {
@Test
fun testLayoutParams_hasCutoutModeAlwaysFlag() {
- val layoutParams = AuthContainerView.getLayoutParams(windowToken, "")
+ val layoutParams =
+ AuthContainerView.getLayoutParams(windowToken, "", false /* isCredentialView */)
val lpFlags = layoutParams.flags
assertThat(
@@ -717,7 +722,8 @@ open class AuthContainerViewTest : SysuiTestCase() {
@Test
fun testLayoutParams_excludesSystemBarInsets() {
- val layoutParams = AuthContainerView.getLayoutParams(windowToken, "")
+ val layoutParams =
+ AuthContainerView.getLayoutParams(windowToken, "", false /* isCredentialView */)
assertThat((layoutParams.fitInsetsTypes and WindowInsets.Type.systemBars()) == 0).isTrue()
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/common/domain/interactor/SysUIStatePerDisplayInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/common/domain/interactor/SysUIStatePerDisplayInteractorTest.kt
new file mode 100644
index 000000000000..ed9cd98a825a
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/common/domain/interactor/SysUIStatePerDisplayInteractorTest.kt
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.common.domain.interactor
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.model.StateChange
+import com.android.systemui.model.fakeSysUIStatePerDisplayRepository
+import com.android.systemui.model.sysUiStateFactory
+import com.android.systemui.model.sysuiStateInteractor
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import org.junit.Before
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class SysUIStatePerDisplayInteractorTest : SysuiTestCase() {
+
+ private val kosmos = testKosmos()
+
+ val stateRepository = kosmos.fakeSysUIStatePerDisplayRepository
+ val state0 = kosmos.sysUiStateFactory.create(0)
+ val state1 = kosmos.sysUiStateFactory.create(1)
+ val state2 = kosmos.sysUiStateFactory.create(2)
+
+ val underTest = kosmos.sysuiStateInteractor
+
+ @Before
+ fun setup() {
+ stateRepository.apply {
+ add(0, state0)
+ add(1, state1)
+ add(2, state2)
+ }
+ }
+
+ @Test
+ fun setFlagsExclusivelyToDisplay_setsFlagsOnTargetStateAndClearsTheOthers() {
+ val targetDisplayId = 0
+ val stateChange = StateChange().setFlag(1L, true)
+
+ underTest.setFlagsExclusivelyToDisplay(targetDisplayId, stateChange)
+
+ assertThat(state0.isFlagEnabled(1)).isTrue()
+ assertThat(state1.isFlagEnabled(1)).isFalse()
+ assertThat(state2.isFlagEnabled(1)).isFalse()
+
+ underTest.setFlagsExclusivelyToDisplay(1, stateChange)
+
+ assertThat(state0.isFlagEnabled(1)).isFalse()
+ assertThat(state1.isFlagEnabled(1)).isTrue()
+ assertThat(state2.isFlagEnabled(1)).isFalse()
+
+ underTest.setFlagsExclusivelyToDisplay(2, stateChange)
+
+ assertThat(state0.isFlagEnabled(1)).isFalse()
+ assertThat(state1.isFlagEnabled(1)).isFalse()
+ assertThat(state2.isFlagEnabled(1)).isTrue()
+
+ underTest.setFlagsExclusivelyToDisplay(3, stateChange)
+
+ assertThat(state0.isFlagEnabled(1)).isFalse()
+ assertThat(state1.isFlagEnabled(1)).isFalse()
+ assertThat(state2.isFlagEnabled(1)).isFalse()
+ }
+
+ @Test
+ fun setFlagsExclusivelyToDisplay_multipleFlags_setsFlagsOnTargetStateAndClearsTheOthers() {
+ val stateChange = StateChange().setFlag(1L, true).setFlag(2L, true)
+
+ underTest.setFlagsExclusivelyToDisplay(1, stateChange)
+
+ assertThat(state0.isFlagEnabled(1)).isFalse()
+ assertThat(state0.isFlagEnabled(2)).isFalse()
+ assertThat(state1.isFlagEnabled(1)).isTrue()
+ assertThat(state1.isFlagEnabled(2)).isTrue()
+ assertThat(state2.isFlagEnabled(1)).isFalse()
+ assertThat(state2.isFlagEnabled(1)).isFalse()
+ }
+
+ @Test
+ fun setFlagsExclusivelyToDisplay_clearsFlags() {
+ state0.setFlag(1, true).setFlag(2, true).commitUpdate()
+ state1.setFlag(1, true).setFlag(2, true).commitUpdate()
+ state2.setFlag(1, true).setFlag(2, true).commitUpdate()
+
+ val stateChange = StateChange().setFlag(1L, false)
+
+ underTest.setFlagsExclusivelyToDisplay(1, stateChange)
+
+ // Sets it as false in display 1, but also the others.
+ assertThat(state0.isFlagEnabled(1)).isFalse()
+ assertThat(state1.isFlagEnabled(1)).isFalse()
+ assertThat(state2.isFlagEnabled(1)).isFalse()
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt
new file mode 100644
index 000000000000..299105e2dabd
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.display.data.repository
+
+import android.view.Display
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class PerDisplayInstanceRepositoryImplTest : SysuiTestCase() {
+
+ private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+ private val testScope = kosmos.testScope
+ private val fakeDisplayRepository = kosmos.displayRepository
+ private val fakePerDisplayInstanceProviderWithTeardown =
+ kosmos.fakePerDisplayInstanceProviderWithTeardown
+
+ private val underTest: PerDisplayInstanceRepositoryImpl<TestPerDisplayInstance> =
+ kosmos.fakePerDisplayInstanceRepository
+
+ @Before
+ fun addDisplays() = runBlocking {
+ fakeDisplayRepository += createDisplay(DEFAULT_DISPLAY_ID)
+ fakeDisplayRepository += createDisplay(NON_DEFAULT_DISPLAY_ID)
+ }
+
+ @Test
+ fun forDisplay_defaultDisplay_multipleCalls_returnsSameInstance() =
+ testScope.runTest {
+ val instance = underTest[DEFAULT_DISPLAY_ID]
+
+ assertThat(underTest[DEFAULT_DISPLAY_ID]).isSameInstanceAs(instance)
+ }
+
+ @Test
+ fun forDisplay_nonDefaultDisplay_multipleCalls_returnsSameInstance() =
+ testScope.runTest {
+ val instance = underTest[NON_DEFAULT_DISPLAY_ID]
+
+ assertThat(underTest[NON_DEFAULT_DISPLAY_ID]).isSameInstanceAs(instance)
+ }
+
+ @Test
+ fun forDisplay_nonDefaultDisplay_afterDisplayRemoved_returnsNewInstance() =
+ testScope.runTest {
+ val instance = underTest[NON_DEFAULT_DISPLAY_ID]
+
+ fakeDisplayRepository -= NON_DEFAULT_DISPLAY_ID
+ fakeDisplayRepository += createDisplay(NON_DEFAULT_DISPLAY_ID)
+
+ assertThat(underTest[NON_DEFAULT_DISPLAY_ID]).isNotSameInstanceAs(instance)
+ }
+
+ @Test
+ fun forDisplay_nonExistingDisplayId_returnsNull() =
+ testScope.runTest { assertThat(underTest[NON_EXISTING_DISPLAY_ID]).isNull() }
+
+ @Test
+ fun forDisplay_afterDisplayRemoved_destroyInstanceInvoked() =
+ testScope.runTest {
+ val instance = underTest[NON_DEFAULT_DISPLAY_ID]
+
+ fakeDisplayRepository -= NON_DEFAULT_DISPLAY_ID
+
+ assertThat(fakePerDisplayInstanceProviderWithTeardown.destroyed)
+ .containsExactly(instance)
+ }
+
+ @Test
+ fun forDisplay_withoutDisplayRemoval_destroyInstanceIsNotInvoked() =
+ testScope.runTest {
+ underTest[NON_DEFAULT_DISPLAY_ID]
+
+ assertThat(fakePerDisplayInstanceProviderWithTeardown.destroyed).isEmpty()
+ }
+
+ private fun createDisplay(displayId: Int): Display =
+ display(type = Display.TYPE_INTERNAL, id = displayId)
+
+ companion object {
+ private const val DEFAULT_DISPLAY_ID = Display.DEFAULT_DISPLAY
+ private const val NON_DEFAULT_DISPLAY_ID = DEFAULT_DISPLAY_ID + 1
+ private const val NON_EXISTING_DISPLAY_ID = DEFAULT_DISPLAY_ID + 2
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/model/SceneContainerPluginTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/model/SceneContainerPluginTest.kt
new file mode 100644
index 000000000000..b2e29cf60c27
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/model/SceneContainerPluginTest.kt
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.model
+
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.Flags
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.EnableSceneContainer
+import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.shared.model.fakeSceneDataSource
+import com.android.systemui.shade.data.repository.fakeShadeDisplaysRepository
+import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@EnableSceneContainer
+class SceneContainerPluginTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+
+ private val shadeDisplayRepository = kosmos.fakeShadeDisplaysRepository
+ private val sceneDataSource = kosmos.fakeSceneDataSource
+
+ private val underTest = kosmos.sceneContainerPlugin
+
+ @Test
+ @EnableFlags(Flags.FLAG_SHADE_WINDOW_GOES_AROUND)
+ fun flagValueOverride_differentDisplayId_alwaysFalse() {
+ sceneDataSource.changeScene(Scenes.Shade)
+
+ shadeDisplayRepository.setDisplayId(1)
+
+ assertThat(
+ underTest.flagValueOverride(
+ flag = SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE,
+ displayId = 2,
+ )
+ )
+ .isFalse()
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_SHADE_WINDOW_GOES_AROUND)
+ fun flagValueOverride_sameDisplayId_returnsTrue() {
+ sceneDataSource.changeScene(Scenes.Shade)
+
+ shadeDisplayRepository.setDisplayId(1)
+
+ assertThat(
+ underTest.flagValueOverride(
+ flag = SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE,
+ displayId = 1,
+ )
+ )
+ .isTrue()
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_SHADE_WINDOW_GOES_AROUND)
+ fun flagValueOverride_differentDisplayId_shadeGoesAroundFlagOff_returnsTrue() {
+ sceneDataSource.changeScene(Scenes.Shade)
+
+ shadeDisplayRepository.setDisplayId(1)
+
+ assertThat(
+ underTest.flagValueOverride(
+ flag = SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE,
+ displayId = 2,
+ )
+ )
+ .isTrue()
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUIStateDispatcherTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUIStateDispatcherTest.kt
new file mode 100644
index 000000000000..b82f5fce9e14
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUIStateDispatcherTest.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.model
+
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.view.Display
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.Flags
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class SysUIStateDispatcherTest : SysuiTestCase() {
+
+ private val kosmos = testKosmos()
+
+ private val stateFactory = kosmos.sysUiStateFactory
+ private val state0 = stateFactory.create(Display.DEFAULT_DISPLAY)
+ private val state1 = stateFactory.create(DISPLAY_1)
+ private val state2 = stateFactory.create(DISPLAY_2)
+ private val underTest = kosmos.sysUIStateDispatcher
+
+ private val flagsChanges = mutableMapOf<Int, Long>() // display id -> flag value
+ private val callback =
+ SysUiState.SysUiStateCallback { sysUiFlags, displayId ->
+ flagsChanges[displayId] = sysUiFlags
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_SHADE_WINDOW_GOES_AROUND)
+ fun registerUnregisterListener_notifiedOfChanges_receivedForAllDisplayIdsWithOneCallback() {
+ underTest.registerListener(callback)
+
+ state1.setFlag(FLAG_1, true).commitUpdate()
+ state2.setFlag(FLAG_2, true).commitUpdate()
+
+ assertThat(flagsChanges).containsExactly(DISPLAY_1, FLAG_1, DISPLAY_2, FLAG_2)
+
+ underTest.unregisterListener(callback)
+
+ state1.setFlag(0, true).commitUpdate()
+
+ // Didn't change
+ assertThat(flagsChanges).containsExactly(DISPLAY_1, FLAG_1, DISPLAY_2, FLAG_2)
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_SHADE_WINDOW_GOES_AROUND)
+ fun registerUnregisterListener_notifiedOfChangesForNonDefaultDisplay_NotPropagated() {
+ underTest.registerListener(callback)
+
+ state1.setFlag(FLAG_1, true).commitUpdate()
+
+ assertThat(flagsChanges).isEmpty()
+
+ state0.setFlag(FLAG_1, true).commitUpdate()
+
+ assertThat(flagsChanges).containsExactly(Display.DEFAULT_DISPLAY, FLAG_1)
+ }
+
+ private companion object {
+ const val DISPLAY_1 = 1
+ const val DISPLAY_2 = 2
+ const val FLAG_1 = 10L
+ const val FLAG_2 = 20L
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUiStateExtTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUiStateExtTest.kt
index a3be9e35b912..09588f9f3751 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUiStateExtTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUiStateExtTest.kt
@@ -20,7 +20,6 @@ import android.view.Display
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.settings.FakeDisplayTracker
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import org.junit.Test
@@ -32,20 +31,11 @@ class SysUiStateExtTest : SysuiTestCase() {
private val kosmos = testKosmos()
- private val underTest =
- SysUiState(
- FakeDisplayTracker(context),
- kosmos.sceneContainerPlugin,
- )
+ private val underTest = kosmos.sysUiState
@Test
fun updateFlags() {
- underTest.updateFlags(
- Display.DEFAULT_DISPLAY,
- 1L to true,
- 2L to false,
- 3L to true,
- )
+ underTest.updateFlags(Display.DEFAULT_DISPLAY, 1L to true, 2L to false, 3L to true)
assertThat(underTest.flags and 1L).isNotEqualTo(0L)
assertThat(underTest.flags and 2L).isEqualTo(0L)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUiStateTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUiStateTest.java
index 9a78bd93f424..f6de6295212b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUiStateTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/model/SysUiStateTest.java
@@ -19,16 +19,23 @@ package com.android.systemui.model;
import static android.view.Display.DEFAULT_DISPLAY;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import android.view.Display;
+
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dump.DumpManager;
import com.android.systemui.kosmos.KosmosJavaAdapter;
-import com.android.systemui.settings.FakeDisplayTracker;
import org.junit.Before;
import org.junit.Test;
@@ -46,21 +53,33 @@ public class SysUiStateTest extends SysuiTestCase {
private KosmosJavaAdapter mKosmos;
private SysUiState.SysUiStateCallback mCallback;
private SysUiState mFlagsContainer;
+ private SceneContainerPlugin mSceneContainerPlugin;
+ private DumpManager mDumpManager;
+ private SysUIStateDispatcher mSysUIStateDispatcher;
+
+ private SysUiState createInstance(int displayId) {
+ var sysuiState = new SysUiStateImpl(displayId, mSceneContainerPlugin, mDumpManager,
+ mSysUIStateDispatcher);
+ sysuiState.addCallback(mCallback);
+ return sysuiState;
+ }
@Before
public void setup() {
- FakeDisplayTracker displayTracker = new FakeDisplayTracker(mContext);
mKosmos = new KosmosJavaAdapter(this);
- mFlagsContainer = new SysUiState(displayTracker, mKosmos.getSceneContainerPlugin());
+ mFlagsContainer = mKosmos.getSysuiState();
+ mSceneContainerPlugin = mKosmos.getSceneContainerPlugin();
mCallback = mock(SysUiState.SysUiStateCallback.class);
- mFlagsContainer.addCallback(mCallback);
+ mDumpManager = mock(DumpManager.class);
+ mSysUIStateDispatcher = mKosmos.getSysUIStateDispatcher();
+ mFlagsContainer = createInstance(DEFAULT_DISPLAY);
}
@Test
public void addSingle_setFlag() {
setFlags(FLAG_1);
- verify(mCallback, times(1)).onSystemUiStateChanged(FLAG_1);
+ verify(mCallback, times(1)).onSystemUiStateChanged(FLAG_1, DEFAULT_DISPLAY);
}
@Test
@@ -68,22 +87,19 @@ public class SysUiStateTest extends SysuiTestCase {
setFlags(FLAG_1);
setFlags(FLAG_2);
- verify(mCallback, times(1)).onSystemUiStateChanged(FLAG_1);
- verify(mCallback, times(1))
- .onSystemUiStateChanged(FLAG_1 | FLAG_2);
+ verify(mCallback, times(1)).onSystemUiStateChanged(FLAG_1, DEFAULT_DISPLAY);
+ verify(mCallback, times(1)).onSystemUiStateChanged(FLAG_1 | FLAG_2, DEFAULT_DISPLAY);
}
@Test
public void addMultipleRemoveOne_setFlag() {
setFlags(FLAG_1);
setFlags(FLAG_2);
- mFlagsContainer.setFlag(FLAG_1, false)
- .commitUpdate(DISPLAY_ID);
+ mFlagsContainer.setFlag(FLAG_1, false).commitUpdate(DISPLAY_ID);
- verify(mCallback, times(1)).onSystemUiStateChanged(FLAG_1);
- verify(mCallback, times(1))
- .onSystemUiStateChanged(FLAG_1 | FLAG_2);
- verify(mCallback, times(1)).onSystemUiStateChanged(FLAG_2);
+ verify(mCallback, times(1)).onSystemUiStateChanged(FLAG_1, DEFAULT_DISPLAY);
+ verify(mCallback, times(1)).onSystemUiStateChanged(FLAG_1 | FLAG_2, DEFAULT_DISPLAY);
+ verify(mCallback, times(1)).onSystemUiStateChanged(FLAG_2, DEFAULT_DISPLAY);
}
@Test
@@ -91,19 +107,18 @@ public class SysUiStateTest extends SysuiTestCase {
setFlags(FLAG_1, FLAG_2, FLAG_3, FLAG_4);
int expected = FLAG_1 | FLAG_2 | FLAG_3 | FLAG_4;
- verify(mCallback, times(1)).onSystemUiStateChanged(expected);
+ verify(mCallback, times(1)).onSystemUiStateChanged(expected, DEFAULT_DISPLAY);
}
@Test
public void addMultipleRemoveOne_setFlags() {
setFlags(FLAG_1, FLAG_2, FLAG_3, FLAG_4);
- mFlagsContainer.setFlag(FLAG_2, false)
- .commitUpdate(DISPLAY_ID);
+ mFlagsContainer.setFlag(FLAG_2, false).commitUpdate(DISPLAY_ID);
int expected1 = FLAG_1 | FLAG_2 | FLAG_3 | FLAG_4;
- verify(mCallback, times(1)).onSystemUiStateChanged(expected1);
+ verify(mCallback, times(1)).onSystemUiStateChanged(expected1, DEFAULT_DISPLAY);
int expected2 = FLAG_1 | FLAG_3 | FLAG_4;
- verify(mCallback, times(1)).onSystemUiStateChanged(expected2);
+ verify(mCallback, times(1)).onSystemUiStateChanged(expected2, DEFAULT_DISPLAY);
}
@Test
@@ -112,13 +127,37 @@ public class SysUiStateTest extends SysuiTestCase {
setFlags(FLAG_1, FLAG_2, FLAG_3, FLAG_4);
int expected = FLAG_1 | FLAG_2 | FLAG_3 | FLAG_4;
- verify(mCallback, times(0)).onSystemUiStateChanged(expected);
+ verify(mCallback, times(0)).onSystemUiStateChanged(expected, DEFAULT_DISPLAY);
+ }
+
+ @Test
+ public void setFlag_receivedForDefaultDisplay() {
+ setFlags(FLAG_1);
+
+ verify(mCallback, times(1)).onSystemUiStateChanged(FLAG_1, DEFAULT_DISPLAY);
+ }
+
+
+ @Test
+ public void init_registersWithDumpManager() {
+ verify(mDumpManager).registerNormalDumpable(any(), eq(mFlagsContainer));
+ }
+
+ @Test
+ public void destroy_unregistersWithDumpManager() {
+ mFlagsContainer.destroy();
+
+ verify(mDumpManager).unregisterDumpable(anyString());
}
private void setFlags(int... flags) {
- for (int i = 0; i < flags.length; i++) {
- mFlagsContainer.setFlag(flags[i], true);
+ setFlags(mFlagsContainer, flags);
+ }
+
+ private void setFlags(SysUiState instance, int... flags) {
+ for (int flag : flags) {
+ instance.setFlag(flag, true);
}
- mFlagsContainer.commitUpdate(DISPLAY_ID);
+ instance.commitUpdate();
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/view/WindowRootViewKeyEventHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/view/WindowRootViewKeyEventHandlerTest.kt
new file mode 100644
index 000000000000..18ebd4d08486
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/view/WindowRootViewKeyEventHandlerTest.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.scene.ui.view
+
+import android.view.KeyEvent
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.fakeFalsingCollector
+import com.android.systemui.keyevent.domain.interactor.mockSysUIKeyEventHandler
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.testKosmos
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.verify
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class WindowRootViewKeyEventHandlerTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ private val underTest: WindowRootViewKeyEventHandler = kosmos.windowRootViewKeyEventHandler
+
+ @Test
+ fun dispatchKeyEvent_forwardsDispatchKeyEvent() =
+ kosmos.runTest {
+ val keyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_B)
+ underTest.dispatchKeyEvent(keyEvent)
+ verify(mockSysUIKeyEventHandler).dispatchKeyEvent(keyEvent)
+ }
+
+ @Test
+ fun dispatchKeyEventPreIme_forwardsDispatchKeyEventPreIme() =
+ kosmos.runTest {
+ val keyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_B)
+ underTest.dispatchKeyEventPreIme(keyEvent)
+ verify(mockSysUIKeyEventHandler).dispatchKeyEventPreIme(keyEvent)
+ }
+
+ @Test
+ fun interceptMediaKey_forwardsInterceptMediaKey() =
+ kosmos.runTest {
+ val keyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_VOLUME_UP)
+ underTest.interceptMediaKey(keyEvent)
+ verify(mockSysUIKeyEventHandler).interceptMediaKey(keyEvent)
+ }
+
+ @Test
+ fun collectKeyEvent_forwardsCollectKeyEvent() =
+ kosmos.runTest {
+ val keyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A)
+ underTest.collectKeyEvent(keyEvent)
+ assertEquals(keyEvent, fakeFalsingCollector.lastKeyEvent)
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index d852a9dc0bb9..2c852c3f6185 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -17,7 +17,9 @@
package com.android.systemui.shade;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.view.Display.TYPE_INTERNAL;
+import static com.android.systemui.display.data.repository.FakeDisplayRepositoryKt.display;
import static com.android.systemui.log.LogBufferHelperKt.logcatLogBuffer;
import static com.google.common.truth.Truth.assertThat;
@@ -47,6 +49,7 @@ import android.os.Looper;
import android.os.PowerManager;
import android.os.UserManager;
import android.util.DisplayMetrics;
+import android.view.Display;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
@@ -70,6 +73,7 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
import com.android.systemui.classifier.FalsingCollectorFake;
import com.android.systemui.classifier.FalsingManagerFake;
+import com.android.systemui.common.domain.interactor.SysUIStateDisplaysInteractor;
import com.android.systemui.common.ui.view.TouchHandlingView;
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor;
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor;
@@ -291,6 +295,7 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
@Mock private NaturalScrollingSettingObserver mNaturalScrollingSettingObserver;
@Mock private LargeScreenHeaderHelper mLargeScreenHeaderHelper;
@Mock private StatusBarLongPressGestureDetector mStatusBarLongPressGestureDetector;
+ @Mock protected SysUIStateDisplaysInteractor mSysUIStateDisplaysInteractor;
protected final int mMaxUdfpsBurnInOffsetY = 5;
protected FakeFeatureFlagsClassic mFeatureFlags = new FakeFeatureFlagsClassic();
protected KeyguardClockInteractor mKeyguardClockInteractor;
@@ -435,6 +440,9 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
return null;
}).when(mView).setOnTouchListener(any(NotificationPanelViewController.TouchHandler.class));
+ var displayMock = display(TYPE_INTERNAL, /* flags= */ 0, /* id= */Display.DEFAULT_DISPLAY,
+ /* state= */ null);
+ when(mView.getDisplay()).thenReturn(displayMock);
// Any edge transition
when(mKeyguardTransitionInteractor.transition(any()))
.thenReturn(emptyFlow());
@@ -565,6 +573,7 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
mShadeRepository,
mSysUIUnfoldComponent,
mSysUiState,
+ mSysUIStateDisplaysInteractor,
mKeyguardUnlockAnimationController,
mKeyguardIndicationController,
mNotificationListContainer,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index 354c23d48916..f54c36754d31 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -16,10 +16,16 @@
package com.android.systemui.shade;
+import static android.view.Display.TYPE_INTERNAL;
+
+import static com.android.systemui.display.data.repository.FakeDisplayRepositoryKt.display;
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -28,6 +34,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.os.Build;
+import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.testing.TestableLooper;
import android.view.HapticFeedbackConstants;
@@ -38,6 +45,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.DejankUtils;
+import com.android.systemui.Flags;
import com.android.systemui.flags.DisableSceneContainer;
import com.google.android.msdl.data.model.MSDLToken;
@@ -182,4 +190,27 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo
assertThat(mMSDLPlayer.getLatestTokenPlayed()).isEqualTo(MSDLToken.FAILURE);
}
+
+ @Test
+ @EnableFlags(Flags.FLAG_SHADE_WINDOW_GOES_AROUND)
+ public void updateSystemUiStateFlags_updatesSysuiStateInteractor() {
+ var DISPLAY_ID = 10;
+ var displayMock = display(TYPE_INTERNAL, /* flags= */ 0, /* id= */DISPLAY_ID,
+ /* state= */ null);
+ when(mView.getDisplay()).thenReturn(displayMock);
+
+ mNotificationPanelViewController.updateSystemUiStateFlags();
+
+ verify(mSysUIStateDisplaysInteractor).setFlagsExclusivelyToDisplay(eq(DISPLAY_ID), any());
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_SHADE_WINDOW_GOES_AROUND)
+ public void updateSystemUiStateFlags_flagOff_doesNotUpdateSysuiStateInteractor() {
+ mNotificationPanelViewController.updateSystemUiStateFlags();
+
+ verify(mSysUIStateDisplaysInteractor, never()).setFlagsExclusivelyToDisplay(anyInt(),
+ any());
+ }
+
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
index 59e3a2ec08e5..43983593f236 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
@@ -42,6 +42,7 @@ import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING
import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
import com.android.systemui.res.R
+import com.android.systemui.scene.ui.view.WindowRootViewKeyEventHandler
import com.android.systemui.settings.brightness.data.repository.BrightnessMirrorShowingRepository
import com.android.systemui.settings.brightness.domain.interactor.BrightnessMirrorShowingInteractorPassThrough
import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler
@@ -69,7 +70,6 @@ import com.android.systemui.statusbar.window.StatusBarWindowStateController
import com.android.systemui.unfold.SysUIUnfoldComponent
import com.android.systemui.unfold.UnfoldTransitionProgressProvider
import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.time.FakeSystemClock
import com.android.systemui.window.ui.viewmodel.WindowRootViewModel
@@ -85,12 +85,12 @@ import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mock
-import org.mockito.Mockito
import org.mockito.Mockito.never
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
@RunWith(AndroidJUnit4::class)
@RunWithLooper(setAsMainLooper = true)
@@ -175,13 +175,14 @@ class NotificationShadeWindowViewTest : SysuiTestCase() {
featureFlags.set(Flags.SPLIT_SHADE_SUBPIXEL_OPTIMIZATION, true)
mSetFlagsRule.enableFlags(AConfigFlags.FLAG_REVAMPED_BOUNCER_MESSAGES)
testScope = TestScope()
+ val falsingCollector = FalsingCollectorFake()
controller =
NotificationShadeWindowViewController(
blurUtils,
windowRootViewModelFactory,
choreographer,
lockscreenShadeTransitionController,
- FalsingCollectorFake(),
+ falsingCollector,
statusBarStateController,
dockManager,
notificationShadeDepthController,
@@ -212,7 +213,7 @@ class NotificationShadeWindowViewTest : SysuiTestCase() {
NotificationLaunchAnimationInteractor(NotificationLaunchAnimationRepository()),
featureFlags,
FakeSystemClock(),
- Mockito.mock(SysUIKeyEventHandler::class.java),
+ WindowRootViewKeyEventHandler({ mock<SysUIKeyEventHandler>() }, falsingCollector),
quickSettingsController,
primaryBouncerInteractor,
alternateBouncerInteractor,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
index 3eec1cd2d54c..f54c28f4295b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
@@ -200,6 +200,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
private NotificationEntry mSecondaryUserNotif;
private NotificationEntry mWorkProfileNotif;
private NotificationEntry mSensitiveContentNotif;
+ private NotificationEntry mSensitiveNotifWithOldCreationTime;
private long mSensitiveNotifPostTime;
private final FakeFeatureFlagsClassic mFakeFeatureFlags = new FakeFeatureFlagsClassic();
private final FakeSystemClock mFakeSystemClock = new FakeSystemClock();
@@ -274,6 +275,20 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
.setSensitiveContent(true)
.setVisibilityOverride(VISIBILITY_NO_OVERRIDE).build());
mSensitiveNotifPostTime = mSensitiveContentNotif.getSbn().getNotification().getWhen();
+
+ mSensitiveNotifWithOldCreationTime = new NotificationEntryBuilder()
+ .setNotification(notifWithPrivateVisibility)
+ .setUser(new UserHandle(mCurrentUser.id))
+ .setPostTime(System.currentTimeMillis())
+ // creation time of at least -2 hours, no matter what the current value of
+ // SystemClock.currentTimeMillis
+ .setCreationTime(-1 * TimeUnit.HOURS.toMillis(2))
+ .build();
+ mSensitiveNotifWithOldCreationTime.setRanking(
+ new RankingBuilder(mCurrentUserNotif.getRanking())
+ .setChannel(channel)
+ .setSensitiveContent(true)
+ .setVisibilityOverride(VISIBILITY_NO_OVERRIDE).build());
when(mNotifCollection.getEntry(mWorkProfileNotif.getKey())).thenReturn(mWorkProfileNotif);
when(mKeyguardInteractorLazy.get()).thenReturn(mKeyguardInteractor);
when(mKeyguardInteractor.isKeyguardDismissible())
@@ -653,6 +668,23 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
@Test
@EnableFlags(LockscreenOtpRedaction.FLAG_NAME)
+ public void testNewSensitiveNotification_notRedactedIfOldCreationTime() {
+ // Allow private notifications for this user
+ mSettings.putIntForUser(LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1,
+ mCurrentUser.id);
+ changeSetting(LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS);
+ mLockscreenUserManager.mLocked.set(true);
+ // Claim the device was last unlocked 1 hour ago. Old enough to redact, but newer than the
+ // old creation time in the notification (which is -2 hours)
+ mLockscreenUserManager.mLastLockTime
+ .set(mSensitiveNotifPostTime - TimeUnit.HOURS.toMillis(1));
+ mLockscreenUserManager.mConnectedToWifi.set(false);
+ assertEquals(REDACTION_TYPE_NONE,
+ mLockscreenUserManager.getRedactionType(mSensitiveNotifWithOldCreationTime));
+ }
+
+ @Test
+ @EnableFlags(LockscreenOtpRedaction.FLAG_NAME)
public void testHasSensitiveContent_redacted() {
// Allow private notifications for this user
mSettings.putIntForUser(LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationMediaManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationMediaManagerTest.kt
index fed613153a4e..a7fe586cbfa5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationMediaManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationMediaManagerTest.kt
@@ -125,8 +125,7 @@ class NotificationMediaManagerTest : SysuiTestCase() {
}
@Test
- @EnableFlags(Flags.FLAG_NOTIFICATION_MEDIA_MANAGER_BACKGROUND_EXECUTION)
- fun clearMediaNotification_flagOn_resetMediaMetadata() {
+ fun clearMediaNotification_resetMediaMetadata() {
// set up media metadata.
notificationMediaManager.mMediaListener.onMetadataChanged(MediaMetadata.Builder().build())
backgroundExecutor.runAllReady()
@@ -138,17 +137,4 @@ class NotificationMediaManagerTest : SysuiTestCase() {
assertThat(notificationMediaManager.mediaMetadata).isNull()
assertThat(notificationMediaManager.mMediaController).isNull()
}
-
- @Test
- @DisableFlags(Flags.FLAG_NOTIFICATION_MEDIA_MANAGER_BACKGROUND_EXECUTION)
- fun clearMediaNotification_flagOff_resetMediaMetadata() {
- // set up media metadata.
- notificationMediaManager.mMediaListener.onMetadataChanged(MediaMetadata.Builder().build())
-
- // clear media notification.
- notificationMediaManager.clearCurrentMediaNotification()
-
- assertThat(notificationMediaManager.mediaMetadata).isNull()
- assertThat(notificationMediaManager.mMediaController).isNull()
- }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarOrchestratorStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarOrchestratorStoreTest.kt
index 06650f2afe58..b2b28a28ac38 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarOrchestratorStoreTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarOrchestratorStoreTest.kt
@@ -50,11 +50,11 @@ class MultiDisplayStatusBarOrchestratorStoreTest : SysuiTestCase() {
@Before fun addDisplays() = runBlocking { fakeDisplayRepository.addDisplay(DEFAULT_DISPLAY) }
@Test
- fun displayRemoved_stopsInstance() =
+ fun systemDecorationRemovedEvent_stopsInstance() =
testScope.runTest {
val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
- fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
+ fakeDisplayRepository.triggerRemoveSystemDecorationEvent(DEFAULT_DISPLAY)
verify(instance).stop()
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarterTest.kt
index fee939df2cbb..18a2d0794f91 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarterTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarterTest.kt
@@ -17,8 +17,7 @@
package com.android.systemui.statusbar.core
import android.platform.test.annotations.EnableFlags
-import android.view.Display
-import android.view.mockIWindowManager
+import android.view.Display.DEFAULT_DISPLAY
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -29,6 +28,8 @@ import com.android.systemui.statusbar.data.repository.fakePrivacyDotWindowContro
import com.android.systemui.testKosmos
import com.google.common.truth.Expect
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -37,11 +38,11 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.never
import org.mockito.kotlin.verify
-import org.mockito.kotlin.whenever
@SmallTest
@RunWith(AndroidJUnit4::class)
@EnableFlags(StatusBarConnectedDisplays.FLAG_NAME)
+@OptIn(ExperimentalCoroutinesApi::class)
class MultiDisplayStatusBarStarterTest : SysuiTestCase() {
@get:Rule val expect: Expect = Expect.create()
@@ -52,293 +53,116 @@ class MultiDisplayStatusBarStarterTest : SysuiTestCase() {
private val fakeInitializerStore = kosmos.fakeStatusBarInitializerStore
private val fakePrivacyDotStore = kosmos.fakePrivacyDotWindowControllerStore
private val fakeLightBarStore = kosmos.fakeLightBarControllerStore
- private val windowManager = kosmos.mockIWindowManager
// Lazy, so that @EnableFlags is set before initializer is instantiated.
private val underTest by lazy { kosmos.multiDisplayStatusBarStarter }
@Before
- fun setup() {
- whenever(windowManager.shouldShowSystemDecors(Display.DEFAULT_DISPLAY)).thenReturn(true)
- whenever(windowManager.shouldShowSystemDecors(DISPLAY_1)).thenReturn(true)
- whenever(windowManager.shouldShowSystemDecors(DISPLAY_2)).thenReturn(true)
- whenever(windowManager.shouldShowSystemDecors(DISPLAY_3)).thenReturn(true)
- whenever(windowManager.shouldShowSystemDecors(DISPLAY_4_NO_SYSTEM_DECOR)).thenReturn(false)
+ fun setUp() = runBlocking {
+ fakeDisplayRepository.addDisplay(DEFAULT_DISPLAY)
+ fakeDisplayRepository.addDisplay(DISPLAY_2)
}
@Test
- fun start_startsInitializersForCurrentDisplays() =
+ fun start_triggerAddDisplaySystemDecoration_startsInitializersForDisplay() =
testScope.runTest {
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_1)
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_2)
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
-
underTest.start()
runCurrent()
- expect
- .that(fakeInitializerStore.forDisplay(displayId = DISPLAY_1).startedByCoreStartable)
- .isTrue()
- expect
- .that(fakeInitializerStore.forDisplay(displayId = DISPLAY_2).startedByCoreStartable)
- .isTrue()
+ fakeDisplayRepository.triggerAddDisplaySystemDecorationEvent(
+ displayId = DEFAULT_DISPLAY
+ )
+ fakeDisplayRepository.triggerAddDisplaySystemDecorationEvent(displayId = DISPLAY_2)
+
expect
.that(
fakeInitializerStore
- .forDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
+ .forDisplay(displayId = DEFAULT_DISPLAY)
.startedByCoreStartable
)
- .isFalse()
- }
-
- @Test
- fun start_startsOrchestratorForCurrentDisplays() =
- testScope.runTest {
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_1)
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_2)
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
-
- underTest.start()
- runCurrent()
-
- verify(fakeOrchestratorFactory.createdOrchestratorForDisplay(displayId = DISPLAY_1)!!)
- .start()
- verify(fakeOrchestratorFactory.createdOrchestratorForDisplay(displayId = DISPLAY_2)!!)
- .start()
- assertThat(
- fakeOrchestratorFactory.createdOrchestratorForDisplay(
- displayId = DISPLAY_4_NO_SYSTEM_DECOR
- )
- )
- .isNull()
- }
-
- @Test
- fun start_startsPrivacyDotForCurrentDisplays() =
- testScope.runTest {
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_1)
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_2)
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
-
- underTest.start()
- runCurrent()
-
- verify(fakePrivacyDotStore.forDisplay(displayId = DISPLAY_1)).start()
- verify(fakePrivacyDotStore.forDisplay(displayId = DISPLAY_2)).start()
- verify(fakePrivacyDotStore.forDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR), never())
- .start()
- }
-
- @Test
- fun start_doesNotStartLightBarControllerForCurrentDisplays() =
- testScope.runTest {
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_1)
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_2)
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
-
- underTest.start()
- runCurrent()
-
- verify(fakeLightBarStore.forDisplay(displayId = DISPLAY_1), never()).start()
- verify(fakeLightBarStore.forDisplay(displayId = DISPLAY_2), never()).start()
- verify(fakeLightBarStore.forDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR), never())
- .start()
- }
-
- @Test
- fun start_createsLightBarControllerForCurrentDisplays() =
- testScope.runTest {
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_1)
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_2)
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
-
- underTest.start()
- runCurrent()
-
- assertThat(fakeLightBarStore.perDisplayMocks.keys).containsExactly(1, DISPLAY_2)
- }
-
- @Test
- fun start_doesNotStartPrivacyDotForDefaultDisplay() =
- testScope.runTest {
- fakeDisplayRepository.addDisplay(displayId = Display.DEFAULT_DISPLAY)
-
- underTest.start()
- runCurrent()
-
- verify(fakePrivacyDotStore.forDisplay(displayId = Display.DEFAULT_DISPLAY), never())
- .start()
- }
-
- @Test
- fun displayAdded_orchestratorForNewDisplay() =
- testScope.runTest {
- underTest.start()
- runCurrent()
-
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_3)
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
- runCurrent()
-
- verify(fakeOrchestratorFactory.createdOrchestratorForDisplay(displayId = DISPLAY_3)!!)
- .start()
- assertThat(
- fakeOrchestratorFactory.createdOrchestratorForDisplay(
- displayId = DISPLAY_4_NO_SYSTEM_DECOR
- )
- )
- .isNull()
- }
-
- @Test
- fun displayAdded_initializerForNewDisplay() =
- testScope.runTest {
- underTest.start()
- runCurrent()
-
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_3)
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
- runCurrent()
-
- expect
- .that(fakeInitializerStore.forDisplay(displayId = DISPLAY_3).startedByCoreStartable)
.isTrue()
expect
- .that(
- fakeInitializerStore
- .forDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
- .startedByCoreStartable
- )
- .isFalse()
+ .that(fakeInitializerStore.forDisplay(displayId = DISPLAY_2).startedByCoreStartable)
+ .isTrue()
}
@Test
- fun displayAdded_privacyDotForNewDisplay() =
+ fun start_triggerAddDisplaySystemDecoration_startsOrchestratorForDisplay() =
testScope.runTest {
underTest.start()
runCurrent()
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_3)
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
+ fakeDisplayRepository.triggerAddDisplaySystemDecorationEvent(
+ displayId = DEFAULT_DISPLAY
+ )
+ fakeDisplayRepository.triggerAddDisplaySystemDecorationEvent(displayId = DISPLAY_2)
runCurrent()
- verify(fakePrivacyDotStore.forDisplay(displayId = DISPLAY_3)).start()
- verify(fakePrivacyDotStore.forDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR), never())
+ verify(
+ fakeOrchestratorFactory.createdOrchestratorForDisplay(
+ displayId = DEFAULT_DISPLAY
+ )!!
+ )
+ .start()
+ verify(fakeOrchestratorFactory.createdOrchestratorForDisplay(displayId = DISPLAY_2)!!)
.start()
}
@Test
- fun displayAdded_lightBarForNewDisplayCreate() =
+ fun start_triggerAddDisplaySystemDecoration_startsPrivacyDotForNonDefaultDisplay() =
testScope.runTest {
underTest.start()
runCurrent()
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_3)
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
- runCurrent()
+ fakeDisplayRepository.triggerAddDisplaySystemDecorationEvent(displayId = DISPLAY_2)
- assertThat(fakeLightBarStore.perDisplayMocks.keys).containsExactly(DISPLAY_3)
+ verify(fakePrivacyDotStore.forDisplay(displayId = DISPLAY_2)).start()
}
@Test
- fun displayAdded_lightBarForNewDisplayStart() =
+ fun start_triggerAddDisplaySystemDecoration_doesNotStartPrivacyDotForDefaultDisplay() =
testScope.runTest {
underTest.start()
runCurrent()
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_3)
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
- runCurrent()
+ fakeDisplayRepository.triggerAddDisplaySystemDecorationEvent(
+ displayId = DEFAULT_DISPLAY
+ )
- verify(fakeLightBarStore.forDisplay(displayId = DISPLAY_3), never()).start()
- verify(fakeLightBarStore.forDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR), never())
- .start()
+ verify(fakePrivacyDotStore.forDisplay(displayId = DEFAULT_DISPLAY), never()).start()
}
@Test
- fun displayAddedDuringStart_initializerForNewDisplay() =
+ fun start_triggerAddDisplaySystemDecoration_doesNotStartLightBarControllerForDisplays() =
testScope.runTest {
underTest.start()
-
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_3)
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
runCurrent()
- expect
- .that(fakeInitializerStore.forDisplay(displayId = DISPLAY_3).startedByCoreStartable)
- .isTrue()
- expect
- .that(
- fakeInitializerStore
- .forDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
- .startedByCoreStartable
- )
- .isFalse()
- }
-
- @Test
- fun displayAddedDuringStart_orchestratorForNewDisplay() =
- testScope.runTest {
- underTest.start()
-
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_3)
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
- runCurrent()
-
- verify(fakeOrchestratorFactory.createdOrchestratorForDisplay(displayId = DISPLAY_3)!!)
- .start()
- assertThat(
- fakeOrchestratorFactory.createdOrchestratorForDisplay(
- displayId = DISPLAY_4_NO_SYSTEM_DECOR
- )
- )
- .isNull()
- }
-
- @Test
- fun displayAddedDuringStart_privacyDotForNewDisplay() =
- testScope.runTest {
- underTest.start()
-
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_3)
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
- runCurrent()
+ fakeDisplayRepository.triggerAddDisplaySystemDecorationEvent(
+ displayId = DEFAULT_DISPLAY
+ )
+ fakeDisplayRepository.triggerAddDisplaySystemDecorationEvent(displayId = DISPLAY_2)
- verify(fakePrivacyDotStore.forDisplay(displayId = DISPLAY_3)).start()
- verify(fakePrivacyDotStore.forDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR), never())
- .start()
+ verify(fakeLightBarStore.forDisplay(displayId = DEFAULT_DISPLAY), never()).start()
+ verify(fakeLightBarStore.forDisplay(displayId = DISPLAY_2), never()).start()
}
@Test
- fun displayAddedDuringStart_lightBarForNewDisplayCreate() =
+ fun start_triggerAddDisplaySystemDecoration_createsLightBarControllerForDisplay() =
testScope.runTest {
underTest.start()
-
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_3)
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
runCurrent()
- assertThat(fakeLightBarStore.perDisplayMocks.keys).containsExactly(DISPLAY_3)
- }
-
- @Test
- fun displayAddedDuringStart_lightBarForNewDisplayStart() =
- testScope.runTest {
- underTest.start()
-
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_3)
- fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
- runCurrent()
+ fakeDisplayRepository.triggerAddDisplaySystemDecorationEvent(
+ displayId = DEFAULT_DISPLAY
+ )
+ fakeDisplayRepository.triggerAddDisplaySystemDecorationEvent(displayId = DISPLAY_2)
- verify(fakeLightBarStore.forDisplay(displayId = DISPLAY_3), never()).start()
- verify(fakeLightBarStore.forDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR), never())
- .start()
+ assertThat(fakeLightBarStore.perDisplayMocks.keys)
+ .containsExactly(DEFAULT_DISPLAY, DISPLAY_2)
}
companion object {
- const val DISPLAY_1 = 1
const val DISPLAY_2 = 2
- const val DISPLAY_3 = 3
- const val DISPLAY_4_NO_SYSTEM_DECOR = 4
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/LightBarControllerStoreImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/LightBarControllerStoreImplTest.kt
index 884c35c3457d..500332fa4a26 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/LightBarControllerStoreImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/LightBarControllerStoreImplTest.kt
@@ -65,11 +65,11 @@ class LightBarControllerStoreImplTest : SysuiTestCase() {
}
@Test
- fun displayRemoved_stopsInstance() =
+ fun systemDecorationRemovedEvent_stopsInstance() =
testScope.runTest {
val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
- fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
+ fakeDisplayRepository.triggerRemoveSystemDecorationEvent(DEFAULT_DISPLAY)
verify(instance).stop()
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayDarkIconDispatcherStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayDarkIconDispatcherStoreTest.kt
index f37648a639df..62ead9b45adc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayDarkIconDispatcherStoreTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayDarkIconDispatcherStoreTest.kt
@@ -62,11 +62,11 @@ class MultiDisplayDarkIconDispatcherStoreTest : SysuiTestCase() {
}
@Test
- fun displayRemoved_stopsInstance() =
+ fun systemDecorationRemovedEvent_stopsInstance() =
testScope.runTest {
val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
- fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
+ fakeDisplayRepository.triggerRemoveSystemDecorationEvent(DEFAULT_DISPLAY)
verify(instance).stop()
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarContentInsetsProviderStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarContentInsetsProviderStoreTest.kt
index e0a1f273aa44..486a84598410 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarContentInsetsProviderStoreTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarContentInsetsProviderStoreTest.kt
@@ -65,11 +65,11 @@ class MultiDisplayStatusBarContentInsetsProviderStoreTest : SysuiTestCase() {
}
@Test
- fun displayRemoved_stopsInstance() =
+ fun systemDecorationRemovedEvent_stopsInstance() =
testScope.runTest {
val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
- fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
+ fakeDisplayRepository.triggerRemoveSystemDecorationEvent(DEFAULT_DISPLAY)
verify(instance).stop()
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarModeRepositoryStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarModeRepositoryStoreTest.kt
index 11fd902fc50c..2c474da082bf 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarModeRepositoryStoreTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarModeRepositoryStoreTest.kt
@@ -59,11 +59,11 @@ class MultiDisplayStatusBarModeRepositoryStoreTest : SysuiTestCase() {
}
@Test
- fun displayRemoved_stopsInstance() =
+ fun systemDecorationRemovedEvent_stopsInstance() =
testScope.runTest {
val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
- fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
+ fakeDisplayRepository.triggerRemoveSystemDecorationEvent(DEFAULT_DISPLAY)
verify(instance).stop()
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStoreImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStoreImplTest.kt
index a5b7fc283976..bc7d47c52531 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStoreImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStoreImplTest.kt
@@ -23,6 +23,7 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.display.data.repository.displayRepository
import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
import com.android.systemui.testKosmos
import kotlinx.coroutines.runBlocking
@@ -36,7 +37,7 @@ import org.mockito.kotlin.verify
@RunWith(AndroidJUnit4::class)
@EnableFlags(StatusBarConnectedDisplays.FLAG_NAME)
class PrivacyDotWindowControllerStoreImplTest : SysuiTestCase() {
- private val kosmos = testKosmos()
+ private val kosmos = testKosmos().useUnconfinedTestDispatcher()
private val testScope = kosmos.testScope
private val underTest by lazy { kosmos.privacyDotWindowControllerStoreImpl }
@@ -58,11 +59,11 @@ class PrivacyDotWindowControllerStoreImplTest : SysuiTestCase() {
}
@Test
- fun displayRemoved_stopsInstance() =
+ fun systemDecorationRemovedEvent_stopsInstance() =
testScope.runTest {
val instance = underTest.forDisplay(DISPLAY_2)!!
- kosmos.displayRepository.removeDisplay(DISPLAY_2)
+ kosmos.displayRepository.triggerRemoveSystemDecorationEvent(DISPLAY_2)
verify(instance).stop()
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayStoreImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayStoreImplTest.kt
new file mode 100644
index 000000000000..41ae377a13f7
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayStoreImplTest.kt
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.data.repository
+
+import android.view.Display
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.display.data.repository.displayRepository
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class StatusBarPerDisplayStoreImplTest : SysuiTestCase() {
+
+ private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+ private val testScope = kosmos.testScope
+ private val fakeDisplayRepository = kosmos.displayRepository
+
+ private val store = kosmos.fakeStatusBarPerDisplayStore
+
+ @Before
+ fun start() {
+ store.start()
+ }
+
+ @Before
+ fun addDisplays() = runBlocking {
+ fakeDisplayRepository.addDisplay(DEFAULT_DISPLAY_ID)
+ fakeDisplayRepository.addDisplay(NON_DEFAULT_DISPLAY_ID)
+ }
+
+ @Test
+ fun removeSystemDecoration_onDisplayRemovalActionInvoked() =
+ testScope.runTest {
+ val instance = store.forDisplay(NON_DEFAULT_DISPLAY_ID)
+
+ fakeDisplayRepository.triggerRemoveSystemDecorationEvent(NON_DEFAULT_DISPLAY_ID)
+
+ assertThat(store.removalActions).containsExactly(instance)
+ }
+
+ @Test
+ fun removeSystemDecoration_twice_onDisplayRemovalActionInvokedOnce() =
+ testScope.runTest {
+ val instance = store.forDisplay(NON_DEFAULT_DISPLAY_ID)
+
+ fakeDisplayRepository.triggerRemoveSystemDecorationEvent(NON_DEFAULT_DISPLAY_ID)
+ fakeDisplayRepository.triggerRemoveSystemDecorationEvent(NON_DEFAULT_DISPLAY_ID)
+
+ assertThat(store.removalActions).containsExactly(instance)
+ }
+
+ @Test
+ fun forDisplay_withoutDisplayRemoval_onDisplayRemovalActionIsNotInvoked() =
+ testScope.runTest {
+ store.forDisplay(NON_DEFAULT_DISPLAY_ID)
+
+ assertThat(store.removalActions).isEmpty()
+ }
+
+ companion object {
+ private const val DEFAULT_DISPLAY_ID = Display.DEFAULT_DISPLAY
+ private const val NON_DEFAULT_DISPLAY_ID = DEFAULT_DISPLAY_ID + 1
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStoreImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStoreImplTest.kt
index 3cc592c94678..94394ede819e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStoreImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStoreImplTest.kt
@@ -62,11 +62,11 @@ class SystemEventChipAnimationControllerStoreImplTest : SysuiTestCase() {
}
@Test
- fun displayRemoved_stopsInstance() =
+ fun systemDecorationRemovedEvent_stopsInstance() =
testScope.runTest {
val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
- fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
+ fakeDisplayRepository.triggerRemoveSystemDecorationEvent(DEFAULT_DISPLAY)
verify(instance).stop()
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorTest.kt
index aa6e76d08c17..6926677feda0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorTest.kt
@@ -111,7 +111,7 @@ class PromotedNotificationsInteractorTest : SysuiTestCase() {
)
val topPromotedNotificationContent by
- collectLastValue(underTest.topPromotedNotificationContent)
+ collectLastValue(underTest.aodPromotedNotification)
// THEN the ron is first because the call has no content
assertThat(topPromotedNotificationContent?.identity?.key)
@@ -131,7 +131,7 @@ class PromotedNotificationsInteractorTest : SysuiTestCase() {
)
val topPromotedNotificationContent by
- collectLastValue(underTest.topPromotedNotificationContent)
+ collectLastValue(underTest.aodPromotedNotification)
// THEN the call is the top notification
assertThat(topPromotedNotificationContent?.identity?.key)
@@ -148,7 +148,7 @@ class PromotedNotificationsInteractorTest : SysuiTestCase() {
renderNotificationListInteractor.setRenderedList(listOf(callEntry, otherEntry))
val topPromotedNotificationContent by
- collectLastValue(underTest.topPromotedNotificationContent)
+ collectLastValue(underTest.aodPromotedNotification)
// THEN there is no top promoted notification
assertThat(topPromotedNotificationContent).isNull()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/MultiDisplayAutoHideControllerStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/MultiDisplayAutoHideControllerStoreTest.kt
index d16372611e88..b9d9a53fd319 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/MultiDisplayAutoHideControllerStoreTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/MultiDisplayAutoHideControllerStoreTest.kt
@@ -62,11 +62,11 @@ class MultiDisplayAutoHideControllerStoreTest : SysuiTestCase() {
}
@Test
- fun displayRemoved_stopsInstance() =
+ fun systemDecorationRemovedEvent_stopsInstance() =
testScope.runTest {
val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
- fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
+ fakeDisplayRepository.triggerRemoveSystemDecorationEvent(DEFAULT_DISPLAY)
verify(instance).stop()
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java
index 58856d970711..ffde34efa7ad 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java
@@ -48,7 +48,6 @@ import com.android.systemui.animation.back.BackAnimationSpec;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.kosmos.KosmosJavaAdapter;
import com.android.systemui.model.SysUiState;
-import com.android.systemui.settings.FakeDisplayTracker;
import org.junit.Before;
import org.junit.Rule;
@@ -84,8 +83,7 @@ public class SystemUIDialogTest extends SysuiTestCase {
public void setup() {
MockitoAnnotations.initMocks(this);
KosmosJavaAdapter kosmos = new KosmosJavaAdapter(this);
- FakeDisplayTracker displayTracker = new FakeDisplayTracker(mContext);
- mSysUiState = new SysUiState(displayTracker, kosmos.getSceneContainerPlugin());
+ mSysUiState = kosmos.getSysuiState();
mDependency.injectTestDependency(BroadcastDispatcher.class, mBroadcastDispatcher);
when(mDelegate.getBackAnimationSpec(ArgumentMatchers.any()))
.thenReturn(mock(BackAnimationSpec.class));
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
index f91e3a612862..a083e59fe263 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
@@ -31,6 +31,7 @@ import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationSt
import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipModel
import com.android.systemui.statusbar.phone.domain.interactor.IsAreaDark
import com.android.systemui.statusbar.pipeline.battery.ui.viewmodel.BatteryViewModel
+import com.android.systemui.statusbar.pipeline.shared.ui.model.ChipsVisibilityModel
import com.android.systemui.statusbar.pipeline.shared.ui.model.SystemInfoCombinedVisibilityModel
import com.android.systemui.statusbar.pipeline.shared.ui.model.VisibilityModel
import kotlinx.coroutines.flow.Flow
@@ -52,7 +53,10 @@ class FakeHomeStatusBarViewModel(
override val primaryOngoingActivityChip: MutableStateFlow<OngoingActivityChipModel> =
MutableStateFlow(OngoingActivityChipModel.Inactive())
- override val ongoingActivityChips = MutableStateFlow(MultipleOngoingActivityChipsModel())
+ override val ongoingActivityChips =
+ MutableStateFlow(
+ ChipsVisibilityModel(MultipleOngoingActivityChipsModel(), areChipsAllowed = false)
+ )
override val ongoingActivityChipsLegacy =
MutableStateFlow(MultipleOngoingActivityChipsModelLegacy())
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
index 7e8ee1b156df..27aa4bab3deb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
@@ -64,6 +64,7 @@ import com.android.systemui.statusbar.chips.mediaprojection.domain.model.MediaPr
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
import com.android.systemui.statusbar.chips.sharetoapp.ui.viewmodel.shareToAppChipViewModel
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
+import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.assertIsCallChip
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.assertIsScreenRecordChip
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.assertIsShareToAppChip
import com.android.systemui.statusbar.core.StatusBarRootModernization
@@ -88,6 +89,7 @@ import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher
import com.android.systemui.statusbar.phone.data.repository.fakeDarkIconRepository
import com.android.systemui.statusbar.phone.ongoingcall.EnableChipsModernization
import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
+import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallTestHelper.addOngoingCallState
import com.android.systemui.statusbar.pipeline.shared.domain.interactor.setHomeStatusBarIconBlockList
import com.android.systemui.statusbar.pipeline.shared.domain.interactor.setHomeStatusBarInteractorShowOperatorName
import com.android.systemui.statusbar.pipeline.shared.ui.model.VisibilityModel
@@ -716,7 +718,8 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
}
@Test
- fun canShowOngoingActivityChips_statusBarNotHidden_noSecureCamera_hun_false() =
+ @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ fun canShowOngoingActivityChips_statusBarNotHidden_noSecureCamera_hunBySystem_noHunFlagOff_false() =
kosmos.runTest {
val latest by collectLastValue(underTest.canShowOngoingActivityChips)
@@ -725,7 +728,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
headsUpNotificationRepository.setNotifications(
UnconfinedFakeHeadsUpRowRepository(
key = "key",
- pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser),
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedBySystem),
)
)
@@ -733,6 +736,194 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
}
@Test
+ @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ fun canShowOngoingActivityChips_statusBarNotHidden_noSecureCamera_hunByUser_noHunFlagOff_true() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.canShowOngoingActivityChips)
+
+ transitionKeyguardToGone()
+
+ headsUpNotificationRepository.setNotifications(
+ UnconfinedFakeHeadsUpRowRepository(
+ key = "key",
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser),
+ )
+ )
+
+ assertThat(latest).isTrue()
+ }
+
+ @Test
+ @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ fun canShowOngoingActivityChips_statusBarNotHidden_noSecureCamera_hunBySystem_noHunFlagOn_true() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.canShowOngoingActivityChips)
+
+ transitionKeyguardToGone()
+
+ headsUpNotificationRepository.setNotifications(
+ UnconfinedFakeHeadsUpRowRepository(
+ key = "key",
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedBySystem),
+ )
+ )
+
+ assertThat(latest).isTrue()
+ }
+
+ @Test
+ @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ fun canShowOngoingActivityChips_statusBarNotHidden_noSecureCamera_hunByUser_noHunFlagOn_true() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.canShowOngoingActivityChips)
+
+ transitionKeyguardToGone()
+
+ headsUpNotificationRepository.setNotifications(
+ UnconfinedFakeHeadsUpRowRepository(
+ key = "key",
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser),
+ )
+ )
+
+ assertThat(latest).isTrue()
+ }
+
+ @Test
+ @EnableChipsModernization
+ fun ongoingActivityChips_statusBarHidden_noSecureCamera_noHun_notAllowed() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.ongoingActivityChips)
+
+ // home status bar not allowed
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
+ kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(false, taskInfo = null)
+
+ assertThat(latest!!.areChipsAllowed).isFalse()
+ }
+
+ @Test
+ @EnableChipsModernization
+ fun ongoingActivityChips_statusBarNotHidden_noSecureCamera_noHun_isAllowed() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.ongoingActivityChips)
+
+ transitionKeyguardToGone()
+
+ assertThat(latest!!.areChipsAllowed).isTrue()
+ }
+
+ @Test
+ @EnableChipsModernization
+ fun ongoingActivityChips_statusBarNotHidden_secureCamera_noHun_notAllowed() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.ongoingActivityChips)
+
+ fakeKeyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.OCCLUDED,
+ testScope = testScope,
+ )
+ kosmos.keyguardInteractor.onCameraLaunchDetected(CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP)
+
+ assertThat(latest!!.areChipsAllowed).isFalse()
+ }
+
+ @Test
+ @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ @EnableChipsModernization
+ fun ongoingActivityChips_statusBarNotHidden_noSecureCamera_hunBySystem_noHunFlagOff_notAllowed() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.ongoingActivityChips)
+
+ transitionKeyguardToGone()
+
+ headsUpNotificationRepository.setNotifications(
+ UnconfinedFakeHeadsUpRowRepository(
+ key = "key",
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedBySystem),
+ )
+ )
+
+ assertThat(latest!!.areChipsAllowed).isFalse()
+ }
+
+ @Test
+ @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ @EnableChipsModernization
+ fun ongoingActivityChips_statusBarNotHidden_noSecureCamera_hunByUser_noHunFlagOff_isAllowed() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.ongoingActivityChips)
+
+ transitionKeyguardToGone()
+
+ headsUpNotificationRepository.setNotifications(
+ UnconfinedFakeHeadsUpRowRepository(
+ key = "key",
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser),
+ )
+ )
+
+ assertThat(latest!!.areChipsAllowed).isTrue()
+ }
+
+ @Test
+ @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ @EnableChipsModernization
+ fun ongoingActivityChips_tatusBarNotHidden_noSecureCamera_hunBySystem_noHunFlagOn_isAllowed() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.ongoingActivityChips)
+
+ transitionKeyguardToGone()
+
+ headsUpNotificationRepository.setNotifications(
+ UnconfinedFakeHeadsUpRowRepository(
+ key = "key",
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedBySystem),
+ )
+ )
+
+ assertThat(latest!!.areChipsAllowed).isTrue()
+ }
+
+ @Test
+ @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ @EnableChipsModernization
+ fun ongoingActivityChips_statusBarNotHidden_noSecureCamera_hunByUser_noHunFlagOn_isAllowed() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.ongoingActivityChips)
+
+ transitionKeyguardToGone()
+
+ headsUpNotificationRepository.setNotifications(
+ UnconfinedFakeHeadsUpRowRepository(
+ key = "key",
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser),
+ )
+ )
+
+ assertThat(latest!!.areChipsAllowed).isTrue()
+ }
+
+ @Test
+ @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+ @EnableChipsModernization
+ fun ongoingActivityChips_followsChipsViewModel() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.ongoingActivityChips)
+ transitionKeyguardToGone()
+
+ screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+
+ assertIsScreenRecordChip(latest!!.chips.active[0])
+
+ addOngoingCallState(key = "call")
+
+ assertIsScreenRecordChip(latest!!.chips.active[0])
+ assertIsCallChip(latest!!.chips.active[1], "call")
+ }
+
+ @Test
fun isClockVisible_allowedByDisableFlags_visible() =
kosmos.runTest {
val latest by collectLastValue(underTest.isClockVisible)
@@ -892,7 +1083,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
@EnableChipsModernization
- fun isNotificationIconContainerVisible_anyChipShowing_ChipsModernizationOn() =
+ fun isNotificationIconContainerVisible_anyChipShowing_chipsModernizationOn() =
kosmos.runTest {
val latest by collectLastValue(underTest.isNotificationIconContainerVisible)
transitionKeyguardToGone()
@@ -909,7 +1100,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
@DisableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
@EnableFlags(StatusBarNotifChips.FLAG_NAME)
- fun isNotificationIconContainerVisible_anyChipShowing_PromotedNotifsOn() =
+ fun isNotificationIconContainerVisible_anyChipShowing_promotedNotifsOn() =
kosmos.runTest {
val latest by collectLastValue(underTest.isNotificationIconContainerVisible)
transitionKeyguardToGone()
@@ -929,7 +1120,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
StatusBarRootModernization.FLAG_NAME,
StatusBarChipsModernization.FLAG_NAME,
)
- fun isNotificationIconContainerVisible_anyChipShowing_ChipsModernizationAndPromotedNotifsOff() =
+ fun isNotificationIconContainerVisible_anyChipShowing_chipsModernizationAndPromotedNotifsOff() =
kosmos.runTest {
val latest by collectLastValue(underTest.isNotificationIconContainerVisible)
transitionKeyguardToGone()
@@ -943,6 +1134,86 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
assertThat(latest!!.visibility).isEqualTo(View.VISIBLE)
}
+ @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ fun isNotificationIconContainerVisible_hasChipButAlsoHun_hunBySystem_noHunFlagOff_visible() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.isNotificationIconContainerVisible)
+ transitionKeyguardToGone()
+
+ // Chip
+ kosmos.screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+
+ // HUN, PinnedBySystem
+ headsUpNotificationRepository.setNotifications(
+ UnconfinedFakeHeadsUpRowRepository(
+ key = "key",
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedBySystem),
+ )
+ )
+
+ assertThat(latest!!.visibility).isEqualTo(View.VISIBLE)
+ }
+
+ @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ fun isNotificationIconContainerVisible_hasChipButAlsoHun_hunByUser_noHunFlagOff_gone() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.isNotificationIconContainerVisible)
+ transitionKeyguardToGone()
+
+ // Chip
+ kosmos.screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+
+ // HUN, PinnedByUser
+ headsUpNotificationRepository.setNotifications(
+ UnconfinedFakeHeadsUpRowRepository(
+ key = "key",
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser),
+ )
+ )
+
+ assertThat(latest!!.visibility).isEqualTo(View.GONE)
+ }
+
+ @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ fun isNotificationIconContainerVisible_hasChipButAlsoHun_hunBySystem_noHunFlagOn_gone() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.isNotificationIconContainerVisible)
+ transitionKeyguardToGone()
+
+ // Chip
+ kosmos.screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+
+ // HUN, PinnedBySystem
+ headsUpNotificationRepository.setNotifications(
+ UnconfinedFakeHeadsUpRowRepository(
+ key = "key",
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedBySystem),
+ )
+ )
+
+ assertThat(latest!!.visibility).isEqualTo(View.GONE)
+ }
+
+ @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ fun isNotificationIconContainerVisible_hasChipButAlsoHun_hunByUser_noHunFlagOn_gone() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.isNotificationIconContainerVisible)
+ transitionKeyguardToGone()
+
+ // Chip
+ kosmos.screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+
+ // HUN, PinnedByUser
+ headsUpNotificationRepository.setNotifications(
+ UnconfinedFakeHeadsUpRowRepository(
+ key = "key",
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser),
+ )
+ )
+
+ assertThat(latest!!.visibility).isEqualTo(View.GONE)
+ }
+
@Test
fun isSystemInfoVisible_allowedByDisableFlags_visible() =
kosmos.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/MultiDisplayStatusBarWindowControllerStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/MultiDisplayStatusBarWindowControllerStoreTest.kt
index 769f012bfdf7..8722a484417d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/MultiDisplayStatusBarWindowControllerStoreTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/MultiDisplayStatusBarWindowControllerStoreTest.kt
@@ -23,6 +23,7 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.display.data.repository.displayRepository
import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
import com.android.systemui.testKosmos
import kotlinx.coroutines.runBlocking
@@ -37,7 +38,7 @@ import org.mockito.kotlin.verify
@RunWith(AndroidJUnit4::class)
@EnableFlags(StatusBarConnectedDisplays.FLAG_NAME)
class MultiDisplayStatusBarWindowControllerStoreTest : SysuiTestCase() {
- private val kosmos = testKosmos()
+ private val kosmos = testKosmos().useUnconfinedTestDispatcher()
private val fakeDisplayRepository = kosmos.displayRepository
private val testScope = kosmos.testScope
@@ -59,11 +60,11 @@ class MultiDisplayStatusBarWindowControllerStoreTest : SysuiTestCase() {
}
@Test
- fun displayRemoved_stopsInstance() =
+ fun systemDecorationRemovedEvent_stopsInstance() =
testScope.runTest {
val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
- fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
+ fakeDisplayRepository.triggerRemoveSystemDecorationEvent(DEFAULT_DISPLAY)
verify(instance).stop()
}
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index d8e08fc1aec3..4179d8a89dee 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Omgewing"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Links"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Regs"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Vou uit na links- en regsgeskeide kontroles"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Vou in na verenigde kontrole"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Demp omgewing"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Wys laeprioriteit-kennisgewingikone"</string>
<string name="other" msgid="429768510980739978">"Ander"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"wissel die teël se grootte"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"verwyder teël"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"voeg teël by die laaste posisie"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Skuif teël"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Swiep op en hou met drie vingers op die raakpaneel om onlangse apps te bekyk"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Druk die handelingsleutel op jou sleutelbord om al jou apps te bekyk"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Gewysig"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Ontsluit om te kyk"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Ontsluit om kode te kyk"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Kontekstuele opvoeding"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Gebruik jou raakpaneel om terug te gaan"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Swiep links of regs met drie vingers. Tik om meer gebare te leer."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Onbekend"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Stel alle teëls terug?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Alle Kitsinstellingsteëls sal na die toestel se oorspronklike instellings teruggestel word"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index ea51f0003be6..a92a1416fd2c 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"በዙሪያ ያሉ"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ግራ"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ቀኝ"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ወደ ግራ እና ቀኝ የተለያዩ ቁጥጥሮች ዘርጋ"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ወደ የተዋሃደ ቁጥጥር ሰብስብ"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"በዙሪያ ያሉትን ድምፀ-ከል አድርግ"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"አነስተኛ ቅድሚያ ያላቸው የማሳወቂያ አዶዎችን አሳይ"</string>
<string name="other" msgid="429768510980739978">"ሌላ"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"የርዕሱን መጠን ይቀያይሩ"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"ሰቅ አስወግድ"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"በመጨረሻው ቦታ ላይ ሰቅ ያክሉ"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"ሰቁን ውሰድ"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"የቅርብ ጊዜ መተግበሪያዎችን ለማየት የመዳሰሻ ሰሌዳው ላይ በሦስት ጣቶች ወደላይ ያንሸራትቱ እና ይያዙ"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"ሁሉንም መተግበሪያዎችዎን ለማየት በቁልፍ ሰሌዳዎ ላይ ያለውን የተግባር ቁልፍ ይጫኑ"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"ጽሁፍ ተቀይሯል"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"ለመመልከት ይክፈቱ"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"ኮድን ለመመልከት ይክፈቱ"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"የዓውድ ትምህርት"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"ለመመለስ የመዳሰሻ ሰሌዳዎን ይጠቀሙ"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"ሦስት ጣቶችን በመጠቀም ወደ ግራ ወይም ወደ ቀኝ ያንሸራትቱ። ምልክቶችን የበለጠ ለማወቅ መታ ያድርጉ።"</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ያልታወቀ"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"ሁሉም ሰቆች ዳግም ይጀምሩ?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"ሁሉም የፈጣን ቅንብሮች ሰቆች ወደ የመሣሪያው የመጀመሪያ ቅንብሮች ዳግም ይጀምራሉ"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 99c156b9aa2e..13f3fd8d4e1b 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -245,12 +245,9 @@
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"تم توصيل البلوتوث."</string>
<string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"رمز الجهاز الذي يتضمّن بلوتوث"</string>
<string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"انقر هنا لضبط إعدادات الجهاز."</string>
- <!-- no translation found for accessibility_bluetooth_device_settings_gear_with_name (114373701123165491) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_device_settings_see_all (5260390270128256620) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (7988547106800504256) -->
- <skip />
+ <string name="accessibility_bluetooth_device_settings_gear_with_name" msgid="114373701123165491">"‫<xliff:g id="DEVICE_NAME">%s</xliff:g>. ضبط تفاصيل الجهاز"</string>
+ <string name="accessibility_bluetooth_device_settings_see_all" msgid="5260390270128256620">"عرض جميع الأجهزة"</string>
+ <string name="accessibility_bluetooth_device_settings_pair_new_device" msgid="7988547106800504256">"إقران جهاز جديد"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"نسبة شحن البطارية غير معروفة."</string>
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"متصل بـ <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"تم الاتصال بـ <xliff:g id="CAST">%s</xliff:g>."</string>
@@ -427,8 +424,14 @@
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"الإعدادات المسبقة"</string>
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"تمّ اختياره"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"الأصوات المحيطة"</string>
- <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"الجهاز الأيسر"</string>
- <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"الجهاز الأيمن"</string>
+ <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"اليسرى"</string>
+ <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"اليمنى"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"توسيع لوحة التحكّم الموحّدة إلى عناصر تحكُّم منفصلة على اليسار واليمين"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"تصغير عناصر التحكّم في الصوت إلى لوحة تحكُّم موحّدة"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"كتم الأصوات المحيطة"</string>
@@ -906,10 +909,8 @@
<string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"تعدُّد المهام"</string>
<string name="system_multitasking_rhs" msgid="8779289852395243004">"استخدام \"وضع تقسيم الشاشة\" مع تثبيت التطبيق على اليمين"</string>
<string name="system_multitasking_lhs" msgid="7348595296208696452">"استخدام \"وضع تقسيم الشاشة\" مع تثبيت التطبيق على اليسار"</string>
- <!-- no translation found for system_multitasking_full_screen (4221409316059910349) -->
- <skip />
- <!-- no translation found for system_multitasking_desktop_view (8829838918507805921) -->
- <skip />
+ <string name="system_multitasking_full_screen" msgid="4221409316059910349">"استخدام وضع ملء الشاشة"</string>
+ <string name="system_multitasking_desktop_view" msgid="8829838918507805921">"استخدام وضع العرض المخصّص للكمبيوتر المكتبي"</string>
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"التبديل إلى التطبيق على اليسار أو الأسفل أثناء استخدام \"تقسيم الشاشة\""</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"التبديل إلى التطبيق على اليمين أو الأعلى أثناء استخدام \"تقسيم الشاشة\""</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"استبدال تطبيق بآخر في وضع \"تقسيم الشاشة\""</string>
@@ -1511,8 +1512,7 @@
<string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"عرض التطبيقات المستخدَمة مؤخرًا"</string>
<string name="touchpad_tutorial_switch_apps_gesture_button" msgid="7768255095423767779">"التبديل بين التطبيقات"</string>
<string name="touchpad_tutorial_done_button" msgid="176168488821755503">"تم"</string>
- <!-- no translation found for touchpad_tutorial_next_button (9169718126626806688) -->
- <skip />
+ <string name="touchpad_tutorial_next_button" msgid="9169718126626806688">"التالي"</string>
<string name="gesture_error_title" msgid="469064941635578511">"يُرجى إعادة المحاولة"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"رجوع"</string>
<string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"مرِّر سريعًا لليمين أو لليسار باستخدام 3 أصابع على لوحة اللمس"</string>
@@ -1574,4 +1574,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"غير معروفة"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"هل تريد إعادة ضبط كل المربّعات؟"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"ستتم إعادة ضبط جميع مربّعات \"الإعدادات السريعة\" إلى الإعدادات الأصلية للجهاز"</string>
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"\"<xliff:g id="STREAM_NAME">%1$s</xliff:g>\"، <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 17d24da6d327..067649cdea65 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"আশ-পাশ"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"বাওঁফাল"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"সোঁফাল"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"বাওঁ আৰু সোঁফালৰ পৃথক কৰা নিয়ন্ত্ৰণলৈ সংকোচন কৰক"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"একত্ৰিত নিয়ন্ত্ৰণলৈ সংকোচন কৰক"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"আশ-পাশৰ ধ্বনি মিউট কৰক"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"কম গুৰুত্বপূৰ্ণ জাননীৰ আইকনসমূহ দেখুৱাওক"</string>
<string name="other" msgid="429768510980739978">"অন্যান্য"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"টাইলৰ আকাৰ ট’গল কৰক"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"টাইল আঁতৰাবলৈ"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"অন্তিম স্থানত টাইল যোগ দিয়ক"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"টাইল স্থানান্তৰ কৰক"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"শেহতীয়া এপ্‌সমূহ চাবলৈ টাচ্চপেডখনত তিনিটা আঙুলিৰে ওপৰলৈ ছোৱাইপ কৰি ধৰি ৰাখক"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"আপোনাৰ আটাইবোৰ এপ্‌ চাবলৈ আপোনাৰ কীব’ৰ্ডৰ কাৰ্য কীটোত টিপক"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"সম্পাদনা কৰা হৈছে"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"চাবলৈ আনলক কৰক"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"ক’ড চাবলৈ আনলক কৰক"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"প্ৰাসংগিক শিক্ষা"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"উভতি যাবলৈ আপোনাৰ টাচ্চপেড ব্যৱহাৰ কৰক"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"তিনিটা আঙুলি ব্যৱহাৰ কৰি বাওঁফাললৈ বা সোঁফাললৈ ছোৱাইপ কৰক। অধিক নিৰ্দেশ শিকিবলৈ টিপক।"</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"অজ্ঞাত"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"আটাইবোৰ টাইল ৰিছেট কৰিবনে?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"আটাইবোৰ ক্ষিপ্ৰ ছেটিঙৰ টাইল ডিভাইচৰ মূল ছেটিংছলৈ ৰিছেট হ’ব"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index a0eecd13b690..9df9923b115b 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ətraf mühit"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Sol"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Sağ"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Sola və sağa ayrılmış idarəetmələr üçün genişləndirin"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Vahid nəzarət üçün yığcamlaşdırın"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Ətraf mühiti səssiz edin"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Aşağı prioritet bildiriş işarələrini göstərin"</string>
<string name="other" msgid="429768510980739978">"Digər"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"mozaik ölçüsünü aktiv/deaktiv edin"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"lövhəni silin"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"son mövqeyə mozaik əlavə edin"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Lövhəni köçürün"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Son tətbiqlərə baxmaq üçün taçpeddə üç barmağınızla yuxarı çəkib saxlayın"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Bütün tətbiqlərə baxmaq üçün klaviaturada fəaliyyət açarını basın"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Çıxarılıb"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Baxmaq üçün kiliddən çıxarın"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Koda baxmaq üçün kiliddən çıxarın"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Kontekstual təhsil"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Geri qayıtmaq üçün taçped istifadə edin"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Üç barmaqla sola və ya sağa çəkin. Daha çox jest öyrənmək üçün toxunun."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Naməlum"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Bütün mozaiklər sıfırlansın?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Bütün Sürətli Ayarlar mozaiki cihazın orijinal ayarlarına sıfırlanacaq"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 8921effd0cb6..6ab7bf1d10ac 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Povezani ste sa <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Povezani smo sa uređajem <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Proširite grupu."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Dodajte uređaj u grupu."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Uklonite uređaj iz grupe."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Otvorite aplikaciju."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Nije povezano."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Unos"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Slušni aparati"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Uključuje se..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Ne možete da prilagodite osvetljenost jer je kontroliše aplikacija u prvom planu"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatska rotacija"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatsko rotiranje ekrana"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string>
@@ -426,6 +423,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Okruženje"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Levo"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Desno"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Proširi na kontrole razdvojene na levu i desnu stranu"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Skupi u jedinstvenu kontrolu"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Isključi zvuk okruženja"</string>
@@ -1568,4 +1571,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nepoznato"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Želite da resetujete sve pločice?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Sve pločice Brzih podešavanja će se resetovati na prvobitna podešavanja uređaja"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 3568586a75b6..94f950720a20 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Навакольныя гукі"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Левы бок"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Правы бок"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Зрабіць левую і правую панэлі кіравання"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Зрабіць адну панэль кіравання"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Выключыць навакольныя гукі"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Паказваць значкі апавяшчэнняў з нізкім прыярытэтам"</string>
<string name="other" msgid="429768510980739978">"Іншае"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"змяніць памер пліткі"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"выдаліць плітку"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"дадаць плітку ў апошнюю пазіцыю"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Перамясціць плітку"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Для прагляду нядаўніх праграм правядзіце па сэнсарнай панэлі трыма пальцамі ўверх і затрымайцеся"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Каб праглядзець усе праграмы, націсніце на клавішу дзеяння на клавіятуры"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Схавана"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Разблакіруйце экран, каб праглядзець"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Разблакіруйце экран, каб праглядзець код"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Кантэкстнае навучанне"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Выкарыстайце сэнсарную панэль для вяртання"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Правядзіце ўлева ці ўправа трыма пальцамі. Націсніце, каб азнаёміцца з іншымі жэстамі."</string>
@@ -1571,4 +1574,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Невядома"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Скінуць усе пліткі?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Усе пліткі хуткіх налад будуць скінуты да першапачатковых налад прылады"</string>
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 9d6be139efd2..4615e60730f2 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Околни звуци"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Ляво"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Дясно"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Разгъване до отделни контроли за ляво и дясно"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Свиване до обединена контрола"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Спиране на околните звуци"</string>
@@ -1568,4 +1574,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Неизвестно"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Да се нулират ли всички панели?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Всички панели с бързи настройки ще бъдат нулирани до първоначалните настройки на устройството"</string>
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g> – <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 636d4f28c18a..6247bf14f726 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"সারাউন্ডিং"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"বাঁদিক"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ডানদিক"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"বাঁদিক ও ডানদিকের আলাদা করা কন্ট্রোল বড় করুন"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ইউনিফায়েড কন্ট্রোল আড়াল করুন"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"সারাউন্ডিং মিউট করুন"</string>
@@ -582,7 +588,7 @@
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"স্ক্রিন শেয়ার করুন"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> এই বিকল্পটি বন্ধ করে দিয়েছে"</string>
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"শেয়ার করার জন্য অ্যাপ বেছে নিন"</string>
- <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"আপনার স্ক্রিন কাস্ট করুন?"</string>
+ <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"আপনার স্ক্রিন কাস্ট করতে চান?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"একটি অ্যাপ কাস্ট করুন"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"সম্পূর্ণ স্ক্রিন কাস্ট করুন"</string>
<string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"আপনি সম্পূর্ণ স্ক্রিন কাস্ট করলে, আপনার স্ক্রিনে থাকা সব কিছুই দেখা যাবে। তাই পাসওয়ার্ড, পেমেন্টের বিবরণ, মেসেজ, ফটো এবং অডিও ও ভিডিওর মতো বিষয়ে সতর্ক থাকুন।"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"কম-গুরুত্বপূর্ণ বিজ্ঞপ্তির আইকন দেখুন"</string>
<string name="other" msgid="429768510980739978">"অন্যান্য"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"টাইলের সাইজ টগল করুন"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"টাইল সরান"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"শেষ জায়গাতে টাইল যোগ করুন"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"টাইল সরান"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"সম্প্রতি ব্যবহার করা অ্যাপ দেখতে, টাচপ্যাডে তিনটি আঙুল ব্যবহার করে উপরের দিকে সোয়াইপ করে ধরে রাখুন"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"আপনার সব অ্যাপ দেখতে, কীবোর্ডে অ্যাকশন কী প্রেস করুন"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"রিড্যাক্ট করা হয়েছে"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"দেখার জন্য আনলক করুন"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"কোড দেখার জন্য আনলক করুন"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"প্রাসঙ্গিক শিক্ষা"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"ফিরে যেতে টাচপ্যাড ব্যবহার করুন"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"তিনটি আঙুলের ব্যবহার করে ডান বা বাঁদিকে সোয়াইপ করুন। আরও জেসচার সম্পর্কে জানতে ট্যাপ করুন।"</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"অজানা"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"সব টাইল রিসেট করবেন?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"সব কুইক সেটিংস টাইল, ডিভাইসের আসল সেটিংসে রিসেট হয়ে যাবে"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 331bac2fb24e..75f3f08356c2 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Okruženje"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Lijevo"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Desno"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Proširivanje u zasebne kontrole ulijevo i udesno"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Sužavanje u objedinjenu kontrolu"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Isključivanje zvuka okruženja"</string>
@@ -991,7 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Prikaži ikone obavještenja niskog prioriteta"</string>
<string name="other" msgid="429768510980739978">"Ostalo"</string>
- <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"promjenu veličine pločice"</string>
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"uključivanje/isključivanje veličine kartice"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"uklanjanje kartice"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"dodavanje kartice na posljednji položaj"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Pomjeranje kartice"</string>
@@ -1544,8 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Da pregledate nedavne aplikacije, prevucite nagore i zadržite s tri prsta na dodirnoj podlozi"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Da pregledate sve aplikacije, pritisnite tipku radnji na tastaturi"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Redigovano"</string>
- <string name="public_notification_single_line_text" msgid="3576190291791654933">"Otključajte za prikaz"</string>
- <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Otključajte za prikaz koda"</string>
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Otključajte da pogledate"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Otključajte da pogledate kôd"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Kontekstualno obrazovanje"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Koristite dodirnu podlogu da se vratite"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Prevucite ulijevo ili udesno s tri prsta. Dodirnite da naučite više pokreta."</string>
@@ -1568,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nepoznato"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Vratiti sve kartice na zadano?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Sve kartice Brze postavke će se vratiti na originalne postavke uređaja"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 01d769249d9f..19b299f14824 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Entorn"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Esquerra"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Dreta"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Desplega els controls separats d\'esquerra i dreta"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Replega per unificar el control"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Silencia l\'entorn"</string>
@@ -1568,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Desconegut"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Vols restablir totes les icones?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Totes les icones de configuració ràpida es restabliran a les opcions originals del dispositiu"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 15e4703cb702..51dfa2ec680d 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Okolí"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Vlevo"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Vpravo"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Rozbalit na samostatné ovládání levé a pravé strany"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Sbalit na sjednocené ovládání"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Ztlumit okolí"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Zobrazit ikony oznámení s nízkou prioritou"</string>
<string name="other" msgid="429768510980739978">"Jiné"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"přepnout velikost dlaždice"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"odstranit dlaždici"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"přidat dlaždici na poslední pozici"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Přesunout dlaždici"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Pokud chcete zobrazit poslední aplikace, přejeďte na touchpadu třemi prsty nahoru a podržte je"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Pokud chcete zobrazit všechny aplikace, stiskněte na klávesnici akční klávesu"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Odstraněno"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"K zobrazení je potřeba zařízení odemknout"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Pokud chcete zobrazit kód, odemkněte zařízení"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Kontextová výuka"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Návrat zpět pomocí touchpadu"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Přejeďte třemi prsty doleva nebo doprava. Další gesta zjistíte klepnutím."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Neznámé"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Resetovat všechny dlaždice?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Všechny dlaždice Rychlého nastavení se resetují do původní konfigurace zařízení"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index ab87c4672797..ad6633e2cfaf 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Omgivelser"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Venstre"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Højre"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Udvid til adskilte styringselementer til venstre og højre"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Minimer til samlet styringselement"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Ignorer omgivelser"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Vis ikoner for notifikationer med lav prioritet"</string>
<string name="other" msgid="429768510980739978">"Andet"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"ændre feltets størrelse"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"fjern felt"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"føj handlingsfeltet til den sidste position"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Flyt felt"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Du kan se nyligt brugte apps ved at stryge opad og holde tre fingre nede på touchpladen"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Du kan se alle dine apps ved at trykke på handlingstasten på dit tastatur"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Skjult"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Lås op for at se"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Lås op for at se koden"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Kontekstbaseret uddannelse"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Brug din touchplade til at gå tilbage"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Stryg til venstre eller højre med tre fingre. Tryk for at lære flere bevægelser."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Ukendt"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Vil du nulstille alle handlingsfelter?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Alle handlingsfelter i kvikmenuen nulstilles til enhedens oprindelige indstillinger"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 99e32ecd3d52..8bc38157f90a 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Umgebungsgeräusche"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Links"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Rechts"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"In ein linkes und ein rechtes Steuerfeld maximieren"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Zu einem einzigen Steuerfeld minimieren"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Umgebungsgeräusche stummschalten"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Symbole für Benachrichtigungen mit einer niedrigen Priorität anzeigen"</string>
<string name="other" msgid="429768510980739978">"Sonstiges"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"Größe der Kachel umschalten"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"Entfernen der Kachel"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"Kachel an letzter Position hinzufügen"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Kachel verschieben"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Um zuletzt verwendete Apps aufzurufen, wische mit 3 Fingern nach oben und halte das Touchpad gedrückt"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Wenn du alle deine Apps aufrufen möchtest, drücke auf der Tastatur die Aktionstaste"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Entfernt"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Zum Ansehen entsperren"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Zum Ansehen des Codes entsperren"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Kontextbezogene Informationen"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Zum Zurückgehen Touchpad verwenden"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Wische mit drei Fingern nach links oder rechts. Tippe für mehr Infos zu Touch-Gesten."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Unbekannt"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Alle Kacheln zurücksetzen?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Alle Schnelleinstellungen-Kacheln werden auf die Standardeinstellungen des Geräts zurückgesetzt"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index d3bfc99bea7a..dade080e2624 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ήχοι περιβάλλοντος"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Αριστερά"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Δεξιά"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Ανάπτυξη σε ξεχωριστά στοιχεία ελέγχου αριστερά και δεξιά"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Σύμπτυξη σε ενοποιημένο στοιχείο ελέγχου"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Σίγαση ήχων περιβάλλοντος"</string>
@@ -1568,4 +1574,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Άγνωστο"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Επαναφορά σε όλα τα πλακάκια;"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Σε όλα τα πλακάκια Γρήγορων ρυθμίσεων θα γίνει επαναφορά στις αρχικές ρυθμίσεις της συσκευής"</string>
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index c2537110ba58..fb251ddc47a2 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Surroundings"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Left"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Right"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Expand to left and right separated controls"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Collapse to unified control"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Mute surroundings"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Show low-priority notification icons"</string>
<string name="other" msgid="429768510980739978">"Other"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"toggle the tile\'s size"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"remove tile"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"add tile to the last position"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Move tile"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"To view recent apps, swipe up and hold with three fingers on the touchpad"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"To view all your apps, press the action key on your keyboard"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Redacted"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Unlock to view"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Unlock to view code"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Contextual education"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Use your touchpad to go back"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Swipe left or right using three fingers. Tap to learn more gestures."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Unknown"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Reset all tiles?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"All Quick Settings tiles will reset to the device\'s original settings"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 92e9d8d00b9d..54ef0cc72da1 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -423,6 +423,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Surroundings"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Left"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Right"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Expand to left and right separated controls"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Collapse to unified control"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Mute surroundings"</string>
@@ -1565,4 +1571,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Unknown"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Reset all tiles?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"All Quick Settings tiles will reset to the device’s original settings"</string>
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index c2537110ba58..fb251ddc47a2 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Surroundings"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Left"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Right"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Expand to left and right separated controls"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Collapse to unified control"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Mute surroundings"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Show low-priority notification icons"</string>
<string name="other" msgid="429768510980739978">"Other"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"toggle the tile\'s size"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"remove tile"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"add tile to the last position"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Move tile"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"To view recent apps, swipe up and hold with three fingers on the touchpad"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"To view all your apps, press the action key on your keyboard"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Redacted"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Unlock to view"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Unlock to view code"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Contextual education"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Use your touchpad to go back"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Swipe left or right using three fingers. Tap to learn more gestures."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Unknown"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Reset all tiles?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"All Quick Settings tiles will reset to the device\'s original settings"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index c2537110ba58..fb251ddc47a2 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Surroundings"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Left"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Right"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Expand to left and right separated controls"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Collapse to unified control"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Mute surroundings"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Show low-priority notification icons"</string>
<string name="other" msgid="429768510980739978">"Other"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"toggle the tile\'s size"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"remove tile"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"add tile to the last position"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Move tile"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"To view recent apps, swipe up and hold with three fingers on the touchpad"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"To view all your apps, press the action key on your keyboard"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Redacted"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Unlock to view"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Unlock to view code"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Contextual education"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Use your touchpad to go back"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Swipe left or right using three fingers. Tap to learn more gestures."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Unknown"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Reset all tiles?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"All Quick Settings tiles will reset to the device\'s original settings"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 7f096712c6b8..371638b311c7 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Sonido envolvente"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Izquierda"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Derecha"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Expandir los controles separados a la izquierda y a la derecha"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Contraer al control unificado"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Silenciar el sonido envolvente"</string>
@@ -1568,4 +1574,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Desconocido"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"¿Quieres restablecer todas las tarjetas?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Se restablecerán todas las tarjeta de Configuración rápida a la configuración original del dispositivo"</string>
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 531d1df02532..b02ab301bf9c 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Alrededores"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Izquierda"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Derecha"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Expandir a los controles separados de izquierda y derecha"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Contraer al control unificado"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Silenciar alrededores"</string>
@@ -588,7 +594,7 @@
<string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Cuando envías toda tu pantalla, se ve todo lo que hay en ella. Debes tener cuidado con elementos como contraseñas, detalles de pagos, mensajes, fotos, audio y vídeo."</string>
<string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Cuando envías una aplicación, se ve todo lo que se muestre o reproduzca en ella. Debes tener cuidado con elementos como contraseñas, detalles de pagos, mensajes, fotos, audio y vídeo."</string>
<string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Enviar pantalla"</string>
- <string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"Elegir una aplicación para enviar"</string>
+ <string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"Elige una aplicación para enviar"</string>
<string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"¿Empezar a compartir?"</string>
<string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Cuando compartes, grabas o envías contenido, Android puede acceder a todo lo que se muestre en la pantalla o se reproduzca en tu dispositivo. Debes tener cuidado con elementos como contraseñas, detalles de pagos, mensajes, fotos, audio y vídeo."</string>
<string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Cuando compartes, grabas o envías una aplicación, Android puede acceder a todo lo que se muestre o se reproduzca en ella. Debes tener cuidado con elementos como contraseñas, detalles de pagos, mensajes, fotos, audio y vídeo."</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar iconos de notificaciones con prioridad baja"</string>
<string name="other" msgid="429768510980739978">"Otros"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"mostrar el tamaño del recuadro"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"quitar recuadro"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"añadir el recuadro a la última posición"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Mover recuadro"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Para ver las aplicaciones recientes, desliza hacia arriba y mantén pulsado el panel táctil con tres dedos"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Para ver todas tus aplicaciones, pulsa la tecla de acción de tu teclado"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Oculta"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Desbloquea para ver"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Desbloquea para ver el código"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Educación contextual"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Usa el panel táctil para volver atrás"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Desliza hacia la izquierda o hacia la derecha con tres dedos. Toca para aprender a usar más gestos."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Desconocido"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"¿Borrar todos los recuadros?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Todos los recuadros de ajustes rápidos se restablecerán a los ajustes originales del dispositivo"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 30b93b0dc578..578ca4d663c3 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ümbritsevad helid"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Vasakule"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Paremale"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Vasaku ja parema poole eraldi juhtimine"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Mõlema poole ühtne juhtimine"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Ümbritsevate helide vaigistamine"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Kuva madala prioriteediga märguande ikoonid"</string>
<string name="other" msgid="429768510980739978">"Muu"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"muutke paani suurust"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"paani eemaldamiseks"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"lisage paan viimasesse asukohta"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Teisalda paan"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Hiljutiste rakenduste kuvamiseks pühkige puuteplaadil kolme sõrmega üles ja hoidke sõrmi puuteplaadil."</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Kõigi oma rakenduste kuvamiseks vajutage klaviatuuril toiminguklahvi"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Peidetud"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Vaatamiseks avage"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Koodi vaatamiseks avage"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Kontekstipõhised õpetused"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Puuteplaadi kasutamine tagasiliikumiseks"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Pühkige kolme sõrmega vasakule või paremale. Puudutage liigutuste kohta lisateabe saamiseks."</string>
@@ -1571,4 +1574,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Teadmata"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Kas lähtestada kõik paanid?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Kõik kiirseadete paanid lähtestatakse seadme algseadetele"</string>
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 50f875013255..c6b8f5641f56 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ingurunea"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Ezkerrekoa"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Eskuinekoa"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Zabaldu ezkerreko eta eskuineko kontrolatzeko aukerak bereiz erabiltzeko"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Tolestu kontrolatzeko aukerak bateratuta erabiltzeko"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Desaktibatu ingurunearen audioa"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Erakutsi lehentasun txikiko jakinarazpenen ikonoak"</string>
<string name="other" msgid="429768510980739978">"Beste bat"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"aldatu lauzaren tamaina"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"kendu lauza"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"gehitu lauza azken posizioan"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Mugitu lauza"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Azkenaldiko aplikazioak ikusteko, pasatu 3 hatz ukipen-panelean gora eta eduki sakatuta"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Aplikazio guztiak ikusteko, sakatu teklatuko ekintza-tekla"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Desitxuratuta"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Desblokeatu ikusteko"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Desblokeatu kodea ikusteko"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Testuinguruaren araberako hezkuntza"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Erabili ukipen-panela atzera egiteko"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Pasatu 3 hatz ezkerrera edo eskuinera. Sakatu keinu gehiago ikasteko."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Ezezagunak"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Lauza guztiak berrezarri nahi dituzu?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Gailuaren jatorrizko ezarpenak berrezarriko dira ezarpen bizkorren lauza guztietan"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index d53805d5b376..6f4d1bc35a8c 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"پیرامون"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"چپ"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"راست"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ازهم بازکردن برای کنترل‌های جداگانه چپ و راست"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"جمع کردن برای کنترل یکپارچه"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"بی‌صدا کردن پیرامون"</string>
@@ -1568,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"نامشخص"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"همه کاشی‌ها بازنشانی شود؟"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"همه کاشی‌های «تنظیمات فوری» به تنظیمات اصلی دستگاه بازنشانی خواهد شد"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index fa9468df5fa0..527a29288bcc 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -428,6 +428,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ympäristö"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Vasen"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Oikea"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Laajenna vasemmalle ja oikealle erilliset ohjaimet"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Tiivistä yhtenäiseksi säätimeksi"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Mykistä ympäristö"</string>
@@ -993,8 +999,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Näytä vähemmän tärkeät ilmoituskuvakkeet"</string>
<string name="other" msgid="429768510980739978">"Muu"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"ruudun koko päälle/pois"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"poista kiekko"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"lisää laatta viimeiseen kohtaan"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Siirrä kiekkoa"</string>
@@ -1547,10 +1552,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Näet äskeiset sovellukset, kun pyyhkäiset ylös ja pidät kosketuslevyä painettuna kolmella sormella."</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Jos haluat nähdä kaikki sovellukset, paina näppäimistön toimintonäppäintä"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Sensuroitu"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Avaa lukitus ja katso tiedot"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Avaa lukitus nähdäksesi koodin"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Kontekstuaalinen koulutus"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Takaisin siirtyminen kosketuslevyn avulla"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Pyyhkäise vasemmalle tai oikealle kolmella sormella. Lue lisää eleistä napauttamalla."</string>
@@ -1573,4 +1576,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Tuntematon"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Nollataanko kaikki laatat?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Kaikki pika-asetuslaatat palautetaan laitteen alkuperäisiin asetuksiin"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 97702f0847e9..6a2d7c809927 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Environnement"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Gauche"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Droit"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Développer les commandes distinctes à gauche et à droite"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Passer au contrôle unifié"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Ignorer les sons de l\'environnement"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Afficher les icônes de notification de faible priorité"</string>
<string name="other" msgid="429768510980739978">"Autre"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"activer ou désactiver la taille de la tuile"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"retirer la tuile"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"Ajouter une tuile à la dernière position"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Déplacer la tuile"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Pour afficher les applis récentes, balayez l\'écran vers le haut avec trois doigts sur le pavé tactile et maintenez-les en place"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Pour afficher toutes vos applis, appuyez sur la touche d\'action de votre clavier"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Supprimé"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Déverrouillez pour afficher"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Déverrouillez pour afficher le code"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Enseignement contextuel"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Utiliser votre pavé tactile pour revenir en arrière"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Balayez vers la gauche ou vers la droite avec trois doigts. Touchez pour apprendre d\'autres gestes."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Inconnu"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Réinitialiser toutes les tuiles?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Toutes les tuiles des paramètres rapides seront réinitialisées aux paramètres par défaut de l\'appareil."</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 1fefa2df4793..62916e8dff07 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Sons environnants"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Gauche"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Droite"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Développer les commandes gauche et droite"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Réduire en une commande unifiée"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Couper le mode Sons environnants"</string>
@@ -1568,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Inconnu"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Réinitialiser tous les blocs ?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Tous les blocs \"Réglages rapides\" seront réinitialisés aux paramètres d\'origine de l\'appareil"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index d9a991e29698..87980c89d949 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ambiente"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Esquerdo"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Dereito"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Despregar para controis separados do lado esquerdo e do dereito"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Contraer para control unificado"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Silenciar o ambiente"</string>
@@ -1568,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Categoría descoñecida"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Queres restablecer todos os atallos?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Restablecerase a configuración orixinal do dispositivo para todos os atallos de Configuración rápida"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 55f6e947197e..e61d4e1fddf1 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"આસપાસના અવાજો"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ડાબે"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"જમણે"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ડાબે અને જમણે અલગ કરેલા નિયંત્રણો સુધી વિસ્તૃત કરો"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"એકીકૃત નિયંત્રણ સુધી નાનું કરો"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"આસપાસના અવાજો મ્યૂટ કરો"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"ઓછી પ્રાધાન્યતાનું નોટિફિકેશન આઇકન બતાવો"</string>
<string name="other" msgid="429768510980739978">"અન્ય"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"ટાઇલના કદને ટૉગલ કરો"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"ટાઇલ કાઢી નાખો"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"છેલ્લા સ્થાનમાં ટાઇલ ઉમેરો"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"ટાઇલ ખસેડો"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"તાજેતરની ઍપ જોવા માટે, ટચપૅડ પર ત્રણ આંગળીઓ વડે ઉપર સ્વાઇપ કરો અને દબાવી રાખો"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"તમારી બધી ઍપ જોવા માટે, તમારા કીબોર્ડ પર ઍક્શન કી દબાવો"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"બદલાવેલું"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"જોવા માટે અનલૉક કરો"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"કોડ જોવા માટે અનલૉક કરો"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"સંદર્ભાત્મક શિક્ષણ"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"પાછા જવા માટે તમારા ટચપૅડનો ઉપયોગ કરો"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"ત્રણ આંગળીનો ઉપયોગ કરીને ડાબે અથવા જમણે સ્વાઇપ કરો. સંકેતો વિશે વધુ જાણવા માટે ટૅપ કરો."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"અજાણ"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"તમામ ટાઇલ રીસેટ કરીએ?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"તમામ ઝડપી સેટિંગ ટાઇલને ડિવાઇસના ઑરિજિનલ સેટિંગ પર રીસેટ કરવામાં આવશે"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 8878c1448abf..0dfbb4cb58b6 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"आस-पास का वॉल्यूम"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"बाईं ओर के वॉल्यूम के लिए"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"दाईं ओर के वॉल्यूम के लिए"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"दाईं और बाईं ओर के वॉल्यूम को अलग-अलग मैनेज करने के लिए, वॉल्यूम पैनल को बड़ा करें"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"यूनिफ़ाइड कंट्रोल पर जाने के लिए पैनल को छोटा करें"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"आस-पास के वॉल्यूम को म्यूट करें"</string>
@@ -606,7 +612,7 @@
<string name="notification_settings_button_description" msgid="2441994740884163889">"सूचना सेटिंग"</string>
<string name="notification_history_button_description" msgid="1578657591405033383">"सूचनाओं का इतिहास"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"नई सूचनाएं"</string>
- <string name="notification_section_header_gentle" msgid="6804099527336337197">"साइलेंट मोड में मिली सूचनाएं"</string>
+ <string name="notification_section_header_gentle" msgid="6804099527336337197">"बिना आवाज़ के मिलने वाली सूचनाएं"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"सूचनाएं"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"बातचीत"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"बिना आवाज़ की सभी सूचनाएं हटाएं"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"कम प्राथमिकता वाली सूचना के आइकॉन दिखाएं"</string>
<string name="other" msgid="429768510980739978">"अन्य"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"टाइल के साइज़ को टॉगल करने के लिए दो बार टैप करें"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"टाइल हटाएं"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"आखिरी जगह पर टाइल जोड़ें"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"टाइल को किसी और पोज़िशन पर ले जाएं"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"हाल ही में इस्तेमाल हुए ऐप देखने के लिए, टचपैड पर तीन उंगलियों से ऊपर की ओर स्वाइप करके दबाकर रखें"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"सभी ऐप्लिकेशन देखने के लिए, कीबोर्ड पर ऐक्शन बटन दबाएं"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"जानकारी छिपाने के लिए सूचना में बदलाव किया गया"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"सार्वजनिक सूचना देखने के लिए डिवाइस अनलॉक करें"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"कोड देखने के लिए अनलॉक करें"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"कॉन्टेक्स्ट के हिसाब से जानकारी"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"वापस जाने के लिए, अपने डिवाइस के टचपैड का इस्तेमाल करें"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"तीन उंगलियों से बाईं या दाईं ओर स्वाइप करें. ज़्यादा जेस्चर के बारे में जानने के लिए टैप करें."</string>
@@ -1571,4 +1574,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"कोई जानकारी नहीं है"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"क्या सभी टाइल रीसेट करनी हैं?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"क्विक सेटिंग टाइल, डिवाइस की ओरिजनल सेटिंग पर रीसेट हो जाएंगी"</string>
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 054f3947ff4d..4dba93076218 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Okruženje"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Lijevo"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Desno"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Proširi u zasebne kontrole slijeva i zdesna"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Sažmi u objedinjenu kontrolu"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Isključi zvuk okruženja"</string>
@@ -1568,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nepoznato"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Želite li poništiti sve pločice?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Sve pločice Brze postavke vratit će se na izvorne postavke uređaja"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 03f1bc6407d8..891cf28a2582 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Környezet"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Bal"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Jobb"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Kibontás a balra és jobbra elválasztott vezérlőkhöz"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Összecsukás az egységes vezérléshez"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Környezet némítása"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Alacsony prioritású értesítési ikonok mutatása"</string>
<string name="other" msgid="429768510980739978">"Egyéb"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"a mozaik méretének módosítása"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"mozaik eltávolításához"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"mozaik hozzáadása az utolsó pozícióhoz"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Mozaik áthelyezése"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"A legutóbbi appokért csúsztasson lefelé három ujjal az érintőpadon, és tartsa lenyomva ujjait."</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Az összes alkalmazás megtekintéséhez nyomja meg a billentyűzet műveletbillentyűjét."</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Törölve"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Oldja fel a megtekintéshez"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Kód a megtekintéshez való feloldáshoz"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Kontextusfüggő tájékoztató párbeszédpanel"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"A visszalépéshez használja az érintőpadot"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Csúsztatasson gyorsan három ujjal balra vagy jobbra. Koppintson a további kézmozdulatokért."</string>
@@ -1571,4 +1574,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Ismeretlen"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Visszaállítja az összes mozaikot?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Az összes Gyorsbeállítások mozaik visszaáll az eszköz eredeti beállításaira"</string>
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index e1b6639b2889..f231822daeb9 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Շրջակայք"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Ձախ"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Աջ"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Ծավալել՝ դարձնելով կառավարման աջ և ձախ առանձնացված տարրեր"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Ծալել՝ դարձնելով կառավարման մեկ միասնական տարր"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Անջատել շրջակայքի ձայները"</string>
@@ -1568,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Անհայտ"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Զրոյացնե՞լ բոլոր սալիկները"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Արագ կարգավորումների բոլոր սալիկները կզրոյացվեն սարքի սկզբնական կարգավորումների համաձայն։"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 6ef3cdc65e69..e0e69a9555af 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Suara sekitar"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Kiri"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Kanan"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Luaskan ke kontrol terpisah kiri dan kanan"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Ciutkan ke kontrol terpadu"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Bisukan suara sekitar"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Tampilkan ikon notifikasi prioritas rendah"</string>
<string name="other" msgid="429768510980739978">"Lainnya"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"mengubah ukuran kartu"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"menghapus kartu"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"menambahkan kartu ke posisi terakhir"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Pindahkan kartu"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Untuk melihat aplikasi terkini, geser ke atas dan tahan menggunakan tiga jari di touchpad"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Untuk melihat semua aplikasi, tekan tombol tindakan di keyboard"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Disamarkan"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Buka kunci untuk melihat"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Buka kunci untuk melihat kode"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Pendidikan kontekstual"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Gunakan touchpad untuk kembali"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Geser ke kiri atau kanan menggunakan tiga jari. Ketuk untuk mempelajari gestur lainnya."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Tidak diketahui"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Reset semua kartu?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Semua kartu Setelan Cepat akan direset ke setelan asli perangkat"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 2b8a5cc51e87..faff4c59f275 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Umhverfi"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Vinstri"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Hægri"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Aðskilja stýringar til vinstri og hægri"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Taka saman í eina stýringu"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Þagga umhverfi"</string>
@@ -1568,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Óþekkt"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Endurstilla alla reiti?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Allir flýtistillingareitir munu endurstillast á upprunalegar stillingar tækisins"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 87507d6297e5..e6f5dee09ce3 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Connesso a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Connesso a: <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Espandi il gruppo."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Aggiungi il dispositivo al gruppo."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Rimuovi il dispositivo dal gruppo."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Apri l\'applicazione."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Non connesso."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Ingresso"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Apparecchi acustici"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Attivazione…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Impossibile regolare la luminosità perché è controllata dall\'app in primo piano."</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotazione automatica"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotazione automatica dello schermo"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Posizione"</string>
@@ -426,6 +423,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Audio ambientale"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Sinistra"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Destra"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Espandi controlli separati a sinistra e a destra"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Comprimi in controllo unificato"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Disattiva audio ambientale"</string>
@@ -1568,4 +1571,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Sconosciuti"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Reimpostare tutti i riquadri?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Tutti i riquadri Impostazioni rapide verranno reimpostati sulle impostazioni originali del dispositivo"</string>
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 8a687af124e0..8e2df321d0fd 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -245,12 +245,9 @@
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"‏Bluetooth מחובר."</string>
<string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"‏סמל של מכשיר Bluetooth"</string>
<string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"יש ללחוץ כדי להגדיר את פרטי המכשיר"</string>
- <!-- no translation found for accessibility_bluetooth_device_settings_gear_with_name (114373701123165491) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_device_settings_see_all (5260390270128256620) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (7988547106800504256) -->
- <skip />
+ <string name="accessibility_bluetooth_device_settings_gear_with_name" msgid="114373701123165491">"‫<xliff:g id="DEVICE_NAME">%s</xliff:g>. הגדרה של פרטי המכשיר"</string>
+ <string name="accessibility_bluetooth_device_settings_see_all" msgid="5260390270128256620">"הצגת כל המכשירים"</string>
+ <string name="accessibility_bluetooth_device_settings_pair_new_device" msgid="7988547106800504256">"התאמה של מכשיר חדש"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"אחוז טעינת הסוללה לא ידוע."</string>
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"התבצע חיבור אל <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"מחובר אל <xliff:g id="CAST">%s</xliff:g>."</string>
@@ -354,7 +351,7 @@
<string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"אין רשתות זמינות"</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"‏אין רשתות Wi-Fi זמינות"</string>
<string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"בתהליך הפעלה…"</string>
- <string name="quick_settings_cast_title" msgid="3033553249449938182">"‏העברה (cast)"</string>
+ <string name="quick_settings_cast_title" msgid="3033553249449938182">"‏הפעלת Cast"</string>
<string name="quick_settings_casting" msgid="1435880708719268055">"‏מופעל Cast"</string>
<string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"מכשיר ללא שם"</string>
<string name="quick_settings_cast_detail_empty_text" msgid="2846282280014617785">"אין מכשירים זמינים"</string>
@@ -429,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"הרעשים בסביבה"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"שמאל"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ימין"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"הרחבה לאמצעי בקרה נפרדים לצד שמאל ולצד ימין"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"כיווץ לאמצעי בקרה מאוחד"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"השתקת הרעשים בסביבה"</string>
@@ -589,7 +592,7 @@
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"‏הפעלת Cast של אפליקציה אחת"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"‏הפעלת Cast של כל המסך"</string>
<string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"‏כשמפעילים Cast של כל המסך, כל מה שמופיע בו יהיה גלוי לצופים. מומלץ להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
- <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"‏כשמפעילים Cast של כל אפליקציה, כל מה שמופיע או מופעל בה יהיה גלוי לצופים. מומלץ להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
+ <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"‏כשמפעילים Cast של אפליקציה, כל מה שרואים או מפעילים בה מופיע גם לצופים. מומלץ להיזהר ולא לחשוף פרטים אישיים כמו סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
<string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"‏הפעלת Cast של המסך"</string>
<string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"‏בחירת אפליקציה להפעלת Cast"</string>
<string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"להתחיל את השיתוף?"</string>
@@ -906,10 +909,8 @@
<string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"ריבוי משימות"</string>
<string name="system_multitasking_rhs" msgid="8779289852395243004">"שימוש במסך מפוצל כשהאפליקציה בצד ימין"</string>
<string name="system_multitasking_lhs" msgid="7348595296208696452">"שימוש במסך מפוצל כשהאפליקציה בצד שמאל"</string>
- <!-- no translation found for system_multitasking_full_screen (4221409316059910349) -->
- <skip />
- <!-- no translation found for system_multitasking_desktop_view (8829838918507805921) -->
- <skip />
+ <string name="system_multitasking_full_screen" msgid="4221409316059910349">"שימוש במסך מלא"</string>
+ <string name="system_multitasking_desktop_view" msgid="8829838918507805921">"שימוש בתצוגה למחשב"</string>
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"מעבר לאפליקציה משמאל או למטה בזמן שימוש במסך מפוצל"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"מעבר לאפליקציה מימין או למעלה בזמן שימוש במסך מפוצל"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"כשהמסך מפוצל: החלפה בין אפליקציה אחת לאחרת"</string>
@@ -996,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"הצגת סמלי התראות בעדיפות נמוכה"</string>
<string name="other" msgid="429768510980739978">"אחר"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"שינוי גודל הלחצן"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"הסרת הלחצן"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"הוספת הלחצן במיקום האחרון"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"העברת הלחצן"</string>
@@ -1512,8 +1512,7 @@
<string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"הצגת האפליקציות האחרונות"</string>
<string name="touchpad_tutorial_switch_apps_gesture_button" msgid="7768255095423767779">"מעבר בין אפליקציות"</string>
<string name="touchpad_tutorial_done_button" msgid="176168488821755503">"סיום"</string>
- <!-- no translation found for touchpad_tutorial_next_button (9169718126626806688) -->
- <skip />
+ <string name="touchpad_tutorial_next_button" msgid="9169718126626806688">"הבא"</string>
<string name="gesture_error_title" msgid="469064941635578511">"צריך לנסות שוב."</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"חזרה"</string>
<string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"מחליקים שמאלה או ימינה עם שלוש אצבעות על לוח המגע"</string>
@@ -1551,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"כדי לראות את האפליקציות האחרונות, מחליקים למעלה לוחצים לחיצה ארוכה עם שלוש אצבעות על לוח המגע"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"כדי לראות את כל האפליקציות, מקישים על מקש הפעולה במקלדת"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"מצונזר"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"צריך לפתוח את הנעילה כדי לראות"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"כדי לראות את הקוד, צריך לפתוח את הנעילה"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"חינוך בהתאם להקשר"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"אפשר להשתמש בלוח המגע כדי לחזור אחורה"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"מחליקים ימינה או שמאלה עם שלוש אצבעות. ניתן ללחוץ כדי לקבל מידע נוסף על התנועות."</string>
@@ -1577,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"לא ידוע"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"לאפס את כל הלחצנים?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"כל הלחצנים ב\'הגדרות מהירות\' יאופסו להגדרות המקוריות של המכשיר"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 29f93cc8c361..5daa645ec0a8 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>に接続しました。"</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g>に接続されています。"</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"グループを開きます。"</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"グループにデバイスを追加します。"</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"グループからデバイスを削除します。"</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"アプリを開きます。"</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"接続されていません。"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"ローミング"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"入力"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"補聴器"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ON にしています…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"明るさはトップ アプリによって制御されているため、調整できません"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"自動回転"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"画面を自動回転します"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"位置情報"</string>
@@ -426,6 +423,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"周囲の音"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"左"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"右"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"開く - 左右それぞれで制御する"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"閉じる - まとめて制御する"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"周囲の音をミュート"</string>
@@ -1568,4 +1571,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"不明"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"すべてのタイルをリセットしますか?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"すべてのクイック設定タイルがデバイスの元の設定にリセットされます"</string>
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>、<xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index d9a5824653c1..68f48b00f3ca 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"გარემოცვა"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"მარცხენა"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"მარჯვენა"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"განცალკევებული მართვის საშუალებების გაფართოება მარცხნივ და მარჯვნივ"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ერთიანი მართვის ჩაკეცვა"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"გარემოცვის დადუმება"</string>
@@ -1568,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"უცნობი"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"გსურთ ყველა ფილის გადაყენება?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"სწრაფი პარამეტრების ყველა ფილა გადაყენდება მოწყობილობის ორიგინალ პარამეტრებზე"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 141e99c10854..1ecc7438b088 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -147,7 +147,7 @@
<string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Қазір қолданбамен бөлісіп жатырсыз."</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Бөлісуді тоқтату"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Экранды трансляциялап жатырсыз."</string>
- <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Трансляциялау тоқтасын ба?"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Трансляцияны тоқтату керек пе?"</string>
<string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"Қазір бүкіл экранды құрылғыға (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) трансляциялап жатырсыз."</string>
<string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"Қазір бүкіл экранды маңайдағы құрылғыға трансляциялап жатырсыз."</string>
<string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"Қазір қолданбаны (<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>) құрылғыға (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>) трансляциялап жатырсыз."</string>
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Айнала"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Сол жақ"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Оң жақ"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Сол жақ және оң жақ бөлек бақылау құралдарына жаю"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Біріктірілген бақылау құралына жию"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Айналаның дыбысын өшіру"</string>
@@ -586,7 +592,7 @@
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Бір қолданба экранын трансляциялау"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Бүкіл экранды трансляциялау"</string>
<string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Бүкіл экранды трансляциялаған кезде экранда барлық нәрсе көрсетіледі. Сондықтан құпия сөздерге, төлем туралы мәліметке, хабарларға, фотосуреттерге, аудиоконтент пен бейнелерге сақ болыңыз."</string>
- <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Қолданба экранын трансляциялаған кезде қолданбадағы барлық контент көрсетіледі. Сондықтан құпия сөздерге, төлем туралы мәліметке, хабарларға, фотосуреттерге, аудиоконтент пен бейнелерге сақ болыңыз."</string>
+ <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Қолданба экранын трансляциялаған кезде, қолданбадағы барлық контент көрсетіледі. Сондықтан құпия сөздерге, төлем туралы мәліметке, хабарларға, фотосуреттерге, аудиоконтент пен бейнелерге сақ болыңыз."</string>
<string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Экранды трансляциялау"</string>
<string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"Трансляциялайтын қолданба экранын таңдау"</string>
<string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Бөлісу басталсын ба?"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Маңызды емес хабарландыру белгішелерін көрсету"</string>
<string name="other" msgid="429768510980739978">"Басқа"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"бөлшек өлшемін ауыстыру"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"бөлшекті өшіру"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"соңғы позицияға бөлшек қосу"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Бөлшекті жылжыту"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Сенсорлық тақтада үш саусақпен жоғары сырғытып, басып тұрсаңыз, соңғы ашылған қолданбаларды көресіз."</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Пернетақтада әрекет пернесін басып, барлық қолданбаны көре аласыз."</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Жасырылған"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Көру үшін құлыпты ашыңыз."</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Кодты көру үшін құлыпты ашыңыз."</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Контекстік білім"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Артқа қайту үшін сенсорлық тақтаны қолданыңыз"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Үш саусақпен солға не оңға сырғытыңыз. Басқа қимылдарды үйрену үшін түртіңіз."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Белгісіз"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Барлық бөлшекті бастапқы күйге қайтару керек пе?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Барлық \"Жылдам параметрлер\" бөлшегі құрылғының бастапқы параметрлеріне қайтарылады."</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 9323308b67b6..8c5ea900a97a 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"មជ្ឈដ្ឋានជុំវិញ"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ឆ្វេង"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ស្ដាំ"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ពង្រីកទៅជាការគ្រប់គ្រងខាងឆ្វេង និងខាងស្ដាំដាច់ដោយឡែកពីគ្នា"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"បង្រួមទៅជាការគ្រប់គ្រងដែលបានរួមបញ្ចូលគ្នា"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"បិទសំឡេងមជ្ឈដ្ឋានជុំវិញ"</string>
@@ -1568,4 +1574,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"មិនស្គាល់"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"កំណត់ប្រអប់ទាំងអស់​ឡើងវិញឬ?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"ប្រអប់​ការកំណត់រហ័សទាំងអស់នឹងកំណត់ឡើងវិញទៅការ​កំណត់ដើមរបស់ឧបករណ៍"</string>
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index d7f8b89878f9..7c785d95ae38 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"ಆ್ಯಂಬಿಯೆಂಟ್ ವಾಲ್ಯೂಮ್"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ಎಡ"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ಬಲ"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ಪ್ರತ್ಯೇಕ ಎಡ ಮತ್ತು ಬಲ ಕಂಟ್ರೋಲ್‌ಗಳಿಗಾಗಿ ವಿಸ್ತರಿಸಿ"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ಯೂನಿಫೈಡ್ ಕಂಟ್ರೋಲ್‌ಗಾಗಿ ಕುಗ್ಗಿಸಿ"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"ಆ್ಯಂಬಿಯೆಂಟ್ ವಾಲ್ಯೂಮ್ ಅನ್ನು ಮ್ಯೂಟ್ ಮಾಡಿ"</string>
@@ -1568,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ಅಪರಿಚಿತ"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"ಎಲ್ಲಾ ಟೈಲ್‌ಗಳನ್ನು ರೀಸೆಟ್ ಮಾಡಬೇಕೆ?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"ಎಲ್ಲಾ ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‌ಗಳ ಟೈಲ್‌ಗಳನ್ನು ಸಾಧನದ ಮೂಲ ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಗೆ ರೀಸೆಟ್ ಮಾಡಲಾಗುತ್ತದೆ"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 0c43ea1de5c2..b3c21b11bf28 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"주변 소리"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"왼쪽"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"오른쪽"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"왼쪽 및 오른쪽 개별 제어로 확장"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"통합 제어로 축소"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"주변 소리 음소거"</string>
@@ -586,7 +592,7 @@
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"앱 1개 전송"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"전체 화면 전송"</string>
<string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"전체 화면을 전송하면 화면에 있는 모든 항목을 볼 수 있게 됩니다. 따라서 비밀번호, 결제 세부정보, 메시지, 사진, 오디오 및 동영상 등이 노출되지 않도록 주의하세요."</string>
- <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"앱을 전송하면 해당 앱에 표시되거나 재생되는 모든 항목을 볼 수 있게 됩니다. 따라서 비밀번호, 결제 세부정보, 메시지, 사진, 오디오 및 동영상 등이 노출되지 않도록 주의하세요."</string>
+ <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"앱을 전송하면 해당 앱에 표시되거나 재생되는 모든 항목을 볼 수 있게 됩니다. 비밀번호, 결제 세부정보, 메시지, 사진, 오디오 및 동영상 등이 노출되지 않도록 주의하세요."</string>
<string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"화면 전송"</string>
<string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"전송할 앱 선택"</string>
<string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"공유를 시작하시겠습니까?"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"우선순위가 낮은 알림 아이콘 표시"</string>
<string name="other" msgid="429768510980739978">"기타"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"타일 크기 전환"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"타일 삭제"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"마지막 위치에 타일 추가"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"타일 이동"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"최근 앱을 보려면 터치패드에서 세 손가락으로 위로 스와이프한 후 잠시 기다리세요"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"모든 앱을 보려면 키보드의 작업 키를 누르세요"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"수정됨"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"잠금 해제하여 보기"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"잠금 해제하여 코드 보기"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"컨텍스트 교육"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"터치패드를 사용하여 돌아가기"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"세 손가락을 사용해 왼쪽 또는 오른쪽으로 스와이프하세요. 더 많은 동작을 알아보려면 탭하세요."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"알 수 없음"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"모든 타일을 재설정하시겠습니까?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"모든 빠른 설정 타일이 기기의 원래 설정으로 재설정됩니다."</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index b411bdcaf466..9aedbb5e0569 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Айланадагы үндөр"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Сол"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Оң"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Cол жана оң жактагы өзүнчө башкаруу элементтерине жайып көрсөтүү"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Бирдиктүү башкаруу элементине жыйыштыруу"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Айланадагы үндөрдү басуу"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Анча маанилүү эмес билдирменин сүрөтчөлөрүн көрсөтүү"</string>
<string name="other" msgid="429768510980739978">"Башка"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"плитканын өлчөмүн которуштуруу"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"ыкчам баскычты өчүрүү"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"аягына карта кошуу"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Ыкчам баскычты жылдыруу"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Акыркы колдонмолорду көрүү үчүн сенсордук тактаны үч манжаңыз менен өйдө сүрүп, кармап туруңуз"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Бардык колдонмолоруңузду көрүү үчүн баскычтобуңуздагы аракет баскычын басыңыз"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Жашырылды"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Көрүү үчүн кулпусун ачыңыз"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Кодду көрүү үчүн кулпусун ачыңыз"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Контексттик билим берүү"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Артка кайтуу үчүн сенсордук тактаны колдонуңуз"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Үч манжаңыз менен солго же оңго сүрүңүз. Башка жаңсоолорду үйрөнүү үчүн таптаңыз."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Белгисиз"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Бардык параметрлерди кайра коесузбу?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Бардык ыкчам параметрлер түзмөктүн баштапкы маанилерине кайтарылат"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index e9e585eda056..47b32354df40 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"ສຽງແວດລ້ອມ"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ຊ້າຍ"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ຂວາ"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ຂະຫຍາຍເປັນການຄວບຄຸມທີ່ແຍກເບື້ອງຊ້າຍ ແລະ ຂວາ"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ຫຍໍ້ລົງເປັນການຄວບຄຸມແບບຮວມ"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"ປິດສຽງແວດລ້ອມ"</string>
@@ -1568,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ບໍ່ຮູ້ຈັກ"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"ຣີເຊັດແຜ່ນທັງໝົດບໍ?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"ແຜ່ນການຕັ້ງຄ່າດ່ວນທັງໝົດຈະຣີເຊັດເປັນການຕັ້ງຄ່າແບບເກົ່າຂອງອຸປະກອນ"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 0d4398eb97bc..5971e730ac74 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Aplinka"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Kairė"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Dešinė"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Išskleisti į atskirus kairįjį ir dešinįjį valdiklius"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Sutraukti į bendrą valdiklį"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Nutildyti aplinką"</string>
@@ -1568,4 +1574,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nežinoma"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Iš naujo nustatyti visus išklotines elementus?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Visi sparčiųjų nustatymų išklotinės elementai bus iš naujo nustatyti į pradinius įrenginio nustatymus"</string>
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 60e1e6f67c42..bb8d7028fce4 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Apkārtnes skaņas"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Pa kreisi"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Pa labi"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Izvērst, lai rādītu atsevišķu kreiso un labo vadīklu"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Sakļaut, lai rādītu vienotu vadīklu"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Izslēgt apkārtnes skaņas"</string>
@@ -1568,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nezināma"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Vai atiestatīt visus elementus?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Visiem ātro iestatījumu elementiem tiks atiestatīti sākotnējie iestatījumi"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 761eac1acae9..189390ff9edc 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Опкружување"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Лево"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Десно"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Прошири на одвоените контроли одлево и оддесно"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Собери на унифицирана контрола"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Исклучи го звукот на опкружувањето"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Прикажувај икони за известувања со низок приоритет"</string>
<string name="other" msgid="429768510980739978">"Друго"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"вклучување/исклучување на големината на плочката"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"отстранување на плочката"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"додајте плочка на последната позиција"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Преместување на плочката"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"За да ги видите скорешните апликации, повлечете нагоре и задржете со три прста на допирната подлога"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Притиснете го копчето за дејство на тастатурата за да ги видите сите апликации"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Редактирано"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Отклучете за да прегледате"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Отклучете за да го прегледате кодот"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Контекстуално образование"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Користете ја допирната подлога за да се вратите назад"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Повлечете налево или надесно со три прста. Допрете за да научите повеќе движења."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Непознато"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Да се ресетираат сите плочки?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Сите плочки на „Брзи поставки“ ќе се ресетираат на првичните поставки на уредот"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index aae5ac48f64c..7e4282f0f70f 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> എന്നതിലേക്ക് കണക്‌റ്റുചെയ്‌തു."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> എന്നതിലേക്ക് കണക്റ്റുചെയ്തു."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"ഗ്രൂപ്പ് വികസിപ്പിക്കുക."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"ഉപകരണം ഗ്രൂപ്പിലേക്ക് ചേർക്കുക."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"ഉപകരണം ഗ്രൂപ്പിൽ നിന്ന് നീക്കം ചെയ്യുക."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"ആപ്പ് തുറക്കുക."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"കണക്റ്റുചെയ്‌തിട്ടില്ല."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"റോമിംഗ്"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ഇൻപുട്ട്"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"ശ്രവണ സഹായികൾ"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ഓണാക്കുന്നു…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"തെളിച്ചം അഡ്‌ജസ്റ്റ് ചെയ്യാനാകില്ല, അത് നിയന്ത്രിക്കുന്നത് ടോപ്പ് ആപ്പാണ്"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"സ്‌ക്രീൻ സ്വയമേവ തിരിയൽ"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"സ്‌ക്രീൻ സ്വയമേവ തിരിക്കുക"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"ലൊക്കേഷൻ"</string>
@@ -426,6 +423,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"സറൗണ്ടിംഗ്‌സ്"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ഇടത്"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"വലത്"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"വേർതിരിച്ച ഇടത്, വലത് നിയന്ത്രണങ്ങളിലേക്ക് വികസിപ്പിക്കുക"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ഏകീകൃത നിയന്ത്രണത്തിലേക്ക് ചുരുക്കുക"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"സറൗണ്ടിംഗ്‌സ് മ്യൂട്ട് ചെയ്യുക"</string>
@@ -1568,4 +1571,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"അജ്ഞാതം"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"എല്ലാ ടൈലുകളും റീസെറ്റ് ചെയ്യണോ?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"എല്ലാ ദ്രുത ക്രമീകരണ ടൈലുകളും ഉപകരണത്തിന്റെ ഒറിജിനൽ ക്രമീകരണത്തിലേക്ക് റീസെറ്റ് ചെയ്യും"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 59388935394c..c6ab2c5a5368 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Орчин тойрон"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Зүүн"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Баруун"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Зүүн, баруун талын тусдаа тохиргоо руу дэлгэх"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Нэгдсэн тохиргоо руу хураах"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Орчин тойрны дууг хаах"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Бага ач холбогдолтой мэдэгдлийн дүрс тэмдгийг харуулах"</string>
<string name="other" msgid="429768510980739978">"Бусад"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"хавтангийн хэмжээг асаах/унтраах"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"хавтанг хасна уу"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"хавтанг сүүлийн байрлалд нэмэх"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Хавтанг зөөх"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Саяхны аппуудыг харахын тулд мэдрэгч самбар дээр гурван хуруугаараа дээш шудраад, удаан дарна уу"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Бүх аппаа харахын тулд гар дээр тань байх тусгай товчлуурыг дарна уу"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Хассан"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Харахын тулд түгжээг тайлна уу"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Кодыг харахын тулд түгжээг тайлна уу"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Хам сэдэвт боловсрол"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Буцахын тулд мэдрэгч самбараа ашиглах"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Гурван хуруугаараа зүүн эсвэл баруун тийш шударна уу. Илүү олон зангаа сурахын тулд товшино уу."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Тодорхойгүй"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Бүх хавтанг шинэчлэх үү?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Шуурхай тохиргооны бүх хавтан төхөөрөмжийн эх тохиргоо руу шинэчлэгдэнэ"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index c3c716055bb0..9fa40510eed0 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"जवळपासचे"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"डावे"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"उजवे"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"डाव्या आणि उजव्या स्वतंत्र नियंत्रणांचा विस्तार करा"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"युनिफाइड नियंत्रणासाठी कोलॅप्स करा"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"जवळपासचे आवाज म्यूट करा"</string>
@@ -696,7 +702,7 @@
<string name="screen_pinning_start" msgid="7483998671383371313">"ॲप पिन केले"</string>
<string name="screen_pinning_exit" msgid="4553787518387346893">"ॲप अनपिन केले"</string>
<string name="stream_voice_call" msgid="7468348170702375660">"कॉल"</string>
- <string name="stream_system" msgid="7663148785370565134">"सिस्टम"</string>
+ <string name="stream_system" msgid="7663148785370565134">"सिस्टीम"</string>
<string name="stream_ring" msgid="7550670036738697526">"रिंग"</string>
<string name="stream_music" msgid="2188224742361847580">"मीडिया"</string>
<string name="stream_alarm" msgid="16058075093011694">"अलार्म"</string>
@@ -741,9 +747,9 @@
<string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> वर प्ले करत आहे"</string>
<string name="media_output_title_without_playing" msgid="3825663683169305013">"यावर ऑडिओ प्ले होईल"</string>
<string name="media_output_title_ongoing_call" msgid="208426888064112006">"यावर कॉल करत आहे"</string>
- <string name="system_ui_tuner" msgid="1471348823289954729">"सिस्टम UI ट्युनर"</string>
+ <string name="system_ui_tuner" msgid="1471348823289954729">"सिस्टीम UI ट्युनर"</string>
<string name="status_bar" msgid="4357390266055077437">"स्टेटस बार"</string>
- <string name="demo_mode" msgid="263484519766901593">"सिस्टम UI डेमो मोड"</string>
+ <string name="demo_mode" msgid="263484519766901593">"सिस्टीम UI डेमो मोड"</string>
<string name="enable_demo_mode" msgid="3180345364745966431">"डेमो मोड सुरू करा"</string>
<string name="show_demo_mode" msgid="3677956462273059726">"डेमो मोड दर्शवा"</string>
<string name="status_bar_ethernet" msgid="5690979758988647484">"इथरनेट"</string>
@@ -781,12 +787,12 @@
<string name="accessibility_signal_full" msgid="1519655809806462972">"पूर्ण सिग्नल"</string>
<string name="accessibility_managed_profile" msgid="4703836746209377356">"कार्य प्रोफाईल"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"सर्वांसाठी नाही तर काहींसाठी मजेदार असू शकते"</string>
- <string name="tuner_warning" msgid="1861736288458481650">"सिस्टम UI ट्युनर आपल्‍याला Android यूझर इंटरफेस ट्विक आणि कस्टमाइझ करण्‍याचे अनेक प्रकार देते. ही प्रयोगात्मक वैशिष्‍ट्ये बदलू शकतात, खंडित होऊ शकतात किंवा भविष्‍यातील रिलीज मध्‍ये कदाचित दिसणार नाहीत. सावधगिरी बाळगून पुढे सुरू ठेवा."</string>
+ <string name="tuner_warning" msgid="1861736288458481650">"सिस्टीम UI ट्युनर आपल्याला Android यूझर इंटरफेस ट्विक आणि कस्टमाइझ करण्याचे अनेक प्रकार देते. ही प्रयोगात्मक वैशिष्ट्ये बदलू शकतात, खंडित होऊ शकतात किंवा भविष्यातील रिलीझ मध्ये कदाचित दिसणार नाहीत. सावधगिरी बाळगून पुढे सुरू ठेवा."</string>
<string name="tuner_persistent_warning" msgid="230466285569307806">"ही प्रयोगात्मक वैशिष्‍ट्ये बदलू शकतात, खंडित होऊ शकतात किंवा भविष्‍यातील रिलीज मध्‍ये कदाचित दिसणार नाहीत."</string>
<string name="got_it" msgid="477119182261892069">"समजले"</string>
- <string name="tuner_toast" msgid="3812684836514766951">"अभिनंदन! सिस्टम UI ट्युनर सेटिंग्जमध्‍ये जोडले गेले आहे"</string>
+ <string name="tuner_toast" msgid="3812684836514766951">"अभिनंदन! सिस्टीम UI ट्युनर सेटिंग्जमध्ये जोडले गेले आहे"</string>
<string name="remove_from_settings" msgid="633775561782209994">"सेटिंग्ज मधून काढा"</string>
- <string name="remove_from_settings_prompt" msgid="551565437265615426">"सेटिंग्ज मधून सिस्टम UI ट्युनर काढून त्याची सर्व वैशिष्ट्‍ये वापरणे थांबवायचे?"</string>
+ <string name="remove_from_settings_prompt" msgid="551565437265615426">"सेटिंग्ज मधून सिस्टीम UI ट्युनर काढून त्याची सर्व वैशिष्ट्ये वापरणे थांबवायचे?"</string>
<string name="enable_bluetooth_title" msgid="866883307336662596">"ब्लूटूथ सुरू करायचे?"</string>
<string name="enable_bluetooth_message" msgid="6740938333772779717">"तुमचा कीबोर्ड तुमच्या टॅबलेटसह कनेक्ट करण्यासाठी, तुम्ही प्रथम ब्लूटूथ सुरू करणे आवश्यक आहे."</string>
<string name="enable_bluetooth_confirmation_ok" msgid="2866408183324184876">"सुरू करा"</string>
@@ -1568,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"अज्ञात"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"सर्व टाइल रीसेट करायच्या?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"सर्व क्विक सेटिंग्ज टाइल डिव्हाइसच्या मूळ सेटिंग्जवर रीसेट केल्या जातील"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 3c96d0a502a8..91e7e6340497 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Disambungkan kepada <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Disambungkan ke <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Kembangkan kumpulan."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Tambahkan peranti pada kumpulan."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Alih keluar peranti daripada kumpulan."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Buka aplikasi."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Tidak disambungkan."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Perayauan"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Alat bantu pendengaran"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Menghidupkan…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Tidak dapat melaraskan kecerahan kerana peranti dikawal oleh apl bahagian atas"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autoputar"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Autoputar skrin"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Lokasi"</string>
@@ -426,6 +423,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Persekitaran"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Kiri"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Kanan"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Kembangkan kepada kawalan berasingan sebelah kiri dan kanan"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Kuncupkan kepada kawalan yang disatukan"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Redamkan persekitaran"</string>
@@ -1568,4 +1571,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Tidak diketahui"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Tetapkan semula semua jubin?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Semua jubin Tetapan Pantas akan ditetapkan semula kepada tetapan asal peranti"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index b259e3996220..703562e0be12 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"ဝန်းကျင်အသံ"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ဘယ်"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ညာ"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ဘယ်ညာခွဲထားသော ထိန်းချုပ်မှုများအဖြစ် ပိုပြပါ"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ပေါင်းစည်းထားသော ထိန်းချုပ်မှုအဖြစ် လျှော့ပြပါ"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"ဝန်းကျင်အသံ ပိတ်ရန်"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"အရေးမကြီးသော အကြောင်းကြားချက် သင်္ကေတများ ပြရန်"</string>
<string name="other" msgid="429768510980739978">"အခြား"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"အကွက်ငယ်၏ အရွယ်အစားကို ပြောင်းရန်"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"အကွက်ငယ်ကို ဖယ်ရှားရန်"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"နောက်ဆုံးနေရာတွင် အကွက်ငယ် ထည့်ရန်"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"အကွက်ငယ်ကို ရွှေ့ရန်"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"လတ်တလောအက်ပ်များကို ကြည့်ရန် တာ့ချ်ပက်ပေါ်တွင် လက်သုံးချောင်းဖြင့် အပေါ်သို့ပွတ်ဆွဲပြီး ဖိထားပါ"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"သင့်အက်ပ်အားလုံးကြည့်ရန် ကီးဘုတ်ပေါ်ရှိ လုပ်ဆောင်ချက်ကီးကို နှိပ်ပါ"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"အစားထိုးထားသည်"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"ကြည့်ရန် ဖွင့်ပါ"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"ကုဒ်ကြည့်ရန် ဖွင့်ပါ"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"အကြောင်းအရာအလိုက် ပညာရေး"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"နောက်ပြန်သွားရန် သင့်တာ့ချ်ပက်ကို သုံးပါ"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"လက်သုံးချောင်းဖြင့် ဘယ် (သို့) ညာသို့ ပွတ်ဆွဲပါ။ လက်ဟန်များ ပိုမိုလေ့လာရန် တို့ပါ။"</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"အမျိုးအမည်မသိ"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"အကွက်ငယ်အားလုံးကို ပြင်ဆင်သတ်မှတ်မလား။"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"အမြန်ဆက်တင်များ အကွက်ငယ်အားလုံးကို စက်ပစ္စည်း၏ မူရင်းဆက်တင်များသို့ ပြင်ဆင်သတ်မှတ်ပါမည်"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 1c655f1859ad..b75f644ec397 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Omgivelser"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Venstre"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Høyre"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Utvid til separate kontroller for venstre og høyre"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Skjul til samlet kontroll"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Kutt lyden for omgivelsene"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Vis ikoner for varsler med lav prioritet"</string>
<string name="other" msgid="429768510980739978">"Annet"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"bytt størrelse på brikken"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"fjerne infobrikken"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"legge til en brikke på den siste posisjonen"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Flytt infobrikken"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"For å se nylige apper, sveip opp og hold med tre fingre på styreflaten"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"For å se alle appene dine, trykk på handlingstasten på tastaturet"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Fjernet"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Lås opp for å se"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Lås opp for å se koden"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Kontekstuell opplæring"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Bruk styreflaten for å gå tilbake"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Sveip til venstre eller høyre med tre fingre. Trykk for å lære flere bevegelser."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Ukjent"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Vil du tilbakestille alle brikkene?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Alle brikker for hurtiginnstillinger tilbakestilles til enhetens opprinnelige innstillinger"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 133003eb71c1..cd20defc7849 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"वरपरका आवाज"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"बायाँ"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"दायाँ"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"दायाँ र बायाँतर्फको भोल्युम छुट्टाछुट्टै व्यवस्थापन गर्न भोल्युम प्यानल छुट्ट्याउनुहोस्"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"कोल्याप्स गरी एउटै कन्ट्रोल बनाउनुहोस्"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"वरपरका आवाज म्युट गर्नुहोस्"</string>
@@ -1571,4 +1577,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"अज्ञात"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"सबै टाइलहरू रिसेट गर्ने हो?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"द्रुत सेटिङका सबै टाइलहरू रिसेट गरी डिभाइसका मूल सेटिङ लागू गरिने छन्"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 388190702462..1df27df11b86 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Omgevingsgeluid"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Links"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Rechts"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Uitvouwen naar gescheiden bediening voor links en rechts"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Samenvouwen tot geïntegreerde bediening"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Omgevingsgeluid uitzetten"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Iconen voor meldingen met lage prioriteit tonen"</string>
<string name="other" msgid="429768510980739978">"Overig"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"het formaat van de tegel schakelen"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"tegel verwijderen"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"tegel toevoegen op de laatste positie"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Tegel verplaatsen"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Als je recente apps wilt bekijken, swipe je met 3 vingers omhoog op de touchpad en houd je vast"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Als je alle apps wilt bekijken, druk je op de actietoets op je toetsenbord"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Verborgen"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Ontgrendelen om te bekijken"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Ontgrendelen om de code te bekijken"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Contextuele educatie"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Je touchpad gebruiken om terug te gaan"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Swipe met 3 vingers naar links of rechts. Tik voor meer gebaren."</string>
@@ -1571,4 +1574,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Onbekend"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Alle tegels resetten?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Alle tegels voor Snelle instellingen worden teruggezet naar de oorspronkelijke instellingen van het apparaat"</string>
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 9c561c92d2ff..ddb9157c3755 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> ସହ ସଂଯୁକ୍ତ"</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> ସହିତ ସଂଯୁକ୍ତ।"</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"ଗ୍ରୁପକୁ ବିସ୍ତାର କରନ୍ତୁ।"</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"ଗ୍ରୁପରେ ଡିଭାଇସ ଯୋଗ କରନ୍ତୁ।"</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"ଗ୍ରୁପରୁ ଡିଭାଇସ କାଢ଼ି ଦିଅନ୍ତୁ।"</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"ଆପ୍ଲିକେସନ ଖୋଲନ୍ତୁ।"</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"କନେକ୍ଟ ହୋଇନାହିଁ।"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"ରୋମିଙ୍ଗ"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ଇନପୁଟ୍"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"ଶ୍ରବଣ ଯନ୍ତ୍ର"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ଅନ୍ ହେଉଛି…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"ଟପ ଆପ ଦ୍ୱାରା ଉଜ୍ଜ୍ୱଳତା ନିୟନ୍ତ୍ରିତ ହେଉଥିବା ଯୋଗୁଁ ଏହାକୁ ଆଡଜଷ୍ଟ କରିପାରିବେ ନାହିଁ"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ଅଟୋ-ରୋଟେଟ"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ଅଟୋ-ରୋଟେଟ ସ୍କ୍ରିନ"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"ଲୋକେସନ"</string>
@@ -426,6 +423,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"ପରିପାର୍ଶ୍ୱ"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ବାମ"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ଡାହାଣ"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ବାମ ଏବଂ ଡାହାଣ ଅଲଗା ନିୟନ୍ତ୍ରଣକୁ ବିସ୍ତାର କରନ୍ତୁ"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ଏକତ୍ରିତ ନିୟନ୍ତ୍ରଣକୁ ସଙ୍କୁଚିତ କରନ୍ତୁ"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"ପରିପାର୍ଶ୍ୱକୁ ମ୍ୟୁଟ କରନ୍ତୁ"</string>
@@ -991,8 +994,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"କମ୍‍-ଅଗ୍ରାଧିକାର ବିଜ୍ଞପ୍ତି ଆଇକନ୍‍ ଦେଖାନ୍ତୁ"</string>
<string name="other" msgid="429768510980739978">"ଅନ୍ୟ"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"ଟାଇଲର ସାଇଜକୁ ଟୋଗଲ କରନ୍ତୁ"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"ଟାଇଲ୍ କାଢ଼ି ଦିଅନ୍ତୁ"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"ଶେଷ ପୋଜିସନରେ ଟାଇଲ ଯୋଗ କରିବା"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"ଟାଇଲ୍ ମୁଭ୍ କରନ୍ତୁ"</string>
@@ -1545,10 +1547,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"ବର୍ତ୍ତମାନର ଆପ୍ସ ଭ୍ୟୁ କରିବାକୁ, ଟଚପେଡରେ ତିନୋଟି ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ କରି ଧରି ରଖନ୍ତୁ"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"ଆପଣଙ୍କ ସମସ୍ତ ଆପ୍ସ ଭ୍ୟୁ କରିବା ପାଇଁ ଆପଣଙ୍କ କୀବୋର୍ଡରେ ଆକ୍ସନ କୀ\'କୁ ଦବାନ୍ତୁ"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"ଲୁଚା ଯାଇଥିବା"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"ଭ୍ୟୁ କରିବାକୁ ଅନଲକ କରନ୍ତୁ"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"ଭ୍ୟୁ କରିବାକୁ ଅନଲକ କରିବା କୋଡ"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"ପ୍ରାସଙ୍ଗିକ ଶିକ୍ଷା"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"ପଛକୁ ଫେରିବା ପାଇଁ ଆପଣଙ୍କ ଟଚପେଡକୁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"ତିନୋଟି ଆଙ୍ଗୁଠିରେ ବାମ ବା ଡାହାଣକୁ ସ୍ୱାଇପ କରନ୍ତୁ। ଜେଶ୍ଚରଗୁଡ଼ିକ ବିଷୟରେ ଅଧିକ ଜାଣିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
@@ -1571,4 +1571,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ଅଜଣା"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"ସମସ୍ତ ଟାଇଲକୁ ରିସେଟ କରିବେ?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"ସମସ୍ତ କୁଇକ ସେଟିଂସ ଟାଇଲ ଡିଭାଇସର ମୂଳ ସେଟିଂସରେ ରିସେଟ ହୋଇଯିବ"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 60275382cabe..39c02d245a89 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ।"</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ।"</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"ਗਰੁੱਪ ਦਾ ਵਿਸਤਾਰ ਕਰੋ।"</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"ਗਰੁੱਪ ਵਿੱਚ ਡੀਵਾਈਸ ਸ਼ਾਮਲ ਕਰੋ।"</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"ਗਰੁੱਪ ਤੋਂ ਡੀਵਾਈਸ ਹਟਾਓ।"</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"ਐਪਲੀਕੇਸ਼ਨ ਖੋਲ੍ਹੋ।"</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ।"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"ਰੋਮਿੰਗ"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ਇਨਪੁੱਟ"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"ਸੁਣਨ ਦੇ ਸਾਧਨ"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ਚਾਲੂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"ਚਮਕ ਨੂੰ ਵਿਵਸਥਿਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ ਕਿਉਂਕਿ ਪਹਿਲਾਂ ਤੋਂ ਚੱਲ ਰਹੀ ਐਪ ਇਸਨੂੰ ਕੰਟਰੋਲ ਕਰ ਰਹੀ ਹੈ"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ਸਵੈ-ਘੁਮਾਓ"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ਸਕ੍ਰੀਨ ਨੂੰ ਆਪਣੇ ਆਪ ਘੁੰਮਾਓ"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"ਟਿਕਾਣਾ"</string>
@@ -426,6 +423,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"ਆਲੇ-ਦੁਆਲੇ"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ਖੱਬੇ"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ਸੱਜੇ"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ਖੱਬੇ ਅਤੇ ਸੱਜੇ ਪਾਸੇ ਦੇ ਸ਼ੋਰ ਨੂੰ ਵੱਖ-ਵੱਖ ਕੰਟਰੋਲ ਕਰਨ ਲਈ ਵਿਸਤਾਰ ਕਰੋ"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ਏਕੀਕ੍ਰਿਤ ਕੰਟਰੋਲ \'ਤੇ ਜਾਣ ਲਈ ਸਮੇਟੋ"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"ਆਲੇ-ਦੁਆਲੇ ਦੇ ਸ਼ੋਰ ਨੂੰ ਮਿਊਟ ਕਰੋ"</string>
@@ -1568,4 +1571,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ਅਗਿਆਤ"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"ਕੀ ਸਾਰੀਆਂ ਟਾਇਲਾਂ ਨੂੰ ਰੀਸੈੱਟ ਕਰਨਾ ਹੈ?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"ਸਾਰੀਆਂ ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਟਾਇਲਾਂ ਡੀਵਾਈਸ ਦੀਆਂ ਮੂਲ ਸੈਟਿੰਗਾਂ \'ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਣਗੀਆਂ"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 35ff6c941b07..b93bf3074ab0 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Otoczenie"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Po lewej"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Po prawej"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Rozwiń, aby oddzielić elementy sterujące po lewej i po prawej stronie"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Zwiń do ujednoliconego sterowania"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Wycisz otoczenie"</string>
@@ -582,13 +588,13 @@
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Udostępnij ekran"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ma wyłączoną tę opcję"</string>
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Wybierz aplikację do udostępniania"</string>
- <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Włączyć przesyłanie treści wyświetlanych na ekranie?"</string>
+ <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Włączyć przesyłanie treści z ekranu?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Przesyłanie obrazu z 1 aplikacji"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Przesyłanie całego ekranu"</string>
<string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Kiedy przesyłasz treści z całego ekranu, widoczny jest cały obraz z wyświetlacza. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
- <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Kiedy przesyłasz obraz z aplikacji, widoczne jest wszystko to, co jest w niej wyświetlane lub odtwarzane. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
+ <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Kiedy przesyłasz obraz z aplikacji, widoczne jest wszystko, co jest w niej wyświetlane lub odtwarzane. Uważaj więc na takie treści jak hasła, dane do płatności, wiadomości, zdjęcia, audio czy filmy."</string>
<string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Prześlij ekran"</string>
- <string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"Wybieranie aplikacji do przesyłania"</string>
+ <string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"Wybierz aplikację do przesyłania"</string>
<string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Rozpocząć udostępnianie?"</string>
<string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Podczas udostępniania, nagrywania lub przesyłania treści Android ma dostęp do wszystkiego, co jest widoczne na ekranie lub odtwarzane na urządzeniu. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, dźwięku i filmów."</string>
<string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Podczas udostępniania, nagrywania lub przesyłania treści Android ma dostęp do wszystkiego, co jest w niej wyświetlane lub odtwarzane. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, dźwięku i filmów."</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Pokazuj ikony powiadomień o niskim priorytecie"</string>
<string name="other" msgid="429768510980739978">"Inne"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"przełącz rozmiar kafelka"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"usunąć kartę"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"dodaj kafelek do ostatniej pozycji"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Przenieś kartę"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Aby wyświetlić ostatnie aplikacje, przesuń w górę za pomocą 3 palców na touchpadzie i przytrzymaj."</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Aby wyświetlić wszystkie swoje aplikacje, naciśnij klawisz działania na klawiaturze"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Usunięto"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Odblokuj, aby zobaczyć"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Odblokuj, aby zobaczyć kod"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Edukacja kontekstowa"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Przechodzenie wstecz za pomocą touchpada"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Przesuń trzema palcami w prawo lub lewo. Kliknij, aby poznać więcej gestów."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nieznane"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Zresetować wszystkie kafelki?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Wszystkie kafelki Szybkich ustawień zostaną zresetowane do oryginalnych ustawień urządzenia"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index fc7e2afd5a2a..7c9028ba068d 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -351,7 +351,7 @@
<string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Redes indisponíveis"</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"Nenhuma rede Wi-Fi disponível"</string>
<string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"Ativando…"</string>
- <string name="quick_settings_cast_title" msgid="3033553249449938182">"Transmitir"</string>
+ <string name="quick_settings_cast_title" msgid="3033553249449938182">"Transmissão"</string>
<string name="quick_settings_casting" msgid="1435880708719268055">"Transmitindo"</string>
<string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"Dispositivo sem nome"</string>
<string name="quick_settings_cast_detail_empty_text" msgid="2846282280014617785">"Não há dispositivos disponíveis"</string>
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Som ambiente"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Lado esquerdo"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Lado direito"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Abrir para controles separados da esquerda e da direita"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Fechar para controle unificado"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Silenciar som ambiente"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar ícones de notificações de baixa prioridade"</string>
<string name="other" msgid="429768510980739978">"Outros"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"alternar o tamanho do bloco"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"remover o bloco"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"adicionar o bloco à última posição"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Mover bloco"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Se quiser ver os apps recentes, deslize para cima e pressione o touchpad com três dedos"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Para ver todos os apps, pressione a tecla de ação no teclado"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Encoberto"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Desbloqueie para ver"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Desbloqueie para ver o código"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Educação contextual"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Use o touchpad para voltar"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Deslize para a esquerda ou direita usando três dedos. Toque para aprender outros gestos."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Desconhecidos"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Redefinir todos os blocos?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Todos os blocos \"Configurações rápidas\" serão redefinidos para as configurações originais do dispositivo"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 14b85b7e9e3e..a8e0f05c971c 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ambiente"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Esquerda"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Direita"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Expandir para controlos separados do lado direito e esquerdo"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Reduzir para controlo unificado"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Desativar som do ambiente"</string>
@@ -1568,4 +1574,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Desconhecido"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Repor todos os mosaicos?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Todos os mosaicos de Definições rápidas vão ser repostos para as definições originais do dispositivo"</string>
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index fc7e2afd5a2a..7c9028ba068d 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -351,7 +351,7 @@
<string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Redes indisponíveis"</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"Nenhuma rede Wi-Fi disponível"</string>
<string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"Ativando…"</string>
- <string name="quick_settings_cast_title" msgid="3033553249449938182">"Transmitir"</string>
+ <string name="quick_settings_cast_title" msgid="3033553249449938182">"Transmissão"</string>
<string name="quick_settings_casting" msgid="1435880708719268055">"Transmitindo"</string>
<string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"Dispositivo sem nome"</string>
<string name="quick_settings_cast_detail_empty_text" msgid="2846282280014617785">"Não há dispositivos disponíveis"</string>
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Som ambiente"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Lado esquerdo"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Lado direito"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Abrir para controles separados da esquerda e da direita"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Fechar para controle unificado"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Silenciar som ambiente"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar ícones de notificações de baixa prioridade"</string>
<string name="other" msgid="429768510980739978">"Outros"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"alternar o tamanho do bloco"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"remover o bloco"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"adicionar o bloco à última posição"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Mover bloco"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Se quiser ver os apps recentes, deslize para cima e pressione o touchpad com três dedos"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Para ver todos os apps, pressione a tecla de ação no teclado"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Encoberto"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Desbloqueie para ver"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Desbloqueie para ver o código"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Educação contextual"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Use o touchpad para voltar"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Deslize para a esquerda ou direita usando três dedos. Toque para aprender outros gestos."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Desconhecidos"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Redefinir todos os blocos?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Todos os blocos \"Configurações rápidas\" serão redefinidos para as configurações originais do dispositivo"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index b577be53ac08..23270ea2e9d8 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Împrejurimi"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Stânga"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Dreapta"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Extinde comenzile separate la stânga și la dreapta"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Restrânge la comanda unificată"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Dezactivează sunetul ambiental"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Afișează pictogramele de notificare cu prioritate redusă"</string>
<string name="other" msgid="429768510980739978">"Altele"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"comută dimensiunea cardului"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"elimină cardul"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"adaugă cardul în ultima poziție"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Mută cardul"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Ca să vezi aplicațiile recente, glisează în sus și ține apăsat cu trei degete pe touchpad"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Ca să vezi toate aplicațiile, apasă tasta de acțiuni de pe tastatură"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Ascunsă"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Deblochează pentru a afișa"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Deblochează pentru a vedea codul"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Educație contextuală"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Folosește-ți touchpadul ca să revii"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Glisează la stânga sau la dreapta cu trei degete. Atinge ca să înveți mai multe gesturi."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Necunoscută"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Resetezi toate cardurile?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Toate cardurile Setări rapide se vor reseta la setările inițiale ale dispozitivului"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 03b5423d59b6..e4c1d45bf912 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Окружающие звуки"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Левый"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Правый"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Разделить на левый и правый элемент управления"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Объединить в один элемент управления"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Заглушить окружающие звуки"</string>
@@ -1568,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Неизвестно"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Сбросить все параметры?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Для всех параметров быстрых настроек будут восстановлены значения по умолчанию."</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 15441b57e7d2..437a35b51e0e 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"වටපිටාව"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"වම"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"දකුණ"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"වමට සහ දකුණට වෙන් වූ පාලන වෙත පුළුල් කරන්න"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ඒකාබද්ධ පාලනයට හකුළන්න"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"අවට පරිසරය නිහඬ කරන්න"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"අඩු ප්‍රමුඛතා දැනුම්දීම් අයිකන පෙන්වන්න"</string>
<string name="other" msgid="429768510980739978">"වෙනත්"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"ටයිල් එකේ ප්‍රමාණය මාරු කරන්න"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"ටයිල් ඉවත් කරන්න"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"ටයිල් එක අවසාන ස්ථානයට එක් කරන්න"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"ටයිල් ගෙන යන්න"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"මෑත යෙදුම් බැලීමට, ඉහළට ස්වයිප් කර ස්පර්ශ පුවරුව මත ඇඟිලි තුනකින් අල්ලාගෙන සිටින්න"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"ඔබේ සියලුම යෙදුම් බැලීමට, ඔබේ යතුරුපුවරුවේ ක්‍රියාකාරී යතුර ඔබන්න"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"නැවත සකස් කරන ලද"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"බැලීමට අගුළු හරින්න"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"කේතය බැලීමට අගුළු හරින්න"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"සන්දර්භීය අධ්‍යාපනය"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"ආපසු යාමට ඔබේ ස්පර්ශ පුවරුව භාවිත කරන්න"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"ඇඟිලි තුනක් භාවිතයෙන් වමට හෝ දකුණට ස්වයිප් කරන්න. තව ඉංගිත දැන ගැනීමට තට්ටු කරන්න."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"නොදනී"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"සියලු ටයිල් නැවත සකසන්න ද?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"සියලු ඉක්මන් සැකසීම් ටයිල් උපාංගයේ මුල් සැකසීම් වෙත නැවත සකසනු ඇත"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 868e9390e5ef..859c976630d7 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Okolie"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Vľavo"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Vpravo"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Rozbaliť na samostatné ovládanie ľavej a pravej strany"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Zbaliť na jednotné ovládanie"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Vypnúť zvuk okolia"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Zobraziť ikony upozornení s nízkou prioritou"</string>
<string name="other" msgid="429768510980739978">"Ďalšie"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"prepnúť veľkosť karty"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"odstrániť kartu"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"pridáte kartu na poslednú pozíciu"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Presunúť kartu"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Ak si chcete zobraziť nedávne aplikácie, potiahnite po touchpade troma prstami nahor a pridržte ich."</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Ak si chcete zobraziť všetky aplikácie, stlačte na klávesnici akčný kláves"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Zamaskované"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Zobrazíte odomknutím"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Kód sa zobrazí po odomknutí"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Kontextová náuka"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Prechádzajte späť pomocou touchpadu"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Potiahnite troma prstami doľava alebo doprava. Viac o gestách sa dozviete klepnutím."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Neznáme"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Chcete resetovať všetky karty?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Všetky karty rýchlych nastavení sa resetujú na pôvodné nastavenia zariadenia"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index e6d133ef61f5..2a1ed4690ac5 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Okolica"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Levo"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Desno"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Razširitev na ločene kontrolnike za levo in desno stran"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Strnitev v enotni kontrolnik"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Izklop okoliškega zvoka"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Pokaži ikone obvestil z nizko stopnjo prednosti"</string>
<string name="other" msgid="429768510980739978">"Drugo"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"preklop velikosti ploščice"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"odstranitev ploščice"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"dodajanje ploščice na zadnji položaj"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Premik ploščice"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Za ogled nedavnih aplikacij povlecite s tremi prsti navzgor po sledilni ploščici in pridržite"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Za ogled vseh aplikacij pritisnite tipko za dejanja na tipkovnici"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Zakrito"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Odklenite za ogled"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Odklenite za ogled kode"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Kontekstualno izobraževanje"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Uporaba sledilne ploščice za pomik nazaj"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"S tremi prsti povlecite levo ali desno. Dotaknite se, če želite spoznati več potez."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Neznano"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Želite ponastaviti vse ploščice?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Vse ploščice v hitrih nastavitvah bodo ponastavljene na prvotne nastavitve naprave."</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 724c6c0d9a41..916595fb55b2 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ambienti rrethues"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Majtas"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Djathtas"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Zgjero te kontrollet e veçuara majtas dhe djathtas"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Palos te kontrolli i unifikuar"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Vendos në heshtje ambientin rrethues"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Shfaq ikonat e njoftimeve me përparësi të ulët"</string>
<string name="other" msgid="429768510980739978">"Të tjera"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"ndrysho madhësinë e pllakëzës"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"hiq pllakëzën"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"shtuar pllakëzën në pozicionin e fundit"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Zhvendos pllakëzën"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Për aplikacionet e fundit, rrëshqit shpejt lart dhe mbaj shtypur me tre gishta në bllokun me prekje"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Për të shikuar të gjitha aplikacionet, shtyp tastin e veprimit në tastierë"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Redaktuar"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Shkyçe për ta parë"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Shkyçe për të parë kodin"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Edukimi kontekstual"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Përdor bllokun me prekje për t\'u kthyer prapa"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Rrëshqit shpejt majtas ose djathtas duke përdorur tre gishta. Trokit për të mësuar më shumë gjeste."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nuk njihet"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Të rivendosen të gjitha pllakëzat?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Të gjitha pllakëzat e \"Cilësimeve të shpejta\" do të rivendosen te cilësimet origjinale të pajisjes"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index e6471eba854d..6bf3a697ab0d 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Повезани сте са <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"Повезани смо са уређајем <xliff:g id="CAST">%s</xliff:g>."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"Проширите групу."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"Додајте уређај у групу."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"Уклоните уређај из групе."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"Отворите апликацију."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"Није повезано."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"Роминг"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Унос"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Слушни апарати"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Укључује се..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Не можете да прилагодите осветљеност јер је контролише апликација у првом плану"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Аутоматска ротација"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Аутоматско ротирање екрана"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Локација"</string>
@@ -426,6 +423,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Окружење"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Лево"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Десно"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Прошири на контроле раздвојене на леву и десну страну"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Скупи у јединствену контролу"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Искључи звук окружења"</string>
@@ -1568,4 +1571,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Непознато"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Желите да ресетујете све плочице?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Све плочице Брзих подешавања ће се ресетовати на првобитна подешавања уређаја"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 9f2a2083175b..aa9f4a4bfcd4 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Omgivningsläge"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Vänster"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Höger"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Utöka till kontroller till vänster och höger"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Komprimera till enhetlig kontroll"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Stäng av omgivningsljudet"</string>
@@ -1568,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Okänt"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Vill du återställa alla rutor?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Alla Snabbinställningsrutor återställs till enhetens ursprungliga inställningar"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 6222a7631fa6..72bfb8312cc4 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Mazingira"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Kushoto"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Kulia"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Panua iwe vidhibiti vilivyotenganishwa kushoto na kulia"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Kunja iwe kidhibiti cha pamoja"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Zima sauti ya mazingira"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Onyesha aikoni za arifa zisizo muhimu"</string>
<string name="other" msgid="429768510980739978">"Nyingine"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"ubadilishe ukubwa wa kigae"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"ondoa kigae"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"weka kigae kwenye nafasi ya mwisho"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Hamisha kigae"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Telezesha vidole vitatu juu na ushikilie kwenye padi ya kugusa ili uangalie programu za hivi majuzi"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Bonyeza kitufe cha vitendo kwenye kibodi yako ili uangalie programu zako zote"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Maandishi yameondolewa"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Fungua ili uone"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Fungua ili uone msimbo"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Elimu inayolingana na muktadha"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Kutumia padi yako ya kugusa ili kurudi nyuma"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Telezesha vidole vitatu kulia au kushoto. Gusa ili upate maelezo kuhusu miguso zaidi."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Visivyojulikana"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Ungependa kubadilisha vigae vyote?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Vigae vyote vya Mipangilio ya Haraka vitabadilishwa kuwa katika mipangilio halisi ya kifaa"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sw/tiles_states_strings.xml b/packages/SystemUI/res/values-sw/tiles_states_strings.xml
index fb6e38f5b58c..a16a7b7792c2 100644
--- a/packages/SystemUI/res/values-sw/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sw/tiles_states_strings.xml
@@ -68,7 +68,7 @@
</string-array>
<string-array name="tile_states_bt">
<item msgid="5330252067413512277">"Hakipatikani"</item>
- <item msgid="5315121904534729843">"Kimezimwa"</item>
+ <item msgid="5315121904534729843">"Imezimwa"</item>
<item msgid="503679232285959074">"Imewashwa"</item>
</string-array>
<string-array name="tile_states_airplane">
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 0bf5f223d139..31ab5155eb35 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"சுற்றுப்புறங்கள்"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"இடது"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"வலது"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"இடது மற்றும் வலதுபுறம் உள்ள கட்டுப்பாடுகளை விரிவாக்கும்"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ஒருங்கிணைந்த கட்டுப்பாட்டுக்குச் சுருக்கும்"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"சுற்றுப்புறங்களின் ஒலியை அடக்கும்"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"குறைந்த முன்னுரிமை உள்ள அறிவிப்பு ஐகான்களைக் காட்டு"</string>
<string name="other" msgid="429768510980739978">"மற்றவை"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"கட்டத்தின் அளவை நிலைமாற்றும்"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"கட்டத்தை அகற்றும்"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"கடைசி இடத்தில் கட்டத்தைச் சேர்க்கலாம்"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"கட்டத்தை நகர்த்து"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"சமீபத்திய ஆப்ஸைப் பார்க்க, டச்பேடில் மூன்று விரல்களால் மேல்நோக்கி ஸ்வைப் செய்து பிடிக்கவும்"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"அனைத்து ஆப்ஸையும் பார்க்க, உங்கள் கீபோர்டில் உள்ள ஆக்ஷன் பட்டனை அழுத்தவும்"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"அர்த்தம் புரியாதபடி திருத்தப்பட்டது"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"பார்ப்பதற்கு அன்லாக் செய்யவும்"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"குறியீட்டைப் பார்க்க அன்லாக் செய்யவும்"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"சூழல் சார்ந்த கல்வி"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"பின்செல்ல, உங்கள் டச்பேடைப் பயன்படுத்துங்கள்"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"மூன்று விரல்களால் இடது அல்லது வலதுபுறம் ஸ்வைப் செய்யவும். சைகைகள் குறித்து மேலும் அறிய தட்டவும்."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"தெரியவில்லை"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"அனைத்துக் கட்டங்களையும் மீட்டமைக்கவா?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"விரைவு அமைப்புகளின் கட்டங்கள் அனைத்தும் சாதனத்தின் அசல் அமைப்புகளுக்கு மீட்டமைக்கப்படும்"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 2042ead675d6..d26bfaccc6cc 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"పరిసరాలు"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ఎడమ వైపునకు"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"కుడి వైపునకు"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ఎడమ, కుడి అని వేరు చేయబడిన కంట్రోల్స్‌కు విస్తరించండి"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"యూనిఫైడ్ కంట్రోల్‌కు కుదించండి"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"పరిసరాలను మ్యూట్ చేయండి"</string>
@@ -1571,4 +1577,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"తెలియదు"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"టైల్స్ అన్ని రీసెట్ చేయాలా?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"అన్ని క్విక్ సెట్టింగ్‌ల టైల్స్, పరికరం తాలూకు ఒరిజినల్ సెట్టింగ్‌లకు రీసెట్ చేయబడతాయి"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 9ac9d01b8ee7..9196f95de203 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"เชื่อมต่อกับ <xliff:g id="BLUETOOTH">%s</xliff:g> แล้ว"</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"เชื่อมต่อกับ <xliff:g id="CAST">%s</xliff:g>"</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"ขยายกลุ่ม"</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"เพิ่มอุปกรณ์ลงในกลุ่ม"</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"นำอุปกรณ์ออกจากกลุ่ม"</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"เปิดแอปพลิเคชัน"</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"ไม่ได้เชื่อมต่อ"</string>
<string name="data_connection_roaming" msgid="375650836665414797">"โรมมิ่ง"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"อินพุต"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"เครื่องช่วยฟัง"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"กำลังเปิด..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"ปรับความสว่างไม่ได้เนื่องจากควบคุมโดยแอปที่อยู่ด้านบน"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"หมุนอัตโนมัติ"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"หมุนหน้าจออัตโนมัติ"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"ตำแหน่ง"</string>
@@ -426,6 +423,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"เสียงแวดล้อม"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ซ้าย"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ขวา"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ขยายเป็นการควบคุมที่แยกด้านซ้ายและขวา"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ยุบเป็นการควบคุมแบบรวม"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"ปิดเสียงแวดล้อม"</string>
@@ -991,8 +994,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"แสดงไอคอนการแจ้งเตือนลำดับความสำคัญต่ำ"</string>
<string name="other" msgid="429768510980739978">"อื่นๆ"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"สลับขนาดของการ์ด"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"นำชิ้นส่วนออก"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"เพิ่มการ์ดไปยังตำแหน่งสุดท้าย"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"ย้ายชิ้นส่วน"</string>
@@ -1545,10 +1547,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"หากต้องการดูแอปล่าสุด ให้ใช้ 3 นิ้วปัดขึ้นแล้วค้างไว้บนทัชแพด"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"หากต้องการดูแอปทั้งหมด ให้กดปุ่มดำเนินการบนแป้นพิมพ์"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"ปกปิดไว้"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"ปลดล็อกเพื่อดู"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"ปลดล็อกเพื่อดูรหัส"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"การศึกษาตามบริบท"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"ใช้ทัชแพดเพื่อย้อนกลับ"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"ใช้ 3 นิ้วปัดไปทางซ้ายหรือขวา แตะเพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับท่าทางสัมผัสต่างๆ"</string>
@@ -1571,4 +1571,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ไม่ทราบ"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"รีเซ็ตการ์ดทั้งหมดใช่ไหม"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"การ์ดการตั้งค่าด่วนทั้งหมดจะรีเซ็ตเป็นการตั้งค่าเดิมของอุปกรณ์"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 516386bd3c9b..a6b0d6aa55df 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Paligid"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Kaliwa"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Kanan"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"I-expand sa kaliwa at kanang magkahiwalay na mga kontrol"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"I-collapse sa pinag-isang kontrol"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"I-mute ang paligid"</string>
@@ -1568,4 +1574,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Hindi Alam"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"I-reset ang lahat ng tile?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Magre-reset sa mga orihinal na setting ng device ang lahat ng tile ng Mga Mabilisang Setting"</string>
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index b6432030aa01..13d6cd7ff9fc 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Çevredeki sesler"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Sol"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Sağ"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Sol ve sağ kontrolleri ayırarak genişlet"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Kontrolleri birleştirerek daralt"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Çevredeki sesleri kapat"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Düşük öncelikli bildirim simgelerini göster"</string>
<string name="other" msgid="429768510980739978">"Diğer"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"kutu boyutunu değiştir"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"Kutuyu kaldırmak için"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"kutuyu son konuma ekleyin"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Kutuyu taşı"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Son uygulamaları görüntülemek için dokunmatik alanda üç parmağınızla yukarı kaydırıp basılı tutun"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Tüm uygulamalarınızı görüntülemek için klavyenizdeki eylem tuşuna basın"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Çıkartıldı"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Görüntülemek için kilidi açın"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Kodu görüntülemek için kilidi açın"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Bağlama dayalı eğitim"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Geri dönmek için dokunmatik alanınızı kullanın"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Üç parmağınızla sola veya sağa kaydırın. Daha fazla hareket öğrenmek için dokunun."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Bilinmiyor"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Tüm ayar kutuları sıfırlansın mı?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Tüm Hızlı Ayarlar kutuları cihazın özgün ayarlarına sıfırlanır"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index db3c02da8fcc..f0f4e38d6040 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Звуки оточення"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Ліворуч"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Праворуч"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Розгорнути в окремі елементи керування ліворуч і праворуч"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Згорнути в єдиний елемент керування"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Вимкнути звуки оточення"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Показувати значки сповіщень із низьким пріоритетом"</string>
<string name="other" msgid="429768510980739978">"Інше"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"змінити розмір плитки"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"вилучити опцію"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"додати панель на останню позицію"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Перемістити опцію"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Щоб переглянути останні додатки, проведіть трьома пальцями вгору по сенсорній панелі й утримуйте їх"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Щоб переглянути всі додатки, натисніть клавішу дії на клавіатурі"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Замасковано"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Розблокуйте, щоб переглянути"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Розблокуйте, щоб переглянути код"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Контекстне навчання"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Щоб повернутися, використовуйте сенсорну панель"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Проведіть трьома пальцями вліво чи вправо. Натисніть, щоб дізнатися про інші жести."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Невідомо"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Скинути всі панелі?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Усі панелі швидких налаштувань буде скинуто до стандартних налаштувань пристрою"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index ffc3f5e7c8aa..ef10b87cbd0f 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"اطراف"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"دائیں"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"بائیں"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"بائیں اور دائیں علیحدہ کردہ کنٹرولز کو پھیلائیں"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"یونیفائیڈ کنٹرول کیلئے سکیڑیں"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"اطراف کو خاموش کریں"</string>
@@ -1568,4 +1574,5 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"نامعلوم"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"سبھی ٹائلز ری سیٹ کریں؟"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"سبھی فوری ترتیبات کی ٹائلز آلہ کی اصل ترتیبات پر ری سیٹ ہو جائیں گی"</string>
+ <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>، <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index e325cf33adb3..facc51f2a1f6 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Atrof-muhit"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Chap"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Oʻng"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Chap va oʻngga ajratilgan boshqaruv elementlariga yoyish"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Yagona boshqaruvga yigʻish"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Atrof-muhitni ovozsiz qilish"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Muhim boʻlmagan bildirishnoma ikonkalarini koʻrsatish"</string>
<string name="other" msgid="429768510980739978">"Boshqa"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"katak oʻlchamini almashtirish"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"katakchani olib tashlash"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"kartochkani oxirgi oʻringa qoʻshish"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Katakchani boshqa joyga olish"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Oxirgi ilovalarni koʻrish uchun sensorli panelda uchta barmoq bilan tepaga surib, bosib turing"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Barcha ishoralarni koʻrish uchun klaviaturadagi amal tugmasini bosing"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Chiqarildi"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Koʻrish uchun qulfdan chiqaring"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Kodni koʻrish uchun qulfdan chiqaring"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Kontekstual taʼlim"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Sensorli panel orqali orqaga qaytish"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Uchta barmoq bilan chapga yoki oʻngga suring. Boshqa ishoralar bilan tanishish uchun bosing."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Noaniq"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Barcha katakchalar asliga qaytarilsinmi?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Barcha Tezkor sozlamalar katakchalari qurilmaning asl sozlamalariga qaytariladi"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index f64f0843304b..80db132b304f 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Âm lượng xung quanh"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Trái"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Phải"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Mở rộng thành các nút điều khiển tách biệt bên trái và bên phải"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Thu gọn thành nút điều khiển hợp nhất"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Tắt tiếng xung quanh"</string>
@@ -586,7 +592,7 @@
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Truyền một ứng dụng"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Truyền toàn bộ màn hình"</string>
<string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Khi bạn truyền toàn bộ màn hình thì người khác sẽ thấy được mọi nội dung trên màn hình của bạn. Vì vậy, hãy thận trọng đối với những thông tin như mật khẩu, thông tin thanh toán, tin nhắn, ảnh, âm thanh và video."</string>
- <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Khi bạn truyền một ứng dụng, thì người khác sẽ thấy được mọi nội dung xuất hiện hoặc phát trên ứng dụng đó. Vì vậy, hãy thận trọng đối với những thông tin như mật khẩu, thông tin thanh toán, tin nhắn, ảnh, âm thanh và video."</string>
+ <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Khi bạn truyền một ứng dụng, mọi nội dung xuất hiện hoặc phát trên ứng dụng đó đều hiển thị trên thiết bị được truyền tới. Vì vậy, hãy thận trọng đối với những thông tin như mật khẩu, thông tin thanh toán, tin nhắn, ảnh, âm thanh và video."</string>
<string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Màn hình truyền"</string>
<string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"Chọn ứng dụng để truyền"</string>
<string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Bắt đầu chia sẻ?"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Hiển thị biểu tượng thông báo có mức ưu tiên thấp"</string>
<string name="other" msgid="429768510980739978">"Khác"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"bật hoặc tắt kích thước của ô"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"xóa ô"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"thêm ô vào vị trí cuối cùng"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Di chuyển ô"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Để xem các ứng dụng gần đây, hãy dùng 3 ngón tay vuốt lên và giữ trên bàn di chuột"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Để xem tất cả ứng dụng của bạn, hãy nhấn phím hành động trên bàn phím"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Bị loại bỏ"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Mở khoá để xem"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Mở khoá để xem mã"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Hướng dẫn theo bối cảnh"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Dùng bàn di chuột để quay lại"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Dùng 3 ngón tay vuốt sang trái hoặc sang phải. Hãy nhấn để tìm hiểu các cử chỉ khác."</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Không xác định"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Đặt lại mọi ô?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Mọi ô Cài đặt nhanh sẽ được đặt lại về chế độ cài đặt ban đầu của thiết bị"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index a355a678cfc9..feb3989114cb 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"周围声音"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"左侧"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"右侧"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"展开为左侧和右侧的单独控件"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"收起为统一控件"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"将周围声音静音"</string>
@@ -991,8 +997,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"显示低优先级的通知图标"</string>
<string name="other" msgid="429768510980739978">"其他"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"切换功能块大小"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"移除功能块"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"将功能块添加到最后一个位置"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"移动功能块"</string>
@@ -1545,10 +1550,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"如要查看最近用过的应用,请用三根手指在触控板上向上滑动并按住"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"如要查看所有应用,请按下键盘上的快捷操作按键"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"已隐去"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"解锁即可查看"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"解锁即可查看验证码"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"内容相关指导"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"使用触控板返回"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"用三根手指向左或向右滑动。点按即可了解更多手势。"</string>
@@ -1571,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"未知"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"要重置所有功能块吗?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"所有“快捷设置”功能块都将重置为设备的原始设置"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index c5a81fb25a9b..031df00e1c9c 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"環境聲音"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"左"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"右"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"打開就可以分開左右控制"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"收埋就可以統一控制"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"環境聲音靜音"</string>
@@ -1568,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"不明"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"要重設所有圖塊嗎?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"所有「快速設定」圖塊將重設為裝置的原始設定"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 24a15a14f1b3..df05577ff942 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -426,6 +426,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"環境"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"左"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"右"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"展開為左右獨立控制選項"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"收合為統合控制選項"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"將環境靜音"</string>
@@ -1568,4 +1574,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"不明"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"要重設所有設定方塊嗎?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"所有快速設定方塊都會恢復裝置的原始設定"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 918864886d21..d571f0e58c92 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -428,6 +428,12 @@
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Izindawo ezizungezile"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Kwesokunxele"</string>
<string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Kwesokudla"</string>
+ <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
+ <skip />
+ <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
+ <skip />
<string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Nwebela ezilawulini ezihlukanisiwe zakwesokunxele nakwesokudla"</string>
<string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Goqa ezilawulini ezihlanganisiwe"</string>
<string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Thulisa izindawo ezizungezile"</string>
@@ -993,8 +999,7 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Bonisa izithonjana zesaziso zokubaluleka okuncane"</string>
<string name="other" msgid="429768510980739978">"Okunye"</string>
- <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
- <skip />
+ <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"guqula usayizi wethayela"</string>
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"susa ithayela"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"faka ithayela endaweni yokugcina"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Hambisa ithayela"</string>
@@ -1547,10 +1552,8 @@
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Ukuze ubuke ama-app akamuva, swayiphela phezulu bese ubambe ngeminwe emithathu ephedini yokuthinta"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Ukuze ubuke wonke ama-app wakho, cindezela inkinobho yokufinyelela kukhibhodi yakho"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Kwenziwe iredact"</string>
- <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
- <skip />
- <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
- <skip />
+ <string name="public_notification_single_line_text" msgid="3576190291791654933">"Vula ukuze ubuke"</string>
+ <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"Vula ukuze ubone ikhodi"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Imfundo yokuqukethwe"</string>
<string name="back_edu_notification_title" msgid="5624780717751357278">"Sebenzisa iphedi yokuthinta ukuze ubuyele emuva"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"Swayiphela kwesokunxele noma kwesokudla usebenzisa iminwe emithathu. Thepha ukuze ufunde kabanzi ngokunyakazisa umzimba."</string>
@@ -1573,4 +1576,6 @@
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Akwaziwa"</string>
<string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Qala kabusha onke amathayela?"</string>
<string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Ithayela Lamasethingi Asheshayo lizosetha kabusha libuyele kumasethingi okuqala edivayisi"</string>
+ <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 43ea2c3f7633..786ac69dc8fd 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2599,6 +2599,9 @@
<!-- Accessibility description indicating the currently selected tile's position. Only used for tiles that are currently in use [CHAR LIMIT=NONE] -->
<string name="accessibility_qs_edit_position">Position <xliff:g id="position" example="5">%1$d</xliff:g></string>
+ <!-- Accessibility description indicating the currently selected tile is already added [CHAR LIMIT=NONE] -->
+ <string name="accessibility_qs_edit_tile_already_added">Tile already added</string>
+
<!-- Accessibility announcement after a tile has been added [CHAR LIMIT=NONE] -->
<string name="accessibility_qs_edit_tile_added">Tile added</string>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ILauncherProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ILauncherProxy.aidl
index 10b930381c44..ade63b1dc9c9 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ILauncherProxy.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ILauncherProxy.aidl
@@ -66,7 +66,7 @@ oneway interface ILauncherProxy {
/**
* Sent when some system ui state changes.
*/
- void onSystemUiStateChanged(long stateFlags) = 16;
+ void onSystemUiStateChanged(long stateFlags, int displayId) = 16;
/**
* Sent when suggested rotation button could be shown
diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
index 94342349e727..e827b2d54a19 100644
--- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
@@ -386,7 +386,7 @@ constructor(
@VisibleForTesting
internal fun listenForDnd(scope: CoroutineScope): Job {
- ModesUi.assertInNewMode()
+ ModesUi.unsafeAssertInNewMode()
return scope.launch {
zenModeInteractor.dndMode.collect {
val zenMode =
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index bd09e392c883..d84b034eade8 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -2923,13 +2923,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, CoreSt
private boolean isPrimaryBouncerShowingOrWillBeShowing(
ObservableTransitionState transitionState
) {
- SceneContainerFlag.assertInNewMode();
+ SceneContainerFlag.unsafeAssertInNewMode();
return isPrimaryBouncerFullyShown(transitionState)
|| transitionState.isTransitioning(null, Overlays.Bouncer);
}
private boolean isPrimaryBouncerFullyShown(ObservableTransitionState transitionState) {
- SceneContainerFlag.assertInNewMode();
+ SceneContainerFlag.unsafeAssertInNewMode();
return transitionState.isIdle(Overlays.Bouncer);
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 4c8a8f1c13d7..b8e95ee1dbf0 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -539,7 +539,8 @@ public class AuthContainerView extends LinearLayout
}
public void show(WindowManager wm) {
- wm.addView(this, getLayoutParams(mWindowToken, mConfig.mPromptInfo.getTitle()));
+ wm.addView(this, getLayoutParams(mWindowToken, mConfig.mPromptInfo.getTitle(),
+ mPromptViewModel.getPromptKind().getValue().isCredential()));
}
private void forceExecuteAnimatedIn() {
@@ -738,7 +739,8 @@ public class AuthContainerView extends LinearLayout
}
@VisibleForTesting
- static WindowManager.LayoutParams getLayoutParams(IBinder windowToken, CharSequence title) {
+ static WindowManager.LayoutParams getLayoutParams(IBinder windowToken, CharSequence title,
+ boolean isCredentialView) {
final int windowFlags = WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
| WindowManager.LayoutParams.FLAG_SECURE
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
@@ -754,7 +756,7 @@ public class AuthContainerView extends LinearLayout
& ~WindowInsets.Type.systemBars());
lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
lp.setTitle("BiometricPrompt");
- lp.accessibilityTitle = title;
+ lp.accessibilityTitle = isCredentialView ? " " : title;
lp.dimAmount = BACKGROUND_DIM_AMOUNT;
lp.token = windowToken;
return lp;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPasswordViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPasswordViewBinder.kt
index e4c45402bb52..6842c90e957c 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPasswordViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPasswordViewBinder.kt
@@ -43,6 +43,9 @@ object CredentialPasswordViewBinder {
// the header info never changes - do it early
val header = viewModel.header.first()
passwordField.setTextOperationUser(UserHandle.of(header.user.userIdForPasswordEntry))
+ viewModel.inputBoxContentDescription.firstOrNull()?.let { descriptionId ->
+ passwordField.contentDescription = view.context.getString(descriptionId)
+ }
viewModel.inputFlags.firstOrNull()?.let { flags -> passwordField.inputType = flags }
if (requestFocusForInput) {
passwordField.requestFocus()
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt
index 0c5c723a4b2f..37cfc3342b6d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt
@@ -59,6 +59,17 @@ constructor(
}
}
+ /** Input box accessibility description for text based credential views */
+ val inputBoxContentDescription: Flow<Int?> =
+ credentialInteractor.prompt.map {
+ when (it) {
+ is BiometricPromptRequest.Credential.Pin -> R.string.keyguard_accessibility_pin_area
+ is BiometricPromptRequest.Credential.Password ->
+ R.string.keyguard_accessibility_password
+ else -> null
+ }
+ }
+
/** If stealth mode is active (hide user credential input). */
val stealthMode: Flow<Boolean> =
credentialInteractor.prompt.map {
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModel.kt
index 7ecd27647238..c5349c855948 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModel.kt
@@ -99,7 +99,7 @@ constructor(
*/
fun bindDetailsView(view: View) {
// If `QsDetailedView` is not enabled, it should show the dialog.
- QsDetailedView.assertInNewMode()
+ QsDetailedView.unsafeAssertInNewMode()
cancelJob()
diff --git a/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt b/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt
index 79748a255ed0..52204b84346d 100644
--- a/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt
+++ b/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt
@@ -165,20 +165,15 @@ fun BrightnessSlider(
val activeIconColor = colors.activeTickColor
val inactiveIconColor = colors.inactiveTickColor
- val trackIcon: DrawScope.(Offset, Color, Float) -> Unit =
- remember(painter) {
- { offset, color, alpha ->
- translate(offset.x + IconPadding.toPx(), offset.y) {
- with(painter) {
- draw(
- IconSize.toSize(),
- colorFilter = ColorFilter.tint(color),
- alpha = alpha,
- )
- }
+ val trackIcon: DrawScope.(Offset, Color, Float) -> Unit = remember {
+ { offset, color, alpha ->
+ translate(offset.x + IconPadding.toPx(), offset.y) {
+ with(painter) {
+ draw(IconSize.toSize(), colorFilter = ColorFilter.tint(color), alpha = alpha)
}
}
}
+ }
Slider(
value = animatedValue,
diff --git a/packages/SystemUI/src/com/android/systemui/common/domain/interactor/SysUIStateDisplaysInteractor.kt b/packages/SystemUI/src/com/android/systemui/common/domain/interactor/SysUIStateDisplaysInteractor.kt
new file mode 100644
index 000000000000..097d50bb8f9d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/common/domain/interactor/SysUIStateDisplaysInteractor.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.common.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.display.data.repository.PerDisplayRepository
+import com.android.systemui.model.StateChange
+import com.android.systemui.model.SysUiState
+import javax.inject.Inject
+
+/** Handles [SysUiState] changes between displays. */
+@SysUISingleton
+class SysUIStateDisplaysInteractor
+@Inject
+constructor(private val sysUIStateRepository: PerDisplayRepository<SysUiState>) {
+
+ /**
+ * Sets the flags on the given [targetDisplayId] based on the [stateChanges], while making sure
+ * that those flags are not set in any other display.
+ */
+ fun setFlagsExclusivelyToDisplay(targetDisplayId: Int, stateChanges: StateChange) {
+ sysUIStateRepository.forEachInstance { displayId, instance ->
+ if (displayId == targetDisplayId) {
+ stateChanges.applyTo(instance)
+ } else {
+ stateChanges.clearAllChangedFlagsIn(instance)
+ }
+ }
+ }
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/common/shared/model/Color.kt b/packages/SystemUI/src/com/android/systemui/common/shared/model/Color.kt
index d53a737480a3..72159252efec 100644
--- a/packages/SystemUI/src/com/android/systemui/common/shared/model/Color.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/shared/model/Color.kt
@@ -19,11 +19,13 @@ package com.android.systemui.common.shared.model
import android.annotation.AttrRes
import android.annotation.ColorInt
import android.annotation.ColorRes
+import androidx.compose.runtime.Stable
/**
* Models a color that can be either a specific [Color.Loaded] value or a resolvable theme
* [Color.Attribute]
*/
+@Stable
sealed interface Color {
data class Loaded(@ColorInt val color: Int) : Color
diff --git a/packages/SystemUI/src/com/android/systemui/common/shared/model/ContentDescription.kt b/packages/SystemUI/src/com/android/systemui/common/shared/model/ContentDescription.kt
index d628aca7f9e8..b7d8ae6ce153 100644
--- a/packages/SystemUI/src/com/android/systemui/common/shared/model/ContentDescription.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/shared/model/ContentDescription.kt
@@ -18,11 +18,13 @@ package com.android.systemui.common.shared.model
import android.annotation.StringRes
import android.content.Context
+import androidx.compose.runtime.Stable
/**
* Models a content description, that can either be already [loaded][ContentDescription.Loaded] or
* be a [reference][ContentDescription.Resource] to a resource.
*/
+@Stable
sealed class ContentDescription {
data class Loaded(val description: String?) : ContentDescription()
diff --git a/packages/SystemUI/src/com/android/systemui/common/shared/model/Icon.kt b/packages/SystemUI/src/com/android/systemui/common/shared/model/Icon.kt
index e6f02457d320..2adaec21867f 100644
--- a/packages/SystemUI/src/com/android/systemui/common/shared/model/Icon.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/shared/model/Icon.kt
@@ -18,11 +18,13 @@ package com.android.systemui.common.shared.model
import android.annotation.DrawableRes
import android.graphics.drawable.Drawable
+import androidx.compose.runtime.Stable
/**
* Models an icon, that can either be already [loaded][Icon.Loaded] or be a [reference]
* [Icon.Resource] to a resource. In case of [Loaded], the resource ID [res] is optional.
*/
+@Stable
sealed class Icon {
abstract val contentDescription: ContentDescription?
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/PerDisplayRepositoriesModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/PerDisplayRepositoriesModule.kt
new file mode 100644
index 000000000000..39708a743c23
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dagger/PerDisplayRepositoriesModule.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.dagger
+
+import com.android.systemui.display.data.repository.DefaultDisplayOnlyInstanceRepositoryImpl
+import com.android.systemui.display.data.repository.PerDisplayInstanceRepositoryImpl
+import com.android.systemui.display.data.repository.PerDisplayRepository
+import com.android.systemui.model.SysUIStateInstanceProvider
+import com.android.systemui.model.SysUiState
+import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround
+import dagger.Module
+import dagger.Provides
+
+/** This module is meant to contain all the code to create the various [PerDisplayRepository<>]. */
+@Module
+class PerDisplayRepositoriesModule {
+
+ @SysUISingleton
+ @Provides
+ fun provideSysUiStateRepository(
+ repositoryFactory: PerDisplayInstanceRepositoryImpl.Factory<SysUiState>,
+ instanceProvider: SysUIStateInstanceProvider,
+ ): PerDisplayRepository<SysUiState> {
+ val debugName = "SysUiStatePerDisplayRepo"
+ return if (ShadeWindowGoesAround.isEnabled) {
+ repositoryFactory.create(debugName, instanceProvider)
+ } else {
+ DefaultDisplayOnlyInstanceRepositoryImpl(debugName, instanceProvider)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index f8cf6b007041..f08126af0a7a 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -21,6 +21,7 @@ import android.app.Service;
import android.app.backup.BackupManager;
import android.content.Context;
import android.service.dreams.IDreamManager;
+import android.view.Display;
import androidx.annotation.Nullable;
@@ -64,9 +65,9 @@ import com.android.systemui.dagger.qualifiers.UiBackground;
import com.android.systemui.demomode.dagger.DemoModeModule;
import com.android.systemui.deviceentry.DeviceEntryModule;
import com.android.systemui.display.DisplayModule;
+import com.android.systemui.display.data.repository.PerDisplayRepository;
import com.android.systemui.doze.dagger.DozeComponent;
import com.android.systemui.dreams.dagger.DreamModule;
-import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.FlagDependenciesModule;
import com.android.systemui.flags.FlagsModule;
@@ -86,7 +87,6 @@ import com.android.systemui.mediaprojection.MediaProjectionModule;
import com.android.systemui.mediaprojection.appselector.MediaProjectionActivitiesModule;
import com.android.systemui.mediaprojection.taskswitcher.MediaProjectionTaskSwitcherModule;
import com.android.systemui.mediarouter.MediaRouterModule;
-import com.android.systemui.model.SceneContainerPlugin;
import com.android.systemui.model.SysUiState;
import com.android.systemui.motiontool.MotionToolModule;
import com.android.systemui.navigationbar.NavigationBarComponent;
@@ -113,7 +113,6 @@ import com.android.systemui.scene.ui.view.WindowRootViewComponent;
import com.android.systemui.screenrecord.ScreenRecordModule;
import com.android.systemui.screenshot.dagger.ScreenshotModule;
import com.android.systemui.security.data.repository.SecurityRepositoryModule;
-import com.android.systemui.settings.DisplayTracker;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shade.ShadeController;
import com.android.systemui.shade.ShadeDisplayAwareModule;
@@ -289,7 +288,8 @@ import javax.inject.Named;
UtilModule.class,
NoteTaskModule.class,
WalletModule.class,
- LowLightModule.class
+ LowLightModule.class,
+ PerDisplayRepositoriesModule.class
},
subcomponents = {
ComplicationComponent.class,
@@ -326,12 +326,8 @@ public abstract class SystemUIModule {
@SysUISingleton
@Provides
static SysUiState provideSysUiState(
- DisplayTracker displayTracker,
- DumpManager dumpManager,
- SceneContainerPlugin sceneContainerPlugin) {
- final SysUiState state = new SysUiState(displayTracker, sceneContainerPlugin);
- dumpManager.registerDumpable(state);
- return state;
+ PerDisplayRepository<SysUiState> repository) {
+ return repository.get(Display.DEFAULT_DISPLAY);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/development/domain/interactor/BuildNumberInteractor.kt b/packages/SystemUI/src/com/android/systemui/development/domain/interactor/BuildNumberInteractor.kt
index fa5556d44674..cedd5161a777 100644
--- a/packages/SystemUI/src/com/android/systemui/development/domain/interactor/BuildNumberInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/development/domain/interactor/BuildNumberInteractor.kt
@@ -23,6 +23,7 @@ import android.os.Build
import android.os.UserHandle
import com.android.internal.R as InternalR
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.development.data.repository.DevelopmentSettingRepository
@@ -32,9 +33,12 @@ import com.android.systemui.user.data.repository.UserRepository
import com.android.systemui.user.utils.UserScopedService
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted.Companion.WhileSubscribed
+import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.flatMapConcat
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.withContext
@SysUISingleton
@@ -46,6 +50,7 @@ constructor(
private val userRepository: UserRepository,
private val clipboardManagerProvider: UserScopedService<ClipboardManager>,
@Background private val backgroundDispatcher: CoroutineDispatcher,
+ @Application private val applicationScope: CoroutineScope,
) {
/**
@@ -53,10 +58,11 @@ constructor(
*
* @see DevelopmentSettingRepository.isDevelopmentSettingEnabled
*/
- val buildNumber: Flow<BuildNumber?> =
+ val buildNumber: StateFlow<BuildNumber?> =
userRepository.selectedUserInfo
.flatMapConcat { userInfo -> repository.isDevelopmentSettingEnabled(userInfo) }
.map { enabled -> buildText.takeIf { enabled } }
+ .stateIn(applicationScope, WhileSubscribed(), null)
private val buildText =
BuildNumber(
diff --git a/packages/SystemUI/src/com/android/systemui/development/ui/viewmodel/BuildNumberViewModel.kt b/packages/SystemUI/src/com/android/systemui/development/ui/viewmodel/BuildNumberViewModel.kt
index 68c51ea80ffd..31d0471f55e2 100644
--- a/packages/SystemUI/src/com/android/systemui/development/ui/viewmodel/BuildNumberViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/development/ui/viewmodel/BuildNumberViewModel.kt
@@ -41,7 +41,6 @@ constructor(private val buildNumberInteractor: BuildNumberInteractor) : Exclusiv
val buildNumber: BuildNumber? by
hydrator.hydratedStateOf(
traceName = "buildNumber",
- initialValue = null,
source = buildNumberInteractor.buildNumber,
)
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayScopeRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayScopeRepository.kt
index f4d256a5b2ba..d912b6a13d0f 100644
--- a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayScopeRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayScopeRepository.kt
@@ -53,7 +53,7 @@ constructor(
}
override fun start() {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
backgroundApplicationScope.launch {
displayRepository.displayRemovalEvent.collect { displayId ->
val scope = perDisplayScopes.remove(displayId)
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/FakePerDisplayRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/FakePerDisplayRepository.kt
new file mode 100644
index 000000000000..083191c8ecde
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/FakePerDisplayRepository.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.display.data.repository
+
+class FakePerDisplayRepository<T> : PerDisplayRepository<T> {
+
+ private val instances = mutableMapOf<Int, T>()
+
+ fun add(displayId: Int, instance: T) {
+ instances[displayId] = instance
+ }
+
+ fun remove(displayId: Int) {
+ instances.remove(displayId)
+ }
+
+ override fun get(displayId: Int): T? {
+ return instances[displayId]
+ }
+
+ override val displayIds: Set<Int>
+ get() = instances.keys
+
+ override val debugName: String
+ get() = "FakePerDisplayRepository"
+}
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepository.kt
new file mode 100644
index 000000000000..04f245e91914
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepository.kt
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.display.data.repository
+
+import android.util.Log
+import android.view.Display
+import com.android.app.tracing.coroutines.launchTraced as launch
+import com.android.app.tracing.traceSection
+import com.android.systemui.Dumpable
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dump.DumpManager
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import java.io.PrintWriter
+import java.util.concurrent.ConcurrentHashMap
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.collectLatest
+
+/**
+ * Used to create instances of type `T` for a specific display.
+ *
+ * This is useful for resources or objects that need to be managed independently for each connected
+ * display (e.g., UI state, rendering contexts, or display-specific configurations).
+ *
+ * Note that in most cases this can be implemented by a simple `@AssistedFactory` with `displayId`
+ * parameter
+ *
+ * ```kotlin
+ * class SomeType @AssistedInject constructor(@Assisted displayId: Int,..)
+ * @AssistedFactory
+ * interface Factory {
+ * fun create(displayId: Int): SomeType
+ * }
+ * }
+ * ```
+ *
+ * Then it can be used to create a [PerDisplayRepository] as follows:
+ * ```kotlin
+ * // Injected:
+ * val repositoryFactory: PerDisplayRepositoryImpl.Factory
+ * val instanceFactory: PerDisplayRepositoryImpl.Factory
+ * // repository creation:
+ * repositoryFactory.create(instanceFactory::create)
+ * ```
+ *
+ * @see PerDisplayRepository For how to retrieve and manage instances created by this factory.
+ */
+fun interface PerDisplayInstanceProvider<T> {
+ /** Creates an instance for a display. */
+ fun createInstance(displayId: Int): T?
+}
+
+/**
+ * Extends [PerDisplayInstanceProvider], adding support for destroying the instance.
+ *
+ * This is useful for releasing resources associated with a display when it is disconnected or when
+ * the per-display instance is no longer needed.
+ */
+interface PerDisplayInstanceProviderWithTeardown<T> : PerDisplayInstanceProvider<T> {
+ /** Destroys a previously created instance of `T` forever. */
+ fun destroyInstance(instance: T)
+}
+
+/**
+ * Provides access to per-display instances of type `T`.
+ *
+ * Acts as a repository, managing the caching and retrieval of instances created by a
+ * [PerDisplayInstanceProvider]. It ensures that only one instance of `T` exists per display ID.
+ */
+interface PerDisplayRepository<T> {
+ /** Gets the cached instance or create a new one for a given display. */
+ operator fun get(displayId: Int): T?
+
+ /** List of display ids for which this repository has an instance. */
+ val displayIds: Set<Int>
+
+ /** Debug name for this repository, mainly for tracing and logging. */
+ val debugName: String
+
+ /**
+ * Invokes the specified action on each instance held by this repository.
+ *
+ * The action will receive the displayId and the instance associated with that display.
+ * If there is no instance for the display, the action is not called.
+ */
+ fun forEachInstance(action: (Int, T) -> Unit) {
+ displayIds.forEach { displayId ->
+ get(displayId)?.let { instance -> action(displayId, instance) }
+ }
+ }
+}
+
+/**
+ * Default implementation of [PerDisplayRepository].
+ *
+ * This class manages a cache of per-display instances of type `T`, creating them using a provided
+ * [PerDisplayInstanceProvider] and optionally tearing them down using a
+ * [PerDisplayInstanceProviderWithTeardown] when displays are disconnected.
+ *
+ * It listens to the [DisplayRepository] to detect when displays are added or removed, and
+ * automatically manages the lifecycle of the per-display instances.
+ *
+ * Note that this is a [PerDisplayStoreImpl] 2.0 that doesn't require [CoreStartable] bindings,
+ * providing all args in the constructor.
+ */
+class PerDisplayInstanceRepositoryImpl<T>
+@AssistedInject
+constructor(
+ @Assisted override val debugName: String,
+ @Assisted private val instanceProvider: PerDisplayInstanceProvider<T>,
+ @Background private val backgroundApplicationScope: CoroutineScope,
+ private val displayRepository: DisplayRepository,
+ private val dumpManager: DumpManager,
+) : PerDisplayRepository<T>, Dumpable {
+
+ private val perDisplayInstances = ConcurrentHashMap<Int, T?>()
+
+ init {
+ backgroundApplicationScope.launch("$debugName#start") { start() }
+ }
+
+ override val displayIds: Set<Int>
+ get() = perDisplayInstances.keys
+
+ private suspend fun start() {
+ dumpManager.registerDumpable(this)
+ displayRepository.displayIds.collectLatest { displayIds ->
+ val toRemove = perDisplayInstances.keys - displayIds
+ toRemove.forEach { displayId ->
+ perDisplayInstances.remove(displayId)?.let { instance ->
+ (instanceProvider as? PerDisplayInstanceProviderWithTeardown)?.destroyInstance(
+ instance
+ )
+ }
+ }
+ }
+ }
+
+ override fun get(displayId: Int): T? {
+ if (displayRepository.getDisplay(displayId) == null) {
+ Log.e(TAG, "<$debugName: Display with id $displayId doesn't exist.")
+ return null
+ }
+
+ // If it doesn't exist, create it and put it in the map.
+ return perDisplayInstances.computeIfAbsent(displayId) { key ->
+ val instance =
+ traceSection({ "creating instance of $debugName for displayId=$key" }) {
+ instanceProvider.createInstance(key)
+ }
+ if (instance == null) {
+ Log.e(
+ TAG,
+ "<$debugName> returning null because createInstance($key) returned null.",
+ )
+ }
+ instance
+ }
+ }
+
+ @AssistedFactory
+ interface Factory<T> {
+ fun create(
+ debugName: String,
+ instanceProvider: PerDisplayInstanceProvider<T>,
+ ): PerDisplayInstanceRepositoryImpl<T>
+ }
+
+ companion object {
+ private const val TAG = "PerDisplayInstanceRepo"
+ }
+
+ override fun dump(pw: PrintWriter, args: Array<out String>) {
+ pw.println(perDisplayInstances)
+ }
+}
+
+/**
+ * Provides an instance of a given class **only** for the default display, even if asked for another
+ * display.
+ *
+ * This is useful in case of flag refactors: it can be provided instead of an instance of
+ * [PerDisplayInstanceRepositoryImpl] when a flag related to multi display refactoring is off.
+ */
+class DefaultDisplayOnlyInstanceRepositoryImpl<T>(
+ override val debugName: String,
+ private val instanceProvider: PerDisplayInstanceProvider<T>,
+) : PerDisplayRepository<T> {
+ private val lazyDefaultDisplayInstance by lazy {
+ instanceProvider.createInstance(Display.DEFAULT_DISPLAY)
+ }
+ override val displayIds: Set<Int> = setOf(Display.DEFAULT_DISPLAY)
+
+ override fun get(displayId: Int): T? = lazyDefaultDisplayInstance
+}
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt
index 564588c159bd..46048868f503 100644
--- a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt
@@ -26,6 +26,7 @@ import java.util.concurrent.ConcurrentHashMap
import kotlinx.coroutines.CoroutineScope
/** Provides per display instances of [T]. */
+@Deprecated("Use PerDisplayInstanceProvider<T> instead")
interface PerDisplayStore<T> {
/**
@@ -43,12 +44,13 @@ interface PerDisplayStore<T> {
fun forDisplay(displayId: Int): T?
}
+@Deprecated("Use PerDisplayRepository<T> instead")
abstract class PerDisplayStoreImpl<T>(
@Background private val backgroundApplicationScope: CoroutineScope,
private val displayRepository: DisplayRepository,
) : PerDisplayStore<T>, CoreStartable {
- private val perDisplayInstances = ConcurrentHashMap<Int, T>()
+ protected val perDisplayInstances = ConcurrentHashMap<Int, T>()
/**
* The instance for the default/main display of the device. For example, on a phone or a tablet,
@@ -106,6 +108,11 @@ abstract class PerDisplayStoreImpl<T>(
* Will be called when the display associated with [instance] was removed. It allows to perform
* any clean up if needed.
*/
+ @Deprecated(
+ "Use PerDisplayInstanceProviderWithTeardown instead, and let " +
+ "PerDisplayInstanceRepositoryImpl decide when to destroy the instance (e.g. on " +
+ "display removal or other conditions."
+ )
open suspend fun onDisplayRemovalAction(instance: T) {}
override fun dump(pw: PrintWriter, args: Array<out String>) {
diff --git a/packages/SystemUI/src/com/android/systemui/flags/RefactorFlagUtils.kt b/packages/SystemUI/src/com/android/systemui/flags/RefactorFlagUtils.kt
index 4d89a826b60a..ca157afb7721 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/RefactorFlagUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/RefactorFlagUtils.kt
@@ -86,12 +86,12 @@ object RefactorFlagUtils {
* Example usage:
* ```
* public void setSomeNewController(SomeController someController) {
- * SomeRefactor.assertInNewMode();
+ * SomeRefactor.unsafeAssertInNewMode();
* mSomeController = someController;
* }
* ````
*/
- inline fun assertInNewMode(isEnabled: Boolean, flagName: Any) =
+ inline fun unsafeAssertInNewMode(isEnabled: Boolean, flagName: Any) =
check(isEnabled) { "New code path not supported when $flagName is disabled." }
/**
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
index f11ebee46659..07ed194dd68f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
@@ -98,7 +98,7 @@ class DoNotDisturbQuickAffordanceConfig(
private var settingsValue: Int = 0
private val isAvailable: StateFlow<Boolean> by lazy {
- ModesUi.assertInNewMode()
+ ModesUi.unsafeAssertInNewMode()
interactor.isZenAvailable.stateIn(
scope = backgroundScope,
started = SharingStarted.Eagerly,
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 acb98ede3e80..affcd33b7170 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
@@ -662,12 +662,12 @@ constructor(
}
override fun setShowKeyguardWhenReenabled(isShowKeyguardWhenReenabled: Boolean) {
- SceneContainerFlag.assertInNewMode()
+ SceneContainerFlag.unsafeAssertInNewMode()
this.isShowKeyguardWhenReenabled = isShowKeyguardWhenReenabled
}
override fun isShowKeyguardWhenReenabled(): Boolean {
- SceneContainerFlag.assertInNewMode()
+ SceneContainerFlag.unsafeAssertInNewMode()
return isShowKeyguardWhenReenabled
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModel.kt
index 1ca08febd7ef..cff651114c93 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModel.kt
@@ -47,7 +47,7 @@ constructor(
/** Reports the alternate bouncer visible state if the scene container flag is enabled. */
val isVisible: Flow<Boolean> =
- alternateBouncerInteractor.get().isVisible.onEach { SceneContainerFlag.assertInNewMode() }
+ alternateBouncerInteractor.get().isVisible.onEach { SceneContainerFlag.unsafeAssertInNewMode() }
/** Progress to a fully transitioned alternate bouncer. 1f represents fully transitioned. */
val transitionToAlternateBouncerProgress: Flow<Float> =
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt
index 69006c6107cc..ec7d3328a2fd 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt
@@ -51,6 +51,7 @@ import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.media.dream.MediaDreamComplication
import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.qs.flags.QSComposeFragment
import com.android.systemui.res.R
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.shade.ShadeDisplayAware
@@ -289,6 +290,9 @@ constructor(
updateUserVisibility()
}
+ /** The expansion fraction of notification shade. */
+ var shadeExpandedFraction: Float = 0.0f
+
/**
* distance that the full shade transition takes in order for media to fully transition to the
* shade
@@ -868,7 +872,13 @@ constructor(
if (isCurrentlyInGuidedTransformation()) {
return false
}
- if (skipQqsOnExpansion) {
+ if (
+ skipQqsOnExpansion ||
+ (QSComposeFragment.isEnabled &&
+ desiredLocation == LOCATION_QQS &&
+ previousLocation == LOCATION_QS &&
+ shadeExpandedFraction == 0.0f)
+ ) {
return false
}
if (isHubTransition) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/remedia/shared/model/MediaSessionState.kt b/packages/SystemUI/src/com/android/systemui/media/remedia/shared/model/MediaSessionState.kt
new file mode 100644
index 000000000000..40d55af9ba3e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/remedia/shared/model/MediaSessionState.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.remedia.shared.model
+
+sealed interface MediaSessionState {
+ data object Playing : MediaSessionState
+
+ data object Paused : MediaSessionState
+
+ data object Buffering : MediaSessionState
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt
new file mode 100644
index 000000000000..ae276707c3db
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.remedia.ui.compose
+
+import androidx.compose.animation.Crossfade
+import androidx.compose.animation.core.animateDpAsState
+import androidx.compose.animation.graphics.res.animatedVectorResource
+import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter
+import androidx.compose.animation.graphics.vector.AnimatedImageVector
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.CircularProgressIndicator
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButtonDefaults
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import com.android.compose.PlatformButton
+import com.android.compose.PlatformIconButton
+import com.android.compose.animation.scene.ContentScope
+import com.android.compose.animation.scene.ElementKey
+import com.android.compose.theme.LocalAndroidColorScheme
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.common.ui.compose.Icon
+import com.android.systemui.common.ui.compose.load
+import com.android.systemui.media.remedia.shared.model.MediaSessionState
+import com.android.systemui.media.remedia.ui.viewmodel.MediaOutputSwitcherChipViewModel
+import com.android.systemui.media.remedia.ui.viewmodel.MediaPlayPauseActionViewModel
+import com.android.systemui.media.remedia.ui.viewmodel.MediaSecondaryActionViewModel
+
+/** Renders the metadata labels of a track. */
+@Composable
+private fun ContentScope.Metadata(
+ title: String,
+ subtitle: String,
+ color: Color,
+ modifier: Modifier = Modifier,
+) {
+ // This element can be animated when switching between scenes inside a media card.
+ Element(key = Media.Elements.Metadata, modifier = modifier) {
+ // When the title and/or subtitle change, crossfade between the old and the new.
+ Crossfade(targetState = title to subtitle, label = "Labels.crossfade") { (title, subtitle)
+ ->
+ Column {
+ Text(
+ text = title,
+ style = MaterialTheme.typography.bodyLarge,
+ color = color,
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ )
+
+ Text(
+ text = subtitle,
+ style = MaterialTheme.typography.bodyMedium,
+ color = color,
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ )
+ }
+ }
+ }
+}
+
+/**
+ * Renders a small chip showing the current output device and providing a way to switch to a
+ * different output device.
+ */
+@Composable
+private fun OutputSwitcherChip(
+ viewModel: MediaOutputSwitcherChipViewModel,
+ modifier: Modifier = Modifier,
+) {
+ PlatformButton(
+ onClick = viewModel.onClick,
+ colors =
+ ButtonDefaults.buttonColors(
+ containerColor = LocalAndroidColorScheme.current.primaryFixed
+ ),
+ contentPadding = PaddingValues(start = 8.dp, end = 12.dp, top = 4.dp, bottom = 4.dp),
+ modifier = modifier.height(24.dp),
+ ) {
+ Icon(
+ icon = viewModel.icon,
+ tint = LocalAndroidColorScheme.current.onPrimaryFixed,
+ modifier = Modifier.size(16.dp),
+ )
+ viewModel.text?.let {
+ Spacer(Modifier.size(4.dp))
+ Text(
+ text = viewModel.text,
+ style = MaterialTheme.typography.bodySmall,
+ color = LocalAndroidColorScheme.current.onPrimaryFixed,
+ )
+ }
+ }
+}
+
+/** Renders the primary action of media controls: the play/pause button. */
+@Composable
+private fun ContentScope.PlayPauseAction(
+ viewModel: MediaPlayPauseActionViewModel,
+ buttonWidth: Dp,
+ buttonColor: Color,
+ iconColor: Color,
+ buttonCornerRadius: (isPlaying: Boolean) -> Dp,
+ modifier: Modifier = Modifier,
+) {
+ val cornerRadius: Dp by
+ animateDpAsState(
+ targetValue = buttonCornerRadius(viewModel.state != MediaSessionState.Paused),
+ label = "PlayPauseAction.cornerRadius",
+ )
+ // This element can be animated when switching between scenes inside a media card.
+ Element(key = Media.Elements.PlayPauseButton, modifier = modifier) {
+ PlatformButton(
+ onClick = viewModel.onClick,
+ colors = ButtonDefaults.buttonColors(containerColor = buttonColor),
+ shape = RoundedCornerShape(cornerRadius),
+ modifier = Modifier.size(width = buttonWidth, height = 48.dp),
+ ) {
+ when (viewModel.state) {
+ is MediaSessionState.Playing,
+ is MediaSessionState.Paused -> {
+ // TODO(b/399860531): load this expensive-to-load animated vector drawable off
+ // the main thread.
+ val iconResource = checkNotNull(viewModel.icon)
+ Icon(
+ painter =
+ rememberAnimatedVectorPainter(
+ animatedImageVector =
+ AnimatedImageVector.animatedVectorResource(
+ id = iconResource.res
+ ),
+ atEnd = viewModel.state == MediaSessionState.Playing,
+ ),
+ contentDescription = iconResource.contentDescription?.load(),
+ tint = iconColor,
+ modifier = Modifier.size(24.dp),
+ )
+ }
+ is MediaSessionState.Buffering -> {
+ CircularProgressIndicator(color = iconColor, modifier = Modifier.size(24.dp))
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Renders an icon button for an action that's not the play/pause action.
+ *
+ * If [element] is provided, the secondary action element will be able to animate when switching
+ * between scenes inside a media card.
+ */
+@Composable
+private fun ContentScope.SecondaryAction(
+ viewModel: MediaSecondaryActionViewModel,
+ modifier: Modifier = Modifier,
+ element: ElementKey? = null,
+ iconColor: Color = Color.White,
+) {
+ if (element != null) {
+ Element(key = element, modifier = modifier) {
+ SecondaryActionContent(viewModel = viewModel, iconColor = iconColor)
+ }
+ } else {
+ SecondaryActionContent(viewModel = viewModel, iconColor = iconColor, modifier = modifier)
+ }
+}
+
+/** The content of a [SecondaryAction]. */
+@Composable
+private fun SecondaryActionContent(
+ viewModel: MediaSecondaryActionViewModel,
+ iconColor: Color,
+ modifier: Modifier = Modifier,
+) {
+ PlatformIconButton(
+ onClick = viewModel.onClick,
+ iconResource = (viewModel.icon as Icon.Resource).res,
+ contentDescription = viewModel.icon.contentDescription?.load(),
+ colors = IconButtonDefaults.iconButtonColors(contentColor = iconColor),
+ modifier = modifier.size(48.dp).padding(13.dp),
+ )
+}
+
+private object Media {
+
+ /**
+ * Element keys.
+ *
+ * Composables that are wrapped in [ContentScope.Element] with one of these as their `key`
+ * parameter will automatically be picked up by the STL transition animation framework and will
+ * be animated from their bounds in the original scene to their bounds in the destination scene.
+ *
+ * In addition, tagging such elements with a key allows developers to customize the transition
+ * animations even further.
+ */
+ object Elements {
+ val PlayPauseButton = ElementKey("play_pause")
+ val Metadata = ElementKey("metadata")
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaOutputSwitcherChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaOutputSwitcherChipViewModel.kt
new file mode 100644
index 000000000000..f2724da2c3af
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaOutputSwitcherChipViewModel.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.remedia.ui.viewmodel
+
+import com.android.systemui.common.shared.model.Icon
+
+data class MediaOutputSwitcherChipViewModel(
+ val icon: Icon,
+ val text: String? = null,
+ val onClick: () -> Unit,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaPlayPauseActionViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaPlayPauseActionViewModel.kt
new file mode 100644
index 000000000000..4cb11bc0b8d0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaPlayPauseActionViewModel.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.remedia.ui.viewmodel
+
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.media.remedia.shared.model.MediaSessionState
+
+/** Models UI state for the play/pause action button within media controls. */
+data class MediaPlayPauseActionViewModel(
+ val isVisible: Boolean,
+ val state: MediaSessionState,
+ val icon: Icon.Resource?,
+ val onClick: () -> Unit,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaSecondaryActionViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaSecondaryActionViewModel.kt
new file mode 100644
index 000000000000..2d7765d861a7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaSecondaryActionViewModel.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.remedia.ui.viewmodel
+
+import com.android.systemui.common.shared.model.Icon
+
+/** Models UI state for a secondary action button within media controls. */
+data class MediaSecondaryActionViewModel(val icon: Icon, val onClick: () -> Unit)
diff --git a/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt b/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt
index ea515c96d3f0..4559a7aea1a2 100644
--- a/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt
+++ b/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt
@@ -25,6 +25,8 @@ import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.shade.data.repository.ShadeDisplaysRepository
+import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_COMMUNAL_HUB_SHOWING
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED
@@ -35,6 +37,7 @@ import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_B
import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags
import dagger.Lazy
import javax.inject.Inject
+import kotlinx.coroutines.flow.StateFlow
/**
* A plugin for [SysUiState] that provides overrides for certain state flags that must be pulled
@@ -46,17 +49,28 @@ class SceneContainerPlugin
constructor(
private val sceneInteractor: Lazy<SceneInteractor>,
private val occlusionInteractor: Lazy<SceneContainerOcclusionInteractor>,
+ private val shadeDisplaysRepository: Lazy<ShadeDisplaysRepository>,
) {
+ private val shadeDisplayId: StateFlow<Int> by lazy { shadeDisplaysRepository.get().displayId }
+
/**
* Returns an override value for the given [flag] or `null` if the scene framework isn't enabled
* or if the flag value doesn't need to be overridden.
*/
- fun flagValueOverride(@SystemUiStateFlags flag: Long): Boolean? {
+ fun flagValueOverride(@SystemUiStateFlags flag: Long, displayId: Int): Boolean? {
if (!SceneContainerFlag.isEnabled) {
return null
}
+ if (ShadeWindowGoesAround.isEnabled && shadeDisplayId.value != displayId) {
+ // The shade is in another display. All flags related to the shade container will map to
+ // false on other displays now.
+ //
+ // Note that this assumes there is only one SceneContainer and it is only on the shade
+ // window display. If there will be more, this will need to be revisited
+ return false
+ }
val transitionState = sceneInteractor.get().transitionState.value
val idleTransitionStateOrNull = transitionState as? ObservableTransitionState.Idle
val invisibleDueToOcclusion = occlusionInteractor.get().invisibleDueToOcclusion.value
diff --git a/packages/SystemUI/src/com/android/systemui/model/SysUIStateChange.kt b/packages/SystemUI/src/com/android/systemui/model/SysUIStateChange.kt
new file mode 100644
index 000000000000..f29b15730986
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/model/SysUIStateChange.kt
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.model
+
+/**
+ * Represents a set of state changes. A bit can either be set to `true` or `false`.
+ *
+ * This is used in [SysUIStateDisplaysInteractor] to selectively change bits.
+ */
+class StateChange {
+ private var flagsToSet: Long = 0
+ private var flagsToClear: Long = 0
+
+ /**
+ * Sets the [state] of the given [bit].
+ *
+ * @return `this` for chaining purposes
+ */
+ fun setFlag(bit: Long, state: Boolean): StateChange {
+ if (state) {
+ flagsToSet = flagsToSet or bit
+ flagsToClear = flagsToClear and bit.inv()
+ } else {
+ flagsToClear = flagsToClear or bit
+ flagsToSet = flagsToSet and bit.inv()
+ }
+ return this
+ }
+
+ fun hasChanges() = flagsToSet != 0L || flagsToClear != 0L
+
+ /** Applies all changed flags to [sysUiState]. */
+ fun applyTo(sysUiState: SysUiState) {
+ iterateBits(flagsToSet or flagsToClear) { bit ->
+ val isBitSetInNewState = flagsToSet and bit != 0L
+ sysUiState.setFlag(bit, isBitSetInNewState)
+ }
+ sysUiState.commitUpdate()
+ }
+
+ fun applyTo(sysUiState: Long): Long {
+ var newState = sysUiState
+ newState = newState or flagsToSet
+ newState = newState and flagsToClear.inv()
+ return newState
+ }
+
+ private inline fun iterateBits(flags: Long, action: (bit: Long) -> Unit) {
+ var remaining = flags
+ while (remaining != 0L) {
+ val lowestBit = remaining and -remaining
+ action(lowestBit)
+
+ remaining -= lowestBit
+ }
+ }
+
+ /** Clears all the flags changed in a [sysUiState] */
+ fun clearAllChangedFlagsIn(sysUiState: SysUiState) {
+ iterateBits(flagsToSet or flagsToClear) { bit -> sysUiState.setFlag(bit, false) }
+ sysUiState.commitUpdate()
+ }
+
+ fun clear() {
+ flagsToSet = 0
+ flagsToClear = 0
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/model/SysUIStateDispatcher.kt b/packages/SystemUI/src/com/android/systemui/model/SysUIStateDispatcher.kt
new file mode 100644
index 000000000000..f95ae2501acb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/model/SysUIStateDispatcher.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.model
+
+import android.view.Display
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround
+import java.util.concurrent.CopyOnWriteArrayList
+import javax.inject.Inject
+
+/**
+ * Channels changes from several [SysUiState]s to a single callback.
+ *
+ * There are several [SysUiState]s (one per display). This class allows for listeners to listen to
+ * sysui state updates from any of those [SysUiState] instances.
+ *
+ * ┌────────────────────┐
+ * │ SysUIStateOverride │
+ * │ displayId=2 │
+ * └┬───────────────────┘
+ * │ ▲
+ * ┌───────────────┐ │ │ ┌────────────────────┐
+ * │ SysUIState │ │ │ │ SysUIStateOverride │
+ * │ displayId=0 │ │ │ │ displayId=1 │
+ * └────────────┬──┘ │ │ └┬───────────────────┘
+ * │ │ │ │ ▲
+ * ▼ ▼ │ ▼ │
+ * ┌─────────────┴─────┴─┐
+ * │SysUiStateDispatcher │
+ * └────────┬────────────┘
+ * │
+ * ▼
+ * ┌──────────────────┐
+ * │ listeners for │
+ * │ all displays │
+ * └──────────────────┘
+ */
+@SysUISingleton
+class SysUIStateDispatcher @Inject constructor() {
+
+ private val listeners = CopyOnWriteArrayList<SysUiState.SysUiStateCallback>()
+
+ /** Called from each [SysUiState] to propagate new state changes. */
+ fun dispatchSysUIStateChange(sysUiFlags: Long, displayId: Int) {
+ if (displayId != Display.DEFAULT_DISPLAY && !ShadeWindowGoesAround.isEnabled) return;
+ listeners.forEach { listener ->
+ listener.onSystemUiStateChanged(sysUiFlags = sysUiFlags, displayId = displayId)
+ }
+ }
+
+ /**
+ * Registers a listener to listen for system UI state changes.
+ *
+ * Listeners will have [SysUiState.SysUiStateCallback.onSystemUiStateChanged] called whenever a
+ * system UI state changes.
+ */
+ fun registerListener(listener: SysUiState.SysUiStateCallback) {
+ listeners += listener
+ }
+
+ fun unregisterListener(listener: SysUiState.SysUiStateCallback) {
+ listeners -= listener
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/model/SysUiState.kt b/packages/SystemUI/src/com/android/systemui/model/SysUiState.kt
index ed190a14e680..53105b2c0f6a 100644
--- a/packages/SystemUI/src/com/android/systemui/model/SysUiState.kt
+++ b/packages/SystemUI/src/com/android/systemui/model/SysUiState.kt
@@ -18,62 +18,115 @@ package com.android.systemui.model
import android.util.Log
import com.android.systemui.Dumpable
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.settings.DisplayTracker
+import com.android.systemui.display.data.repository.PerDisplayInstanceProviderWithTeardown
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.model.SysUiState.SysUiStateCallback
import com.android.systemui.shared.system.QuickStepContract
import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
import dalvik.annotation.optimization.NeverCompile
import java.io.PrintWriter
+import javax.inject.Inject
/** Contains sysUi state flags and notifies registered listeners whenever changes happen. */
-@SysUISingleton
-class SysUiState(
- private val displayTracker: DisplayTracker,
+interface SysUiState : Dumpable {
+ /**
+ * Add listener to be notified of changes made to SysUI state.
+ *
+ * The callback will also be called as part of this function.
+ */
+ fun addCallback(callback: SysUiStateCallback)
+
+ /** Removes a callback for state changes. */
+ fun removeCallback(callback: SysUiStateCallback)
+
+ /** Returns whether a flag is enabled in this state. */
+ fun isFlagEnabled(@SystemUiStateFlags flag: Long): Boolean {
+ return (flags and flag) != 0L
+ }
+
+ /** Returns the current sysui state flags. */
+ val flags: Long
+
+ /** Methods to this call can be chained together before calling [commitUpdate]. */
+ fun setFlag(@SystemUiStateFlags flag: Long, enabled: Boolean): SysUiState
+
+ /** Call to save all the flags updated from [setFlag]. */
+ @Deprecated("Each SysUIState instance is now display specific. Just use commitUpdate()")
+ fun commitUpdate(displayId: Int)
+
+ /** Call to save all the flags updated from [setFlag]. */
+ fun commitUpdate()
+
+ /** Callback to be notified whenever system UI state flags are changed. */
+ fun interface SysUiStateCallback {
+
+ /** To be called when any SysUiStateFlag gets updated for a specific [displayId]. */
+ fun onSystemUiStateChanged(@SystemUiStateFlags sysUiFlags: Long, displayId: Int)
+ }
+
+ /**
+ * Destroys an instance. It shouldn't be used anymore afterwards.
+ *
+ * This is mainly used to clean up instances associated with displays that are removed.
+ */
+ fun destroy()
+
+ companion object {
+ const val DEBUG: Boolean = false
+ }
+}
+
+private const val TAG = "SysUIState"
+
+class SysUiStateImpl
+@AssistedInject
+constructor(
+ @Assisted private val displayId: Int,
private val sceneContainerPlugin: SceneContainerPlugin?,
-) : Dumpable {
+ private val dumpManager: DumpManager,
+ private val stateDispatcher: SysUIStateDispatcher,
+) : SysUiState {
+
+ private val debugName = "SysUiStateImpl-ForDisplay=$displayId"
+
+ init {
+ dumpManager.registerNormalDumpable(debugName, this)
+ }
+
/** Returns the current sysui state flags. */
@get:SystemUiStateFlags
@SystemUiStateFlags
- var flags: Long = 0
- private set
+ override val flags: Long
+ get() = _flags
- private val callbacks: MutableList<SysUiStateCallback> = ArrayList()
+ private var _flags: Long = 0
private var flagsToSet: Long = 0
private var flagsToClear: Long = 0
/**
* Add listener to be notified of changes made to SysUI state. The callback will also be called
* as part of this function.
+ *
+ * Note that the listener would receive updates for all displays.
*/
- fun addCallback(callback: SysUiStateCallback) {
- callbacks.add(callback)
- callback.onSystemUiStateChanged(flags)
+ override fun addCallback(callback: SysUiStateCallback) {
+ stateDispatcher.registerListener(callback)
+ callback.onSystemUiStateChanged(flags, displayId)
}
/** Callback will no longer receive events on state change */
- fun removeCallback(callback: SysUiStateCallback) {
- callbacks.remove(callback)
- }
-
- fun isFlagEnabled(@SystemUiStateFlags flag: Long): Boolean {
- return (flags and flag) != 0L
+ override fun removeCallback(callback: SysUiStateCallback) {
+ stateDispatcher.unregisterListener(callback)
}
/** Methods to this call can be chained together before calling [.commitUpdate]. */
- fun setFlag(@SystemUiStateFlags flag: Long, enabled: Boolean): SysUiState {
- var enabled = enabled
- val overrideOrNull = sceneContainerPlugin?.flagValueOverride(flag)
- if (overrideOrNull != null && enabled != overrideOrNull) {
- if (DEBUG) {
- Log.d(
- TAG,
- "setFlag for flag $flag and value $enabled overridden to $overrideOrNull by scene container plugin",
- )
- }
-
- enabled = overrideOrNull
- }
+ override fun setFlag(@SystemUiStateFlags flag: Long, enabled: Boolean): SysUiState {
+ val toSet = flagWithOptionalOverrides(flag, enabled, displayId, sceneContainerPlugin)
- if (enabled) {
+ if (toSet) {
flagsToSet = flagsToSet or flag
} else {
flagsToClear = flagsToClear or flag
@@ -81,20 +134,22 @@ class SysUiState(
return this
}
- /** Call to save all the flags updated from [.setFlag]. */
- fun commitUpdate(displayId: Int) {
- updateFlags(displayId)
+ @Deprecated(
+ "Each SysUIState instance is now display specific. Just use commitUpdate.",
+ ReplaceWith("commitUpdate()"),
+ )
+ override fun commitUpdate(displayId: Int) {
+ // TODO b/398011576 - handle updates for different displays.
+ commitUpdate()
+ }
+
+ override fun commitUpdate() {
+ updateFlags()
flagsToSet = 0
flagsToClear = 0
}
- private fun updateFlags(displayId: Int) {
- if (displayId != displayTracker.defaultDisplayId) {
- // Ignore non-default displays for now
- Log.w(TAG, "Ignoring flag update for display: $displayId", Throwable())
- return
- }
-
+ private fun updateFlags() {
var newState = flags
newState = newState or flagsToSet
newState = newState and flagsToClear.inv()
@@ -103,15 +158,12 @@ class SysUiState(
/** Notify all those who are registered that the state has changed. */
private fun notifyAndSetSystemUiStateChanged(newFlags: Long, oldFlags: Long) {
- if (DEBUG) {
+ if (SysUiState.DEBUG) {
Log.d(TAG, "SysUiState changed: old=$oldFlags new=$newFlags")
}
if (newFlags != oldFlags) {
- callbacks.forEach { callback: SysUiStateCallback ->
- callback.onSystemUiStateChanged(newFlags)
- }
-
- flags = newFlags
+ _flags = newFlags
+ stateDispatcher.dispatchSysUIStateChange(newFlags, displayId)
}
}
@@ -127,14 +179,53 @@ class SysUiState(
pw.println(QuickStepContract.isAssistantGestureDisabled(flags))
}
- /** Callback to be notified whenever system UI state flags are changed. */
- interface SysUiStateCallback {
- /** To be called when any SysUiStateFlag gets updated */
- fun onSystemUiStateChanged(@SystemUiStateFlags sysUiFlags: Long)
+ override fun destroy() {
+ dumpManager.unregisterDumpable(debugName)
+ }
+
+ @AssistedFactory
+ interface Factory {
+ /** Creates a new instance of [SysUiStateImpl] for a given [displayId]. */
+ fun create(displayId: Int): SysUiStateImpl
}
companion object {
private val TAG: String = SysUiState::class.java.simpleName
- const val DEBUG: Boolean = false
+ }
+}
+
+/** Returns the flag value taking into account [SceneContainerPlugin] potential overrides. */
+fun flagWithOptionalOverrides(
+ flag: Long,
+ enabled: Boolean,
+ displayId: Int,
+ sceneContainerPlugin: SceneContainerPlugin?,
+): Boolean {
+ var toSet = enabled
+ val overrideOrNull = sceneContainerPlugin?.flagValueOverride(flag = flag, displayId = displayId)
+ if (overrideOrNull != null && toSet != overrideOrNull) {
+ if (SysUiState.DEBUG) {
+ Log.d(
+ TAG,
+ "setFlag for flag $flag and value $toSet overridden to " +
+ "$overrideOrNull by scene container plugin",
+ )
+ }
+
+ toSet = overrideOrNull
+ }
+ return toSet
+}
+
+/** Creates and destroy instances of [SysUiState] */
+@SysUISingleton
+class SysUIStateInstanceProvider @Inject constructor(private val factory: SysUiStateImpl.Factory) :
+ PerDisplayInstanceProviderWithTeardown<SysUiState> {
+ override fun createInstance(displayId: Int): SysUiState {
+ return factory.create(displayId)
+ }
+
+ override fun destroyInstance(instance: SysUiState) {
+ instance.destroy()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/modes/shared/ModesUi.kt b/packages/SystemUI/src/com/android/systemui/modes/shared/ModesUi.kt
index e293e202633e..a344a5cce6ba 100644
--- a/packages/SystemUI/src/com/android/systemui/modes/shared/ModesUi.kt
+++ b/packages/SystemUI/src/com/android/systemui/modes/shared/ModesUi.kt
@@ -42,7 +42,7 @@ object ModesUi {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, Flags.FLAG_MODES_UI)
+ inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, Flags.FLAG_MODES_UI)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/modes/shared/ModesUiIcons.kt b/packages/SystemUI/src/com/android/systemui/modes/shared/ModesUiIcons.kt
index 032b0aca1770..44a3d77a6818 100644
--- a/packages/SystemUI/src/com/android/systemui/modes/shared/ModesUiIcons.kt
+++ b/packages/SystemUI/src/com/android/systemui/modes/shared/ModesUiIcons.kt
@@ -42,8 +42,8 @@ object ModesUiIcons {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun assertInNewMode() =
- RefactorFlagUtils.assertInNewMode(isEnabled, Flags.FLAG_MODES_UI_ICONS)
+ inline fun unsafeAssertInNewMode() =
+ RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, Flags.FLAG_MODES_UI_ICONS)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index f44c2c01951c..7af538105cae 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -355,11 +355,12 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
private final SysUiState.SysUiStateCallback mSysUiStateCallback =
new SysUiState.SysUiStateCallback() {
- @Override
- public void onSystemUiStateChanged(@SystemUiStateFlags long sysUiFlags) {
- mSysUiFlags = sysUiFlags;
- }
- };
+ @Override
+ public void onSystemUiStateChanged(@SystemUiStateFlags long sysUiFlags,
+ int displayId) {
+ mSysUiFlags = sysUiFlags;
+ }
+ };
private final Consumer<Boolean> mOnIsInPipStateChangedListener =
(isInPip) -> mIsInPip = isInPip;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index fa987ddbe266..9fc1b7aea687 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -255,7 +255,7 @@ public class QSContainerImpl extends FrameLayout implements Dumpable {
* @return size in pixels of QQS
*/
public int getQqsHeight() {
- SceneContainerFlag.assertInNewMode();
+ SceneContainerFlag.unsafeAssertInNewMode();
return mHeader.getMeasuredHeight();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/flags/QsDetailedView.kt b/packages/SystemUI/src/com/android/systemui/qs/flags/QsDetailedView.kt
index 3afaef5ea6a1..2eba36a25ae7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/flags/QsDetailedView.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/flags/QsDetailedView.kt
@@ -81,7 +81,7 @@ object QsDetailedView {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME)
+ inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/** Returns a developer-readable string that describes the current requirement list. */
@JvmStatic
diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsButtonViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsButtonViewModel.kt
index 2670787909b4..c45fa973f973 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsButtonViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsButtonViewModel.kt
@@ -18,6 +18,7 @@ package com.android.systemui.qs.footer.ui.viewmodel
import android.annotation.AttrRes
import android.annotation.ColorInt
+import androidx.compose.runtime.Stable
import com.android.systemui.animation.Expandable
import com.android.systemui.common.shared.model.Icon
@@ -25,6 +26,7 @@ import com.android.systemui.common.shared.model.Icon
* A ViewModel for a simple footer actions button. This is used for the user switcher, settings and
* power buttons.
*/
+@Stable
data class FooterActionsButtonViewModel(
val id: Int,
val icon: Icon,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
index 9546e355dca2..aea280cc9f91 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
@@ -75,6 +75,7 @@ class FooterActionsViewModel(
/** The model for the power button. */
val power: Flow<FooterActionsButtonViewModel?>,
+ val initialPower: () -> FooterActionsButtonViewModel?,
/**
* Observe the device monitoring dialog requests and show the dialog accordingly. This function
@@ -181,7 +182,7 @@ class FooterActionsViewModel(
fun createFooterActionsViewModel(
@ShadeDisplayAware appContext: Context,
footerActionsInteractor: FooterActionsInteractor,
- shadeMode: Flow<ShadeMode>,
+ shadeMode: StateFlow<ShadeMode>,
falsingManager: FalsingManager,
globalActionsDialogLite: GlobalActionsDialogLite,
activityStarter: ActivityStarter,
@@ -291,6 +292,12 @@ fun createFooterActionsViewModel(
settings = settings,
power = power,
observeDeviceMonitoringDialogRequests = ::observeDeviceMonitoringDialogRequests,
+ initialPower =
+ if (showPowerButton) {
+ { powerButtonViewModel(qsThemedContext, ::onPowerButtonClicked, shadeMode.value) }
+ } else {
+ { null }
+ },
)
}
@@ -411,20 +418,28 @@ fun powerButtonViewModel(
shadeMode: Flow<ShadeMode>,
): Flow<FooterActionsButtonViewModel?> {
return shadeMode.map { mode ->
- val isDualShade = mode is ShadeMode.Dual
- FooterActionsButtonViewModel(
- id = R.id.pm_lite,
- Icon.Resource(
- android.R.drawable.ic_lock_power_off,
- ContentDescription.Resource(R.string.accessibility_quick_settings_power_menu),
- ),
- iconTint =
- Utils.getColorAttrDefaultColor(
- qsThemedContext,
- if (isDualShade) R.attr.onShadeInactiveVariant else R.attr.onShadeActive,
- ),
- backgroundColor = if (isDualShade) R.attr.shadeInactive else R.attr.shadeActive,
- onPowerButtonClicked,
- )
+ powerButtonViewModel(qsThemedContext, onPowerButtonClicked, mode)
}
}
+
+fun powerButtonViewModel(
+ qsThemedContext: Context,
+ onPowerButtonClicked: (Expandable) -> Unit,
+ shadeMode: ShadeMode,
+): FooterActionsButtonViewModel {
+ val isDualShade = shadeMode is ShadeMode.Dual
+ return FooterActionsButtonViewModel(
+ id = R.id.pm_lite,
+ Icon.Resource(
+ android.R.drawable.ic_lock_power_off,
+ ContentDescription.Resource(R.string.accessibility_quick_settings_power_menu),
+ ),
+ iconTint =
+ Utils.getColorAttrDefaultColor(
+ qsThemedContext,
+ if (isDualShade) R.attr.onShadeInactiveVariant else R.attr.onShadeActive,
+ ),
+ backgroundColor = if (isDualShade) R.attr.shadeInactive else R.attr.shadeActive,
+ onPowerButtonClicked,
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
index ddadb8879f07..6e6c0b61d85b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
@@ -22,6 +22,7 @@ import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.animateDpAsState
+import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
@@ -78,6 +79,7 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
+import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
@@ -140,6 +142,7 @@ import com.android.systemui.qs.panels.ui.compose.selection.TileState
import com.android.systemui.qs.panels.ui.compose.selection.rememberResizingState
import com.android.systemui.qs.panels.ui.compose.selection.rememberSelectionState
import com.android.systemui.qs.panels.ui.compose.selection.selectableTile
+import com.android.systemui.qs.panels.ui.model.AvailableTileGridCell
import com.android.systemui.qs.panels.ui.model.GridCell
import com.android.systemui.qs.panels.ui.model.SpacerGridCell
import com.android.systemui.qs.panels.ui.model.TileGridCell
@@ -290,8 +293,19 @@ fun DefaultEditTileGrid(
Text(text = stringResource(id = R.string.drag_to_add_tiles))
}
+ val availableTiles = remember {
+ mutableStateListOf<AvailableTileGridCell>().apply {
+ addAll(toAvailableTiles(listState.tiles, otherTiles))
+ }
+ }
+ LaunchedEffect(listState.tiles, otherTiles) {
+ availableTiles.apply {
+ clear()
+ addAll(toAvailableTiles(listState.tiles, otherTiles))
+ }
+ }
AvailableTileGrid(
- otherTiles,
+ availableTiles,
selectionState,
columns,
onAddTile,
@@ -444,7 +458,7 @@ private fun CurrentTilesGrid(
@Composable
private fun AvailableTileGrid(
- tiles: List<SizedTile<EditTileViewModel>>,
+ tiles: List<AvailableTileGridCell>,
selectionState: MutableSelectionState,
columns: Int,
onAddTile: (TileSpec) -> Unit,
@@ -453,7 +467,7 @@ private fun AvailableTileGrid(
// Available tiles aren't visible during drag and drop, so the row/col isn't needed
val groupedTiles =
remember(tiles.fastMap { it.tile.category }, tiles.fastMap { it.tile.label }) {
- groupAndSort(tiles.fastMap { TileGridCell(it, 0, 0) })
+ groupAndSort(tiles)
}
val labelColors = EditModeTileDefaults.editTileColors()
@@ -478,11 +492,10 @@ private fun AvailableTileGrid(
horizontalArrangement = spacedBy(TileArrangementPadding),
modifier = Modifier.fillMaxWidth().height(IntrinsicSize.Max),
) {
- row.forEachIndexed { index, tileGridCell ->
- key(tileGridCell.tile.tileSpec) {
+ row.forEach { tileGridCell ->
+ key(tileGridCell.key) {
AvailableTileGridCell(
cell = tileGridCell,
- index = index,
dragAndDropState = dragAndDropState,
selectionState = selectionState,
onAddTile = onAddTile,
@@ -505,10 +518,7 @@ fun gridHeight(rows: Int, tileHeight: Dp, tilePadding: Dp, gridPadding: Dp): Dp
}
private fun GridCell.key(index: Int): Any {
- return when (this) {
- is TileGridCell -> key
- is SpacerGridCell -> index
- }
+ return if (this is TileGridCell) key else index
}
/**
@@ -687,41 +697,44 @@ private fun TileGridCell(
@Composable
private fun AvailableTileGridCell(
- cell: TileGridCell,
- index: Int,
+ cell: AvailableTileGridCell,
dragAndDropState: DragAndDropState,
selectionState: MutableSelectionState,
onAddTile: (TileSpec) -> Unit,
modifier: Modifier = Modifier,
) {
- val onClickActionName = stringResource(id = R.string.accessibility_qs_edit_tile_add_action)
- val stateDescription = stringResource(id = R.string.accessibility_qs_edit_position, index + 1)
+ val stateDescription: String? =
+ if (cell.isAvailable) null
+ else stringResource(R.string.accessibility_qs_edit_tile_already_added)
+
+ val alpha by animateFloatAsState(if (cell.isAvailable) 1f else .38f)
val colors = EditModeTileDefaults.editTileColors()
- val onClick = {
- onAddTile(cell.tile.tileSpec)
- selectionState.select(cell.tile.tileSpec)
- }
// Displays the tile as an icon tile with the label underneath
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = spacedBy(CommonTileDefaults.TilePadding, Alignment.Top),
- modifier = modifier,
+ modifier =
+ modifier
+ .graphicsLayer { this.alpha = alpha }
+ .semantics(mergeDescendants = true) {
+ stateDescription?.let { this.stateDescription = it }
+ },
) {
Box(Modifier.fillMaxWidth().height(TileHeight)) {
- Box(
- Modifier.fillMaxSize()
- .clickable(onClick = onClick, onClickLabel = onClickActionName)
- .semantics(mergeDescendants = true) { this.stateDescription = stateDescription }
- .dragAndDropTileSource(
+ val draggableModifier =
+ if (cell.isAvailable) {
+ Modifier.dragAndDropTileSource(
SizedTileImpl(cell.tile, cell.width),
dragAndDropState,
DragType.Add,
) {
selectionState.unSelect()
}
- .tileBackground(colors.background)
- ) {
+ } else {
+ Modifier
+ }
+ Box(draggableModifier.fillMaxSize().tileBackground(colors.background)) {
// Icon
SmallTileContent(
iconProvider = { cell.tile.icon },
@@ -733,9 +746,13 @@ private fun AvailableTileGridCell(
StaticTileBadge(
icon = Icons.Default.Add,
- contentDescription = onClickActionName,
- onClick = onClick,
- )
+ contentDescription =
+ stringResource(id = R.string.accessibility_qs_edit_tile_add_action),
+ enabled = cell.isAvailable,
+ ) {
+ onAddTile(cell.tile.tileSpec)
+ selectionState.select(cell.tile.tileSpec)
+ }
}
Box(Modifier.fillMaxSize()) {
Text(
@@ -819,6 +836,15 @@ fun EditTile(
}
}
+private fun toAvailableTiles(
+ currentTiles: List<GridCell>,
+ otherTiles: List<SizedTile<EditTileViewModel>>,
+): List<AvailableTileGridCell> {
+ return currentTiles.filterIsInstance<TileGridCell>().fastMap {
+ AvailableTileGridCell(it.tile, isAvailable = false)
+ } + otherTiles.fastMap { AvailableTileGridCell(it.tile) }
+}
+
private fun MeasureScope.iconHorizontalCenter(containerSize: Int): Float {
return (containerSize - ToggleTargetSize.roundToPx()) / 2f -
CommonTileDefaults.TilePadding.toPx()
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/Selection.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/Selection.kt
index 699e5f6b77e9..153238fc91c9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/Selection.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/Selection.kt
@@ -19,6 +19,7 @@ package com.android.systemui.qs.panels.ui.compose.selection
import androidx.compose.animation.animateColor
import androidx.compose.animation.core.Transition
import androidx.compose.animation.core.animateFloat
+import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.animateOffset
import androidx.compose.animation.core.animateSize
import androidx.compose.animation.core.updateTransition
@@ -61,6 +62,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.toSize
import androidx.compose.ui.zIndex
import com.android.compose.modifiers.size
+import com.android.compose.modifiers.thenIf
import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.InactiveCornerRadius
import com.android.systemui.qs.panels.ui.compose.selection.SelectionDefaults.BADGE_ANGLE_RAD
import com.android.systemui.qs.panels.ui.compose.selection.SelectionDefaults.BadgeSize
@@ -184,18 +186,37 @@ private fun Modifier.selectionBorder(
}
}
+/**
+ * Draws a clickable badge in the top end corner of the parent composable.
+ *
+ * The badge will fade in and fade out based on whether or not it's enabled.
+ *
+ * @param icon the [ImageVector] to display in the badge
+ * @param contentDescription the content description for the icon
+ * @param enabled Whether the badge should be visible and clickable
+ * @param onClick the callback when the badge is clicked
+ */
@Composable
-fun StaticTileBadge(icon: ImageVector, contentDescription: String?, onClick: () -> Unit) {
+fun StaticTileBadge(
+ icon: ImageVector,
+ contentDescription: String?,
+ enabled: Boolean,
+ onClick: () -> Unit,
+) {
val offset = with(LocalDensity.current) { Offset(BadgeXOffset.toPx(), BadgeYOffset.toPx()) }
+ val alpha by animateFloatAsState(if (enabled) 1f else 0f)
MinimumInteractiveSizeComponent(angle = { BADGE_ANGLE_RAD }, offset = { offset }) {
Box(
Modifier.fillMaxSize()
- .clickable(
- interactionSource = null,
- indication = null,
- onClickLabel = contentDescription,
- onClick = onClick,
- )
+ .graphicsLayer { this.alpha = alpha }
+ .thenIf(enabled) {
+ Modifier.clickable(
+ interactionSource = null,
+ indication = null,
+ onClickLabel = contentDescription,
+ onClick = onClick,
+ )
+ }
) {
val secondaryColor = MaterialTheme.colorScheme.secondary
Icon(
@@ -214,7 +235,8 @@ fun StaticTileBadge(icon: ImageVector, contentDescription: String?, onClick: ()
private fun MinimumInteractiveSizeComponent(
angle: () -> Float,
offset: () -> Offset,
- content: @Composable BoxScope.() -> Unit,
+ modifier: Modifier = Modifier,
+ content: @Composable BoxScope.() -> Unit = {},
) {
// Use a higher zIndex than the tile to draw over it, and manually create the touch target
// as we're drawing over neighbor tiles as well.
@@ -222,7 +244,8 @@ private fun MinimumInteractiveSizeComponent(
Box(
contentAlignment = Alignment.Center,
modifier =
- Modifier.zIndex(2f)
+ modifier
+ .zIndex(2f)
.systemGestureExclusion { Rect(Offset.Zero, it.size.toSize()) }
.layout { measurable, constraints ->
val size = minTouchTargetSize.roundToPx()
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/toolbar/Toolbar.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/toolbar/Toolbar.kt
index 360266a31be3..99f52c28a137 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/toolbar/Toolbar.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/toolbar/Toolbar.kt
@@ -46,8 +46,10 @@ fun Toolbar(viewModel: ToolbarViewModel, modifier: Modifier = Modifier) {
Spacer(modifier = Modifier.weight(1f))
- viewModel.powerButtonViewModel?.let {
- IconButton(it, useModifierBasedExpandable = true, Modifier.sysuiResTag("pm_lite"))
- }
+ IconButton(
+ { viewModel.powerButtonViewModel },
+ useModifierBasedExpandable = true,
+ Modifier.sysuiResTag("pm_lite"),
+ )
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/model/TileGridCell.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/model/TileGridCell.kt
index c0441f8a38a1..78fd8c0168dd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/model/TileGridCell.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/model/TileGridCell.kt
@@ -21,13 +21,13 @@ import androidx.compose.runtime.Immutable
import com.android.systemui.qs.panels.shared.model.SizedTile
import com.android.systemui.qs.panels.shared.model.splitInRowsSequence
import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
+import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.qs.shared.model.CategoryAndName
/** Represents an item from a grid associated with a row and a span */
sealed interface GridCell {
val row: Int
val span: GridItemSpan
- val s: String
}
/**
@@ -40,7 +40,6 @@ data class TileGridCell(
override val row: Int,
override val width: Int,
override val span: GridItemSpan = GridItemSpan(width),
- override val s: String = "${tile.tileSpec.spec}-$row-$width",
val column: Int,
) : GridCell, SizedTile<EditTileViewModel>, CategoryAndName by tile {
val key: String = "${tile.tileSpec.spec}-$row"
@@ -52,12 +51,23 @@ data class TileGridCell(
) : this(tile = sizedTile.tile, row = row, column = column, width = sizedTile.width)
}
+/**
+ * Represents a [EditTileViewModel] from the edit mode available tiles grid and whether it is
+ * available to add or not.
+ */
+@Immutable
+data class AvailableTileGridCell(
+ override val tile: EditTileViewModel,
+ override val width: Int = 1,
+ val isAvailable: Boolean = true,
+ val key: TileSpec = tile.tileSpec,
+) : SizedTile<EditTileViewModel>, CategoryAndName by tile
+
/** Represents an empty space used to fill incomplete rows. Will always display as a 1x1 tile */
@Immutable
data class SpacerGridCell(
override val row: Int,
override val span: GridItemSpan = GridItemSpan(1),
- override val s: String = "spacer",
) : GridCell
/**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/QSPipelineFlagsRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/QSPipelineFlagsRepository.kt
index 5dc8d1bd4643..26148deb735e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/QSPipelineFlagsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/QSPipelineFlagsRepository.kt
@@ -14,7 +14,7 @@ class QSPipelineFlagsRepository @Inject constructor() {
companion object Utils {
fun assertNewTiles() =
- RefactorFlagUtils.assertInNewMode(
+ RefactorFlagUtils.unsafeAssertInNewMode(
AconfigFlags.qsNewTiles(),
AconfigFlags.FLAG_QS_NEW_TILES
)
diff --git a/packages/SystemUI/src/com/android/systemui/recents/LauncherProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/LauncherProxyService.java
index 9af4630bf492..7a6426c741a6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/LauncherProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/LauncherProxyService.java
@@ -66,6 +66,7 @@ import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
+import android.view.Display;
import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
@@ -94,6 +95,7 @@ import com.android.systemui.keyguard.KeyguardWmStateRefactor;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.keyguard.ui.view.InWindowLauncherUnlockAnimationManager;
import com.android.systemui.model.SysUiState;
+import com.android.systemui.model.SysUiState.SysUiStateCallback;
import com.android.systemui.navigationbar.NavigationBarController;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.navigationbar.views.NavigationBar;
@@ -584,7 +586,8 @@ public class LauncherProxyService implements CallbackController<LauncherProxyLis
// Force-update the systemui state flags
updateSystemUiStateFlags();
- notifySystemUiStateFlags(mSysUiState.getFlags());
+ // TODO b/398011576 - send the state for all displays.
+ notifySystemUiStateFlags(mSysUiState.getFlags(), Display.DEFAULT_DISPLAY);
notifyConnectionChanged();
}
@@ -650,6 +653,13 @@ public class LauncherProxyService implements CallbackController<LauncherProxyLis
}
};
+ private final SysUiStateCallback mSysUiStateCallback =
+ new SysUiStateCallback() {
+ @Override
+ public void onSystemUiStateChanged(long sysUiFlags, int displayId) {
+ notifySystemUiStateFlags(sysUiFlags, displayId);
+ }
+ };
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
@Inject
public LauncherProxyService(Context context,
@@ -708,8 +718,10 @@ public class LauncherProxyService implements CallbackController<LauncherProxyLis
com.android.internal.R.string.config_recentsComponentName));
mQuickStepIntent = new Intent(ACTION_QUICKSTEP)
.setPackage(mRecentsComponentName.getPackageName());
+ // TODO b/398011576 - Here we're still only handling the default display state. We should
+ // have a callback for any sysuiState change.
mSysUiState = sysUiState;
- mSysUiState.addCallback(this::notifySystemUiStateFlags);
+ mSysUiState.addCallback(mSysUiStateCallback);
mUiEventLogger = uiEventLogger;
mDisplayTracker = displayTracker;
mUnfoldTransitionProgressForwarder = unfoldTransitionProgressForwarder;
@@ -815,14 +827,14 @@ public class LauncherProxyService implements CallbackController<LauncherProxyLis
}
}
- private void notifySystemUiStateFlags(@SystemUiStateFlags long flags) {
+ private void notifySystemUiStateFlags(@SystemUiStateFlags long flags, int displayId) {
if (SysUiState.DEBUG) {
Log.d(TAG_OPS, "Notifying sysui state change to launcher service: proxy="
- + mLauncherProxy + " flags=" + flags);
+ + mLauncherProxy + " flags=" + flags + " displayId=" + displayId);
}
try {
if (mLauncherProxy != null) {
- mLauncherProxy.onSystemUiStateChanged(flags);
+ mLauncherProxy.onSystemUiStateChanged(flags, displayId);
}
} catch (RemoteException e) {
Log.e(TAG_OPS, "Failed to notify sysui state change", e);
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/KeyguardStateCallbackStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/KeyguardStateCallbackStartable.kt
index 4044381e25e7..ecd93b2a4946 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/KeyguardStateCallbackStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/KeyguardStateCallbackStartable.kt
@@ -69,7 +69,7 @@ constructor(
}
fun addCallback(callback: IKeyguardStateCallback) {
- SceneContainerFlag.assertInNewMode()
+ SceneContainerFlag.unsafeAssertInNewMode()
callbacks.add(callback)
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt
index 733b4210950f..b0fb6193ee45 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt
@@ -83,7 +83,7 @@ object SceneContainerFlag {
* testing.
*/
@JvmStatic
- inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, DESCRIPTION)
+ inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, DESCRIPTION)
/** Returns a developer-readable string that describes the current requirement list. */
@JvmStatic
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt
index 0dd0e3dd87c6..1d470c2143da 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt
@@ -33,6 +33,7 @@ class SceneWindowRootView(context: Context, attrs: AttributeSet?) : WindowRootVi
sceneDataSourceDelegator: SceneDataSourceDelegator,
qsSceneAdapter: Provider<QSSceneAdapter>,
sceneJankMonitorFactory: SceneJankMonitor.Factory,
+ windowRootViewKeyEventHandler: WindowRootViewKeyEventHandler,
) {
setLayoutInsetsController(layoutInsetController)
SceneWindowRootViewBinder.bind(
@@ -53,6 +54,7 @@ class SceneWindowRootView(context: Context, attrs: AttributeSet?) : WindowRootVi
qsSceneAdapter = qsSceneAdapter,
sceneJankMonitorFactory = sceneJankMonitorFactory,
)
+ setWindowRootViewKeyEventHandler(windowRootViewKeyEventHandler)
}
override fun setVisibility(visibility: Int) {
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 364da5f8e80d..42bf75337270 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
@@ -21,6 +21,7 @@ import android.content.Context
import android.util.AttributeSet
import android.util.Pair
import android.view.DisplayCutout
+import android.view.KeyEvent
import android.view.View
import android.view.WindowInsets
import android.widget.FrameLayout
@@ -37,6 +38,11 @@ open class WindowRootView(context: Context, attrs: AttributeSet?) : FrameLayout(
private var rightInset = 0
private var previousInsets: WindowInsets? = null
+ private lateinit var windowRootViewKeyEventHandler: WindowRootViewKeyEventHandler
+
+ fun setWindowRootViewKeyEventHandler(wrvkeh: WindowRootViewKeyEventHandler) {
+ windowRootViewKeyEventHandler = wrvkeh
+ }
override fun onAttachedToWindow() {
super.onAttachedToWindow()
@@ -137,6 +143,24 @@ open class WindowRootView(context: Context, attrs: AttributeSet?) : FrameLayout(
return parent.let { it !is View || it.id == android.R.id.content }
}
+ override fun dispatchKeyEvent(event: KeyEvent): Boolean {
+ windowRootViewKeyEventHandler.collectKeyEvent(event)
+
+ if (windowRootViewKeyEventHandler.interceptMediaKey(event)) {
+ return true
+ }
+
+ if (super.dispatchKeyEvent(event)) {
+ return true
+ }
+
+ return windowRootViewKeyEventHandler.dispatchKeyEvent(event)
+ }
+
+ override fun dispatchKeyEventPreIme(event: KeyEvent): Boolean {
+ return windowRootViewKeyEventHandler.dispatchKeyEventPreIme(event) ?: false
+ }
+
/** Controller responsible for calculating insets for the shade window. */
interface LayoutInsetsController {
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootViewKeyEventHandler.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootViewKeyEventHandler.kt
new file mode 100644
index 000000000000..863af92a3b49
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootViewKeyEventHandler.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.scene.ui.view
+
+import android.view.KeyEvent
+import com.android.systemui.classifier.FalsingCollector
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyevent.domain.interactor.SysUIKeyEventHandler
+import dagger.Lazy
+import javax.inject.Inject
+
+@SysUISingleton
+class WindowRootViewKeyEventHandler
+@Inject
+constructor(
+ val sysUIKeyEventHandlerLazy: Lazy<SysUIKeyEventHandler>,
+ val falsingCollector: FalsingCollector,
+) {
+ fun dispatchKeyEvent(event: KeyEvent): Boolean {
+ return sysUIKeyEventHandlerLazy.get().dispatchKeyEvent(event)
+ }
+
+ fun dispatchKeyEventPreIme(event: KeyEvent): Boolean {
+ return sysUIKeyEventHandlerLazy.get().dispatchKeyEventPreIme(event)
+ }
+
+ fun interceptMediaKey(event: KeyEvent): Boolean {
+ return sysUIKeyEventHandlerLazy.get().interceptMediaKey(event)
+ }
+
+ /** Collects the KeyEvent without intercepting it. */
+ fun collectKeyEvent(event: KeyEvent) {
+ falsingCollector.onKeyEvent(event)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index eea04701a9a4..17fb50aa6890 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -65,6 +65,7 @@ import android.os.Trace;
import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.MathUtils;
+import android.view.Display;
import android.view.HapticFeedbackConstants;
import android.view.InputDevice;
import android.view.MotionEvent;
@@ -96,6 +97,7 @@ import com.android.systemui.Gefingerpoken;
import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
import com.android.systemui.classifier.Classifier;
import com.android.systemui.classifier.FalsingCollector;
+import com.android.systemui.common.domain.interactor.SysUIStateDisplaysInteractor;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.DisplayId;
import com.android.systemui.dagger.qualifiers.Main;
@@ -119,6 +121,7 @@ import com.android.systemui.keyguard.ui.viewmodel.KeyguardTouchHandlingViewModel
import com.android.systemui.media.controls.domain.pipeline.MediaDataManager;
import com.android.systemui.media.controls.ui.controller.KeyguardMediaController;
import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager;
+import com.android.systemui.model.StateChange;
import com.android.systemui.model.SysUiState;
import com.android.systemui.navigationbar.NavigationBarController;
import com.android.systemui.navigationbar.NavigationModeController;
@@ -450,7 +453,9 @@ public final class NotificationPanelViewController implements
private final MediaDataManager mMediaDataManager;
@PanelState
private int mCurrentPanelState = STATE_CLOSED;
+ @Deprecated // Use SysUIStateInteractor instead
private final SysUiState mSysUiState;
+ private final SysUIStateDisplaysInteractor mSysUIStateDisplaysInteractor;
private final NotificationShadeDepthController mDepthController;
private final NavigationBarController mNavigationBarController;
private final int mDisplayId;
@@ -607,6 +612,7 @@ public final class NotificationPanelViewController implements
ShadeRepository shadeRepository,
Optional<SysUIUnfoldComponent> unfoldComponent,
SysUiState sysUiState,
+ SysUIStateDisplaysInteractor sysUIStateDisplaysInteractor,
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
KeyguardIndicationController keyguardIndicationController,
NotificationListContainer notificationListContainer,
@@ -738,6 +744,7 @@ public final class NotificationPanelViewController implements
mMediaDataManager = mediaDataManager;
mTapAgainViewController = tapAgainViewController;
mSysUiState = sysUiState;
+ mSysUIStateDisplaysInteractor = sysUIStateDisplaysInteractor;
mKeyguardBypassController = bypassController;
mUpdateMonitor = keyguardUpdateMonitor;
mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
@@ -2253,7 +2260,7 @@ public final class NotificationPanelViewController implements
Log.i(TAG, "Ignoring status Bar long press on virtualized test device.");
return;
}
- ShadeExpandsOnStatusBarLongPress.assertInNewMode();
+ ShadeExpandsOnStatusBarLongPress.unsafeAssertInNewMode();
mStatusBarLongPressDowntime = event.getDownTime();
if (isTracking()) {
onTrackingStopped(true);
@@ -2701,13 +2708,41 @@ public final class NotificationPanelViewController implements
Log.d(TAG, "Updating panel sysui state flags: fullyExpanded="
+ isFullyExpanded() + " inQs=" + mQsController.getExpanded());
}
+ if (ShadeWindowGoesAround.isEnabled()) {
+ setPerDisplaySysUIStateFlags();
+ } else {
+ setDefaultDisplayFlags();
+ }
+ }
+
+ private int getShadeDisplayId() {
+ if (mView != null && mView.getDisplay() != null) return mView.getDisplay().getDisplayId();
+ return Display.DEFAULT_DISPLAY;
+ }
+
+ private void setPerDisplaySysUIStateFlags() {
+ mSysUIStateDisplaysInteractor.setFlagsExclusivelyToDisplay(
+ getShadeDisplayId(),
+ new StateChange()
+ .setFlag(SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE,
+ isPanelExpanded() && !isCollapsing())
+ .setFlag(SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED,
+ isFullyExpanded() && !mQsController.getExpanded())
+ .setFlag(SYSUI_STATE_QUICK_SETTINGS_EXPANDED,
+ isFullyExpanded() && mQsController.getExpanded())
+ );
+ }
+
+ @Deprecated
+ private void setDefaultDisplayFlags() {
mSysUiState
.setFlag(SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE,
isPanelExpanded() && !isCollapsing())
.setFlag(SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED,
isFullyExpanded() && !mQsController.getExpanded())
.setFlag(SYSUI_STATE_QUICK_SETTINGS_EXPANDED,
- isFullyExpanded() && mQsController.getExpanded()).commitUpdate(mDisplayId);
+ isFullyExpanded() && mQsController.getExpanded()).commitUpdate(
+ mDisplayId);
}
private void debugLog(String fmt, Object... args) {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
index 1721700d2aaf..84efdc274521 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
@@ -105,26 +105,6 @@ public class NotificationShadeWindowView extends WindowRootView {
}
}
- @Override
- public boolean dispatchKeyEvent(KeyEvent event) {
- mInteractionEventHandler.collectKeyEvent(event);
-
- if (mInteractionEventHandler.interceptMediaKey(event)) {
- return true;
- }
-
- if (super.dispatchKeyEvent(event)) {
- return true;
- }
-
- return mInteractionEventHandler.dispatchKeyEvent(event);
- }
-
- @Override
- public boolean dispatchKeyEventPreIme(KeyEvent event) {
- return mInteractionEventHandler.dispatchKeyEventPreIme(event);
- }
-
protected void setInteractionEventHandler(InteractionEventHandler listener) {
mInteractionEventHandler = listener;
}
@@ -363,17 +343,6 @@ public class NotificationShadeWindowView extends WindowRootView {
boolean handleTouchEvent(MotionEvent ev);
void didNotHandleTouchEvent(MotionEvent ev);
-
- boolean interceptMediaKey(KeyEvent event);
-
- boolean dispatchKeyEvent(KeyEvent event);
-
- boolean dispatchKeyEventPreIme(KeyEvent event);
-
- /**
- * Collects the KeyEvent without intercepting it
- */
- void collectKeyEvent(KeyEvent event);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index 10a9fd20ee5a..c74f6c3fd914 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -27,7 +27,6 @@ import android.app.StatusBarManager;
import android.util.Log;
import android.view.Choreographer;
import android.view.GestureDetector;
-import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
@@ -50,7 +49,6 @@ import com.android.systemui.dock.DockManager;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlagsClassic;
import com.android.systemui.flags.Flags;
-import com.android.systemui.keyevent.domain.interactor.SysUIKeyEventHandler;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.keyguard.shared.model.Edge;
@@ -60,6 +58,7 @@ import com.android.systemui.keyguard.shared.model.TransitionStep;
import com.android.systemui.qs.flags.QSComposeFragment;
import com.android.systemui.res.R;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
+import com.android.systemui.scene.ui.view.WindowRootViewKeyEventHandler;
import com.android.systemui.settings.brightness.domain.interactor.BrightnessMirrorShowingInteractor;
import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor;
import com.android.systemui.shade.domain.interactor.ShadeAnimationInteractor;
@@ -89,7 +88,6 @@ import com.android.systemui.window.ui.WindowRootViewBinder;
import com.android.systemui.window.ui.viewmodel.WindowRootViewModel;
import kotlinx.coroutines.CoroutineDispatcher;
-import kotlinx.coroutines.ExperimentalCoroutinesApi;
import kotlinx.coroutines.flow.Flow;
import java.io.PrintWriter;
@@ -117,8 +115,7 @@ public class NotificationShadeWindowViewController implements Dumpable {
private final AmbientState mAmbientState;
private final PulsingGestureListener mPulsingGestureListener;
private final NotificationInsetsController mNotificationInsetsController;
- private final FeatureFlagsClassic mFeatureFlagsClassic;
- private final SysUIKeyEventHandler mSysUIKeyEventHandler;
+ private final WindowRootViewKeyEventHandler mWindowRootViewKeyEventHandler;
private final PrimaryBouncerInteractor mPrimaryBouncerInteractor;
private final AlternateBouncerInteractor mAlternateBouncerInteractor;
private final QuickSettingsController mQuickSettingsController;
@@ -202,7 +199,7 @@ public class NotificationShadeWindowViewController implements Dumpable {
NotificationLaunchAnimationInteractor notificationLaunchAnimationInteractor,
FeatureFlagsClassic featureFlagsClassic,
SystemClock clock,
- SysUIKeyEventHandler sysUIKeyEventHandler,
+ WindowRootViewKeyEventHandler windowRootViewKeyEventHandler,
QuickSettingsController quickSettingsController,
PrimaryBouncerInteractor primaryBouncerInteractor,
AlternateBouncerInteractor alternateBouncerInteractor,
@@ -232,8 +229,7 @@ public class NotificationShadeWindowViewController implements Dumpable {
mNotificationInsetsController = notificationInsetsController;
mKeyguardTransitionInteractor = keyguardTransitionInteractor;
mGlanceableHubContainerController = glanceableHubContainerController;
- mFeatureFlagsClassic = featureFlagsClassic;
- mSysUIKeyEventHandler = sysUIKeyEventHandler;
+ mWindowRootViewKeyEventHandler = windowRootViewKeyEventHandler;
mPrimaryBouncerInteractor = primaryBouncerInteractor;
mAlternateBouncerInteractor = alternateBouncerInteractor;
mQuickSettingsController = quickSettingsController;
@@ -370,6 +366,7 @@ public class NotificationShadeWindowViewController implements Dumpable {
mPulsingWakeupGestureHandler = new GestureDetector(mView.getContext(),
mPulsingGestureListener);
mView.setLayoutInsetsController(mNotificationInsetsController);
+ mView.setWindowRootViewKeyEventHandler(mWindowRootViewKeyEventHandler);
mView.setInteractionEventHandler(new NotificationShadeWindowView.InteractionEventHandler() {
boolean mUseDragDownHelperForTouch = false;
boolean mLastInterceptWasDragDownHelper = false;
@@ -605,26 +602,6 @@ public class NotificationShadeWindowViewController implements Dumpable {
mService.setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
}
}
-
- @Override
- public boolean interceptMediaKey(KeyEvent event) {
- return mSysUIKeyEventHandler.interceptMediaKey(event);
- }
-
- @Override
- public boolean dispatchKeyEventPreIme(KeyEvent event) {
- return mSysUIKeyEventHandler.dispatchKeyEventPreIme(event);
- }
-
- @Override
- public boolean dispatchKeyEvent(KeyEvent event) {
- return mSysUIKeyEventHandler.dispatchKeyEvent(event);
- }
-
- @Override
- public void collectKeyEvent(KeyEvent event) {
- mFalsingCollector.onKeyEvent(event);
- }
});
mView.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java
index 42c63f9fcdb1..c671f7d9db14 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java
@@ -959,6 +959,7 @@ public class QuickSettingsControllerImpl implements QuickSettingsController, Dum
void setShadeExpansion(float expandedHeight, float expandedFraction) {
mShadeExpandedHeight = expandedHeight;
mShadeExpandedFraction = expandedFraction;
+ mMediaHierarchyManager.setShadeExpandedFraction(expandedFraction);
}
@VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeExpandsOnStatusBarLongPress.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeExpandsOnStatusBarLongPress.kt
index 6d8e8986443e..79e63330e3a5 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeExpandsOnStatusBarLongPress.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeExpandsOnStatusBarLongPress.kt
@@ -50,7 +50,7 @@ object ShadeExpandsOnStatusBarLongPress {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME)
+ inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt
index 55ee27d1027c..150ef3afdd82 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt
@@ -42,6 +42,7 @@ import com.android.systemui.scene.ui.composable.Scene
import com.android.systemui.scene.ui.view.SceneJankMonitor
import com.android.systemui.scene.ui.view.SceneWindowRootView
import com.android.systemui.scene.ui.view.WindowRootView
+import com.android.systemui.scene.ui.view.WindowRootViewKeyEventHandler
import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.LightRevealScrim
@@ -88,6 +89,7 @@ abstract class ShadeViewProviderModule {
sceneDataSourceDelegator: Provider<SceneDataSourceDelegator>,
qsSceneAdapter: Provider<QSSceneAdapter>,
sceneJankMonitorFactory: SceneJankMonitor.Factory,
+ windowRootViewKeyEventHandler: WindowRootViewKeyEventHandler,
): WindowRootView {
return if (SceneContainerFlag.isEnabled) {
checkNoSceneDuplicates(scenesProvider.get())
@@ -104,6 +106,7 @@ abstract class ShadeViewProviderModule {
sceneDataSourceDelegator = sceneDataSourceDelegator.get(),
qsSceneAdapter = qsSceneAdapter,
sceneJankMonitorFactory = sceneJankMonitorFactory,
+ windowRootViewKeyEventHandler = windowRootViewKeyEventHandler,
)
sceneWindowRootView
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDialogContextInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDialogContextInteractor.kt
index 4edba2785e89..3b9870881c60 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDialogContextInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDialogContextInteractor.kt
@@ -47,14 +47,16 @@ class ShadeDialogContextInteractorImpl
constructor(
@Main private val defaultContext: Context,
private val displayWindowPropertyRepository: Provider<DisplayWindowPropertiesRepository>,
- private val shadeDisplaysRepository: ShadeDisplaysRepository,
+ private val shadeDisplaysRepository: Provider<ShadeDisplaysRepository>,
@Background private val bgScope: CoroutineScope,
) : CoreStartable, ShadeDialogContextInteractor {
override fun start() {
if (ShadeWindowGoesAround.isUnexpectedlyInLegacyMode()) return
bgScope.launchTraced(TAG) {
- shadeDisplaysRepository.displayId
+ shadeDisplaysRepository
+ .get()
+ .displayId
// No need for default display pre-warming.
.filter { it != Display.DEFAULT_DISPLAY }
.collectLatest { displayId ->
@@ -70,7 +72,7 @@ constructor(
if (!ShadeWindowGoesAround.isEnabled) {
return defaultContext
}
- val displayId = shadeDisplaysRepository.displayId.value
+ val displayId = shadeDisplaysRepository.get().displayId.value
return getContextOrDefault(displayId)
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt
index 9a5c96824e77..930b1cb1905c 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt
@@ -108,7 +108,8 @@ constructor(
val currentDisplay = shadeContext.display ?: error("Current shade display is null")
currentId = currentDisplay.displayId
if (currentId == destinationId) {
- error("Trying to move the shade to a display it was already in")
+ Log.w(TAG, "Trying to move the shade to a display ($currentId) it was already in ")
+ return
}
withContext(mainThreadContext) {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt
index 81146852aefc..52de0abf7d3c 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt
@@ -56,7 +56,7 @@ constructor(
private val shadeModeInteractor: ShadeModeInteractor,
) : BaseShadeInteractor {
init {
- SceneContainerFlag.assertInNewMode()
+ SceneContainerFlag.unsafeAssertInNewMode()
}
override val shadeExpansion: StateFlow<Float> =
diff --git a/packages/SystemUI/src/com/android/systemui/shade/shared/flag/ShadeWindowGoesAround.kt b/packages/SystemUI/src/com/android/systemui/shade/shared/flag/ShadeWindowGoesAround.kt
index dc444ffc2a34..016f50f471de 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/shared/flag/ShadeWindowGoesAround.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/shared/flag/ShadeWindowGoesAround.kt
@@ -67,7 +67,7 @@ object ShadeWindowGoesAround {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME)
+ inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index 32da6fff6bcc..c9b96e9871ed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -47,6 +47,7 @@ import android.database.ExecutorContentObserver;
import android.net.Uri;
import android.os.Looper;
import android.os.Process;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
@@ -817,6 +818,7 @@ public class NotificationLockscreenUserManagerImpl implements
return false;
}
+ long notificationTime = getEarliestNotificationTime(ent);
if (!mRedactOtpOnWifi.get()) {
if (mConnectedToWifi.get()) {
return false;
@@ -824,7 +826,7 @@ public class NotificationLockscreenUserManagerImpl implements
long lastWifiConnectTime = mLastWifiConnectionTime.get();
// If the device has connected to wifi since receiving the notification, do not redact
- if (ent.getSbn().getPostTime() < lastWifiConnectTime) {
+ if (notificationTime < lastWifiConnectTime) {
return false;
}
}
@@ -837,13 +839,22 @@ public class NotificationLockscreenUserManagerImpl implements
// when this notification arrived, do not redact
long latestTimeForRedaction = mLastLockTime.get() + mOtpRedactionRequiredLockTimeMs.get();
- if (ent.getSbn().getPostTime() < latestTimeForRedaction) {
+ if (notificationTime < latestTimeForRedaction) {
return false;
}
return true;
}
+ // Get the earliest time the user might have seen this notification. This is either the
+ // notification's "when" time, or the notification entry creation time
+ private long getEarliestNotificationTime(NotificationEntry notif) {
+ long notifWhenWallClock = notif.getSbn().getNotification().getWhen();
+ long creationTimeDelta = SystemClock.elapsedRealtime() - notif.getCreationTime();
+ long creationTimeWallClock = System.currentTimeMillis() - creationTimeDelta;
+ return Math.min(notifWhenWallClock, creationTimeWallClock);
+ }
+
private boolean packageHasVisibilityOverride(String key) {
if (mCommonNotifCollectionLazy.get() == null) {
Log.wtf(TAG, "mEntryManager was null!", new Throwable());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index 240953d6bfcd..18f4b4ab9b88 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -16,7 +16,6 @@
package com.android.systemui.statusbar;
import static com.android.systemui.Flags.mediaControlsUserInitiatedDeleteintent;
-import static com.android.systemui.Flags.notificationMediaManagerBackgroundExecution;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -116,12 +115,7 @@ public class NotificationMediaManager implements Dumpable {
if (DEBUG_MEDIA) {
Log.v(TAG, "DEBUG_MEDIA: onMetadataChanged: " + metadata);
}
- if (notificationMediaManagerBackgroundExecution()) {
- mBackgroundExecutor.execute(() -> setMediaMetadata(metadata));
- } else {
- setMediaMetadata(metadata);
- }
-
+ mBackgroundExecutor.execute(() -> setMediaMetadata(metadata));
dispatchUpdateMediaMetaData();
}
};
@@ -283,11 +277,7 @@ public class NotificationMediaManager implements Dumpable {
public void addCallback(MediaListener callback) {
mMediaListeners.add(callback);
- if (notificationMediaManagerBackgroundExecution()) {
- mBackgroundExecutor.execute(() -> updateMediaMetaData(callback));
- } else {
- updateMediaMetaData(callback);
- }
+ mBackgroundExecutor.execute(() -> updateMediaMetaData(callback));
}
private void updateMediaMetaData(MediaListener callback) {
@@ -303,55 +293,13 @@ public class NotificationMediaManager implements Dumpable {
public void findAndUpdateMediaNotifications() {
// TODO(b/169655907): get the semi-filtered notifications for current user
Collection<NotificationEntry> allNotifications = mNotifPipeline.getAllNotifs();
- if (notificationMediaManagerBackgroundExecution()) {
- // Create new sbn list to be accessed in background thread.
- List<StatusBarNotification> statusBarNotifications = new ArrayList<>();
- for (NotificationEntry entry: allNotifications) {
- statusBarNotifications.add(entry.getSbn());
- }
- mBackgroundExecutor.execute(() -> findPlayingMediaNotification(statusBarNotifications));
- } else {
- findPlayingMediaNotification(allNotifications);
- }
- dispatchUpdateMediaMetaData();
- }
-
- /**
- * Find a notification and media controller associated with the playing media session, and
- * update this manager's internal state.
- * TODO(b/273443374) check this method
- */
- void findPlayingMediaNotification(@NonNull Collection<NotificationEntry> allNotifications) {
- // Promote the media notification with a controller in 'playing' state, if any.
- NotificationEntry mediaNotification = null;
- MediaController controller = null;
+ // Create new sbn list to be accessed in background thread.
+ List<StatusBarNotification> statusBarNotifications = new ArrayList<>();
for (NotificationEntry entry : allNotifications) {
- Notification notif = entry.getSbn().getNotification();
- if (notif.isMediaNotification()) {
- final MediaSession.Token token =
- entry.getSbn().getNotification().extras.getParcelable(
- Notification.EXTRA_MEDIA_SESSION, MediaSession.Token.class);
- if (token != null) {
- MediaController aController = new MediaController(mContext, token);
- if (PlaybackState.STATE_PLAYING
- == getMediaControllerPlaybackState(aController)) {
- if (DEBUG_MEDIA) {
- Log.v(TAG, "DEBUG_MEDIA: found mediastyle controller matching "
- + entry.getSbn().getKey());
- }
- mediaNotification = entry;
- controller = aController;
- break;
- }
- }
- }
- }
-
- StatusBarNotification statusBarNotification = null;
- if (mediaNotification != null) {
- statusBarNotification = mediaNotification.getSbn();
+ statusBarNotifications.add(entry.getSbn());
}
- setUpControllerAndKey(controller, statusBarNotification);
+ mBackgroundExecutor.execute(() -> findPlayingMediaNotification(statusBarNotifications));
+ dispatchUpdateMediaMetaData();
}
/**
@@ -415,11 +363,7 @@ public class NotificationMediaManager implements Dumpable {
}
public void clearCurrentMediaNotification() {
- if (notificationMediaManagerBackgroundExecution()) {
- mBackgroundExecutor.execute(this::clearMediaNotification);
- } else {
- clearMediaNotification();
- }
+ mBackgroundExecutor.execute(this::clearMediaNotification);
}
private void clearMediaNotification() {
@@ -429,11 +373,7 @@ public class NotificationMediaManager implements Dumpable {
private void dispatchUpdateMediaMetaData() {
ArrayList<MediaListener> callbacks = new ArrayList<>(mMediaListeners);
- if (notificationMediaManagerBackgroundExecution()) {
- mBackgroundExecutor.execute(() -> updateMediaMetaData(callbacks));
- } else {
- updateMediaMetaData(callbacks);
- }
+ mBackgroundExecutor.execute(() -> updateMediaMetaData(callbacks));
}
private void updateMediaMetaData(List<MediaListener> callbacks) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
index f466278e15a8..be3afad4e1d1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
@@ -144,7 +144,7 @@ constructor(
} else {
OngoingActivityChipModel.ClickBehavior.ExpandAction(
onClick = { expandable ->
- StatusBarChipsModernization.assertInNewMode()
+ StatusBarChipsModernization.unsafeAssertInNewMode()
val animationController =
expandable.activityTransitionController(
Cuj.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractor.kt
index edb44185459c..35e622ba8e44 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractor.kt
@@ -73,7 +73,7 @@ constructor(
_promotedNotificationChipTapEvent.asSharedFlow()
suspend fun onPromotedNotificationChipTapped(key: String) {
- StatusBarNotifChips.assertInNewMode()
+ StatusBarNotifChips.unsafeAssertInNewMode()
_promotedNotificationChipTapEvent.emit(key)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/shared/StatusBarNotifChips.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/shared/StatusBarNotifChips.kt
index 47ffbafe3735..947e93c8a432 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/shared/StatusBarNotifChips.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/shared/StatusBarNotifChips.kt
@@ -50,7 +50,7 @@ object StatusBarNotifChips {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME)
+ inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
index 994357f909e4..2fe627020ebf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
@@ -71,7 +71,7 @@ constructor(
private fun NotificationChipModel.toActivityChipModel(
headsUpState: TopPinnedState
): OngoingActivityChipModel.Active {
- StatusBarNotifChips.assertInNewMode()
+ StatusBarNotifChips.unsafeAssertInNewMode()
val contentDescription = getContentDescription(this.appName)
val icon =
if (this.statusBarChipIconView != null) {
@@ -81,7 +81,7 @@ constructor(
contentDescription,
)
} else {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon(
this.key,
contentDescription,
@@ -103,7 +103,7 @@ constructor(
}
val clickBehavior =
OngoingActivityChipModel.ClickBehavior.ShowHeadsUpNotification({
- StatusBarChipsModernization.assertInNewMode()
+ StatusBarChipsModernization.unsafeAssertInNewMode()
clickListener.invoke()
})
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt
index 20dec11577df..02e4ba4d6437 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt
@@ -202,7 +202,7 @@ object OngoingActivityChipBinder {
)
}
is OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon -> {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
val iconView = fetchStatusBarIconView(iconViewStore, icon)
if (iconView == null) {
// This means that the notification key doesn't exist anymore.
@@ -223,7 +223,7 @@ object OngoingActivityChipBinder {
iconViewStore: IconViewStore?,
icon: OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon,
): StatusBarIconView? {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
if (iconViewStore == null) {
throw IllegalStateException("Store should always be non-null when flag is enabled.")
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt
index 95e454ac7bda..e8ab39692558 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt
@@ -195,7 +195,7 @@ private fun ChipIcon(
StatusBarIcon(colors, viewModel.impl.notification?.key, modifier) { viewModel.impl }
}
is OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon -> {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
check(iconViewStore != null)
StatusBarIcon(colors, viewModel.notificationKey, modifier) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
index cf0342b89c00..0cfc3216beb5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
@@ -148,7 +148,7 @@ sealed class OngoingActivityChipModel {
shouldAnimate,
) {
init {
- StatusBarNotifChips.assertInNewMode()
+ StatusBarNotifChips.unsafeAssertInNewMode()
}
override val logName = "Active.ShortTimeDelta"
@@ -227,7 +227,7 @@ sealed class OngoingActivityChipModel {
val contentDescription: ContentDescription,
) : ChipIcon {
init {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModel.kt
index a978c04d2a2e..229d1a56e177 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModel.kt
@@ -71,7 +71,7 @@ interface OngoingActivityChipViewModel {
tag: String,
): (Expandable) -> Unit {
return { expandable ->
- StatusBarChipsModernization.assertInNewMode()
+ StatusBarChipsModernization.unsafeAssertInNewMode()
logger.log(tag, LogLevel.INFO, {}, { "Chip clicked" })
val dialog = dialogDelegate.createDialog()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/CommandQueueInitializer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/CommandQueueInitializer.kt
index d25ca285c53b..601d105dfa8d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/CommandQueueInitializer.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/CommandQueueInitializer.kt
@@ -47,7 +47,7 @@ constructor(
) : CoreStartable {
override fun start() {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
val resultPerDisplay: Map<String, RegisterStatusBarResult> =
try {
barService.registerStatusBarForAllDisplays(commandQueue)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarOrchestratorStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarOrchestratorStore.kt
index 70697913447f..7964950a2917 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarOrchestratorStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarOrchestratorStore.kt
@@ -16,25 +16,19 @@
package com.android.systemui.statusbar.core
-import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.display.data.repository.DisplayScopeRepository
-import com.android.systemui.display.data.repository.PerDisplayStoreImpl
import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryStore
+import com.android.systemui.statusbar.data.repository.StatusBarPerDisplayStoreImpl
import com.android.systemui.statusbar.phone.AutoHideControllerStore
import com.android.systemui.statusbar.window.StatusBarWindowControllerStore
import com.android.systemui.statusbar.window.data.repository.StatusBarWindowStateRepositoryStore
-import dagger.Lazy
-import dagger.Module
-import dagger.Provides
-import dagger.multibindings.ClassKey
-import dagger.multibindings.IntoMap
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
-/** [PerDisplayStoreImpl] for providing display specific [StatusBarOrchestrator]. */
+/** [StatusBarPerDisplayStoreImpl] for providing display specific [StatusBarOrchestrator]. */
@SysUISingleton
class MultiDisplayStatusBarOrchestratorStore
@Inject
@@ -48,10 +42,14 @@ constructor(
private val autoHideControllerStore: AutoHideControllerStore,
private val displayScopeRepository: DisplayScopeRepository,
private val statusBarWindowStateRepositoryStore: StatusBarWindowStateRepositoryStore,
-) : PerDisplayStoreImpl<StatusBarOrchestrator>(backgroundApplicationScope, displayRepository) {
+) :
+ StatusBarPerDisplayStoreImpl<StatusBarOrchestrator>(
+ backgroundApplicationScope,
+ displayRepository,
+ ) {
init {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
}
override fun createInstanceForDisplay(displayId: Int): StatusBarOrchestrator? {
@@ -79,21 +77,3 @@ constructor(
instance.stop()
}
}
-
-@Module
-interface MultiDisplayStatusBarOrchestratorStoreModule {
-
- @Provides
- @SysUISingleton
- @IntoMap
- @ClassKey(MultiDisplayStatusBarOrchestratorStore::class)
- fun storeAsCoreStartable(
- multiDisplayLazy: Lazy<MultiDisplayStatusBarOrchestratorStore>
- ): CoreStartable {
- return if (StatusBarConnectedDisplays.isEnabled) {
- multiDisplayLazy.get()
- } else {
- CoreStartable.NOP
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt
index dfb3763fd3f6..30c4ca5269d3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt
@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.core
import android.view.Display
-import android.view.IWindowManager
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
@@ -44,28 +43,21 @@ constructor(
private val statusBarInitializerStore: StatusBarInitializerStore,
private val privacyDotWindowControllerStore: PrivacyDotWindowControllerStore,
private val lightBarControllerStore: LightBarControllerStore,
- private val windowManager: IWindowManager,
) : CoreStartable {
init {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
}
override fun start() {
applicationScope.launch {
- displayRepository.displays
+ displayRepository.displayIdsWithSystemDecorations
.pairwiseBy { previousDisplays, currentDisplays ->
currentDisplays - previousDisplays
}
- .onStart { emit(displayRepository.displays.value) }
+ .onStart { emit(displayRepository.displayIdsWithSystemDecorations.value) }
.collect { newDisplays ->
- newDisplays.forEach {
- // TODO(b/393191204): Split navbar, status bar, etc. functionality
- // from WindowManager#shouldShowSystemDecors.
- if (windowManager.shouldShowSystemDecors(it.displayId)) {
- createAndStartComponentsForDisplay(it.displayId)
- }
- }
+ newDisplays.forEach { createAndStartComponentsForDisplay(it) }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/NewStatusBarIcons.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/NewStatusBarIcons.kt
index 402881d438dc..9e1686ae135f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/NewStatusBarIcons.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/NewStatusBarIcons.kt
@@ -49,7 +49,7 @@ object NewStatusBarIcons {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME)
+ inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarConnectedDisplays.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarConnectedDisplays.kt
index 06474b01287d..cb1827d57c2a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarConnectedDisplays.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarConnectedDisplays.kt
@@ -50,7 +50,7 @@ object StatusBarConnectedDisplays {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME)
+ inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializerStore.kt
index de6cd072afd7..48955cc4ab21 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializerStore.kt
@@ -20,11 +20,11 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.display.data.repository.PerDisplayStore
-import com.android.systemui.display.data.repository.PerDisplayStoreImpl
import com.android.systemui.display.data.repository.SingleDisplayStore
import com.android.systemui.statusbar.data.repository.DarkIconDispatcherStore
import com.android.systemui.statusbar.data.repository.StatusBarConfigurationControllerStore
import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryStore
+import com.android.systemui.statusbar.data.repository.StatusBarPerDisplayStoreImpl
import com.android.systemui.statusbar.window.StatusBarWindowControllerStore
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -45,10 +45,13 @@ constructor(
private val darkIconDispatcherStore: DarkIconDispatcherStore,
) :
StatusBarInitializerStore,
- PerDisplayStoreImpl<StatusBarInitializer>(backgroundApplicationScope, displayRepository) {
+ StatusBarPerDisplayStoreImpl<StatusBarInitializer>(
+ backgroundApplicationScope,
+ displayRepository,
+ ) {
init {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
}
override fun createInstanceForDisplay(displayId: Int): StatusBarInitializer? {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarOrchestrator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarOrchestrator.kt
index 73ada546a9fc..c4c25c21a3b4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarOrchestrator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarOrchestrator.kt
@@ -146,7 +146,7 @@ constructor(
/** Starts status bar orchestration. To be called when status bar is created. */
fun start() {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
startJob =
coroutineScope
// Perform animations on the main thread to prevent crashes.
@@ -280,7 +280,7 @@ constructor(
* Called when the [StatusBarOrchestrator] should stop doing any work and clean up if needed.
*/
fun stop() {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
dumpManager.unregisterDumpable(dumpableName)
startJob?.cancel()
startJob = null
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarRootModernization.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarRootModernization.kt
index 3c30f3cbec85..4ee49d82b2fd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarRootModernization.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarRootModernization.kt
@@ -52,7 +52,7 @@ object StatusBarRootModernization {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME)
+ inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStore.kt
index 041f3c816149..f353c0198b1c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStore.kt
@@ -24,7 +24,6 @@ import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository
import com.android.systemui.display.data.repository.PerDisplayStore
-import com.android.systemui.display.data.repository.PerDisplayStoreImpl
import com.android.systemui.display.data.repository.SingleDisplayStore
import com.android.systemui.plugins.DarkIconDispatcher
import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
@@ -59,10 +58,13 @@ constructor(
private val displayWindowPropertiesRepository: DisplayWindowPropertiesRepository,
) :
SysuiDarkIconDispatcherStore,
- PerDisplayStoreImpl<SysuiDarkIconDispatcher>(backgroundApplicationScope, displayRepository) {
+ StatusBarPerDisplayStoreImpl<SysuiDarkIconDispatcher>(
+ backgroundApplicationScope,
+ displayRepository,
+ ) {
init {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
}
override fun createInstanceForDisplay(displayId: Int): SysuiDarkIconDispatcher? {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt
index c629d10b90b0..3c0d6c3b8df3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt
@@ -22,7 +22,6 @@ import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.display.data.repository.DisplayScopeRepository
import com.android.systemui.display.data.repository.PerDisplayStore
-import com.android.systemui.display.data.repository.PerDisplayStoreImpl
import com.android.systemui.statusbar.phone.LightBarController
import com.android.systemui.statusbar.phone.LightBarControllerImpl
import dagger.Binds
@@ -47,7 +46,10 @@ constructor(
private val darkIconDispatcherStore: DarkIconDispatcherStore,
) :
LightBarControllerStore,
- PerDisplayStoreImpl<LightBarController>(backgroundApplicationScope, displayRepository) {
+ StatusBarPerDisplayStoreImpl<LightBarController>(
+ backgroundApplicationScope,
+ displayRepository,
+ ) {
override fun createInstanceForDisplay(displayId: Int): LightBarController? {
val darkIconDispatcher = darkIconDispatcherStore.forDisplay(displayId) ?: return null
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt
index d48c94bd0893..32dc8407ac90 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt
@@ -22,7 +22,6 @@ import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.display.data.repository.DisplayScopeRepository
import com.android.systemui.display.data.repository.PerDisplayStore
-import com.android.systemui.display.data.repository.PerDisplayStoreImpl
import com.android.systemui.display.data.repository.SingleDisplayStore
import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
import com.android.systemui.statusbar.events.PrivacyDotViewController
@@ -50,7 +49,10 @@ constructor(
private val contentInsetsProviderStore: StatusBarContentInsetsProviderStore,
) :
PrivacyDotViewControllerStore,
- PerDisplayStoreImpl<PrivacyDotViewController>(backgroundApplicationScope, displayRepository) {
+ StatusBarPerDisplayStoreImpl<PrivacyDotViewController>(
+ backgroundApplicationScope,
+ displayRepository,
+ ) {
override fun createInstanceForDisplay(displayId: Int): PrivacyDotViewController? {
val configurationController =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStore.kt
index 86c3c483165c..7fc5e8abe904 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStore.kt
@@ -25,7 +25,6 @@ import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository
import com.android.systemui.display.data.repository.PerDisplayStore
-import com.android.systemui.display.data.repository.PerDisplayStoreImpl
import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
import com.android.systemui.statusbar.events.PrivacyDotWindowController
import dagger.Binds
@@ -52,10 +51,13 @@ constructor(
private val viewCaptureAwareWindowManagerFactory: ViewCaptureAwareWindowManager.Factory,
) :
PrivacyDotWindowControllerStore,
- PerDisplayStoreImpl<PrivacyDotWindowController>(backgroundApplicationScope, displayRepository) {
+ StatusBarPerDisplayStoreImpl<PrivacyDotWindowController>(
+ backgroundApplicationScope,
+ displayRepository,
+ ) {
init {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
}
override fun createInstanceForDisplay(displayId: Int): PrivacyDotWindowController? {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationControllerStore.kt
index 38cea832ad76..36b11ac60827 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationControllerStore.kt
@@ -24,7 +24,6 @@ import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository
import com.android.systemui.display.data.repository.PerDisplayStore
-import com.android.systemui.display.data.repository.PerDisplayStoreImpl
import com.android.systemui.display.data.repository.SingleDisplayStore
import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
import com.android.systemui.statusbar.phone.ConfigurationControllerImpl
@@ -53,13 +52,13 @@ constructor(
private val configurationControllerFactory: ConfigurationControllerImpl.Factory,
) :
StatusBarConfigurationControllerStore,
- PerDisplayStoreImpl<StatusBarConfigurationController>(
+ StatusBarPerDisplayStoreImpl<StatusBarConfigurationController>(
backgroundApplicationScope,
displayRepository,
) {
init {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
}
override fun createInstanceForDisplay(displayId: Int): StatusBarConfigurationController? {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarContentInsetsProviderStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarContentInsetsProviderStore.kt
index 5ea12110b00c..3cd4b5c885de 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarContentInsetsProviderStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarContentInsetsProviderStore.kt
@@ -25,7 +25,6 @@ import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository
import com.android.systemui.display.data.repository.PerDisplayStore
-import com.android.systemui.display.data.repository.PerDisplayStoreImpl
import com.android.systemui.display.data.repository.SingleDisplayStore
import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
import com.android.systemui.statusbar.layout.StatusBarContentInsetsProvider
@@ -54,7 +53,7 @@ constructor(
private val cameraProtectionLoaderFactory: CameraProtectionLoaderImpl.Factory,
) :
StatusBarContentInsetsProviderStore,
- PerDisplayStoreImpl<StatusBarContentInsetsProvider>(
+ StatusBarPerDisplayStoreImpl<StatusBarContentInsetsProvider>(
backgroundApplicationScope,
displayRepository,
) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryStore.kt
index 143e99823860..5980c9c57214 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryStore.kt
@@ -22,7 +22,6 @@ import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.DisplayId
import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.display.data.repository.PerDisplayStore
-import com.android.systemui.display.data.repository.PerDisplayStoreImpl
import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
import com.android.systemui.statusbar.core.StatusBarInitializer
import com.android.systemui.statusbar.phone.fragment.dagger.HomeStatusBarComponent
@@ -48,13 +47,13 @@ constructor(
displayRepository: DisplayRepository,
) :
StatusBarModeRepositoryStore,
- PerDisplayStoreImpl<StatusBarModePerDisplayRepository>(
+ StatusBarPerDisplayStoreImpl<StatusBarModePerDisplayRepository>(
backgroundApplicationScope,
displayRepository,
) {
init {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
}
override fun createInstanceForDisplay(displayId: Int): StatusBarModePerDisplayRepository {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayStoreImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayStoreImpl.kt
new file mode 100644
index 000000000000..e873c02fd4d5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayStoreImpl.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.data.repository
+
+import com.android.app.tracing.coroutines.launchTraced as launch
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.display.data.repository.DisplayRepository
+import com.android.systemui.display.data.repository.PerDisplayStoreImpl
+import com.android.systemui.util.kotlin.pairwiseBy
+import kotlinx.coroutines.CoroutineScope
+
+/** [PerDisplayStoreImpl] for Status Bar related classes. */
+abstract class StatusBarPerDisplayStoreImpl<T>(
+ @Background private val backgroundApplicationScope: CoroutineScope,
+ private val displayRepository: DisplayRepository,
+) : PerDisplayStoreImpl<T>(backgroundApplicationScope, displayRepository) {
+
+ override fun start() {
+ val instanceType = instanceClass.simpleName
+ backgroundApplicationScope.launch("StatusBarPerDisplayStore#<$instanceType>start") {
+ displayRepository.displayIdsWithSystemDecorations
+ .pairwiseBy { previousDisplays, currentDisplays ->
+ previousDisplays - currentDisplays
+ }
+ .collect { removedDisplayIds ->
+ removedDisplayIds.forEach { removedDisplayId ->
+ val removedInstance = perDisplayInstances.remove(removedDisplayId)
+ removedInstance?.let { onDisplayRemovalAction(it) }
+ }
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStore.kt
index ffc125539521..7b9ea697a9ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStore.kt
@@ -23,7 +23,6 @@ import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository
import com.android.systemui.display.data.repository.PerDisplayStore
-import com.android.systemui.display.data.repository.PerDisplayStoreImpl
import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
import com.android.systemui.statusbar.events.SystemEventChipAnimationController
import com.android.systemui.statusbar.events.SystemEventChipAnimationControllerImpl
@@ -53,13 +52,13 @@ constructor(
private val statusBarContentInsetsProviderStore: StatusBarContentInsetsProviderStore,
) :
SystemEventChipAnimationControllerStore,
- PerDisplayStoreImpl<SystemEventChipAnimationController>(
+ StatusBarPerDisplayStoreImpl<SystemEventChipAnimationController>(
backgroundApplicationScope,
displayRepository,
) {
init {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
}
override fun createInstanceForDisplay(displayId: Int): SystemEventChipAnimationController? {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/MultiDisplaySystemEventChipAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/MultiDisplaySystemEventChipAnimationController.kt
index 4b9721ea4fe5..b881c920c34b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/MultiDisplaySystemEventChipAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/MultiDisplaySystemEventChipAnimationController.kt
@@ -37,7 +37,7 @@ constructor(
) : SystemEventChipAnimationController {
init {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
}
override fun prepareChipAnimation(viewCreator: ViewCreator) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
index 63410d7465b8..3200ca18b0a7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
@@ -190,7 +190,7 @@ constructor(
}
override fun stop() {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
contentInsetsProvider.removeCallback(insetsChangedListener)
configurationController.removeCallback(configurationListener)
stateController.removeCallback(statusBarStateListener)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/ui/view/BatteryStatusEventComposeChip.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/ui/view/BatteryStatusEventComposeChip.kt
index a90e3ff4b2dc..05d32567c4e1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/ui/view/BatteryStatusEventComposeChip.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/ui/view/BatteryStatusEventComposeChip.kt
@@ -54,7 +54,7 @@ constructor(level: Int, context: Context, attrs: AttributeSet? = null) :
get() = composeInner
init {
- NewStatusBarIcons.assertInNewMode()
+ NewStatusBarIcons.unsafeAssertInNewMode()
inflate(context, R.layout.status_bar_event_chip_compose, this)
roundedContainer = requireViewById(R.id.rounded_container)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/StatusBarPopupChips.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/StatusBarPopupChips.kt
index a9f72ff21a7c..08a8960f6c96 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/StatusBarPopupChips.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/StatusBarPopupChips.kt
@@ -50,7 +50,7 @@ object StatusBarPopupChips {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME)
+ inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/headsup/shared/StatusBarNoHunBehavior.kt b/packages/SystemUI/src/com/android/systemui/statusbar/headsup/shared/StatusBarNoHunBehavior.kt
index c9024d934068..7a985e7fae9a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/headsup/shared/StatusBarNoHunBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/headsup/shared/StatusBarNoHunBehavior.kt
@@ -50,7 +50,7 @@ object StatusBarNoHunBehavior {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME)
+ inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/layout/StatusBarContentInsetsProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/layout/StatusBarContentInsetsProvider.kt
index 9d5d87f6db7c..e588dd303346 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/layout/StatusBarContentInsetsProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/layout/StatusBarContentInsetsProvider.kt
@@ -201,7 +201,7 @@ constructor(
}
override fun stop() {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
configurationController.removeCallback(this)
dumpManager.unregisterDumpable(dumpableName)
commandRegistry.unregisterCommand(commandName)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/layout/ui/viewmodel/StatusBarContentInsetsViewModelStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/layout/ui/viewmodel/StatusBarContentInsetsViewModelStore.kt
index d2dccc49ffd7..d7e9bb2ad64a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/layout/ui/viewmodel/StatusBarContentInsetsViewModelStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/layout/ui/viewmodel/StatusBarContentInsetsViewModelStore.kt
@@ -21,10 +21,10 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.display.data.repository.PerDisplayStore
-import com.android.systemui.display.data.repository.PerDisplayStoreImpl
import com.android.systemui.display.data.repository.SingleDisplayStore
import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
import com.android.systemui.statusbar.data.repository.StatusBarContentInsetsProviderStore
+import com.android.systemui.statusbar.data.repository.StatusBarPerDisplayStoreImpl
import dagger.Lazy
import dagger.Module
import dagger.Provides
@@ -45,7 +45,7 @@ constructor(
private val statusBarContentInsetsProviderStore: StatusBarContentInsetsProviderStore,
) :
StatusBarContentInsetsViewModelStore,
- PerDisplayStoreImpl<StatusBarContentInsetsViewModel>(
+ StatusBarPerDisplayStoreImpl<StatusBarContentInsetsViewModel>(
backgroundApplicationScope,
displayRepository,
) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/PhysicsPropertyAnimator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/PhysicsPropertyAnimator.kt
index 0a24d7a71ce9..68c13afe82dc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/PhysicsPropertyAnimator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/PhysicsPropertyAnimator.kt
@@ -88,8 +88,8 @@ class PhysicsPropertyAnimator {
@JvmStatic
fun createDefaultSpring(): SpringForce {
return SpringForce()
- .setStiffness(380f) // MEDIUM LOW STIFFNESS
- .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY) // LOW BOUNCINESS
+ .setStiffness(380f)
+ .setDampingRatio(0.68f);
}
@JvmStatic
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
index 611e0ef77fac..f6e66237d438 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
@@ -125,7 +125,7 @@ constructor(
* Must be run on the main thread.
*/
private fun onPromotedNotificationChipTapEvent(key: String) {
- StatusBarNotifChips.assertInNewMode()
+ StatusBarNotifChips.unsafeAssertInNewMode()
val entry = notifCollection.getEntry(key)
if (entry == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StabilizeHeadsUpGroup.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StabilizeHeadsUpGroup.kt
index a0e44bfd7620..179a87d7f007 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StabilizeHeadsUpGroup.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StabilizeHeadsUpGroup.kt
@@ -50,7 +50,7 @@ object StabilizeHeadsUpGroup {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME)
+ inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
index c5ae8756ded6..0d4207bd95a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
@@ -162,7 +162,7 @@ public class GroupExpansionManagerImpl implements GroupExpansionManager, Dumpabl
@Override
public boolean isGroupExpanded(EntryAdapter entry) {
- NotificationBundleUi.assertInNewMode();
+ NotificationBundleUi.unsafeAssertInNewMode();
ExpandableNotificationRow parent = entry.getRow().getNotificationParent();
return mExpandedCollections.contains(entry)
|| (parent != null && mExpandedCollections.contains(parent.getEntryAdapter()));
@@ -170,7 +170,7 @@ public class GroupExpansionManagerImpl implements GroupExpansionManager, Dumpabl
@Override
public void setGroupExpanded(EntryAdapter groupRoot, boolean expanded) {
- NotificationBundleUi.assertInNewMode();
+ NotificationBundleUi.unsafeAssertInNewMode();
if (!groupRoot.isAttached()) {
if (expanded) {
Log.wtf(TAG, "Cannot expand group that is not attached");
@@ -192,7 +192,7 @@ public class GroupExpansionManagerImpl implements GroupExpansionManager, Dumpabl
@Override
public boolean toggleGroupExpansion(EntryAdapter groupRoot) {
- NotificationBundleUi.assertInNewMode();
+ NotificationBundleUi.unsafeAssertInNewMode();
setGroupExpanded(groupRoot, !isGroupExpanded(groupRoot));
return isGroupExpanded(groupRoot);
}
@@ -231,7 +231,7 @@ public class GroupExpansionManagerImpl implements GroupExpansionManager, Dumpabl
}
private void sendOnGroupExpandedChange(EntryAdapter entry, boolean expanded) {
- NotificationBundleUi.assertInNewMode();
+ NotificationBundleUi.unsafeAssertInNewMode();
for (OnGroupExpansionChangeListener listener : mOnGroupChangeListeners) {
listener.onGroupExpansionChange(entry.getRow(), expanded);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerImpl.java
index aec0d70e4a88..66a4f9fe3f80 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerImpl.java
@@ -59,7 +59,7 @@ public class GroupMembershipManagerImpl implements GroupMembershipManager {
@Override
public boolean isGroupRoot(@NonNull EntryAdapter entry) {
- NotificationBundleUi.assertInNewMode();
+ NotificationBundleUi.unsafeAssertInNewMode();
return entry.isGroupRoot();
}
@@ -85,7 +85,7 @@ public class GroupMembershipManagerImpl implements GroupMembershipManager {
@Override
public boolean isChildInGroup(@NonNull EntryAdapter entry) {
- NotificationBundleUi.assertInNewMode();
+ NotificationBundleUi.unsafeAssertInNewMode();
// An entry is a child if it's not a group root or top level entry, but it is attached.
return entry.isAttached() && !entry.isGroupRoot() && !entry.isTopLevelEntry();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/emptyshade/shared/ModesEmptyShadeFix.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/emptyshade/shared/ModesEmptyShadeFix.kt
index f1fc2751d11f..d3a44f9b1497 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/emptyshade/shared/ModesEmptyShadeFix.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/emptyshade/shared/ModesEmptyShadeFix.kt
@@ -50,7 +50,7 @@ object ModesEmptyShadeFix {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME)
+ inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/emptyshade/ui/viewmodel/EmptyShadeViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/emptyshade/ui/viewmodel/EmptyShadeViewModel.kt
index 7e6c6050d0b4..9bb9b9aedc3e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/emptyshade/ui/viewmodel/EmptyShadeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/emptyshade/ui/viewmodel/EmptyShadeViewModel.kt
@@ -124,7 +124,7 @@ constructor(
}
val footer: FooterMessageViewModel by lazy {
- ModesEmptyShadeFix.assertInNewMode()
+ ModesEmptyShadeFix.unsafeAssertInNewMode()
FooterMessageViewModel(
messageId = R.string.unlock_to_see_notif_text,
iconId = R.drawable.ic_friction_lock_closed,
@@ -133,7 +133,7 @@ constructor(
}
val onClick: Flow<SettingsIntent> by lazy {
- ModesEmptyShadeFix.assertInNewMode()
+ ModesEmptyShadeFix.unsafeAssertInNewMode()
combine(
zenModeInteractor.modesHidingNotifications,
notificationSettingsInteractor.isNotificationHistoryEnabled,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/shared/NotifRedesignFooter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/shared/NotifRedesignFooter.kt
index 0307d90aaf4c..dbe046fdf30b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/shared/NotifRedesignFooter.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/shared/NotifRedesignFooter.kt
@@ -50,7 +50,7 @@ object NotifRedesignFooter {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME)
+ inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpAnimator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpAnimator.kt
index f9bd805a2628..177574f57c1c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpAnimator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpAnimator.kt
@@ -25,7 +25,7 @@ import com.android.systemui.res.R
*/
class HeadsUpAnimator(context: Context) {
init {
- NotificationsHunSharedAnimationValues.assertInNewMode()
+ NotificationsHunSharedAnimationValues.unsafeAssertInNewMode()
}
var headsUpAppearHeightBottom: Int = 0
@@ -41,7 +41,7 @@ class HeadsUpAnimator(context: Context) {
* of the animation.
*/
fun getHeadsUpYTranslation(isHeadsUpFromBottom: Boolean): Int {
- NotificationsHunSharedAnimationValues.assertInNewMode()
+ NotificationsHunSharedAnimationValues.unsafeAssertInNewMode()
if (isHeadsUpFromBottom) {
// start from or end at the bottom of the screen
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java
index 5157e7a5e42f..d16ad80ca8b9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java
@@ -1096,7 +1096,7 @@ public class HeadsUpManagerImpl
@Override
public void setExpanded(@NonNull String entryKey, @NonNull ExpandableNotificationRow row,
boolean expanded) {
- NotificationBundleUi.assertInNewMode();
+ NotificationBundleUi.unsafeAssertInNewMode();
HeadsUpEntry headsUpEntry = getHeadsUpEntry(entryKey);
if (headsUpEntry != null && row.getPinnedStatus().isPinned()) {
headsUpEntry.setExpanded(expanded);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/NotificationsHunSharedAnimationValues.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/NotificationsHunSharedAnimationValues.kt
index ca9d498c0e7f..c53831671bfc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/NotificationsHunSharedAnimationValues.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/NotificationsHunSharedAnimationValues.kt
@@ -50,7 +50,7 @@ object NotificationsHunSharedAnimationValues {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME)
+ inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
index c512b43c91a3..294b8d35c9a6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
@@ -90,12 +90,12 @@ constructor(
ConcurrentHashMap<String, Job>()
fun addIconsUpdateListener(listener: OnIconUpdateRequiredListener) {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
onIconUpdateRequiredListeners += listener
}
fun removeIconsUpdateListener(listener: OnIconUpdateRequiredListener) {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
onIconUpdateRequiredListeners -= listener
}
@@ -140,7 +140,7 @@ constructor(
*/
fun createSbIconView(context: Context, entry: NotificationEntry): StatusBarIconView =
traceSection("IconManager.createSbIconView") {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
val sbIcon = iconBuilder.createIconView(entry, context)
sbIcon.scaleType = ImageView.ScaleType.CENTER_INSIDE
@@ -200,7 +200,7 @@ constructor(
/** Update the [StatusBarIconView] for the given [NotificationEntry]. */
fun updateSbIcon(entry: NotificationEntry, iconView: StatusBarIconView) =
traceSection("IconManager.updateSbIcon") {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
val (normalIconDescriptor, _) = getIconDescriptors(entry)
val notificationContentDescription =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUi.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUi.kt
index 632421980772..5bf5766a886c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUi.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUi.kt
@@ -50,7 +50,7 @@ object PromotedNotificationUi {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME)
+ inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiAod.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiAod.kt
index fa1f32cc367e..8679975998f2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiAod.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiAod.kt
@@ -49,7 +49,7 @@ object PromotedNotificationUiAod {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME)
+ inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiForceExpanded.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiForceExpanded.kt
index cb0d67403521..287e00257bc5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiForceExpanded.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiForceExpanded.kt
@@ -50,7 +50,7 @@ object PromotedNotificationUiForceExpanded {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME)
+ inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/AODPromotedNotificationInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/AODPromotedNotificationInteractor.kt
index 4bc685423659..ec4ee4560ea1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/AODPromotedNotificationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/AODPromotedNotificationInteractor.kt
@@ -19,7 +19,6 @@ package com.android.systemui.statusbar.notification.promoted.domain.interactor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
-import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.Style
import com.android.systemui.util.kotlin.FlowDumperImpl
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
@@ -34,10 +33,7 @@ constructor(
) : FlowDumperImpl(dumpManager) {
/** The content to show as the promoted notification on AOD */
val content: Flow<PromotedNotificationContentModel?> =
- promotedNotificationsInteractor.topPromotedNotificationContent
+ promotedNotificationsInteractor.aodPromotedNotification
- val isPresent: Flow<Boolean> =
- content
- .map { (it != null) && (it.style != Style.Ineligible) }
- .dumpWhileCollecting("isPresent")
+ val isPresent: Flow<Boolean> = content.map { it != null }.dumpWhileCollecting("isPresent")
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractor.kt
index 1015cfbefc41..1abd48c0c50b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractor.kt
@@ -22,6 +22,8 @@ import com.android.systemui.statusbar.chips.call.domain.interactor.CallChipInter
import com.android.systemui.statusbar.chips.notification.domain.interactor.StatusBarNotificationChipsInteractor
import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.Style.Ineligible
+import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
@@ -83,13 +85,13 @@ constructor(
.map { list -> list.firstNotNullOfOrNull { it.promotedContent } }
.distinctUntilNewInstance()
- /** This is the top-most promoted notification, which should avoid regular changing. */
- val topPromotedNotificationContent: Flow<PromotedNotificationContentModel?> =
+ /** This is the AOD promoted notification, which should avoid regular changing. */
+ val aodPromotedNotification: Flow<PromotedNotificationContentModel?> =
combine(
topPromotedChipNotification,
activeNotificationsInteractor.topLevelRepresentativeNotifications,
) { topChipNotif, topLevelNotifs ->
- topChipNotif ?: topLevelNotifs.firstNotNullOfOrNull { it.promotedContent }
+ topChipNotif?.takeIfAodEligible() ?: topLevelNotifs.firstAodEligibleOrNull()
}
// #equals() can be a bit expensive on this object, but this flow will regularly try to
// emit the same immutable instance over and over, so just prevent that.
@@ -105,6 +107,16 @@ constructor(
.distinctUntilChanged()
.flowOn(backgroundDispatcher)
+ private fun List<ActiveNotificationModel>.firstAodEligibleOrNull():
+ PromotedNotificationContentModel? {
+ return this.firstNotNullOfOrNull { it.promotedContent?.takeIfAodEligible() }
+ }
+
+ private fun PromotedNotificationContentModel.takeIfAodEligible():
+ PromotedNotificationContentModel? {
+ return this.takeUnless { it.style == Ineligible }
+ }
+
/**
* Returns flow where all subsequent repetitions of the same object instance are filtered out.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 3ef1fd2275a2..66929a579eca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -947,7 +947,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
@Nullable
public EntryAdapter getEntryAdapter() {
- NotificationBundleUi.assertInNewMode();
+ NotificationBundleUi.unsafeAssertInNewMode();
return mEntryAdapter;
}
@@ -1679,7 +1679,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
view.setBackgroundTintColor(color);
}
if (notificationRowTransparency() && mBackgroundNormal != null) {
- if (NotificationBundleUi.isEnabled()) {
+ if (NotificationBundleUi.isEnabled() && mEntryAdapter != null) {
mBackgroundNormal.setBgIsColorized(
usesTransparentBackground() && mEntryAdapter.isColorized());
} else {
@@ -2074,7 +2074,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
*/
public ExpandableNotificationRow(Context context, AttributeSet attrs, UserHandle user) {
this(context, attrs, userContextForEntry(context, user));
- NotificationBundleUi.assertInNewMode();
+ NotificationBundleUi.unsafeAssertInNewMode();
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationBundleUi.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationBundleUi.kt
index 72372319009c..11c942c9bcc0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationBundleUi.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationBundleUi.kt
@@ -49,7 +49,7 @@ object NotificationBundleUi {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME)
+ inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 1a17b8efb4ae..f70d57653ac0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -6469,30 +6469,50 @@ public class NotificationStackScrollLayout
static AnimationFilter[] FILTERS = new AnimationFilter[]{
// ANIMATION_TYPE_ADD
- new AnimationFilter()
- .animateAlpha()
- .animateHeight()
- .animateTopInset()
- .animateY()
- .animateZ()
- .hasDelays(),
+ physicalNotificationMovement()
+ ? new AnimationFilter()
+ .animateAlpha()
+ .animateHeight()
+ .animateTopInset()
+ .animateY()
+ .animateZ()
+ : new AnimationFilter()
+ .animateAlpha()
+ .animateHeight()
+ .animateTopInset()
+ .animateY()
+ .animateZ()
+ .hasDelays(),
// ANIMATION_TYPE_REMOVE
- new AnimationFilter()
- .animateAlpha()
- .animateHeight()
- .animateTopInset()
- .animateY()
- .animateZ()
- .hasDelays(),
+ physicalNotificationMovement()
+ ? new AnimationFilter()
+ .animateAlpha()
+ .animateHeight()
+ .animateTopInset()
+ .animateY()
+ .animateZ()
+ : new AnimationFilter()
+ .animateAlpha()
+ .animateHeight()
+ .animateTopInset()
+ .animateY()
+ .animateZ()
+ .hasDelays(),
// ANIMATION_TYPE_REMOVE_SWIPED_OUT
- new AnimationFilter()
- .animateHeight()
- .animateTopInset()
- .animateY()
- .animateZ()
- .hasDelays(),
+ physicalNotificationMovement()
+ ? new AnimationFilter()
+ .animateHeight()
+ .animateTopInset()
+ .animateY()
+ .animateZ()
+ : new AnimationFilter()
+ .animateHeight()
+ .animateTopInset()
+ .animateY()
+ .animateZ()
+ .hasDelays(),
// ANIMATION_TYPE_TOP_PADDING_CHANGED
new AnimationFilter()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
index 4e916804318d..fcb63df1a528 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
@@ -409,12 +409,12 @@ constructor(
if (counter != null) {
if (NotificationBundleUi.isEnabled) {
- val entry = (currentNotification as? ExpandableNotificationRow)?.entry
- counter.incrementForBucket(entry?.bucket)
- } else {
val entryAdapter =
(currentNotification as? ExpandableNotificationRow)?.entryAdapter
counter.incrementForBucket(entryAdapter?.sectionBucket)
+ } else {
+ val entry = (currentNotification as? ExpandableNotificationRow)?.entry
+ counter.incrementForBucket(entry?.bucket)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
index 19abfa8140df..efbcaed73b62 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
@@ -289,6 +289,10 @@ public class StackStateAnimator {
long delayPerElement = ANIMATION_DELAY_PER_ELEMENT_INTERRUPTING;
switch (event.animationType) {
case NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_ADD: {
+ if (physicalNotificationMovement()) {
+ // We don't want any delays when adding anymore
+ continue;
+ }
int ownIndex = viewState.notGoneIndex;
int changingIndex =
((ExpandableView) (event.mChangingView)).getViewState().notGoneIndex;
@@ -302,6 +306,10 @@ public class StackStateAnimator {
case NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_REMOVE_SWIPED_OUT:
delayPerElement = ANIMATION_DELAY_PER_ELEMENT_MANUAL;
case NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_REMOVE: {
+ if (physicalNotificationMovement()) {
+ // We don't want any delays when removing anymore
+ continue;
+ }
int ownIndex = viewState.notGoneIndex;
boolean noNextView = event.viewAfterChangingView == null;
ExpandableView viewAfterChangingView = noNextView
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt
index 10b665d8ef01..1c079c198cd4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt
@@ -231,7 +231,7 @@ constructor(
emptyShadeViewModel: EmptyShadeViewModel,
parentView: NotificationStackScrollLayout,
) {
- ModesEmptyShadeFix.assertInNewMode()
+ ModesEmptyShadeFix.unsafeAssertInNewMode()
// The empty shade needs to be re-inflated every time the theme or the font size
// changes.
configuration
@@ -269,7 +269,7 @@ constructor(
emptyShadeView: EmptyShadeView,
emptyShadeViewModel: EmptyShadeViewModel,
): Unit = coroutineScope {
- ModesEmptyShadeFix.assertInNewMode()
+ ModesEmptyShadeFix.unsafeAssertInNewMode()
launch {
emptyShadeView.repeatWhenAttachedToWindow {
EmptyShadeViewBinder.bind(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerStore.kt
index 2ae38dd488bd..616bab60e02f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerStore.kt
@@ -22,9 +22,9 @@ import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository
import com.android.systemui.display.data.repository.PerDisplayStore
-import com.android.systemui.display.data.repository.PerDisplayStoreImpl
import com.android.systemui.display.data.repository.SingleDisplayStore
import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
+import com.android.systemui.statusbar.data.repository.StatusBarPerDisplayStoreImpl
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -41,10 +41,13 @@ constructor(
private val autoHideControllerFactory: AutoHideControllerImpl.Factory,
) :
AutoHideControllerStore,
- PerDisplayStoreImpl<AutoHideController>(backgroundApplicationScope, displayRepository) {
+ StatusBarPerDisplayStoreImpl<AutoHideController>(
+ backgroundApplicationScope,
+ displayRepository,
+ ) {
init {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
}
override fun createInstanceForDisplay(displayId: Int): AutoHideController? {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt
index 323b7d8eaaeb..ba5570026c1c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt
@@ -21,6 +21,7 @@ import com.android.systemui.dagger.qualifiers.Default
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.core.CommandQueueInitializer
import com.android.systemui.statusbar.core.MultiDisplayStatusBarInitializerStore
+import com.android.systemui.statusbar.core.MultiDisplayStatusBarOrchestratorStore
import com.android.systemui.statusbar.core.MultiDisplayStatusBarStarter
import com.android.systemui.statusbar.core.SingleDisplayStatusBarInitializerStore
import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
@@ -197,5 +198,19 @@ interface StatusBarPhoneModule {
CoreStartable.NOP
}
}
+
+ @Provides
+ @SysUISingleton
+ @IntoMap
+ @ClassKey(MultiDisplayStatusBarOrchestratorStore::class)
+ fun orchestratorStoreAsCoreStartable(
+ multiDisplayLazy: Lazy<MultiDisplayStatusBarOrchestratorStore>
+ ): CoreStartable {
+ return if (StatusBarConnectedDisplays.isEnabled) {
+ multiDisplayLazy.get()
+ } else {
+ CoreStartable.NOP
+ }
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
index c541cff4448c..d8d6979e1379 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
@@ -875,7 +875,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
}
private void showSecondaryOngoingActivityChip(boolean animate) {
- StatusBarNotifChips.assertInNewMode();
+ StatusBarNotifChips.unsafeAssertInNewMode();
StatusBarRootModernization.assertInLegacyMode();
animateShow(mSecondaryOngoingActivityChip, animate);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/StatusBarChipsModernization.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/StatusBarChipsModernization.kt
index b77e8f2ffefc..6afcd8a4fad8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/StatusBarChipsModernization.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/StatusBarChipsModernization.kt
@@ -52,7 +52,7 @@ object StatusBarChipsModernization {
* the flag is not enabled to ensure that the refactor author catches issues in testing.
*/
@JvmStatic
- inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME)
+ inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ethernet/shared/StatusBarSignalPolicyRefactorEthernet.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ethernet/shared/StatusBarSignalPolicyRefactorEthernet.kt
index 48747df23e0c..1d1cfd6cdf68 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ethernet/shared/StatusBarSignalPolicyRefactorEthernet.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ethernet/shared/StatusBarSignalPolicyRefactorEthernet.kt
@@ -50,7 +50,7 @@ object StatusBarSignalPolicyRefactorEthernet {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME)
+ inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt
index d7348892356d..cdd02865bbee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt
@@ -47,7 +47,8 @@ import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernizat
import com.android.systemui.statusbar.pipeline.shared.ui.model.VisibilityModel
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel
import javax.inject.Inject
-import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
/**
@@ -153,39 +154,43 @@ constructor(
OngoingActivityChipBinder.createBinding(primaryChipView)
launch {
- viewModel.primaryOngoingActivityChip.collect { primaryChipModel ->
- OngoingActivityChipBinder.bind(
- primaryChipModel,
- primaryChipViewBinding,
- iconViewStore,
+ combine(
+ viewModel.primaryOngoingActivityChip,
+ viewModel.canShowOngoingActivityChips,
+ ::Pair,
)
+ .distinctUntilChanged()
+ .collect { (primaryChipModel, areChipsAllowed) ->
+ OngoingActivityChipBinder.bind(
+ primaryChipModel,
+ primaryChipViewBinding,
+ iconViewStore,
+ )
- if (StatusBarRootModernization.isEnabled) {
- launch {
+ if (StatusBarRootModernization.isEnabled) {
bindLegacyPrimaryOngoingActivityChipWithVisibility(
- viewModel,
+ areChipsAllowed,
primaryChipModel,
primaryChipViewBinding,
)
- }
- } else {
- when (primaryChipModel) {
- is OngoingActivityChipModel.Active ->
- listener?.onOngoingActivityStatusChanged(
- hasPrimaryOngoingActivity = true,
- hasSecondaryOngoingActivity = false,
- shouldAnimate = true,
- )
-
- is OngoingActivityChipModel.Inactive ->
- listener?.onOngoingActivityStatusChanged(
- hasPrimaryOngoingActivity = false,
- hasSecondaryOngoingActivity = false,
- shouldAnimate = primaryChipModel.shouldAnimate,
- )
+ } else {
+ when (primaryChipModel) {
+ is OngoingActivityChipModel.Active ->
+ listener?.onOngoingActivityStatusChanged(
+ hasPrimaryOngoingActivity = true,
+ hasSecondaryOngoingActivity = false,
+ shouldAnimate = true,
+ )
+
+ is OngoingActivityChipModel.Inactive ->
+ listener?.onOngoingActivityStatusChanged(
+ hasPrimaryOngoingActivity = false,
+ hasSecondaryOngoingActivity = false,
+ shouldAnimate = primaryChipModel.shouldAnimate,
+ )
+ }
}
}
- }
}
}
@@ -199,49 +204,53 @@ constructor(
view.requireViewById(R.id.ongoing_activity_chip_secondary)
)
launch {
- viewModel.ongoingActivityChipsLegacy.collectLatest { chips ->
- OngoingActivityChipBinder.bind(
- chips.primary,
- primaryChipViewBinding,
- iconViewStore,
+ combine(
+ viewModel.ongoingActivityChipsLegacy,
+ viewModel.canShowOngoingActivityChips,
+ ::Pair,
)
- OngoingActivityChipBinder.bind(
- chips.secondary,
- secondaryChipViewBinding,
- iconViewStore,
- )
-
- if (StatusBarRootModernization.isEnabled) {
- launch {
+ .distinctUntilChanged()
+ .collect { (chips, areChipsAllowed) ->
+ OngoingActivityChipBinder.bind(
+ chips.primary,
+ primaryChipViewBinding,
+ iconViewStore,
+ )
+ OngoingActivityChipBinder.bind(
+ chips.secondary,
+ secondaryChipViewBinding,
+ iconViewStore,
+ )
+ if (StatusBarRootModernization.isEnabled) {
bindOngoingActivityChipsWithVisibility(
- viewModel,
+ areChipsAllowed,
chips,
primaryChipViewBinding,
secondaryChipViewBinding,
)
+ } else {
+ listener?.onOngoingActivityStatusChanged(
+ hasPrimaryOngoingActivity =
+ chips.primary is OngoingActivityChipModel.Active,
+ hasSecondaryOngoingActivity =
+ chips.secondary is OngoingActivityChipModel.Active,
+ // TODO(b/364653005): Figure out the animation story here.
+ shouldAnimate = true,
+ )
}
- } else {
- listener?.onOngoingActivityStatusChanged(
- hasPrimaryOngoingActivity =
- chips.primary is OngoingActivityChipModel.Active,
- hasSecondaryOngoingActivity =
- chips.secondary is OngoingActivityChipModel.Active,
- // TODO(b/364653005): Figure out the animation story here.
- shouldAnimate = true,
- )
- }
-
- viewModel.contentArea.collect { _ ->
- OngoingActivityChipBinder.resetPrimaryChipWidthRestrictions(
- primaryChipViewBinding,
- viewModel.ongoingActivityChipsLegacy.value.primary,
- )
- OngoingActivityChipBinder.resetSecondaryChipWidthRestrictions(
- secondaryChipViewBinding,
- viewModel.ongoingActivityChipsLegacy.value.secondary,
- )
- view.requestLayout()
}
+ }
+ launch {
+ viewModel.contentArea.collect { _ ->
+ OngoingActivityChipBinder.resetPrimaryChipWidthRestrictions(
+ primaryChipViewBinding,
+ viewModel.ongoingActivityChipsLegacy.value.primary,
+ )
+ OngoingActivityChipBinder.resetSecondaryChipWidthRestrictions(
+ secondaryChipViewBinding,
+ viewModel.ongoingActivityChipsLegacy.value.secondary,
+ )
+ view.requestLayout()
}
}
}
@@ -314,48 +323,42 @@ constructor(
}
/** Bind the (legacy) single primary ongoing activity chip with the status bar visibility */
- private suspend fun bindLegacyPrimaryOngoingActivityChipWithVisibility(
- viewModel: HomeStatusBarViewModel,
+ private fun bindLegacyPrimaryOngoingActivityChipWithVisibility(
+ areChipsAllowed: Boolean,
primaryChipModel: OngoingActivityChipModel,
primaryChipViewBinding: OngoingActivityChipViewBinding,
) {
- viewModel.canShowOngoingActivityChips.collectLatest { visible ->
- if (!visible) {
- primaryChipViewBinding.rootView.hide(shouldAnimateChange = false)
- } else {
- when (primaryChipModel) {
- is OngoingActivityChipModel.Active -> {
- primaryChipViewBinding.rootView.show(shouldAnimateChange = true)
- }
+ if (!areChipsAllowed) {
+ primaryChipViewBinding.rootView.hide(shouldAnimateChange = false)
+ } else {
+ when (primaryChipModel) {
+ is OngoingActivityChipModel.Active -> {
+ primaryChipViewBinding.rootView.show(shouldAnimateChange = true)
+ }
- is OngoingActivityChipModel.Inactive -> {
- primaryChipViewBinding.rootView.hide(
- state = View.GONE,
- shouldAnimateChange = primaryChipModel.shouldAnimate,
- )
- }
+ is OngoingActivityChipModel.Inactive -> {
+ primaryChipViewBinding.rootView.hide(
+ state = View.GONE,
+ shouldAnimateChange = primaryChipModel.shouldAnimate,
+ )
}
}
}
}
/** Bind the primary/secondary chips along with the home status bar's visibility */
- private suspend fun bindOngoingActivityChipsWithVisibility(
- viewModel: HomeStatusBarViewModel,
+ private fun bindOngoingActivityChipsWithVisibility(
+ areChipsAllowed: Boolean,
chips: MultipleOngoingActivityChipsModelLegacy,
primaryChipViewBinding: OngoingActivityChipViewBinding,
secondaryChipViewBinding: OngoingActivityChipViewBinding,
) {
- viewModel.canShowOngoingActivityChips.collectLatest { canShow ->
- if (!canShow) {
- primaryChipViewBinding.rootView.hide(shouldAnimateChange = false)
- secondaryChipViewBinding.rootView.hide(shouldAnimateChange = false)
- } else {
- primaryChipViewBinding.rootView.adjustVisibility(chips.primary.toVisibilityModel())
- secondaryChipViewBinding.rootView.adjustVisibility(
- chips.secondary.toVisibilityModel()
- )
- }
+ if (!areChipsAllowed) {
+ primaryChipViewBinding.rootView.hide(shouldAnimateChange = false)
+ secondaryChipViewBinding.rootView.hide(shouldAnimateChange = false)
+ } else {
+ primaryChipViewBinding.rootView.adjustVisibility(chips.primary.toVisibilityModel())
+ secondaryChipViewBinding.rootView.adjustVisibility(chips.secondary.toVisibilityModel())
}
}
@@ -428,10 +431,15 @@ constructor(
// See CollapsedStatusBarFragment#hide.
private fun View.hide(state: Int = View.INVISIBLE, shouldAnimateChange: Boolean) {
animate().cancel()
- if (visibility == View.INVISIBLE || visibility == View.GONE) {
+
+ if (
+ (visibility == View.INVISIBLE && state == View.INVISIBLE) ||
+ (visibility == View.GONE && state == View.GONE)
+ ) {
return
}
- if (!shouldAnimateChange) {
+ val isAlreadyHidden = visibility == View.INVISIBLE || visibility == View.GONE
+ if (!shouldAnimateChange || isAlreadyHidden) {
alpha = 0f
visibility = state
return
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
index 4189221d8a83..c91ea9a50028 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
@@ -196,13 +196,15 @@ fun StatusBarRoot(
setContent {
PlatformTheme {
- val chips by
+ val chipsVisibilityModel by
statusBarViewModel.ongoingActivityChips
.collectAsStateWithLifecycle()
- OngoingActivityChips(
- chips = chips,
- iconViewStore = iconViewStore,
- )
+ if (chipsVisibilityModel.areChipsAllowed) {
+ OngoingActivityChips(
+ chips = chipsVisibilityModel.chips,
+ iconViewStore = iconViewStore,
+ )
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/ChipsVisibilityModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/ChipsVisibilityModel.kt
new file mode 100644
index 000000000000..5cc432fc6771
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/ChipsVisibilityModel.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.shared.ui.model
+
+import com.android.systemui.statusbar.chips.ui.model.MultipleOngoingActivityChipsModel
+
+data class ChipsVisibilityModel(
+ val chips: MultipleOngoingActivityChipsModel,
+ /**
+ * True if the chips are allowed to be shown and false otherwise (e.g. if we're on lockscreen).
+ */
+ val areChipsAllowed: Boolean,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
index 807e90567eb7..9975aff938d6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
@@ -67,6 +67,7 @@ import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernizat
import com.android.systemui.statusbar.pipeline.battery.ui.viewmodel.BatteryViewModel
import com.android.systemui.statusbar.pipeline.shared.domain.interactor.HomeStatusBarIconBlockListInteractor
import com.android.systemui.statusbar.pipeline.shared.domain.interactor.HomeStatusBarInteractor
+import com.android.systemui.statusbar.pipeline.shared.ui.model.ChipsVisibilityModel
import com.android.systemui.statusbar.pipeline.shared.ui.model.SystemInfoCombinedVisibilityModel
import com.android.systemui.statusbar.pipeline.shared.ui.model.VisibilityModel
import dagger.assisted.Assisted
@@ -125,7 +126,7 @@ interface HomeStatusBarViewModel : Activatable {
val primaryOngoingActivityChip: StateFlow<OngoingActivityChipModel>
/** All supported activity chips, whether they are currently active or not. */
- val ongoingActivityChips: StateFlow<MultipleOngoingActivityChipsModel>
+ val ongoingActivityChips: StateFlow<ChipsVisibilityModel>
/**
* The multiple ongoing activity chips that should be shown on the left-hand side of the status
@@ -252,8 +253,6 @@ constructor(
override val primaryOngoingActivityChip = ongoingActivityChipsViewModel.primaryChip
- override val ongoingActivityChips = ongoingActivityChipsViewModel.chips
-
override val ongoingActivityChipsLegacy = ongoingActivityChipsViewModel.chipsLegacy
override val popupChips
@@ -369,15 +368,6 @@ constructor(
)
.flowOn(bgDispatcher)
- private val isAnyChipVisible =
- if (StatusBarChipsModernization.isEnabled) {
- ongoingActivityChips.map { it.active.any { chip -> !chip.isHidden } }
- } else if (StatusBarNotifChips.isEnabled) {
- ongoingActivityChipsLegacy.map { it.primary is OngoingActivityChipModel.Active }
- } else {
- primaryOngoingActivityChip.map { it is OngoingActivityChipModel.Active }
- }
-
/**
* True if we need to hide the usual start side content in order to show the heads up
* notification info.
@@ -419,9 +409,38 @@ constructor(
combine(
isHomeStatusBarAllowed,
keyguardInteractor.isSecureCameraActive,
- headsUpNotificationInteractor.statusBarHeadsUpStatus,
- ) { isHomeStatusBarAllowed, isSecureCameraActive, headsUpState ->
- isHomeStatusBarAllowed && !isSecureCameraActive && !headsUpState.isPinned
+ hideStartSideContentForHeadsUp,
+ ) { isHomeStatusBarAllowed, isSecureCameraActive, hideStartSideContentForHeadsUp ->
+ isHomeStatusBarAllowed && !isSecureCameraActive && !hideStartSideContentForHeadsUp
+ }
+
+ override val ongoingActivityChips =
+ combine(ongoingActivityChipsViewModel.chips, canShowOngoingActivityChips) { chips, canShow
+ ->
+ ChipsVisibilityModel(chips, areChipsAllowed = canShow)
+ }
+ .stateIn(
+ bgScope,
+ SharingStarted.WhileSubscribed(),
+ initialValue =
+ ChipsVisibilityModel(
+ chips = MultipleOngoingActivityChipsModel(),
+ areChipsAllowed = false,
+ ),
+ )
+
+ private val hasOngoingActivityChips =
+ if (StatusBarChipsModernization.isEnabled) {
+ ongoingActivityChips.map { it.chips.active.any { chip -> !chip.isHidden } }
+ } else if (StatusBarNotifChips.isEnabled) {
+ ongoingActivityChipsLegacy.map { it.primary is OngoingActivityChipModel.Active }
+ } else {
+ primaryOngoingActivityChip.map { it is OngoingActivityChipModel.Active }
+ }
+
+ private val isAnyChipVisible =
+ combine(hasOngoingActivityChips, canShowOngoingActivityChips) { hasChips, canShowChips ->
+ hasChips && canShowChips
}
override val isClockVisible: Flow<VisibilityModel> =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
index d41ef97f4664..ab5b3499d9c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
@@ -425,7 +425,7 @@ public class SecurityControllerImpl implements SecurityController {
@Override
@Nullable
public Drawable getIcon() {
- DeprecateDpmSupervisionApis.assertInNewMode();
+ DeprecateDpmSupervisionApis.unsafeAssertInNewMode();
return isParentalControlsEnabled()
? mContext.getDrawable(R.drawable.ic_supervision)
: null;
@@ -439,7 +439,7 @@ public class SecurityControllerImpl implements SecurityController {
@Override
@Nullable
public CharSequence getLabel() {
- DeprecateDpmSupervisionApis.assertInNewMode();
+ DeprecateDpmSupervisionApis.unsafeAssertInNewMode();
return isParentalControlsEnabled()
? mContext.getString(R.string.status_bar_supervision)
: null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt
index a28d14fd908d..e8347df5653f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt
@@ -137,7 +137,7 @@ constructor(
)
else MutableStateFlow<ZenMode?>(null)
get() {
- ModesUi.assertInNewMode()
+ ModesUi.unsafeAssertInNewMode()
return field
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java
index 0596a80a85b0..25972ac2bedf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java
@@ -185,7 +185,7 @@ public class StatusBarWindowControllerImpl implements StatusBarWindowController
@Override
public void stop() {
- StatusBarConnectedDisplays.assertInNewMode();
+ StatusBarConnectedDisplays.unsafeAssertInNewMode();
try {
mWindowManager.removeView(mStatusBarWindowView);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStore.kt
index f7688d2feab5..39afc38dad11 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStore.kt
@@ -24,11 +24,11 @@ import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository
import com.android.systemui.display.data.repository.PerDisplayStore
-import com.android.systemui.display.data.repository.PerDisplayStoreImpl
import com.android.systemui.display.data.repository.SingleDisplayStore
import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
import com.android.systemui.statusbar.data.repository.StatusBarConfigurationControllerStore
import com.android.systemui.statusbar.data.repository.StatusBarContentInsetsProviderStore
+import com.android.systemui.statusbar.data.repository.StatusBarPerDisplayStoreImpl
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -48,10 +48,13 @@ constructor(
displayRepository: DisplayRepository,
) :
StatusBarWindowControllerStore,
- PerDisplayStoreImpl<StatusBarWindowController>(backgroundApplicationScope, displayRepository) {
+ StatusBarPerDisplayStoreImpl<StatusBarWindowController>(
+ backgroundApplicationScope,
+ displayRepository,
+ ) {
init {
- StatusBarConnectedDisplays.assertInNewMode()
+ StatusBarConnectedDisplays.unsafeAssertInNewMode()
}
override fun createInstanceForDisplay(displayId: Int): StatusBarWindowController? {
diff --git a/packages/SystemUI/src/com/android/systemui/supervision/shared/DeprecateDpmSupervisionApis.kt b/packages/SystemUI/src/com/android/systemui/supervision/shared/DeprecateDpmSupervisionApis.kt
index cbd3dc73c6c0..59c05c2493c3 100644
--- a/packages/SystemUI/src/com/android/systemui/supervision/shared/DeprecateDpmSupervisionApis.kt
+++ b/packages/SystemUI/src/com/android/systemui/supervision/shared/DeprecateDpmSupervisionApis.kt
@@ -50,7 +50,7 @@ object DeprecateDpmSupervisionApis {
* Caution!! Using this check incorrectly will cause crashes in nextfood builds!
*/
@JvmStatic
- inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME)
+ inline fun unsafeAssertInNewMode() = RefactorFlagUtils.unsafeAssertInNewMode(isEnabled, FLAG_NAME)
/**
* Called to ensure code is only run when the flag is disabled. This will throw an exception if
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/shared/flag/VolumePanelFlag.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/shared/flag/VolumePanelFlag.kt
index 485f4b5cbfd7..4919139385ab 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/shared/flag/VolumePanelFlag.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/shared/flag/VolumePanelFlag.kt
@@ -29,6 +29,6 @@ class VolumePanelFlag @Inject constructor() {
}
fun assertNewVolumePanel() {
- RefactorFlagUtils.assertInNewMode(Flags.newVolumePanel(), Flags.FLAG_NEW_VOLUME_PANEL)
+ RefactorFlagUtils.unsafeAssertInNewMode(Flags.newVolumePanel(), Flags.FLAG_NEW_VOLUME_PANEL)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index feaf1a630a53..8e713495902a 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -302,7 +302,7 @@ public final class WMShell implements
.commitUpdate(mDisplayTracker.getDefaultDisplayId());
}
});
- mSysUiState.addCallback(sysUiStateFlag -> {
+ mSysUiState.addCallback((sysUiStateFlag, displayId) -> {
mIsSysUiStateValid = (sysUiStateFlag & INVALID_SYSUI_STATE_MASK) == 0;
pip.onSystemUiStateChanged(mIsSysUiStateValid, sysUiStateFlag);
});
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
index 7cf93277bb5b..5b32b922d377 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
@@ -191,7 +191,7 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
mWindowManager = spy(new TestableWindowManager(wm));
mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager);
- mSysUiState = new SysUiState(mDisplayTracker, mKosmos.getSceneContainerPlugin());
+ mSysUiState = mKosmos.getSysuiState();
mSysUiState.addCallback(Mockito.mock(SysUiState.SysUiStateCallback.class));
when(mSecureSettings.getIntForUser(anyString(), anyInt(), anyInt())).then(
returnsSecondArg());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/EditModeTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/EditModeTest.kt
index 8c09b81744d7..e76be82c9340 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/EditModeTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/EditModeTest.kt
@@ -25,6 +25,8 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onAllNodesWithText
+import androidx.compose.ui.test.onFirst
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
@@ -80,7 +82,9 @@ class EditModeTest : SysuiTestCase() {
composeRule.assertCurrentTilesGridContainsExactly(
listOf("tileA", "tileB", "tileC", "tileD_large", "tileE", "tileF")
)
- composeRule.assertAvailableTilesGridContainsExactly(listOf("tileG_large"))
+ composeRule.assertAvailableTilesGridContainsExactly(
+ TestEditTiles.map { it.tile.tileSpec.spec }
+ )
}
@Test
@@ -88,7 +92,8 @@ class EditModeTest : SysuiTestCase() {
composeRule.setContent { EditTileGridUnderTest() }
composeRule.waitForIdle()
- composeRule.onNodeWithContentDescription("tileA").performClick() // Selects
+ // Selects first "tileA", i.e. the one in the current grid
+ composeRule.onAllNodesWithText("tileA").onFirst().performClick()
composeRule.onNodeWithText("Remove").performClick() // Removes
composeRule.waitForIdle()
@@ -96,7 +101,9 @@ class EditModeTest : SysuiTestCase() {
composeRule.assertCurrentTilesGridContainsExactly(
listOf("tileB", "tileC", "tileD_large", "tileE")
)
- composeRule.assertAvailableTilesGridContainsExactly(listOf("tileA", "tileF", "tileG_large"))
+ composeRule.assertAvailableTilesGridContainsExactly(
+ TestEditTiles.map { it.tile.tileSpec.spec }
+ )
}
private fun ComposeContentTestRule.assertCurrentTilesGridContainsExactly(specs: List<String>) =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/ResizingTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/ResizingTest.kt
index bd4c5f50eee7..021be3235ee1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/ResizingTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/ResizingTest.kt
@@ -25,7 +25,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.click
import androidx.compose.ui.test.junit4.createComposeRule
-import androidx.compose.ui.test.onNodeWithContentDescription
+import androidx.compose.ui.test.onAllNodesWithText
+import androidx.compose.ui.test.onFirst
import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performCustomAccessibilityActionWithLabel
import androidx.compose.ui.test.performTouchInput
@@ -85,7 +86,8 @@ class ResizingTest : SysuiTestCase() {
composeRule.waitForIdle()
composeRule
- .onNodeWithContentDescription("tileA")
+ .onAllNodesWithText("tileA")
+ .onFirst()
.performCustomAccessibilityActionWithLabel(
context.getString(R.string.accessibility_qs_edit_toggle_tile_size_action)
)
@@ -103,7 +105,8 @@ class ResizingTest : SysuiTestCase() {
composeRule.waitForIdle()
composeRule
- .onNodeWithContentDescription("tileD_large")
+ .onAllNodesWithText("tileD_large")
+ .onFirst()
.performCustomAccessibilityActionWithLabel(
context.getString(R.string.accessibility_qs_edit_toggle_tile_size_action)
)
@@ -121,7 +124,8 @@ class ResizingTest : SysuiTestCase() {
composeRule.waitForIdle()
composeRule
- .onNodeWithContentDescription("tileA")
+ .onAllNodesWithText("tileA")
+ .onFirst()
.performClick() // Select
.performTouchInput { // Tap on resizing handle
click(centerRight)
@@ -141,7 +145,8 @@ class ResizingTest : SysuiTestCase() {
composeRule.waitForIdle()
composeRule
- .onNodeWithContentDescription("tileD_large")
+ .onAllNodesWithText("tileD_large")
+ .onFirst()
.performClick() // Select
.performTouchInput { // Tap on resizing handle
click(centerRight)
@@ -161,7 +166,8 @@ class ResizingTest : SysuiTestCase() {
composeRule.waitForIdle()
composeRule
- .onNodeWithContentDescription("tileA")
+ .onAllNodesWithText("tileA")
+ .onFirst()
.performClick() // Select
.performTouchInput { // Resize up
swipeRight(startX = right, endX = right * 2)
@@ -181,7 +187,8 @@ class ResizingTest : SysuiTestCase() {
composeRule.waitForIdle()
composeRule
- .onNodeWithContentDescription("tileD_large")
+ .onAllNodesWithText("tileD_large")
+ .onFirst()
.performClick() // Select
.performTouchInput { // Resize down
swipeLeft()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/recents/LauncherProxyServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/recents/LauncherProxyServiceTest.kt
index 40547c2787ac..0a5efb7bb286 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/recents/LauncherProxyServiceTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/recents/LauncherProxyServiceTest.kt
@@ -24,6 +24,7 @@ import android.os.PowerManager
import android.os.UserManager
import android.testing.TestableContext
import android.testing.TestableLooper
+import android.view.Display
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.app.AssistUtils
@@ -35,8 +36,7 @@ import com.android.systemui.dump.DumpManager
import com.android.systemui.keyguard.KeyguardUnlockAnimationController
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.keyguard.ui.view.InWindowLauncherUnlockAnimationManager
-import com.android.systemui.model.SysUiState
-import com.android.systemui.model.sceneContainerPlugin
+import com.android.systemui.model.sysUiState
import com.android.systemui.navigationbar.NavigationBarController
import com.android.systemui.navigationbar.NavigationModeController
import com.android.systemui.process.ProcessWrapper
@@ -67,6 +67,7 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers
+import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
import org.mockito.Mockito.any
import org.mockito.Mockito.anyInt
@@ -93,7 +94,7 @@ class LauncherProxyServiceTest : SysuiTestCase() {
@Mock private lateinit var processWrapper: ProcessWrapper
private val displayTracker = FakeDisplayTracker(mContext)
private val fakeSystemClock = FakeSystemClock()
- private val sysUiState = SysUiState(displayTracker, kosmos.sceneContainerPlugin)
+ private val sysUiState = kosmos.sysUiState
private val wakefulnessLifecycle =
WakefulnessLifecycle(mContext, null, fakeSystemClock, dumpManager)
@@ -161,11 +162,13 @@ class LauncherProxyServiceTest : SysuiTestCase() {
wakefulnessLifecycle.dispatchFinishedGoingToSleep()
clearInvocations(launcherProxy)
- wakefulnessLifecycle.dispatchFinishedWakingUp()
+ wakefulnessLifecycle
+ .dispatchFinishedWakingUp()
verify(launcherProxy)
.onSystemUiStateChanged(
- longThat { it and SYSUI_STATE_WAKEFULNESS_MASK == WAKEFULNESS_AWAKE }
+ longThat { it and SYSUI_STATE_WAKEFULNESS_MASK == WAKEFULNESS_AWAKE },
+ eq(Display.DEFAULT_DISPLAY),
)
}
@@ -175,7 +178,8 @@ class LauncherProxyServiceTest : SysuiTestCase() {
verify(launcherProxy)
.onSystemUiStateChanged(
- longThat { it and SYSUI_STATE_WAKEFULNESS_MASK == WAKEFULNESS_WAKING }
+ longThat { it and SYSUI_STATE_WAKEFULNESS_MASK == WAKEFULNESS_WAKING },
+ eq(Display.DEFAULT_DISPLAY),
)
}
@@ -185,7 +189,8 @@ class LauncherProxyServiceTest : SysuiTestCase() {
verify(launcherProxy)
.onSystemUiStateChanged(
- longThat { it and SYSUI_STATE_WAKEFULNESS_MASK == WAKEFULNESS_ASLEEP }
+ longThat { it and SYSUI_STATE_WAKEFULNESS_MASK == WAKEFULNESS_ASLEEP },
+ eq(Display.DEFAULT_DISPLAY),
)
}
@@ -197,7 +202,8 @@ class LauncherProxyServiceTest : SysuiTestCase() {
verify(launcherProxy)
.onSystemUiStateChanged(
- longThat { it and SYSUI_STATE_WAKEFULNESS_MASK == WAKEFULNESS_GOING_TO_SLEEP }
+ longThat { it and SYSUI_STATE_WAKEFULNESS_MASK == WAKEFULNESS_GOING_TO_SLEEP },
+ eq(Display.DEFAULT_DISPLAY),
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
index e42bf19663a5..51bb38fa5ba9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
@@ -23,7 +23,6 @@ import android.platform.test.flag.junit.FlagsParameterization
import android.testing.TestableLooper
import android.testing.TestableLooper.RunWithLooper
import android.view.Choreographer
-import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
@@ -54,6 +53,7 @@ import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.qs.flags.QSComposeFragment
import com.android.systemui.res.R
+import com.android.systemui.scene.ui.view.WindowRootViewKeyEventHandler
import com.android.systemui.settings.brightness.data.repository.BrightnessMirrorShowingRepository
import com.android.systemui.settings.brightness.domain.interactor.BrightnessMirrorShowingInteractorPassThrough
import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler
@@ -96,7 +96,6 @@ import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.setMain
-import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -245,7 +244,7 @@ class NotificationShadeWindowViewControllerTest(flags: FlagsParameterization) :
notificationLaunchAnimationInteractor,
featureFlagsClassic,
fakeClock,
- sysUIKeyEventHandler,
+ WindowRootViewKeyEventHandler({ sysUIKeyEventHandler }, falsingCollector),
quickSettingsController,
primaryBouncerInteractor,
alternateBouncerInteractor,
@@ -591,34 +590,6 @@ class NotificationShadeWindowViewControllerTest(flags: FlagsParameterization) :
}
@Test
- fun forwardsDispatchKeyEvent() {
- val keyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_B)
- interactionEventHandler.dispatchKeyEvent(keyEvent)
- verify(sysUIKeyEventHandler).dispatchKeyEvent(keyEvent)
- }
-
- @Test
- fun forwardsDispatchKeyEventPreIme() {
- val keyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_B)
- interactionEventHandler.dispatchKeyEventPreIme(keyEvent)
- verify(sysUIKeyEventHandler).dispatchKeyEventPreIme(keyEvent)
- }
-
- @Test
- fun forwardsInterceptMediaKey() {
- val keyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_VOLUME_UP)
- interactionEventHandler.interceptMediaKey(keyEvent)
- verify(sysUIKeyEventHandler).interceptMediaKey(keyEvent)
- }
-
- @Test
- fun forwardsCollectKeyEvent() {
- val keyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A)
- interactionEventHandler.collectKeyEvent(keyEvent)
- assertEquals(keyEvent, falsingCollector.lastKeyEvent)
- }
-
- @Test
fun cancelCurrentTouch_callsDragDownHelper() {
underTest.cancelCurrentTouch()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index 8281132e7502..341bd3a38999 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -33,8 +33,6 @@ import static com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_BAR;
import static com.google.common.truth.Truth.assertThat;
-import static kotlinx.coroutines.flow.StateFlowKt.MutableStateFlow;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -57,6 +55,8 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
+import static kotlinx.coroutines.flow.StateFlowKt.MutableStateFlow;
+
import android.app.ActivityManager;
import android.app.IActivityManager;
import android.app.INotificationManager;
@@ -464,8 +464,8 @@ public class BubblesTest extends SysuiTestCase {
mZenModeConfig.suppressedVisualEffects = 0;
when(mZenModeController.getConfig()).thenReturn(mZenModeConfig);
- mSysUiState = new SysUiState(mDisplayTracker, mKosmos.getSceneContainerPlugin());
- mSysUiState.addCallback(sysUiFlags -> {
+ mSysUiState = mKosmos.getSysuiState();
+ mSysUiState.addCallback((sysUiFlags, displayId) -> {
mSysUiStateBubblesManageMenuExpanded =
(sysUiFlags
& QuickStepContract.SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED) != 0;
@@ -624,7 +624,8 @@ public class BubblesTest extends SysuiTestCase {
TAG,
String.format("waiting for animations to complete. attempt %d", retryCount));
// post a message to the looper and wait for it to be processed
- mTestableLooper.runWithLooper(() -> {});
+ mTestableLooper.runWithLooper(() -> {
+ });
retryCount++;
}
mTestableLooper.processAllMessages();
@@ -2996,9 +2997,11 @@ public class BubblesTest extends SysuiTestCase {
}
@Override
- public void onDragItemOverBubbleBarDragZone(@NonNull BubbleBarLocation location) {}
+ public void onDragItemOverBubbleBarDragZone(@NonNull BubbleBarLocation location) {
+ }
@Override
- public void onItemDraggedOutsideBubbleBarDropZone() {}
+ public void onItemDraggedOutsideBubbleBarDropZone() {
+ }
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/development/domain/interactor/BuildNumberInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/development/domain/interactor/BuildNumberInteractorKosmos.kt
index aa4dd18a6cba..74d53b088c9b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/development/domain/interactor/BuildNumberInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/development/domain/interactor/BuildNumberInteractorKosmos.kt
@@ -20,6 +20,7 @@ import android.content.clipboardManager
import android.content.res.mainResources
import com.android.systemui.development.data.repository.developmentSettingRepository
import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.user.data.repository.userRepository
@@ -31,5 +32,6 @@ val Kosmos.buildNumberInteractor by
userRepository,
{ clipboardManager },
testDispatcher,
+ applicationCoroutineScope,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayRepository.kt
index d6f0e06e104d..663a85330f70 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayRepository.kt
@@ -53,6 +53,7 @@ class FakeDisplayRepository @Inject constructor() : DisplayRepository {
MutableSharedFlow<DisplayRepository.PendingDisplay?>(replay = 1)
private val displayAdditionEventFlow = MutableSharedFlow<Display?>(replay = 0)
private val displayRemovalEventFlow = MutableSharedFlow<Int>(replay = 0)
+ private val displayIdsWithSystemDecorationsFlow = MutableStateFlow<Set<Int>>(emptySet())
suspend fun addDisplay(displayId: Int, type: Int = Display.TYPE_EXTERNAL) {
addDisplay(display(type, id = displayId))
@@ -62,10 +63,19 @@ class FakeDisplayRepository @Inject constructor() : DisplayRepository {
displays.forEach { addDisplay(it) }
}
+ suspend operator fun plusAssign(display: Display) {
+ addDisplay(display)
+ }
+
+ suspend operator fun minusAssign(displayId: Int) {
+ removeDisplay(displayId)
+ }
+
suspend fun addDisplay(display: Display) {
flow.value += display
displayIdFlow.value += display.displayId
displayAdditionEventFlow.emit(display)
+ displayIdsWithSystemDecorationsFlow.value += display.displayId
}
suspend fun removeDisplay(displayId: Int) {
@@ -74,6 +84,16 @@ class FakeDisplayRepository @Inject constructor() : DisplayRepository {
displayRemovalEventFlow.emit(displayId)
}
+ suspend fun triggerAddDisplaySystemDecorationEvent(displayId: Int) {
+ displayIdsWithSystemDecorationsFlow.value += displayId
+ displayIdsWithSystemDecorationsFlow.emit(displayIdsWithSystemDecorationsFlow.value)
+ }
+
+ suspend fun triggerRemoveSystemDecorationEvent(displayId: Int) {
+ displayIdsWithSystemDecorationsFlow.value -= displayId
+ displayIdsWithSystemDecorationsFlow.emit(displayIdsWithSystemDecorationsFlow.value)
+ }
+
/** Emits [value] as [displayAdditionEvent] flow value. */
suspend fun emit(value: Display?) = displayAdditionEventFlow.emit(value)
@@ -104,7 +124,8 @@ class FakeDisplayRepository @Inject constructor() : DisplayRepository {
private val _displayChangeEvent = MutableSharedFlow<Int>(replay = 1)
override val displayChangeEvent: Flow<Int> = _displayChangeEvent
- override val displayIdsWithSystemDecorations: StateFlow<Set<Int>> = MutableStateFlow(emptySet())
+ override val displayIdsWithSystemDecorations: StateFlow<Set<Int>> =
+ displayIdsWithSystemDecorationsFlow
suspend fun emitDisplayChangeEvent(displayId: Int) = _displayChangeEvent.emit(displayId)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/PerDisplayStoreKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/PerDisplayStoreKosmos.kt
index e3797260ed6d..aa23aa30b7bc 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/PerDisplayStoreKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/PerDisplayStoreKosmos.kt
@@ -16,8 +16,10 @@
package com.android.systemui.display.data.repository
+import com.android.systemui.dump.dumpManager
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testScope
import kotlinx.coroutines.CoroutineScope
class FakePerDisplayStore(
@@ -47,3 +49,30 @@ val Kosmos.fakePerDisplayStore by
displayRepository = displayRepository,
)
}
+
+class FakePerDisplayInstanceProviderWithTeardown :
+ PerDisplayInstanceProviderWithTeardown<TestPerDisplayInstance> {
+ val destroyed = mutableListOf<TestPerDisplayInstance>()
+
+ override fun destroyInstance(instance: TestPerDisplayInstance) {
+ destroyed += instance
+ }
+
+ override fun createInstance(displayId: Int): TestPerDisplayInstance? {
+ return TestPerDisplayInstance(displayId)
+ }
+}
+
+val Kosmos.fakePerDisplayInstanceProviderWithTeardown by
+ Kosmos.Fixture { FakePerDisplayInstanceProviderWithTeardown() }
+
+val Kosmos.fakePerDisplayInstanceRepository by
+ Kosmos.Fixture {
+ PerDisplayInstanceRepositoryImpl(
+ debugName = "fakePerDisplayInstanceRepository",
+ instanceProvider = fakePerDisplayInstanceProviderWithTeardown,
+ testScope.backgroundScope,
+ displayRepository,
+ dumpManager,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyevent/domain/interactor/SysUIKeyEventHandlerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyevent/domain/interactor/SysUIKeyEventHandlerKosmos.kt
new file mode 100644
index 000000000000..6fd7ef315fcc
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyevent/domain/interactor/SysUIKeyEventHandlerKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyevent.domain.interactor
+
+import com.android.systemui.kosmos.Kosmos
+import org.mockito.kotlin.mock
+
+var Kosmos.mockSysUIKeyEventHandler by Kosmos.Fixture { mock<SysUIKeyEventHandler>() }
+var Kosmos.sysUIKeyEventHandler by Kosmos.Fixture { mockSysUIKeyEventHandler }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
index dff9f3abfc05..af89403c5397 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
@@ -53,6 +53,8 @@ import com.android.systemui.keyguard.domain.interactor.pulseExpansionInteractor
import com.android.systemui.keyguard.ui.viewmodel.glanceableHubToLockscreenTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.lockscreenToGlanceableHubTransitionViewModel
import com.android.systemui.model.sceneContainerPlugin
+import com.android.systemui.model.sysUIStateDispatcher
+import com.android.systemui.model.sysUiState
import com.android.systemui.plugins.statusbar.statusBarStateController
import com.android.systemui.power.data.repository.fakePowerRepository
import com.android.systemui.power.domain.interactor.powerInteractor
@@ -64,6 +66,7 @@ import com.android.systemui.scene.sceneContainerConfig
import com.android.systemui.scene.shared.model.sceneDataSource
import com.android.systemui.scene.ui.view.mockWindowRootViewProvider
import com.android.systemui.settings.brightness.data.repository.brightnessMirrorShowingRepository
+import com.android.systemui.settings.displayTracker
import com.android.systemui.shade.data.repository.shadeRepository
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.shade.domain.interactor.shadeLayoutParams
@@ -198,4 +201,7 @@ class KosmosJavaAdapter() {
val fakeDisableFlagsRepository by lazy { kosmos.fakeDisableFlagsRepository }
val mockWindowRootViewProvider by lazy { kosmos.mockWindowRootViewProvider }
val windowRootViewBlurInteractor by lazy { kosmos.windowRootViewBlurInteractor }
+ val sysuiState by lazy { kosmos.sysUiState }
+ val displayTracker by lazy { kosmos.displayTracker }
+ val sysUIStateDispatcher by lazy { kosmos.sysUIStateDispatcher }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/model/SceneContainerPluginKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/model/SceneContainerPluginKosmos.kt
index d19dfe8d74fb..79506f9e75a5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/model/SceneContainerPluginKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/model/SceneContainerPluginKosmos.kt
@@ -20,10 +20,12 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.shade.data.repository.fakeShadeDisplaysRepository
val Kosmos.sceneContainerPlugin by Fixture {
SceneContainerPlugin(
sceneInteractor = { sceneInteractor },
occlusionInteractor = { sceneContainerOcclusionInteractor },
+ shadeDisplaysRepository = { fakeShadeDisplaysRepository },
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt
index 6ddf633e58e5..00deaafd7009 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt
@@ -16,16 +16,34 @@
package com.android.systemui.model
+import android.view.Display
+import com.android.systemui.common.domain.interactor.SysUIStateDisplaysInteractor
+import com.android.systemui.display.data.repository.FakePerDisplayRepository
+import com.android.systemui.dump.dumpManager
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.settings.displayTracker
import org.mockito.Mockito.spy
-val Kosmos.sysUiState by Fixture {
- spy(
- SysUiState(
- displayTracker,
- sceneContainerPlugin,
- )
- )
+val Kosmos.sysUiState by Fixture { sysUiStateFactory.create(Display.DEFAULT_DISPLAY) }
+val Kosmos.sysUIStateDispatcher by Fixture { SysUIStateDispatcher() }
+
+val Kosmos.sysUiStateFactory by Fixture {
+ object : SysUiStateImpl.Factory {
+ override fun create(displayId: Int): SysUiStateImpl {
+ return spy(
+ SysUiStateImpl(
+ displayId,
+ sceneContainerPlugin,
+ dumpManager,
+ sysUIStateDispatcher,
+ )
+ )
+ }
+ }
+}
+
+val Kosmos.fakeSysUIStatePerDisplayRepository by Fixture { FakePerDisplayRepository<SysUiState>() }
+
+val Kosmos.sysuiStateInteractor by Fixture {
+ SysUIStateDisplaysInteractor(fakeSysUIStatePerDisplayRepository)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/FooterActionsTestUtils.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/FooterActionsTestUtils.kt
index 43307701b6fb..4618dc78dcc6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/FooterActionsTestUtils.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/FooterActionsTestUtils.kt
@@ -58,7 +58,7 @@ import com.android.systemui.util.mockito.mock
import com.android.systemui.util.settings.FakeGlobalSettings
import com.android.systemui.util.settings.GlobalSettings
import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestCoroutineScheduler
@@ -94,7 +94,7 @@ class FooterActionsTestUtils(
return createFooterActionsViewModel(
context,
footerActionsInteractor,
- flowOf(shadeMode),
+ MutableStateFlow(shadeMode),
falsingManager,
globalActionsDialogLite,
mockActivityStarter,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/ui/view/WindowRootViewKeyEventHandlerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/ui/view/WindowRootViewKeyEventHandlerKosmos.kt
new file mode 100644
index 000000000000..9369057240f0
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/ui/view/WindowRootViewKeyEventHandlerKosmos.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.scene.ui.view
+
+import com.android.systemui.classifier.falsingCollector
+import com.android.systemui.keyevent.domain.interactor.sysUIKeyEventHandler
+import com.android.systemui.kosmos.Kosmos
+
+val Kosmos.windowRootViewKeyEventHandler by
+ Kosmos.Fixture {
+ WindowRootViewKeyEventHandler(
+ sysUIKeyEventHandlerLazy = { sysUIKeyEventHandler },
+ falsingCollector = falsingCollector,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarOrchestratorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarOrchestratorKosmos.kt
index 9776fd91134d..66a17514c106 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarOrchestratorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarOrchestratorKosmos.kt
@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.core
import android.content.testableContext
-import android.view.mockIWindowManager
import com.android.systemui.bouncer.domain.interactor.primaryBouncerInteractor
import com.android.systemui.display.data.repository.displayRepository
import com.android.systemui.display.data.repository.displayScopeRepository
@@ -94,6 +93,5 @@ val Kosmos.multiDisplayStatusBarStarter by
statusBarInitializerStore,
privacyDotWindowControllerStore,
lightBarControllerStore,
- mockIWindowManager,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayStoreKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayStoreKosmos.kt
new file mode 100644
index 000000000000..0db8ee8a9109
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayStoreKosmos.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.data.repository
+
+import com.android.systemui.display.data.repository.DisplayRepository
+import com.android.systemui.display.data.repository.displayRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import kotlinx.coroutines.CoroutineScope
+
+class FakeStatusBarPerDisplayStore(
+ backgroundApplicationScope: CoroutineScope,
+ displayRepository: DisplayRepository,
+) :
+ StatusBarPerDisplayStoreImpl<TestPerDisplayInstance>(
+ backgroundApplicationScope,
+ displayRepository,
+ ) {
+
+ val removalActions = mutableListOf<TestPerDisplayInstance>()
+
+ override fun createInstanceForDisplay(displayId: Int): TestPerDisplayInstance {
+ return TestPerDisplayInstance(displayId)
+ }
+
+ override val instanceClass = TestPerDisplayInstance::class.java
+
+ override suspend fun onDisplayRemovalAction(instance: TestPerDisplayInstance) {
+ removalActions += instance
+ }
+}
+
+data class TestPerDisplayInstance(val displayId: Int)
+
+val Kosmos.fakeStatusBarPerDisplayStore by
+ Kosmos.Fixture {
+ FakeStatusBarPerDisplayStore(
+ backgroundApplicationScope = applicationCoroutineScope,
+ displayRepository = displayRepository,
+ )
+ }
diff --git a/services/core/java/com/android/server/am/BroadcastController.java b/services/core/java/com/android/server/am/BroadcastController.java
index bec5db79ff9d..afd639d6c8c5 100644
--- a/services/core/java/com/android/server/am/BroadcastController.java
+++ b/services/core/java/com/android/server/am/BroadcastController.java
@@ -1961,7 +1961,9 @@ class BroadcastController {
private void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
mService.mProcessList.sendPackageBroadcastLocked(cmd, packages, userId);
- }private List<ResolveInfo> collectReceiverComponents(
+ }
+
+ private List<ResolveInfo> collectReceiverComponents(
Intent intent, String resolvedType, int callingUid, int callingPid,
int[] users, int[] broadcastAllowList) {
// TODO: come back and remove this assumption to triage all broadcasts
diff --git a/services/core/java/com/android/server/am/BroadcastProcessedEventRecord.java b/services/core/java/com/android/server/am/BroadcastProcessedEventRecord.java
new file mode 100644
index 000000000000..1bcedf6afd63
--- /dev/null
+++ b/services/core/java/com/android/server/am/BroadcastProcessedEventRecord.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import static com.android.internal.util.FrameworkStatsLog.BROADCAST_PROCESSED;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import com.android.internal.util.FrameworkStatsLog;
+
+final class BroadcastProcessedEventRecord {
+
+ /**
+ * Minimum threshold for logging the broadcast processed event.
+ */
+ private static final int MIN_THRESHOLD_FOR_LOGGING_TIME_MILLIS = 10;
+
+ @Nullable
+ private String mIntentAction;
+
+ private int mSenderUid;
+
+ private int mReceiverUid;
+
+ private int mNumberOfReceivers;
+
+ @NonNull
+ private String mReceiverProcessName;
+
+ private long mTotalBroadcastFinishTimeMillis;
+
+ private long mMaxReceiverFinishTimeMillis = Long.MIN_VALUE;
+
+ @NonNull
+ private int[] mBroadcastTypes;
+
+ @NonNull
+ public BroadcastProcessedEventRecord setBroadcastTypes(@NonNull int[] broadcastTypes) {
+ this.mBroadcastTypes = broadcastTypes;
+ return this;
+ }
+
+ @NonNull
+ public BroadcastProcessedEventRecord setReceiverProcessName(
+ @NonNull String receiverProcessName) {
+ mReceiverProcessName = receiverProcessName;
+ return this;
+ }
+
+ @NonNull
+ public BroadcastProcessedEventRecord setIntentAction(@Nullable String intentAction) {
+ mIntentAction = intentAction;
+ return this;
+ }
+
+ @NonNull
+ public BroadcastProcessedEventRecord setSenderUid(int uid) {
+ mSenderUid = uid;
+ return this;
+ }
+
+ @NonNull
+ public BroadcastProcessedEventRecord setReceiverUid(int uid) {
+ mReceiverUid = uid;
+ return this;
+ }
+
+ public void addReceiverFinishTime(long timeMillis) {
+ mTotalBroadcastFinishTimeMillis += timeMillis;
+ mMaxReceiverFinishTimeMillis = Math.max(mMaxReceiverFinishTimeMillis, timeMillis);
+ mNumberOfReceivers++;
+ }
+
+ @Nullable
+ String getIntentActionForTest() {
+ return mIntentAction;
+ }
+
+ int getSenderUidForTest() {
+ return mSenderUid;
+ }
+
+ int getReceiverUidForTest() {
+ return mReceiverUid;
+ }
+
+ int getNumberOfReceiversForTest() {
+ return mNumberOfReceivers;
+ }
+
+ @NonNull
+ String getReceiverProcessNameForTest() {
+ return mReceiverProcessName;
+ }
+
+ long getTotalBroadcastFinishTimeMillisForTest() {
+ return mTotalBroadcastFinishTimeMillis;
+ }
+
+ long getMaxReceiverFinishTimeMillisForTest() {
+ return mMaxReceiverFinishTimeMillis;
+ }
+
+ @NonNull
+ int[] getBroadcastTypesForTest() {
+ return mBroadcastTypes;
+ }
+
+ public void logToStatsD() {
+ // We do not care about the processes where total time to process the
+ // broadcast is less than 10ms/ are quick to process the broadcast.
+ if (mTotalBroadcastFinishTimeMillis <= MIN_THRESHOLD_FOR_LOGGING_TIME_MILLIS) {
+ return;
+ }
+
+ FrameworkStatsLog.write(
+ BROADCAST_PROCESSED,
+ mIntentAction,
+ mSenderUid,
+ mReceiverUid,
+ mNumberOfReceivers,
+ mReceiverProcessName,
+ mTotalBroadcastFinishTimeMillis,
+ mMaxReceiverFinishTimeMillis,
+ mBroadcastTypes);
+ }
+}
diff --git a/services/core/java/com/android/server/am/BroadcastQueueImpl.java b/services/core/java/com/android/server/am/BroadcastQueueImpl.java
index 78beb18263a7..c76a0d0ac59a 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueImpl.java
@@ -2189,6 +2189,11 @@ class BroadcastQueueImpl extends BroadcastQueue {
logBroadcastDeliveryEventReported(queue, app, r, index, receiver);
}
+ if (!r.isAssumedDelivered(index) && r.wasDelivered(index)) {
+ r.updateBroadcastProcessedEventRecord(receiver,
+ r.terminalTime[index] - r.scheduledTime[index]);
+ }
+
final boolean recordFinished = (r.terminalCount == r.receivers.size());
if (recordFinished) {
notifyFinishBroadcast(r);
@@ -2254,6 +2259,7 @@ class BroadcastQueueImpl extends BroadcastQueue {
mHistory.onBroadcastFinishedLocked(r);
logBootCompletedBroadcastCompletionLatencyIfPossible(r);
+ r.logBroadcastProcessedEventRecord();
if (r.intent.getComponent() == null && r.intent.getPackage() == null
&& (r.intent.getFlags() & Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index c1b0a76b24af..45c7d59b2392 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -167,6 +167,12 @@ final class BroadcastRecord extends Binder {
@Nullable
private ArrayMap<BroadcastRecord, Boolean> mMatchingRecordsCache;
+ // Stores the {@link BroadcastProcessedEventRecord} for each process associated with this
+ // record.
+ @NonNull
+ private ArrayMap<String, BroadcastProcessedEventRecord> mBroadcastProcessedRecords =
+ new ArrayMap<>();
+
private @Nullable String mCachedToString;
private @Nullable String mCachedToShortString;
@@ -654,6 +660,17 @@ final class BroadcastRecord extends Binder {
}
}
+ boolean wasDelivered(int index) {
+ final int deliveryState = getDeliveryState(index);
+ switch (deliveryState) {
+ case DELIVERY_DELIVERED:
+ case DELIVERY_TIMEOUT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
void copyEnqueueTimeFrom(@NonNull BroadcastRecord replacedBroadcast) {
originalEnqueueClockTime = enqueueClockTime;
enqueueTime = replacedBroadcast.enqueueTime;
@@ -1327,4 +1344,48 @@ final class BroadcastRecord extends Binder {
proto.write(BroadcastRecordProto.INTENT_ACTION, intent.getAction());
proto.end(token);
}
+
+ /**
+ * Uses the {@link BroadcastProcessedEventRecord} pojo to store the logging information related
+ * to {@param receiver} object.
+ */
+ public void updateBroadcastProcessedEventRecord(@NonNull Object receiver, long timeMillis) {
+ if (!Flags.logBroadcastProcessedEvent()) {
+ return;
+ }
+
+ final String receiverProcessName = getReceiverProcessName(receiver);
+ BroadcastProcessedEventRecord broadcastProcessedEventRecord =
+ mBroadcastProcessedRecords.get(receiverProcessName);
+ if (broadcastProcessedEventRecord == null) {
+ broadcastProcessedEventRecord = new BroadcastProcessedEventRecord()
+ .setBroadcastTypes(calculateTypesForLogging())
+ .setIntentAction(intent.getAction())
+ .setReceiverProcessName(receiverProcessName)
+ .setReceiverUid(getReceiverUid(receiver))
+ .setSenderUid(callingUid);
+
+ mBroadcastProcessedRecords.put(receiverProcessName, broadcastProcessedEventRecord);
+ }
+
+ broadcastProcessedEventRecord.addReceiverFinishTime(timeMillis);
+ }
+
+ public void logBroadcastProcessedEventRecord() {
+ if (!Flags.logBroadcastProcessedEvent()) {
+ return;
+ }
+
+ int size = mBroadcastProcessedRecords.size();
+ for (int i = 0; i < size; i++) {
+ mBroadcastProcessedRecords.valueAt(i).logToStatsD();
+ }
+ mBroadcastProcessedRecords.clear();
+ }
+
+ @VisibleForTesting
+ @NonNull
+ ArrayMap<String, BroadcastProcessedEventRecord> getBroadcastProcessedRecordsForTest() {
+ return mBroadcastProcessedRecords;
+ }
}
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 0954c49f94d6..3a041fd3b38a 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -228,6 +228,7 @@ public class SettingsToPropertiesMapper {
"media_reliability",
"media_solutions",
"media_tv",
+ "microxr",
"nearby",
"nfc",
"pdf_viewer",
diff --git a/services/core/java/com/android/server/am/broadcasts_flags.aconfig b/services/core/java/com/android/server/am/broadcasts_flags.aconfig
index 68e21a35a531..3867f77e408a 100644
--- a/services/core/java/com/android/server/am/broadcasts_flags.aconfig
+++ b/services/core/java/com/android/server/am/broadcasts_flags.aconfig
@@ -26,4 +26,15 @@ flag {
metadata {
purpose: PURPOSE_BUGFIX
}
-} \ No newline at end of file
+}
+
+flag {
+ name: "log_broadcast_processed_event"
+ namespace: "backstage_power"
+ description: "Log the broadcast processed event to Statsd"
+ bug: "387576580"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java b/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
index ca9a25b86aed..6f8c241a86ae 100644
--- a/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
+++ b/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
@@ -341,17 +341,15 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker {
}
private void commitUidPendingState(int uid) {
- int pendingUidState = mPendingUidStates.get(uid,
- mUidStates.get(uid, MIN_PRIORITY_UID_STATE));
- int pendingCapability = mPendingCapability.get(uid,
- mCapability.get(uid, PROCESS_CAPABILITY_NONE));
- boolean pendingAppWidgetVisible = mPendingAppWidgetVisible.get(uid,
- mAppWidgetVisible.get(uid, false));
int uidState = mUidStates.get(uid, MIN_PRIORITY_UID_STATE);
int capability = mCapability.get(uid, PROCESS_CAPABILITY_NONE);
boolean appWidgetVisible = mAppWidgetVisible.get(uid, false);
+ int pendingUidState = mPendingUidStates.get(uid, uidState);
+ int pendingCapability = mPendingCapability.get(uid, capability);
+ boolean pendingAppWidgetVisible = mPendingAppWidgetVisible.get(uid, appWidgetVisible);
+
boolean foregroundChange = uidState <= UID_STATE_MAX_LAST_NON_RESTRICTED
!= pendingUidState <= UID_STATE_MAX_LAST_NON_RESTRICTED
|| capability != pendingCapability
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index ef80d59993e9..8ef79a916530 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -16,6 +16,22 @@
package com.android.server.audio;
import static android.media.audio.Flags.scoManagedByAudio;
+import static android.media.AudioSystem.DEVICE_IN_ALL_SCO_SET;
+import static android.media.AudioSystem.DEVICE_IN_BLE_HEADSET;
+import static android.media.AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET;
+import static android.media.AudioSystem.DEVICE_IN_USB_HEADSET;
+import static android.media.AudioSystem.DEVICE_IN_WIRED_HEADSET;
+import static android.media.AudioSystem.DEVICE_OUT_ALL_SCO_SET;
+import static android.media.AudioSystem.DEVICE_OUT_BLE_HEADSET;
+import static android.media.AudioSystem.DEVICE_OUT_BLUETOOTH_SCO;
+import static android.media.AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
+import static android.media.AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
+import static android.media.AudioSystem.DEVICE_OUT_BUS;
+import static android.media.AudioSystem.DEVICE_OUT_EARPIECE;
+import static android.media.AudioSystem.DEVICE_OUT_SPEAKER;
+import static android.media.AudioSystem.DEVICE_OUT_USB_HEADSET;
+import static android.media.AudioSystem.DEVICE_OUT_WIRED_HEADSET;
+import static android.media.AudioSystem.isBluetoothScoOutDevice;
import static com.android.media.audio.Flags.equalScoLeaVcIndexRange;
import static com.android.media.audio.Flags.optimizeBtDeviceSwitch;
@@ -78,9 +94,11 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
@@ -514,7 +532,7 @@ public class AudioDeviceBroker {
@GuardedBy("mDeviceStateLock")
private CommunicationRouteClient topCommunicationRouteClient() {
for (CommunicationRouteClient crc : mCommunicationRouteClients) {
- if (crc.getUid() == mAudioModeOwner.mUid) {
+ if (crc.getUid() == mAudioModeOwner.mUid && !crc.isDisabled()) {
return crc;
}
}
@@ -574,36 +592,6 @@ public class AudioDeviceBroker {
return false;
}
- /*package */
- void postCheckCommunicationDeviceRemoval(@NonNull AudioDeviceAttributes device) {
- if (!isValidCommunicationDeviceType(
- AudioDeviceInfo.convertInternalDeviceToDeviceType(device.getInternalType()))) {
- return;
- }
- sendLMsgNoDelay(MSG_L_CHECK_COMMUNICATION_DEVICE_REMOVAL, SENDMSG_QUEUE, device);
- }
-
- @GuardedBy("mDeviceStateLock")
- void onCheckCommunicationDeviceRemoval(@NonNull AudioDeviceAttributes device) {
- if (AudioService.DEBUG_COMM_RTE) {
- Log.v(TAG, "onCheckCommunicationDeviceRemoval device: " + device.toString());
- }
- for (CommunicationRouteClient crc : mCommunicationRouteClients) {
- if (device.equals(crc.getDevice())) {
- if (AudioService.DEBUG_COMM_RTE) {
- Log.v(TAG, "onCheckCommunicationDeviceRemoval removing client: "
- + crc.toString());
- }
- // Cancelling the route for this client will remove it from the stack and update
- // the communication route.
- CommunicationDeviceInfo deviceInfo = new CommunicationDeviceInfo(
- crc.getBinder(), crc.getAttributionSource(), device, false,
- BtHelper.SCO_MODE_UNDEFINED, "onCheckCommunicationDeviceRemoval",
- crc.isPrivileged());
- postSetCommunicationDeviceForClient(deviceInfo);
- }
- }
- }
// check playback or record activity after 6 seconds for UIDs
private static final int CHECK_CLIENT_STATE_DELAY_MS = 6000;
@@ -1693,8 +1681,18 @@ public class AudioDeviceBroker {
boolean connect, @Nullable BluetoothDevice btDevice,
boolean deviceSwitch) {
synchronized (mDeviceStateLock) {
- return mDeviceInventory.handleDeviceConnection(
+ boolean status = mDeviceInventory.handleDeviceConnection(
attributes, connect, false /*for test*/, btDevice, deviceSwitch);
+ if (isValidCommunicationDeviceType(attributes.getType())
+ || mDuplexCommunicationDevices.containsValue(attributes.getInternalType())) {
+ checkCommunicationRouteClientsDevices();
+ if (connect || !deviceSwitch) {
+ onUpdateCommunicationRouteClient(
+ bluetoothScoRequestOwnerAttributionSource(),
+ "handleDeviceConnection");
+ }
+ }
+ return status;
}
}
@@ -1953,15 +1951,17 @@ public class AudioDeviceBroker {
|| btInfo.mIsLeOutput)
? mAudioService.getBluetoothContextualVolumeStream()
: AudioSystem.STREAM_DEFAULT);
- if ((btInfo.mProfile == BluetoothProfile.LE_AUDIO
+ if (btInfo.mProfile == BluetoothProfile.LE_AUDIO
|| btInfo.mProfile == BluetoothProfile.HEARING_AID
|| (mScoManagedByAudio
- && btInfo.mProfile == BluetoothProfile.HEADSET))
- && (btInfo.mState == BluetoothProfile.STATE_CONNECTED
- || !btInfo.mIsDeviceSwitch)) {
- onUpdateCommunicationRouteClient(
+ && btInfo.mProfile == BluetoothProfile.HEADSET)) {
+ checkCommunicationRouteClientsDevices();
+ if (btInfo.mState == BluetoothProfile.STATE_CONNECTED
+ || !btInfo.mIsDeviceSwitch) {
+ onUpdateCommunicationRouteClient(
bluetoothScoRequestOwnerAttributionSource(),
"setBluetoothActiveDevice");
+ }
}
}
}
@@ -2123,13 +2123,6 @@ public class AudioDeviceBroker {
final BluetoothDevice btDevice = (BluetoothDevice) msg.obj;
BtHelper.onNotifyPreferredAudioProfileApplied(btDevice);
} break;
- case MSG_L_CHECK_COMMUNICATION_DEVICE_REMOVAL: {
- synchronized (mSetModeLock) {
- synchronized (mDeviceStateLock) {
- onCheckCommunicationDeviceRemoval((AudioDeviceAttributes) msg.obj);
- }
- }
- } break;
case MSG_PERSIST_AUDIO_DEVICE_SETTINGS:
onPersistAudioDeviceSettings();
break;
@@ -2227,7 +2220,6 @@ public class AudioDeviceBroker {
private static final int MSG_IIL_BTLEAUDIO_TIMEOUT = 49;
private static final int MSG_L_NOTIFY_PREFERRED_AUDIOPROFILE_APPLIED = 52;
- private static final int MSG_L_CHECK_COMMUNICATION_DEVICE_REMOVAL = 53;
private static final int MSG_PERSIST_AUDIO_DEVICE_SETTINGS = 54;
@@ -2431,18 +2423,21 @@ public class AudioDeviceBroker {
private final IBinder mCb;
@NonNull private final AttributionSource mAttributionSource;
private final boolean mIsPrivileged;
- private AudioDeviceAttributes mDevice;
+ @NonNull private AudioDeviceAttributes mDevice;
private boolean mPlaybackActive;
private boolean mRecordingActive;
+ private boolean mDisabled;
+
CommunicationRouteClient(IBinder cb, @NonNull AttributionSource attributionSource,
- AudioDeviceAttributes device, boolean isPrivileged) {
+ @NonNull AudioDeviceAttributes device, boolean isPrivileged) {
mCb = cb;
mAttributionSource = attributionSource;
mDevice = device;
mIsPrivileged = isPrivileged;
mPlaybackActive = mAudioService.isPlaybackActiveForUid(attributionSource.getUid());
mRecordingActive = mAudioService.isRecordingActiveForUid(attributionSource.getUid());
+ mDisabled = false;
}
public boolean registerDeathRecipient() {
@@ -2485,7 +2480,10 @@ public class AudioDeviceBroker {
return mIsPrivileged;
}
- AudioDeviceAttributes getDevice() {
+ void setDevice(@NonNull AudioDeviceAttributes device) {
+ mDevice = device;
+ }
+ @NonNull AudioDeviceAttributes getDevice() {
return mDevice;
}
@@ -2498,7 +2496,14 @@ public class AudioDeviceBroker {
}
public boolean isActive() {
- return mIsPrivileged || mRecordingActive || mPlaybackActive;
+ return !mDisabled && (mIsPrivileged || mRecordingActive || mPlaybackActive);
+ }
+
+ public void setDisabled(boolean disabled) {
+ mDisabled = disabled;
+ }
+ public boolean isDisabled() {
+ return mDisabled;
}
@Override
@@ -2507,7 +2512,8 @@ public class AudioDeviceBroker {
+ " mDevice: " + mDevice.toString()
+ " mIsPrivileged: " + mIsPrivileged
+ " mPlaybackActive: " + mPlaybackActive
- + " mRecordingActive: " + mRecordingActive + "]";
+ + " mRecordingActive: " + mRecordingActive
+ + " mDisabled: " + mDisabled + "]";
}
}
@@ -2593,6 +2599,76 @@ public class AudioDeviceBroker {
onUpdatePhoneStrategyDevice(preferredCommunicationDevice);
}
+ // Pairs of input and output devices for duplex communication devices (headsets)
+ private final HashMap<Integer, Integer> mDuplexCommunicationDevices = new HashMap<>(
+ Map.of(DEVICE_OUT_BLE_HEADSET, DEVICE_IN_BLE_HEADSET,
+ DEVICE_OUT_WIRED_HEADSET, DEVICE_IN_WIRED_HEADSET,
+ DEVICE_OUT_USB_HEADSET, DEVICE_IN_USB_HEADSET,
+ DEVICE_OUT_BLUETOOTH_SCO, DEVICE_IN_BLUETOOTH_SCO_HEADSET,
+ DEVICE_OUT_BLUETOOTH_SCO_HEADSET, DEVICE_IN_BLUETOOTH_SCO_HEADSET,
+ DEVICE_OUT_BLUETOOTH_SCO_CARKIT, DEVICE_IN_BLUETOOTH_SCO_HEADSET
+ ));
+ /**
+ * Scan communication route clients and disable them if their selected device is not connected
+ * or re-enable them if a device of the same type as their connected device is connected
+ */
+ // @GuardedBy("mSetModeLock")
+ @GuardedBy("mDeviceStateLock")
+ private void checkCommunicationRouteClientsDevices() {
+ for (CommunicationRouteClient crc : mCommunicationRouteClients) {
+ int deviceType = crc.getDevice().getInternalType();
+ // Skip non detachable devices
+ if (deviceType == DEVICE_OUT_EARPIECE || deviceType == DEVICE_OUT_SPEAKER
+ || deviceType == DEVICE_OUT_BUS) {
+ continue;
+ }
+
+ // outDeviceSet is the expected connected output device types for the requested device
+ Set<Integer> outDeviceSet = null;
+ // inDeviceSet is the expected input device for outDeviceSet. Null for non
+ // duplex devices
+ Set<Integer> inDeviceSet = null;
+ // Special case for SCO because several device types are equivalent
+ if (isBluetoothScoOutDevice(deviceType)) {
+ outDeviceSet = DEVICE_OUT_ALL_SCO_SET;
+ inDeviceSet = DEVICE_IN_ALL_SCO_SET;
+ } else {
+ outDeviceSet = new HashSet<>();
+ outDeviceSet.add(deviceType);
+ if (mDuplexCommunicationDevices.containsKey(deviceType)) {
+ inDeviceSet = new HashSet<>();
+ inDeviceSet.add(mDuplexCommunicationDevices.get(deviceType));
+ }
+ }
+
+ AudioDeviceAttributes outAda =
+ mDeviceInventory.getFirstConnectedDeviceAttributesOfTypes(outDeviceSet);
+ AudioDeviceAttributes inAda = (inDeviceSet == null) ? null
+ : mDeviceInventory.getFirstConnectedDeviceAttributesOfTypes(inDeviceSet);
+
+ // A device is fully connected if the output device is connect and if not duplex
+ // or an input device with the same address is connected
+ boolean fullyConnected = outAda != null && (inDeviceSet == null
+ || (inAda != null && inAda.getAddress().equals(outAda.getAddress())));
+
+ if (fullyConnected) {
+ crc.setDevice(outAda);
+ if (crc.isDisabled()) {
+ crc.setDisabled(false);
+ if (AudioService.DEBUG_COMM_RTE) {
+ Log.v(TAG,
+ "checkCommunicationRouteClientsDevices, enabling client: " + crc);
+ }
+ }
+ } else if (!crc.isDisabled()) {
+ crc.setDisabled(true);
+ if (AudioService.DEBUG_COMM_RTE) {
+ Log.v(TAG, "checkCommunicationRouteClientsDevices, disabling client: " + crc);
+ }
+ }
+ }
+ }
+
/**
* Select new communication device from communication route client at the top of the stack
* and restore communication route including restarting SCO audio if needed.
@@ -2601,6 +2677,7 @@ public class AudioDeviceBroker {
@GuardedBy("mDeviceStateLock")
private void onUpdateCommunicationRouteClient(
@Nullable AttributionSource previousBtScoRequesterAS, String eventSource) {
+
CommunicationRouteClient crc = topCommunicationRouteClient();
if (AudioService.DEBUG_COMM_RTE) {
Log.v(TAG, "onUpdateCommunicationRouteClient, crc: " + crc
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index ae91934e7498..829d9ea7495f 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -1867,7 +1867,6 @@ public class AudioDeviceInventory {
deviceSwitch);
// always remove even if disconnection failed
mConnectedDevices.remove(deviceKey);
- mDeviceBroker.postCheckCommunicationDeviceRemoval(attributes);
status = true;
}
if (status) {
@@ -2413,7 +2412,7 @@ public class AudioDeviceInventory {
} else {
AudioService.sDeviceLogger.enqueue((new EventLogger.StringEvent(
"A2DP device addr=" + Utils.anonymizeBluetoothAddress(address)
- + " made unavailable, deviceSwitch" + deviceSwitch))
+ + " made unavailable, deviceSwitch: " + deviceSwitch))
.printSlog(EventLogger.Event.ALOGI, TAG));
}
mApmConnectedDevices.remove(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
@@ -2423,7 +2422,6 @@ public class AudioDeviceInventory {
mmi.record();
updateBluetoothPreferredModes_l(null /*connectedDevice*/);
purgeDevicesRoles_l();
- mDeviceBroker.postCheckCommunicationDeviceRemoval(ada);
}
@GuardedBy("mDevicesLock")
@@ -2479,7 +2477,6 @@ public class AudioDeviceInventory {
// always remove regardless of the result
mConnectedDevices.remove(
DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address));
- mDeviceBroker.postCheckCommunicationDeviceRemoval(ada);
}
@GuardedBy("mDevicesLock")
@@ -2541,7 +2538,6 @@ public class AudioDeviceInventory {
.set(MediaMetrics.Property.DEVICE,
AudioSystem.getDeviceName(DEVICE_OUT_HEARING_AID))
.record();
- mDeviceBroker.postCheckCommunicationDeviceRemoval(ada);
}
@GuardedBy("mDevicesLock")
@@ -2572,6 +2568,15 @@ public class AudioDeviceInventory {
}
/**
+ * Returns a DeviceInfo for the first connected device matching one of the supplied types
+ */
+ AudioDeviceAttributes getFirstConnectedDeviceAttributesOfTypes(Set<Integer> internalTypes) {
+ DeviceInfo di = getFirstConnectedDeviceOfTypes(internalTypes);
+ return di == null ? null : new AudioDeviceAttributes(
+ di.mDeviceType, di.mDeviceAddress, di.mDeviceName);
+ }
+
+ /**
* Returns a list of connected devices matching one of the supplied types
*/
private List<DeviceInfo> getConnectedDevicesOfTypes(Set<Integer> internalTypes) {
@@ -2689,13 +2694,16 @@ public class AudioDeviceInventory {
if (res != AudioSystem.AUDIO_STATUS_OK) {
AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
- "APM failed to make unavailable LE Audio device addr=" + address
- + " error=" + res).printSlog(EventLogger.Event.ALOGE, TAG));
+ "APM failed to make unavailable LE Audio "
+ + (AudioSystem.isInputDevice(device) ? "source" : "sink")
+ + " device addr=" + address
+ + " error=" + res).printSlog(EventLogger.Event.ALOGE, TAG));
// not taking further action: proceeding as if disconnection from APM worked
} else {
AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
- "LE Audio device addr=" + Utils.anonymizeBluetoothAddress(address)
- + " made unavailable, deviceSwitch" + deviceSwitch)
+ "LE Audio " + (AudioSystem.isInputDevice(device) ? "source" : "sink")
+ + "device addr=" + Utils.anonymizeBluetoothAddress(address)
+ + " made unavailable, deviceSwitch: " + deviceSwitch)
.printSlog(EventLogger.Event.ALOGI, TAG));
}
mConnectedDevices.remove(DeviceInfo.makeDeviceListKey(device, address));
@@ -2704,9 +2712,6 @@ public class AudioDeviceInventory {
setCurrentAudioRouteNameIfPossible(null, false /*fromA2dp*/);
updateBluetoothPreferredModes_l(null /*connectedDevice*/);
purgeDevicesRoles_l();
- if (ada != null) {
- mDeviceBroker.postCheckCommunicationDeviceRemoval(ada);
- }
}
@GuardedBy("mDevicesLock")
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 0f1228f44b0d..ada1cd73f775 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -7806,7 +7806,8 @@ public class AudioService extends IAudioService.Stub
return AudioSystem.STREAM_RING;
}
default:
- if (isInCommunication()) {
+ if (isInCommunication()
+ || mAudioSystem.isStreamActive(AudioManager.STREAM_VOICE_CALL, 0)) {
if (!replaceStreamBtSco()
&& mBtCommDeviceActive.get() == BT_COMM_DEVICE_ACTIVE_SCO) {
if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO");
diff --git a/services/core/java/com/android/server/compat/overrides/AppCompatOverridesService.java b/services/core/java/com/android/server/compat/overrides/AppCompatOverridesService.java
index 8637d2dfe565..47b1c5449dc2 100644
--- a/services/core/java/com/android/server/compat/overrides/AppCompatOverridesService.java
+++ b/services/core/java/com/android/server/compat/overrides/AppCompatOverridesService.java
@@ -103,12 +103,6 @@ public final class AppCompatOverridesService {
}
}
- @Override
- public void finalize() {
- unregisterDeviceConfigListeners();
- unregisterPackageReceiver();
- }
-
@VisibleForTesting
void registerDeviceConfigListeners() {
for (DeviceConfigListener listener : mDeviceConfigListeners) {
@@ -116,21 +110,11 @@ public final class AppCompatOverridesService {
}
}
- private void unregisterDeviceConfigListeners() {
- for (DeviceConfigListener listener : mDeviceConfigListeners) {
- listener.unregister();
- }
- }
-
@VisibleForTesting
void registerPackageReceiver() {
mPackageReceiver.register();
}
- private void unregisterPackageReceiver() {
- mPackageReceiver.unregister();
- }
-
/**
* Same as {@link #applyOverrides(Properties, Set, Map)} except all properties of the given
* {@code namespace} are fetched via {@link DeviceConfig#getProperties}.
@@ -374,10 +358,6 @@ public final class AppCompatOverridesService {
this);
}
- private void unregister() {
- DeviceConfig.removeOnPropertiesChangedListener(this);
- }
-
@Override
public void onPropertiesChanged(Properties properties) {
boolean removeOverridesFlagChanged = properties.getKeyset().contains(
@@ -426,10 +406,6 @@ public final class AppCompatOverridesService {
null, /* scheduler= */ null);
}
- private void unregister() {
- mContext.unregisterReceiver(this);
- }
-
@Override
public void onReceive(@NonNull final Context context, @NonNull final Intent intent) {
Uri data = intent.getData();
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
index 23e9ac5008f7..96e453963741 100644
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
@@ -983,6 +983,14 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider {
Objects.requireNonNull(providerInfo, "providerInfo must not be null");
for (MediaRoute2Info route : providerInfo.getRoutes()) {
+ if (Flags.enableMirroringInMediaRouter2()
+ && route.supportsRemoteRouting()
+ && route.supportsSystemMediaRouting()
+ && route.getDeduplicationIds().isEmpty()) {
+ // This code is not accessible if the app is using the public API.
+ throw new SecurityException("Route is missing deduplication id: " + route);
+ }
+
if (route.isSystemRoute()) {
throw new SecurityException(
"Only the system is allowed to publish system routes. "
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index f27194a7b792..22f20028eb9c 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -6706,12 +6706,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return mKeyguardDelegate.isInputRestricted();
}
- /** {@inheritDoc} */
- @Override
- public boolean isKeyguardUnoccluding() {
- return keyguardOn() && !mWindowManagerFuncs.isAppTransitionStateIdle();
- }
-
@Override
public void dismissKeyguardLw(IKeyguardDismissCallback callback, CharSequence message) {
if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) {
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index cc31bb17dc9d..d7de22edf8ce 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -337,12 +337,6 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
void moveDisplayToTopIfAllowed(int displayId);
/**
- * Return whether the app transition state is idle.
- * @return {@code true} if app transition state is idle on the default display.
- */
- boolean isAppTransitionStateIdle();
-
- /**
* Enables the screen if all conditions are met.
*/
void enableScreenIfNeeded();
@@ -989,14 +983,6 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
public boolean isKeyguardOccluded();
/**
- * Return whether the keyguard is unoccluding.
- * @return {@code true} if the keyguard is unoccluding.
- */
- default boolean isKeyguardUnoccluding() {
- return false;
- }
-
- /**
* @return true if in keyguard is on.
*/
boolean isKeyguardShowing();
diff --git a/services/core/java/com/android/server/updates/CertPinInstallReceiver.java b/services/core/java/com/android/server/updates/CertPinInstallReceiver.java
index 250e99b47b1a..c8e7a8dea5c3 100644
--- a/services/core/java/com/android/server/updates/CertPinInstallReceiver.java
+++ b/services/core/java/com/android/server/updates/CertPinInstallReceiver.java
@@ -19,7 +19,10 @@ package com.android.server.updates;
import android.content.Context;
import android.content.Intent;
+import java.io.File;
+
public class CertPinInstallReceiver extends ConfigUpdateInstallReceiver {
+ private static final String KEYCHAIN_DIR = "/data/misc/keychain/";
public CertPinInstallReceiver() {
super("/data/misc/keychain/", "pins", "metadata/", "version");
@@ -27,7 +30,22 @@ public class CertPinInstallReceiver extends ConfigUpdateInstallReceiver {
@Override
public void onReceive(final Context context, final Intent intent) {
- if (!com.android.server.flags.Flags.certpininstallerRemoval()) {
+ if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
+ if (com.android.server.flags.Flags.certpininstallerRemoval()) {
+ File pins = new File(KEYCHAIN_DIR + "pins");
+ if (pins.exists()) {
+ pins.delete();
+ }
+ File version = new File(KEYCHAIN_DIR + "metadata/version");
+ if (version.exists()) {
+ version.delete();
+ }
+ File metadata = new File(KEYCHAIN_DIR + "metadata");
+ if (metadata.exists()) {
+ metadata.delete();
+ }
+ }
+ } else if (!com.android.server.flags.Flags.certpininstallerRemoval()) {
super.onReceive(context, intent);
}
}
diff --git a/services/core/java/com/android/server/vibrator/VendorVibrationSession.java b/services/core/java/com/android/server/vibrator/VendorVibrationSession.java
index 621a128a736e..94e8ca5464b0 100644
--- a/services/core/java/com/android/server/vibrator/VendorVibrationSession.java
+++ b/services/core/java/com/android/server/vibrator/VendorVibrationSession.java
@@ -51,7 +51,9 @@ import java.util.NoSuchElementException;
final class VendorVibrationSession extends IVibrationSession.Stub
implements VibrationSession, CancellationSignal.OnCancelListener, IBinder.DeathRecipient {
private static final String TAG = "VendorVibrationSession";
- private static final boolean DEBUG = false;
+ // To enable these logs, run:
+ // 'adb shell setprop persist.log.tag.VendorVibrationSession DEBUG && adb reboot'
+ private static final boolean DEBUG = VibratorDebugUtils.isDebuggable(TAG);
/** Calls into VibratorManager functionality needed for playing an {@link ExternalVibration}. */
interface VibratorManagerHooks {
diff --git a/services/core/java/com/android/server/vibrator/VibrationThread.java b/services/core/java/com/android/server/vibrator/VibrationThread.java
index cb9988fd698e..ab30cdc730eb 100644
--- a/services/core/java/com/android/server/vibrator/VibrationThread.java
+++ b/services/core/java/com/android/server/vibrator/VibrationThread.java
@@ -36,7 +36,9 @@ import java.util.Objects;
/** Plays a {@link HalVibration} in dedicated thread. */
final class VibrationThread extends Thread {
static final String TAG = "VibrationThread";
- static final boolean DEBUG = false;
+ // To enable these logs, run:
+ // 'adb shell setprop persist.log.tag.VibrationThread DEBUG && adb reboot'
+ static final boolean DEBUG = VibratorDebugUtils.isDebuggable(TAG);
/** Calls into VibratorManager functionality needed for playing a {@link HalVibration}. */
interface VibratorManagerHooks {
diff --git a/services/core/java/com/android/server/vibrator/VibratorDebugUtils.java b/services/core/java/com/android/server/vibrator/VibratorDebugUtils.java
new file mode 100644
index 000000000000..9f37e76f0d6d
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/VibratorDebugUtils.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vibrator;
+
+import android.util.Log;
+
+class VibratorDebugUtils {
+
+ /**
+ * Checks if debugging is enabled for the specified tag or globally.
+ *
+ * <p>To enable debugging:<br>
+ * {@code adb shell setprop persist.log.tag.Vibrator_All DEBUG}<br>
+ * To disable debugging:<br>
+ * {@code adb shell setprop persist.log.tag.Vibrator_All \"\" }
+ *
+ * @param tag The tag to check for debugging. Use the tag name from the calling class.
+ * @return True if debugging is enabled for the tag or globally (Vibrator_All), false otherwise.
+ */
+ public static boolean isDebuggable(String tag) {
+ return Log.isLoggable(tag, Log.DEBUG) || Log.isLoggable("Vibrator_All", Log.DEBUG);
+ }
+}
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index ce91e63b4849..b9530978e850 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -108,7 +108,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
private static final String EXTERNAL_VIBRATOR_SERVICE = "external_vibrator_service";
private static final String VIBRATOR_CONTROL_SERVICE =
"android.frameworks.vibrator.IVibratorControlService/default";
- private static final boolean DEBUG = false;
+ // To enable these logs, run:
+ // 'adb shell setprop persist.log.tag.VibratorManagerService DEBUG && adb reboot'
+ private static final boolean DEBUG = VibratorDebugUtils.isDebuggable(TAG);
private static final VibrationAttributes DEFAULT_ATTRIBUTES =
new VibrationAttributes.Builder().build();
private static final int ATTRIBUTES_ALL_BYPASS_FLAGS =
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
index 7ce52b101824..7da4beb95114 100644
--- a/services/core/java/com/android/server/wm/ActivityClientController.java
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -1113,11 +1113,11 @@ class ActivityClientController extends IActivityClientController.Stub {
false /* fromClient */);
}
+ final EnterPipRequestedItem item = new EnterPipRequestedItem(r.token);
try {
- final EnterPipRequestedItem item = new EnterPipRequestedItem(r.token);
- mService.getLifecycleManager().scheduleTransactionItem(r.app.getThread(), item);
- return true;
- } catch (Exception e) {
+ return mService.getLifecycleManager().scheduleTransactionItem(r.app.getThread(), item);
+ } catch (RemoteException e) {
+ // TODO(b/323801078): remove Exception when cleanup
Slog.w(TAG, "Failed to send enter pip requested item: "
+ r.intent.getComponent(), e);
return false;
@@ -1129,10 +1129,11 @@ class ActivityClientController extends IActivityClientController.Stub {
*/
void onPictureInPictureUiStateChanged(@NonNull ActivityRecord r,
PictureInPictureUiState pipState) {
+ final PipStateTransactionItem item = new PipStateTransactionItem(r.token, pipState);
try {
- final PipStateTransactionItem item = new PipStateTransactionItem(r.token, pipState);
mService.getLifecycleManager().scheduleTransactionItem(r.app.getThread(), item);
- } catch (Exception e) {
+ } catch (RemoteException e) {
+ // TODO(b/323801078): remove Exception when cleanup
Slog.w(TAG, "Failed to send pip state transaction item: "
+ r.intent.getComponent(), e);
}
@@ -1510,9 +1511,6 @@ class ActivityClientController extends IActivityClientController.Stub {
synchronized (mGlobalLock) {
final ActivityRecord r = ActivityRecord.isInRootTaskLocked(token);
if (r != null && r.isState(RESUMED, PAUSING)) {
- r.mDisplayContent.mAppTransition.overridePendingAppTransition(
- packageName, enterAnim, exitAnim, backgroundColor, null, null,
- r.mOverrideTaskTransition);
r.mTransitionController.setOverrideAnimation(
TransitionInfo.AnimationOptions.makeCustomAnimOptions(packageName,
enterAnim, 0 /* changeResId */, exitAnim,
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index d452d76db18d..199a6d85f73f 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -253,6 +253,7 @@ import android.annotation.Size;
import android.app.Activity;
import android.app.ActivityManager.TaskDescription;
import android.app.ActivityOptions;
+import android.app.IApplicationThread;
import android.app.IScreenCaptureObserver;
import android.app.PendingIntent;
import android.app.PictureInPictureParams;
@@ -1351,15 +1352,16 @@ final class ActivityRecord extends WindowToken {
this, displayId);
return;
}
- try {
- ProtoLog.v(WM_DEBUG_SWITCH, "Reporting activity moved to "
- + "display, activityRecord=%s, displayId=%d, config=%s", this, displayId,
- config);
+ ProtoLog.v(WM_DEBUG_SWITCH, "Reporting activity moved to "
+ + "display, activityRecord=%s, displayId=%d, config=%s", this, displayId,
+ config);
- final MoveToDisplayItem item =
- new MoveToDisplayItem(token, displayId, config, activityWindowInfo);
+ final MoveToDisplayItem item =
+ new MoveToDisplayItem(token, displayId, config, activityWindowInfo);
+ try {
mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), item);
} catch (RemoteException e) {
+ // TODO(b/323801078): remove Exception when cleanup
// If process died, whatever.
}
}
@@ -1371,14 +1373,15 @@ final class ActivityRecord extends WindowToken {
+ "update - client not running, activityRecord=%s", this);
return;
}
- try {
- ProtoLog.v(WM_DEBUG_CONFIGURATION, "Sending new config to %s, "
- + "config: %s", this, config);
+ ProtoLog.v(WM_DEBUG_CONFIGURATION, "Sending new config to %s, "
+ + "config: %s", this, config);
- final ActivityConfigurationChangeItem item =
- new ActivityConfigurationChangeItem(token, config, activityWindowInfo);
+ final ActivityConfigurationChangeItem item =
+ new ActivityConfigurationChangeItem(token, config, activityWindowInfo);
+ try {
mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), item);
} catch (RemoteException e) {
+ // TODO(b/323801078): remove Exception when cleanup
// If process died, whatever.
}
}
@@ -1393,19 +1396,18 @@ final class ActivityRecord extends WindowToken {
if (onTop) {
app.addToPendingTop();
}
- try {
- ProtoLog.v(WM_DEBUG_STATES, "Sending position change to %s, onTop: %b",
- this, onTop);
+ ProtoLog.v(WM_DEBUG_STATES, "Sending position change to %s, onTop: %b",
+ this, onTop);
- final TopResumedActivityChangeItem item =
- new TopResumedActivityChangeItem(token, onTop);
- mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), item);
+ final TopResumedActivityChangeItem item = new TopResumedActivityChangeItem(token, onTop);
+ try {
+ return mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), item);
} catch (RemoteException e) {
+ // TODO(b/323801078): remove Exception when cleanup
// If process died, whatever.
Slog.w(TAG, "Failed to send top-resumed=" + onTop + " to " + this, e);
return false;
}
- return true;
}
void updateMultiWindowMode() {
@@ -2604,14 +2606,21 @@ final class ActivityRecord extends WindowToken {
removeStartingWindow();
return;
}
+ mTransferringSplashScreenState = TRANSFER_SPLASH_SCREEN_ATTACH_TO_CLIENT;
+ final TransferSplashScreenViewStateItem item =
+ new TransferSplashScreenViewStateItem(token, parcelable, windowAnimationLeash);
+ boolean isSuccessful;
try {
- mTransferringSplashScreenState = TRANSFER_SPLASH_SCREEN_ATTACH_TO_CLIENT;
- final TransferSplashScreenViewStateItem item =
- new TransferSplashScreenViewStateItem(token, parcelable, windowAnimationLeash);
- mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), item);
- scheduleTransferSplashScreenTimeout();
- } catch (Exception e) {
+ isSuccessful = mAtmService.getLifecycleManager().scheduleTransactionItem(
+ app.getThread(), item);
+ } catch (RemoteException e) {
+ // TODO(b/323801078): remove Exception when cleanup
Slog.w(TAG, "onCopySplashScreenComplete fail: " + this);
+ isSuccessful = false;
+ }
+ if (isSuccessful) {
+ scheduleTransferSplashScreenTimeout();
+ } else {
mStartingWindow.cancelAnimation();
parcelable.clearIfNeeded();
mTransferringSplashScreenState = TRANSFER_SPLASH_SCREEN_FINISH;
@@ -3957,11 +3966,23 @@ final class ActivityRecord extends WindowToken {
boolean skipDestroy = false;
- try {
- if (DEBUG_SWITCH) Slog.i(TAG_SWITCH, "Destroying: " + this);
+ if (DEBUG_SWITCH) Slog.i(TAG_SWITCH, "Destroying: " + this);
+ boolean isSuccessful;
+ final IApplicationThread client = app.getThread();
+ if (client == null) {
+ Slog.w(TAG_WM, "Failed to schedule DestroyActivityItem because client is inactive");
+ isSuccessful = false;
+ } else {
final DestroyActivityItem item = new DestroyActivityItem(token, finishing);
- mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), item);
- } catch (Exception e) {
+ try {
+ isSuccessful = mAtmService.getLifecycleManager().scheduleTransactionItem(
+ client, item);
+ } catch (RemoteException e) {
+ // TODO(b/323801078): remove Exception when cleanup
+ isSuccessful = false;
+ }
+ }
+ if (!isSuccessful) {
// We can just ignore exceptions here... if the process has crashed, our death
// notification will clean things up.
if (finishing) {
@@ -4884,13 +4905,17 @@ final class ActivityRecord extends WindowToken {
}
if (isState(RESUMED) && attachedToProcess()) {
+ final ArrayList<ResultInfo> list = new ArrayList<>();
+ list.add(new ResultInfo(resultWho, requestCode, resultCode, data, callerToken));
+ final ActivityResultItem item = new ActivityResultItem(token, list);
try {
- final ArrayList<ResultInfo> list = new ArrayList<>();
- list.add(new ResultInfo(resultWho, requestCode, resultCode, data, callerToken));
- final ActivityResultItem item = new ActivityResultItem(token, list);
- mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), item);
- return;
- } catch (Exception e) {
+ final boolean isSuccessful = mAtmService.getLifecycleManager()
+ .scheduleTransactionItem(app.getThread(), item);
+ if (isSuccessful) {
+ return;
+ }
+ } catch (RemoteException e) {
+ // TODO(b/323801078): remove Exception when cleanup
Slog.w(TAG, "Exception thrown sending result to " + this, e);
}
}
@@ -4917,6 +4942,7 @@ final class ActivityRecord extends WindowToken {
app.getThread(), activityResultItem);
}
} catch (RemoteException e) {
+ // TODO(b/323801078): remove Exception when cleanup
Slog.w(TAG, "Exception thrown sending result to " + this, e);
}
// We return here to ensure that result for media projection setup is not stored as a
@@ -4989,7 +5015,6 @@ final class ActivityRecord extends WindowToken {
}
final ReferrerIntent rintent = new ReferrerIntent(intent, getFilteredReferrer(referrer),
callerToken);
- boolean unsent = true;
final boolean isTopActivityWhileSleeping = isSleeping() && isTopRunningActivity();
// We want to immediately deliver the intent to the activity if:
@@ -4998,25 +5023,26 @@ final class ActivityRecord extends WindowToken {
// - The device is sleeping and it is the top activity behind the lock screen (b/6700897).
if ((mState == RESUMED || mState == PAUSED || isTopActivityWhileSleeping)
&& attachedToProcess()) {
+ final ArrayList<ReferrerIntent> ar = new ArrayList<>(1);
+ ar.add(rintent);
+ // Making sure the client state is RESUMED after transaction completed and doing
+ // so only if activity is currently RESUMED. Otherwise, client may have extra
+ // life-cycle calls to RESUMED (and PAUSED later).
+ final NewIntentItem item = new NewIntentItem(token, ar, mState == RESUMED /* resume */);
try {
- ArrayList<ReferrerIntent> ar = new ArrayList<>(1);
- ar.add(rintent);
- // Making sure the client state is RESUMED after transaction completed and doing
- // so only if activity is currently RESUMED. Otherwise, client may have extra
- // life-cycle calls to RESUMED (and PAUSED later).
- final NewIntentItem item =
- new NewIntentItem(token, ar, mState == RESUMED /* resume */);
- mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), item);
- unsent = false;
+ final boolean isSuccessful = mAtmService.getLifecycleManager()
+ .scheduleTransactionItem(app.getThread(), item);
+ if (isSuccessful) {
+ return;
+ }
} catch (RemoteException e) {
- Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
- } catch (NullPointerException e) {
+ // TODO(b/323801078): remove Exception when cleanup
Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
}
}
- if (unsent) {
- addNewIntentLocked(rintent);
- }
+
+ // Didn't send.
+ addNewIntentLocked(rintent);
}
void updateOptionsLocked(ActivityOptions options) {
@@ -6044,11 +6070,12 @@ final class ActivityRecord extends WindowToken {
setState(PAUSING, "makeActiveIfNeeded");
EventLogTags.writeWmPauseActivity(mUserId, System.identityHashCode(this),
shortComponentName, "userLeaving=false", "make-active");
+ final PauseActivityItem item = new PauseActivityItem(token, finishing,
+ false /* userLeaving */, false /* dontReport */, mAutoEnteringPip);
try {
- final PauseActivityItem item = new PauseActivityItem(token, finishing,
- false /* userLeaving */, false /* dontReport */, mAutoEnteringPip);
mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), item);
- } catch (Exception e) {
+ } catch (RemoteException e) {
+ // TODO(b/323801078): remove Exception when cleanup
Slog.w(TAG, "Exception thrown sending pause: " + intent.getComponent(), e);
}
} else if (shouldStartActivity()) {
@@ -6057,10 +6084,11 @@ final class ActivityRecord extends WindowToken {
}
setState(STARTED, "makeActiveIfNeeded");
+ final StartActivityItem item = new StartActivityItem(token, takeSceneTransitionInfo());
try {
- mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(),
- new StartActivityItem(token, takeSceneTransitionInfo()));
- } catch (Exception e) {
+ mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), item);
+ } catch (RemoteException e) {
+ // TODO(b/323801078): remove Exception when cleanup
Slog.w(TAG, "Exception thrown sending start: " + intent.getComponent(), e);
}
// The activity may be waiting for stop, but that is no longer appropriate if we are
@@ -6343,23 +6371,29 @@ final class ActivityRecord extends WindowToken {
return;
}
resumeKeyDispatchingLocked();
- try {
- ProtoLog.v(WM_DEBUG_STATES, "Moving to STOPPING: %s (stop requested)", this);
+ ProtoLog.v(WM_DEBUG_STATES, "Moving to STOPPING: %s (stop requested)", this);
- setState(STOPPING, "stopIfPossible");
- if (DEBUG_VISIBILITY) {
- Slog.v(TAG_VISIBILITY, "Stopping:" + this);
- }
- EventLogTags.writeWmStopActivity(
- mUserId, System.identityHashCode(this), shortComponentName);
- mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(),
- new StopActivityItem(token));
-
- mAtmService.mH.postDelayed(mStopTimeoutRunnable, STOP_TIMEOUT);
- } catch (Exception e) {
+ setState(STOPPING, "stopIfPossible");
+ if (DEBUG_VISIBILITY) {
+ Slog.v(TAG_VISIBILITY, "Stopping:" + this);
+ }
+ EventLogTags.writeWmStopActivity(
+ mUserId, System.identityHashCode(this), shortComponentName);
+ final StopActivityItem item = new StopActivityItem(token);
+ boolean isSuccessful;
+ try {
+ isSuccessful = mAtmService.getLifecycleManager().scheduleTransactionItem(
+ app.getThread(), item);
+ } catch (RemoteException e) {
+ // TODO(b/323801078): remove Exception when cleanup
// Maybe just ignore exceptions here... if the process has crashed, our death
// notification will clean things up.
Slog.w(TAG, "Exception thrown during pause", e);
+ isSuccessful = false;
+ }
+ if (isSuccessful) {
+ mAtmService.mH.postDelayed(mStopTimeoutRunnable, STOP_TIMEOUT);
+ } else {
// Just in case, assume it to be stopped.
mAppStopped = true;
mStoppedTime = SystemClock.uptimeMillis();
@@ -8711,9 +8745,11 @@ final class ActivityRecord extends WindowToken {
}
// Figure out how to handle the changes between the configurations.
- ProtoLog.v(WM_DEBUG_CONFIGURATION, "Checking to restart %s: changed=0x%s, "
- + "handles=0x%s, mLastReportedConfiguration=%s", info.name,
- Integer.toHexString(changes), Integer.toHexString(info.getRealConfigChanged()),
+ ProtoLog.v(WM_DEBUG_CONFIGURATION, "Checking to restart %s: changed=%s, "
+ + "handles=%s, not-handles=%s, mLastReportedConfiguration=%s", info.name,
+ Configuration.configurationDiffToString(changes),
+ Configuration.configurationDiffToString(info.getRealConfigChanged()),
+ Configuration.configurationDiffToString(changes & ~(info.getRealConfigChanged())),
mLastReportedConfiguration);
if (shouldRelaunchLocked(changes, mTmpConfig)) {
@@ -8926,29 +8962,34 @@ final class ActivityRecord extends WindowToken {
task.mTaskId, shortComponentName, Integer.toHexString(configChangeFlags));
}
+ ProtoLog.i(WM_DEBUG_STATES, "Moving to %s Relaunching %s callers=%s" ,
+ (andResume ? "RESUMED" : "PAUSED"), this, Debug.getCallers(6));
+ final ClientTransactionItem callbackItem = new ActivityRelaunchItem(token,
+ pendingResults, pendingNewIntents, configChangeFlags,
+ new MergedConfiguration(getProcessGlobalConfiguration(),
+ getMergedOverrideConfiguration()),
+ preserveWindow, getActivityWindowInfo());
+ final ActivityLifecycleItem lifecycleItem;
+ if (andResume) {
+ lifecycleItem = new ResumeActivityItem(token, isTransitionForward(),
+ shouldSendCompatFakeFocus());
+ } else {
+ lifecycleItem = new PauseActivityItem(token);
+ }
+ boolean isSuccessful;
try {
- ProtoLog.i(WM_DEBUG_STATES, "Moving to %s Relaunching %s callers=%s" ,
- (andResume ? "RESUMED" : "PAUSED"), this, Debug.getCallers(6));
- final ClientTransactionItem callbackItem = new ActivityRelaunchItem(token,
- pendingResults, pendingNewIntents, configChangeFlags,
- new MergedConfiguration(getProcessGlobalConfiguration(),
- getMergedOverrideConfiguration()),
- preserveWindow, getActivityWindowInfo());
- final ActivityLifecycleItem lifecycleItem;
- if (andResume) {
- lifecycleItem = new ResumeActivityItem(token, isTransitionForward(),
- shouldSendCompatFakeFocus());
- } else {
- lifecycleItem = new PauseActivityItem(token);
- }
- mAtmService.getLifecycleManager().scheduleTransactionItems(
+ isSuccessful = mAtmService.getLifecycleManager().scheduleTransactionItems(
app.getThread(), callbackItem, lifecycleItem);
+ } catch (RemoteException e) {
+ // TODO(b/323801078): remove Exception when cleanup
+ Slog.w(TAG, "Failed to relaunch " + this + ": " + e);
+ isSuccessful = false;
+ }
+ if (isSuccessful) {
startRelaunching();
// Note: don't need to call pauseIfSleepingLocked() here, because the caller will only
// request resume if this activity is currently resumed, which implies we aren't
// sleeping.
- } catch (RemoteException e) {
- Slog.w(TAG, "Failed to relaunch " + this + ": " + e);
}
if (andResume) {
@@ -9028,10 +9069,11 @@ final class ActivityRecord extends WindowToken {
private void scheduleStopForRestartProcess() {
// The process will be killed until the activity reports stopped with saved state (see
// {@link ActivityTaskManagerService.activityStopped}).
+ final StopActivityItem item = new StopActivityItem(token);
try {
- mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(),
- new StopActivityItem(token));
+ mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), item);
} catch (RemoteException e) {
+ // TODO(b/323801078): remove Exception when cleanup
Slog.w(TAG, "Exception thrown during restart " + this, e);
}
mTaskSupervisor.scheduleRestartTimeout(this);
diff --git a/services/core/java/com/android/server/wm/ActivityRefresher.java b/services/core/java/com/android/server/wm/ActivityRefresher.java
index 25e38b307b5e..8fe603cad46b 100644
--- a/services/core/java/com/android/server/wm/ActivityRefresher.java
+++ b/services/core/java/com/android/server/wm/ActivityRefresher.java
@@ -88,17 +88,22 @@ class ActivityRefresher {
new RefreshCallbackItem(activity.token, cycleThroughStop ? ON_STOP : ON_PAUSE);
final ResumeActivityItem resumeActivityItem = new ResumeActivityItem(
activity.token, /* isForward */ false, /* shouldSendCompatFakeFocus */ false);
+ boolean isSuccessful;
try {
- activity.mAtmService.getLifecycleManager().scheduleTransactionItems(
+ isSuccessful = activity.mAtmService.getLifecycleManager().scheduleTransactionItems(
activity.app.getThread(), refreshCallbackItem, resumeActivityItem);
+ } catch (RemoteException e) {
+ isSuccessful = false;
+ }
+ if (isSuccessful) {
mHandler.postDelayed(() -> {
synchronized (mWmService.mGlobalLock) {
onActivityRefreshed(activity);
}
}, REFRESH_CALLBACK_TIMEOUT_MS);
- } catch (RemoteException e) {
- activity.mAppCompatController.getCameraOverrides()
- .setIsRefreshRequested(false);
+ } else {
+ activity.mAppCompatController.getCameraOverrides().setIsRefreshRequested(false);
+
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index bdde5fe9dcb5..233f91385ca4 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -59,9 +59,7 @@ import static android.security.Flags.preventIntentRedirectAbortOrThrowException;
import static android.security.Flags.preventIntentRedirectShowToast;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.TRANSIT_FLAG_AVOID_MOVE_TO_FRONT;
-import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_OPEN;
-import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.window.TaskFragmentOperation.OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_CONFIGURATION;
@@ -1992,6 +1990,11 @@ class ActivityStarter {
}
}
+ if (com.android.window.flags.Flags.earlyLaunchHint()) {
+ mRootWindowContainer.startPowerModeLaunchIfNeeded(
+ false /* forceSend */, mStartActivity);
+ }
+
if (mTargetRootTask == null) {
mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, targetTask,
mOptions);
@@ -2064,8 +2067,10 @@ class ActivityStarter {
mStartActivity.getTaskFragment().clearLastPausedActivity();
- mRootWindowContainer.startPowerModeLaunchIfNeeded(
- false /* forceSend */, mStartActivity);
+ if (!com.android.window.flags.Flags.earlyLaunchHint()) {
+ mRootWindowContainer.startPowerModeLaunchIfNeeded(
+ false /* forceSend */, mStartActivity);
+ }
final boolean isTaskSwitch = startedTask != prevTopTask;
mTargetRootTask.startActivityLocked(mStartActivity, topRootTask, newTask, isTaskSwitch,
@@ -2551,11 +2556,6 @@ class ActivityStarter {
if (actuallyMoved) {
// Only record if the activity actually moved.
mMovedToTopActivity = act;
- if (mNoAnimation) {
- act.mDisplayContent.prepareAppTransition(TRANSIT_NONE);
- } else {
- act.mDisplayContent.prepareAppTransition(TRANSIT_TO_FRONT);
- }
}
act.updateOptionsLocked(mOptions);
deliverNewIntent(act, intentGrants);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index c45f7e8a7da2..a7f2153993bb 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -125,6 +125,7 @@ import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
+import android.os.DeadObjectException;
import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
@@ -1045,16 +1046,23 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
// transaction.
mService.getLifecycleManager().dispatchPendingTransaction(proc.getThread());
}
+ final boolean isSuccessful;
try {
- mService.getLifecycleManager().scheduleTransactionItems(
+ isSuccessful = mService.getLifecycleManager().scheduleTransactionItems(
proc.getThread(),
// Immediately dispatch the transaction, so that if it fails, the server can
// restart the process and retry now.
true /* shouldDispatchImmediately */,
launchActivityItem, lifecycleItem);
} catch (RemoteException e) {
+ // TODO(b/323801078): remove Exception when cleanup
return e;
}
+ if (com.android.window.flags.Flags.cleanupDispatchPendingTransactionsRemoteException()
+ && !isSuccessful) {
+ return new DeadObjectException("Failed to dispatch the ClientTransaction to dead"
+ + " process. See earlier log for more details.");
+ }
if (procConfig.seq > mRootWindowContainer.getConfiguration().seq) {
// If the seq is increased, there should be something changed (e.g. registered
diff --git a/services/core/java/com/android/server/wm/AppCompatSizeCompatModePolicy.java b/services/core/java/com/android/server/wm/AppCompatSizeCompatModePolicy.java
index 2cfa242bc5fe..b03aa5263927 100644
--- a/services/core/java/com/android/server/wm/AppCompatSizeCompatModePolicy.java
+++ b/services/core/java/com/android/server/wm/AppCompatSizeCompatModePolicy.java
@@ -23,6 +23,7 @@ import static android.content.pm.ActivityInfo.SIZE_CHANGES_UNSUPPORTED_METADATA;
import static android.content.pm.ActivityInfo.SIZE_CHANGES_UNSUPPORTED_OVERRIDE;
import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
+import static com.android.window.flags.Flags.enableSizeCompatModeImprovementsForConnectedDisplays;
import static com.android.server.wm.AppCompatUtils.isInDesktopMode;
import android.annotation.NonNull;
@@ -357,6 +358,11 @@ class AppCompatSizeCompatModePolicy {
// relatively fixed.
overrideConfig.colorMode = fullConfig.colorMode;
overrideConfig.densityDpi = fullConfig.densityDpi;
+ if (enableSizeCompatModeImprovementsForConnectedDisplays()) {
+ overrideConfig.touchscreen = fullConfig.touchscreen;
+ overrideConfig.navigation = fullConfig.navigation;
+ overrideConfig.fontScale = fullConfig.fontScale;
+ }
// The smallest screen width is the short side of screen bounds. Because the bounds
// and density won't be changed, smallestScreenWidthDp is also fixed.
overrideConfig.smallestScreenWidthDp = fullConfig.smallestScreenWidthDp;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 574ab05075c4..eb6b14545cb8 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -82,7 +82,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManager.REMOVE_CONTENT_MODE_DESTROY;
import static android.view.WindowManager.TRANSIT_CHANGE;
-import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.view.inputmethod.ImeTracker.DEBUG_IME_VISIBILITY;
@@ -108,7 +107,7 @@ import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_W
import static com.android.server.wm.ActivityRecord.State.RESUMED;
import static com.android.server.wm.ActivityTaskManagerService.POWER_MODE_REASON_CHANGE_DISPLAY;
import static com.android.server.wm.DisplayContentProto.APP_TRANSITION;
-import static com.android.server.wm.DisplayContentProto.CURRENT_FOCUS;
+import static com.android.server.wm.DisplayContentProto.CURRENT_FOCUS_IDENTIFIER;
import static com.android.server.wm.DisplayContentProto.DISPLAY_FRAMES;
import static com.android.server.wm.DisplayContentProto.DISPLAY_INFO;
import static com.android.server.wm.DisplayContentProto.DISPLAY_READY;
@@ -118,9 +117,9 @@ import static com.android.server.wm.DisplayContentProto.FOCUSED_APP;
import static com.android.server.wm.DisplayContentProto.FOCUSED_ROOT_TASK_ID;
import static com.android.server.wm.DisplayContentProto.ID;
import static com.android.server.wm.DisplayContentProto.IME_POLICY;
-import static com.android.server.wm.DisplayContentProto.INPUT_METHOD_CONTROL_TARGET;
-import static com.android.server.wm.DisplayContentProto.INPUT_METHOD_INPUT_TARGET;
-import static com.android.server.wm.DisplayContentProto.INPUT_METHOD_TARGET;
+import static com.android.server.wm.DisplayContentProto.INPUT_METHOD_CONTROL_TARGET_IDENTIFIER;
+import static com.android.server.wm.DisplayContentProto.INPUT_METHOD_INPUT_TARGET_IDENTIFIER;
+import static com.android.server.wm.DisplayContentProto.INPUT_METHOD_LAYERING_TARGET_IDENTIFIER;
import static com.android.server.wm.DisplayContentProto.IS_SLEEPING;
import static com.android.server.wm.DisplayContentProto.KEEP_CLEAR_AREAS;
import static com.android.server.wm.DisplayContentProto.MIN_SIZE_OF_RESIZEABLE_TASK_DP;
@@ -156,7 +155,6 @@ import static com.android.server.wm.utils.DisplayInfoOverrides.WM_OVERRIDE_FIELD
import static com.android.server.wm.utils.DisplayInfoOverrides.copyDisplayInfoFields;
import static com.android.server.wm.utils.RegionUtils.forEachRectReverse;
import static com.android.server.wm.utils.RegionUtils.rectListToRegion;
-import static com.android.window.flags.Flags.enablePersistingDensityScaleForConnectedDisplays;
import static com.android.window.flags.Flags.enablePresentationForConnectedDisplays;
import android.annotation.IntDef;
@@ -237,6 +235,7 @@ import android.view.WindowManager;
import android.view.WindowManager.DisplayImePolicy;
import android.view.WindowManagerPolicyConstants.PointerEventListener;
import android.view.inputmethod.ImeTracker;
+import android.window.DesktopExperienceFlags;
import android.window.DisplayWindowPolicyController;
import android.window.IDisplayAreaOrganizer;
import android.window.ScreenCapture;
@@ -3154,7 +3153,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
}
// Update the base density if there is a forced density ratio.
- if (enablePersistingDensityScaleForConnectedDisplays()
+ if (DesktopExperienceFlags.ENABLE_PERSISTING_DISPLAY_SIZE_FOR_CONNECTED_DISPLAYS.isTrue()
&& mIsDensityForced && mExternalDisplayForcedDensityRatio != 0.0f) {
mBaseDisplayDensity = (int)
(mInitialDisplayDensity * mExternalDisplayForcedDensityRatio + 0.5);
@@ -3189,7 +3188,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
density = 0;
}
// Save the new density ratio to settings for external displays.
- if (enablePersistingDensityScaleForConnectedDisplays()
+ if (DesktopExperienceFlags.ENABLE_PERSISTING_DISPLAY_SIZE_FOR_CONNECTED_DISPLAYS.isTrue()
&& mDisplayInfo.type == TYPE_EXTERNAL) {
mExternalDisplayForcedDensityRatio = (float)
mBaseDisplayDensity / getInitialDisplayDensity();
@@ -3612,18 +3611,20 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
if (mImeLayeringTarget != null) {
- mImeLayeringTarget.dumpDebug(proto, INPUT_METHOD_TARGET, logLevel);
+ mImeLayeringTarget.writeIdentifierToProto(
+ proto, INPUT_METHOD_LAYERING_TARGET_IDENTIFIER);
}
- if (mImeInputTarget != null) {
- mImeInputTarget.dumpProto(proto, INPUT_METHOD_INPUT_TARGET, logLevel);
+ if (mImeInputTarget != null && mImeInputTarget.getWindowState() != null) {
+ mImeInputTarget.getWindowState().writeIdentifierToProto(
+ proto, INPUT_METHOD_INPUT_TARGET_IDENTIFIER);
}
if (mImeControlTarget != null
&& mImeControlTarget.getWindow() != null) {
- mImeControlTarget.getWindow().dumpDebug(proto, INPUT_METHOD_CONTROL_TARGET,
- logLevel);
+ mImeControlTarget.getWindow().writeIdentifierToProto(
+ proto, INPUT_METHOD_CONTROL_TARGET_IDENTIFIER);
}
if (mCurrentFocus != null) {
- mCurrentFocus.dumpDebug(proto, CURRENT_FOCUS, logLevel);
+ mCurrentFocus.writeIdentifierToProto(proto, CURRENT_FOCUS_IDENTIFIER);
}
if (mInsetsStateController != null) {
mInsetsStateController.dumpDebug(proto, logLevel);
@@ -5634,29 +5635,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
/**
- * @deprecated new transition should use {@link #requestTransitionAndLegacyPrepare(int, int)}
- */
- @Deprecated
- void prepareAppTransition(@WindowManager.TransitionType int transit) {
- prepareAppTransition(transit, 0 /* flags */);
- }
-
- /**
- * @deprecated new transition should use {@link #requestTransitionAndLegacyPrepare(int, int)}
- */
- @Deprecated
- void prepareAppTransition(@WindowManager.TransitionType int transit,
- @WindowManager.TransitionFlags int flags) {
- mAppTransition.prepareAppTransition(transit, flags);
- }
-
- /**
* Helper that both requests a transition (using the new transition system) and prepares
* the legacy transition system. Use this when both systems have the same start-point.
*
* @see TransitionController#requestTransitionIfNeeded(int, int, WindowContainer,
* WindowContainer)
- * @see AppTransition#prepareAppTransition
*/
void requestTransitionAndLegacyPrepare(@WindowManager.TransitionType int transit,
@WindowManager.TransitionFlags int flags, @Nullable WindowContainer trigger) {
@@ -6544,19 +6527,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// If keyguard is not locked, the change of flags won't affect activity visibility.
return;
}
- // We might change the visibilities here, so prepare an empty app transition which might be
- // overridden later if we actually change visibilities.
- final boolean wasTransitionSet = mAppTransition.isTransitionSet();
- if (!wasTransitionSet) {
- prepareAppTransition(TRANSIT_NONE);
- }
mRootWindowContainer.ensureActivitiesVisible();
-
- // If there was a transition set already we don't want to interfere with it as we might be
- // starting it too early.
- if (!wasTransitionSet) {
- executeAppTransition();
- }
+ // In case there is a visibility change.
+ executeAppTransition();
}
/**
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index f52446ff494c..2a2ae12ab09b 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -22,7 +22,7 @@ import static android.view.InsetsSource.ID_IME;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_IME;
import static com.android.server.wm.DisplayContent.IME_TARGET_CONTROL;
import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
-import static com.android.server.wm.ImeInsetsSourceProviderProto.IME_TARGET_FROM_IME;
+import static com.android.server.wm.ImeInsetsSourceProviderProto.IME_TARGET_FROM_IME_IDENTIFIER;
import static com.android.server.wm.ImeInsetsSourceProviderProto.INSETS_SOURCE_PROVIDER;
import static com.android.server.wm.WindowManagerService.H.UPDATE_MULTI_WINDOW_STACKS;
@@ -774,7 +774,7 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
final WindowState imeRequesterWindow =
mImeRequester != null ? mImeRequester.getWindow() : null;
if (imeRequesterWindow != null) {
- imeRequesterWindow.dumpDebug(proto, IME_TARGET_FROM_IME, logLevel);
+ imeRequesterWindow.writeIdentifierToProto(proto, IME_TARGET_FROM_IME_IDENTIFIER);
}
proto.end(token);
}
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index d1585d06ae40..b7489029768a 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -21,16 +21,16 @@ import static com.android.server.wm.InsetsSourceProviderProto.CAPTURED_LEASH;
import static com.android.server.wm.InsetsSourceProviderProto.CLIENT_VISIBLE;
import static com.android.server.wm.InsetsSourceProviderProto.CONTROL;
import static com.android.server.wm.InsetsSourceProviderProto.CONTROLLABLE;
-import static com.android.server.wm.InsetsSourceProviderProto.CONTROL_TARGET;
+import static com.android.server.wm.InsetsSourceProviderProto.CONTROL_TARGET_IDENTIFIER;
import static com.android.server.wm.InsetsSourceProviderProto.FAKE_CONTROL;
-import static com.android.server.wm.InsetsSourceProviderProto.FAKE_CONTROL_TARGET;
+import static com.android.server.wm.InsetsSourceProviderProto.FAKE_CONTROL_TARGET_IDENTIFIER;
import static com.android.server.wm.InsetsSourceProviderProto.FRAME;
import static com.android.server.wm.InsetsSourceProviderProto.IS_LEASH_READY_FOR_DISPATCHING;
-import static com.android.server.wm.InsetsSourceProviderProto.PENDING_CONTROL_TARGET;
+import static com.android.server.wm.InsetsSourceProviderProto.PENDING_CONTROL_TARGET_IDENTIFIER;
import static com.android.server.wm.InsetsSourceProviderProto.SEAMLESS_ROTATING;
import static com.android.server.wm.InsetsSourceProviderProto.SERVER_VISIBLE;
import static com.android.server.wm.InsetsSourceProviderProto.SOURCE;
-import static com.android.server.wm.InsetsSourceProviderProto.SOURCE_WINDOW_STATE;
+import static com.android.server.wm.InsetsSourceProviderProto.SOURCE_WINDOW_STATE_IDENTIFIER;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_INSETS_CONTROL;
import android.annotation.NonNull;
@@ -803,14 +803,16 @@ class InsetsSourceProvider {
mControl.dumpDebug(proto, CONTROL);
}
if (mControlTarget != null && mControlTarget.getWindow() != null) {
- mControlTarget.getWindow().dumpDebug(proto, CONTROL_TARGET, logLevel);
+ mControlTarget.getWindow().writeIdentifierToProto(proto, CONTROL_TARGET_IDENTIFIER);
}
if (mPendingControlTarget != null && mPendingControlTarget != mControlTarget
&& mPendingControlTarget.getWindow() != null) {
- mPendingControlTarget.getWindow().dumpDebug(proto, PENDING_CONTROL_TARGET, logLevel);
+ mPendingControlTarget.getWindow().writeIdentifierToProto(
+ proto, PENDING_CONTROL_TARGET_IDENTIFIER);
}
if (mFakeControlTarget != null && mFakeControlTarget.getWindow() != null) {
- mFakeControlTarget.getWindow().dumpDebug(proto, FAKE_CONTROL_TARGET, logLevel);
+ mFakeControlTarget.getWindow().writeIdentifierToProto(
+ proto, FAKE_CONTROL_TARGET_IDENTIFIER);
}
if (mAdapter != null && mAdapter.mCapturedLeash != null) {
mAdapter.mCapturedLeash.dumpDebug(proto, CAPTURED_LEASH);
@@ -821,7 +823,8 @@ class InsetsSourceProvider {
proto.write(SEAMLESS_ROTATING, mSeamlessRotating);
proto.write(CONTROLLABLE, mControllable);
if (mWindowContainer != null && mWindowContainer.asWindowState() != null) {
- mWindowContainer.asWindowState().dumpDebug(proto, SOURCE_WINDOW_STATE, logLevel);
+ mWindowContainer.asWindowState().writeIdentifierToProto(
+ proto, SOURCE_WINDOW_STATE_IDENTIFIER);
}
proto.end(token);
}
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index 4eeed5ec8423..ff1e400a4a23 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -28,7 +28,6 @@ import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHA
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_OCCLUDING;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_UNOCCLUDING;
-import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
import static android.view.WindowManager.TRANSIT_OPEN;
@@ -310,7 +309,6 @@ class KeyguardController {
state.writeEventLog("keyguardGoingAway");
final int transitFlags = convertTransitFlags(flags);
final DisplayContent dc = mRootWindowContainer.getDefaultDisplay();
- dc.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, transitFlags);
// We are deprecating TRANSIT_KEYGUARD_GOING_AWAY for Shell transition and use
// TRANSIT_FLAG_KEYGUARD_GOING_AWAY to indicate that it should animate keyguard going
// away.
@@ -490,8 +488,6 @@ class KeyguardController {
if (trigger != null) {
transition.collect(trigger);
}
- } else {
- dc.prepareAppTransition(transitType, transitFlags);
}
} else {
if (tc.inTransition()) {
@@ -515,7 +511,6 @@ class KeyguardController {
private void handleDismissInsecureKeyguard(DisplayContent dc) {
mService.deferWindowLayout();
try {
- dc.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, 0 /* transitFlags */);
// We are deprecating TRANSIT_KEYGUARD_GOING_AWAY for Shell transition and use
// TRANSIT_FLAG_KEYGUARD_GOING_AWAY to indicate that it should animate keyguard going
// away.
@@ -542,14 +537,6 @@ class KeyguardController {
mWindowManager.dismissKeyguard(null /* callback */, null /* message */);
final KeyguardDisplayState state = getDisplayState(displayId);
state.mDismissalRequested = true;
-
- // If we are about to unocclude the Keyguard, but we can dismiss it without security,
- // we immediately dismiss the Keyguard so the activity gets shown without a flicker.
- final DisplayContent dc = mRootWindowContainer.getDefaultDisplay();
- if (state.mKeyguardShowing && canDismissKeyguard()
- && dc.mAppTransition.containsTransitRequest(TRANSIT_KEYGUARD_UNOCCLUDE)) {
- mWindowManager.executeAppTransition();
- }
}
ActivityRecord getTopOccludingActivity(int displayId) {
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index f95698a5b0bd..5183c6b57f15 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -88,6 +88,7 @@ import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.IBinder;
+import android.os.RemoteException;
import android.os.UserHandle;
import android.util.ArraySet;
import android.util.DisplayMetrics;
@@ -1751,67 +1752,80 @@ class TaskFragment extends WindowContainer<WindowContainer> {
}
}
- try {
- final IApplicationThread appThread = next.app.getThread();
- // Deliver all pending results.
- final ArrayList<ResultInfo> a = next.results;
- if (a != null) {
- final int size = a.size();
- if (!next.finishing && size > 0) {
- if (DEBUG_RESULTS) {
- Slog.v(TAG_RESULTS, "Delivering results to " + next + ": " + a);
- }
- final ActivityResultItem item = new ActivityResultItem(next.token, a);
- mAtmService.getLifecycleManager().scheduleTransactionItem(appThread, item);
+ final IApplicationThread appThread = next.app.getThread();
+ // Deliver all pending results.
+ final ArrayList<ResultInfo> a = next.results;
+ if (a != null) {
+ final int size = a.size();
+ if (!next.finishing && size > 0) {
+ if (DEBUG_RESULTS) {
+ Slog.v(TAG_RESULTS, "Delivering results to " + next + ": " + a);
+ }
+ final ActivityResultItem item = new ActivityResultItem(next.token, a);
+ boolean isSuccessful;
+ try {
+ isSuccessful = mAtmService.getLifecycleManager().scheduleTransactionItem(
+ appThread, item);
+ } catch (RemoteException e) {
+ // TODO(b/323801078): remove Exception when cleanup
+ isSuccessful = false;
+ }
+ if (!isSuccessful) {
+ onResumeTopActivityRemoteFailure(lastState, next, lastResumedActivity,
+ lastFocusedRootTask);
+ return true;
}
}
+ }
- if (next.newIntents != null) {
- final NewIntentItem item =
- new NewIntentItem(next.token, next.newIntents, true /* resume */);
- mAtmService.getLifecycleManager().scheduleTransactionItem(appThread, item);
+ if (next.newIntents != null) {
+ final NewIntentItem item =
+ new NewIntentItem(next.token, next.newIntents, true /* resume */);
+ boolean isSuccessful;
+ try {
+ isSuccessful = mAtmService.getLifecycleManager().scheduleTransactionItem(
+ appThread, item);
+ } catch (RemoteException e) {
+ // TODO(b/323801078): remove Exception when cleanup
+ isSuccessful = false;
}
+ if (!isSuccessful) {
+ onResumeTopActivityRemoteFailure(lastState, next, lastResumedActivity,
+ lastFocusedRootTask);
+ return true;
+ }
+ }
- // Well the app will no longer be stopped.
- // Clear app token stopped state in window manager if needed.
- next.notifyAppResumed();
-
- EventLogTags.writeWmResumeActivity(next.mUserId, System.identityHashCode(next),
- next.getTask().mTaskId, next.shortComponentName);
-
- mAtmService.getAppWarningsLocked().onResumeActivity(next);
- final int topProcessState = mAtmService.mTopProcessState;
- next.app.setPendingUiCleanAndForceProcessStateUpTo(topProcessState);
- next.abortAndClearOptionsAnimation();
- final ResumeActivityItem resumeActivityItem = new ResumeActivityItem(
- next.token, topProcessState, dc.isNextTransitionForward(),
- next.shouldSendCompatFakeFocus());
- mAtmService.getLifecycleManager().scheduleTransactionItem(
- appThread, resumeActivityItem);
-
- ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Resumed %s", next);
- } catch (Exception e) {
- // Whoops, need to restart this activity!
- ProtoLog.v(WM_DEBUG_STATES, "Resume failed; resetting state to %s: "
- + "%s", lastState, next);
- next.setState(lastState, "resumeTopActivityInnerLocked");
+ // Well the app will no longer be stopped.
+ // Clear app token stopped state in window manager if needed.
+ next.notifyAppResumed();
- // lastResumedActivity being non-null implies there is a lastStack present.
- if (lastResumedActivity != null) {
- lastResumedActivity.setState(RESUMED, "resumeTopActivityInnerLocked");
- }
+ EventLogTags.writeWmResumeActivity(next.mUserId, System.identityHashCode(next),
+ next.getTask().mTaskId, next.shortComponentName);
- Slog.i(TAG, "Restarting because process died: " + next);
- if (!next.hasBeenLaunched) {
- next.hasBeenLaunched = true;
- } else if (SHOW_APP_STARTING_PREVIEW && lastFocusedRootTask != null
- && lastFocusedRootTask.isTopRootTaskInDisplayArea()) {
- next.showStartingWindow(false /* taskSwitch */);
- }
- mTaskSupervisor.startSpecificActivity(next, true, false);
+ mAtmService.getAppWarningsLocked().onResumeActivity(next);
+ final int topProcessState = mAtmService.mTopProcessState;
+ next.app.setPendingUiCleanAndForceProcessStateUpTo(topProcessState);
+ next.abortAndClearOptionsAnimation();
+ final ResumeActivityItem resumeActivityItem = new ResumeActivityItem(
+ next.token, topProcessState, dc.isNextTransitionForward(),
+ next.shouldSendCompatFakeFocus());
+ boolean isSuccessful;
+ try {
+ isSuccessful = mAtmService.getLifecycleManager().scheduleTransactionItem(
+ appThread, resumeActivityItem);
+ } catch (RemoteException e) {
+ // TODO(b/323801078): remove Exception when cleanup
+ isSuccessful = false;
+ }
+ if (!isSuccessful) {
+ onResumeTopActivityRemoteFailure(lastState, next, lastResumedActivity,
+ lastFocusedRootTask);
return true;
}
+ ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Resumed %s", next);
+
next.completeResumeLocked();
} else {
// Whoops, need to restart this activity!
@@ -1830,6 +1844,29 @@ class TaskFragment extends WindowContainer<WindowContainer> {
return true;
}
+ /** Likely app process has been killed. Needs to restart this activity. */
+ private void onResumeTopActivityRemoteFailure(@NonNull ActivityRecord.State lastState,
+ @NonNull ActivityRecord next, @Nullable ActivityRecord lastResumedActivity,
+ @Nullable Task lastFocusedRootTask) {
+ ProtoLog.v(WM_DEBUG_STATES, "Resume failed; resetting state to %s: "
+ + "%s", lastState, next);
+ next.setState(lastState, "resumeTopActivityInnerLocked");
+
+ // lastResumedActivity being non-null implies there is a lastStack present.
+ if (lastResumedActivity != null) {
+ lastResumedActivity.setState(RESUMED, "resumeTopActivityInnerLocked");
+ }
+
+ Slog.i(TAG, "Restarting because process died: " + next);
+ if (!next.hasBeenLaunched) {
+ next.hasBeenLaunched = true;
+ } else if (SHOW_APP_STARTING_PREVIEW && lastFocusedRootTask != null
+ && lastFocusedRootTask.isTopRootTaskInDisplayArea()) {
+ next.showStartingWindow(false /* taskSwitch */);
+ }
+ mTaskSupervisor.startSpecificActivity(next, true, false);
+ }
+
boolean shouldSleepOrShutDownActivities() {
return shouldSleepActivities() || mAtmService.mShuttingDown;
}
@@ -2034,17 +2071,23 @@ class TaskFragment extends WindowContainer<WindowContainer> {
void schedulePauseActivity(ActivityRecord prev, boolean userLeaving,
boolean pauseImmediately, boolean autoEnteringPip, String reason) {
ProtoLog.v(WM_DEBUG_STATES, "Enqueueing pending pause: %s", prev);
+ prev.mPauseSchedulePendingForPip = false;
+ EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev),
+ prev.shortComponentName, "userLeaving=" + userLeaving, reason);
+
+ final PauseActivityItem item = new PauseActivityItem(prev.token, prev.finishing,
+ userLeaving, pauseImmediately, autoEnteringPip);
+ boolean isSuccessful;
try {
- prev.mPauseSchedulePendingForPip = false;
- EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev),
- prev.shortComponentName, "userLeaving=" + userLeaving, reason);
-
- final PauseActivityItem item = new PauseActivityItem(prev.token, prev.finishing,
- userLeaving, pauseImmediately, autoEnteringPip);
- mAtmService.getLifecycleManager().scheduleTransactionItem(prev.app.getThread(), item);
- } catch (Exception e) {
+ isSuccessful = mAtmService.getLifecycleManager().scheduleTransactionItem(
+ prev.app.getThread(), item);
+ } catch (RemoteException e) {
+ // TODO(b/323801078): remove Exception when cleanup
// Ignore exception, if process died other code will cleanup.
Slog.w(TAG, "Exception thrown during pause", e);
+ isSuccessful = false;
+ }
+ if (!isSuccessful) {
mPausingActivity = null;
mLastPausedActivity = null;
mTaskSupervisor.mNoHistoryActivities.remove(prev);
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 644417ec98e5..3a4d9d27f65a 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -21,7 +21,6 @@ import static android.app.WallpaperManager.COMMAND_UNFREEZE;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_WALLPAPER;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
@@ -118,42 +117,20 @@ class WallpaperController {
private boolean mShouldOffsetWallpaperCenter;
private final ToBooleanFunction<WindowState> mFindWallpaperTargetFunction = w -> {
- final boolean useShellTransition = w.mTransitionController.isShellTransitionsEnabled();
- if (!useShellTransition) {
- if (w.mActivityRecord != null && !w.mActivityRecord.isVisible()
- && !w.mActivityRecord.isAnimating(TRANSITION | PARENTS)) {
- // If this window's app token is hidden and not animating, it is of no interest.
- if (DEBUG_WALLPAPER) Slog.v(TAG, "Skipping hidden and not animating token: " + w);
- return false;
- }
- } else {
- final ActivityRecord ar = w.mActivityRecord;
- // The animating window can still be visible on screen if it is in transition, so we
- // should check whether this window can be wallpaper target even when visibleRequested
- // is false.
- if (ar != null && !ar.isVisibleRequested() && !ar.isVisible()) {
- // An activity that is not going to remain visible shouldn't be the target.
- return false;
- }
+ final ActivityRecord ar = w.mActivityRecord;
+ // The animating window can still be visible on screen if it is in transition, so we
+ // should check whether this window can be wallpaper target even when visibleRequested
+ // is false.
+ if (ar != null && !ar.isVisibleRequested() && !ar.isVisible()) {
+ // An activity that is not going to remain visible shouldn't be the target.
+ return false;
}
if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": isOnScreen=" + w.isOnScreen()
+ " mDrawState=" + w.mWinAnimator.mDrawState);
- final WindowContainer animatingContainer = w.mActivityRecord != null
- ? w.mActivityRecord.getAnimatingContainer() : null;
- if (!useShellTransition && animatingContainer != null
- && animatingContainer.isAnimating(TRANSITION | PARENTS)
- && AppTransition.isKeyguardGoingAwayTransitOld(animatingContainer.mTransit)
- && (animatingContainer.mTransitFlags
- & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER) != 0) {
- // Keep the wallpaper visible when Keyguard is going away.
- mFindResults.setUseTopWallpaperAsTarget(true);
- }
-
if (mService.mPolicy.isKeyguardLocked()) {
if (w.canShowWhenLocked()) {
- if (mService.mPolicy.isKeyguardOccluded() || (useShellTransition
- ? w.inTransition() : mService.mPolicy.isKeyguardUnoccluding())) {
+ if (mService.mPolicy.isKeyguardOccluded() || w.inTransition()) {
// The lowest show-when-locked window decides whether to show wallpaper.
mFindResults.mNeedsShowWhenLockedWallpaper = !isFullscreen(w.mAttrs)
|| (w.mActivityRecord != null && !w.mActivityRecord.fillsParent());
@@ -176,15 +153,11 @@ class WallpaperController {
}
}
- final boolean animationWallpaper = animatingContainer != null
- && animatingContainer.getAnimation() != null
- && animatingContainer.getAnimation().getShowWallpaper();
- final boolean hasWallpaper = w.hasWallpaper() || animationWallpaper;
if (isBackNavigationTarget(w)) {
if (DEBUG_WALLPAPER) Slog.v(TAG, "Found back animation wallpaper target: " + w);
mFindResults.setWallpaperTarget(w);
return true;
- } else if (hasWallpaper
+ } else if (w.hasWallpaper()
&& (w.mActivityRecord != null ? w.isOnScreen() : w.isReadyForDisplay())) {
if (DEBUG_WALLPAPER) Slog.v(TAG, "Found wallpaper target: " + w);
mFindResults.setWallpaperTarget(w);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 28f2825150c2..54f960973eff 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -17,7 +17,6 @@
package com.android.server.wm;
import static android.Manifest.permission.ACCESS_SURFACE_FLINGER;
-import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
import static android.Manifest.permission.INPUT_CONSUMER;
import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.Manifest.permission.MANAGE_APP_TOKENS;
@@ -88,7 +87,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManager.REMOVE_CONTENT_MODE_UNDEFINED;
-import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.view.WindowManager.fixScale;
@@ -3237,49 +3235,17 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- // TODO(multi-display): remove when no default display use case.
- void prepareAppTransitionNone() {
- if (!checkCallingPermission(MANAGE_APP_TOKENS, "prepareAppTransition()")) {
- throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
- }
- getDefaultDisplayContentLocked().prepareAppTransition(TRANSIT_NONE);
- }
-
@Override
public void overridePendingAppTransitionMultiThumbFuture(
IAppTransitionAnimationSpecsFuture specsFuture, IRemoteCallback callback,
boolean scaleUp, int displayId) {
- synchronized (mGlobalLock) {
- final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
- if (displayContent == null) {
- Slog.w(TAG, "Attempted to call overridePendingAppTransitionMultiThumbFuture"
- + " for the display " + displayId + " that does not exist.");
- return;
- }
- displayContent.mAppTransition.overridePendingAppTransitionMultiThumbFuture(specsFuture,
- callback, scaleUp);
- }
+ // TODO(b/365884835): remove this method and callers.
}
@Override
public void overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter,
int displayId) {
- if (!checkCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
- "overridePendingAppTransitionRemote()")) {
- throw new SecurityException(
- "Requires CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS permission");
- }
- synchronized (mGlobalLock) {
- final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
- if (displayContent == null) {
- Slog.w(TAG, "Attempted to call overridePendingAppTransitionRemote"
- + " for the display " + displayId + " that does not exist.");
- return;
- }
- remoteAnimationAdapter.setCallingPidUid(Binder.getCallingPid(), Binder.getCallingUid());
- displayContent.mAppTransition.overridePendingAppTransitionRemote(
- remoteAnimationAdapter);
- }
+ // TODO(b/365884835): remove this method and callers.
}
@Override
@@ -3396,11 +3362,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
- public boolean isAppTransitionStateIdle() {
- return getDefaultDisplayContentLocked().mAppTransition.isIdle();
- }
-
- @Override
public void disableKeyguard(IBinder token, String tag, int userId) {
userId = mAmInternal.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, false /* allowAll */, ALLOW_FULL_ONLY, "disableKeyguard", null);
@@ -6863,7 +6824,7 @@ public class WindowManagerService extends IWindowManager.Stub
pw.print(' '); pw.println(imeControlTarget);
}
pw.print(" Minimum task size of display#"); pw.print(displayId);
- pw.print(' '); pw.print(dc.mMinSizeOfResizeableTaskDp);
+ pw.print(' '); pw.println(dc.mMinSizeOfResizeableTaskDp);
});
pw.print(" mBlurEnabled="); pw.println(mBlurController.getBlurEnabled());
pw.print(" mDisableSecureWindows="); pw.println(mDisableSecureWindows);
@@ -7968,7 +7929,6 @@ public class WindowManagerService extends IWindowManager.Stub
@Override
public void registerAppTransitionListener(AppTransitionListener listener) {
synchronized (mGlobalLock) {
- getDefaultDisplayContentLocked().mAppTransition.registerListenerLocked(listener);
mAtmService.getTransitionController().registerLegacyListener(listener);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 4b4736ec6c59..ea1f35a130b0 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -472,6 +472,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
transition.setAllReady();
}
+ // TODO(b/365884835): remove this method and callers.
@Override
public int startLegacyTransition(int type, @NonNull RemoteAnimationAdapter adapter,
@NonNull IWindowContainerTransactionCallback callback,
@@ -489,16 +490,6 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
throw new IllegalArgumentException("Can't use legacy transitions in"
+ " when shell transitions are enabled.");
}
- final DisplayContent dc =
- mService.mRootWindowContainer.getDisplayContent(DEFAULT_DISPLAY);
- if (dc.mAppTransition.isTransitionSet()) {
- // a transition already exists, so the callback probably won't be called.
- return -1;
- }
- adapter.setCallingPidUid(caller.mPid, caller.mUid);
- dc.prepareAppTransition(type);
- dc.mAppTransition.overridePendingAppTransitionRemote(adapter, true /* sync */,
- false /* isActivityEmbedding */);
syncId = startSyncWithOrganizer(callback);
applyTransaction(t, syncId, mService.mChainTracker.startLegacy("legacyTransit"),
caller);
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 270de0197a4e..bdd13722aba4 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -36,8 +36,8 @@ import static com.android.server.wm.ActivityRecord.State.PAUSED;
import static com.android.server.wm.ActivityRecord.State.PAUSING;
import static com.android.server.wm.ActivityRecord.State.RESUMED;
import static com.android.server.wm.ActivityRecord.State.STARTED;
-import static com.android.server.wm.ActivityRecord.State.STOPPING;
import static com.android.server.wm.ActivityRecord.State.STOPPED;
+import static com.android.server.wm.ActivityRecord.State.STOPPING;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RELEASE;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
@@ -69,7 +69,6 @@ import android.content.pm.ServiceInfo;
import android.content.res.Configuration;
import android.os.Binder;
import android.os.Build;
-import android.os.DeadObjectException;
import android.os.FactoryTest;
import android.os.LocaleList;
import android.os.Message;
@@ -458,6 +457,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
mAtm.getLifecycleManager().scheduleTransactionItemNow(
thread, configurationChangeItem);
} catch (Exception e) {
+ // TODO(b/323801078): remove Exception when cleanup
Slog.e(TAG_CONFIGURATION, "Failed to schedule ConfigurationChangeItem="
+ configurationChangeItem + " owner=" + mOwner, e);
}
@@ -1793,13 +1793,11 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
// Non-UI process can handle the change directly.
mAtm.getLifecycleManager().scheduleTransactionItemNow(thread, transactionItem);
}
- } catch (DeadObjectException e) {
+ } catch (RemoteException e) {
+ // TODO(b/323801078): remove Exception when cleanup
// Expected if the process has been killed.
Slog.w(TAG_CONFIGURATION, "Failed for dead process. ClientTransactionItem="
+ transactionItem + " owner=" + mOwner);
- } catch (Exception e) {
- Slog.e(TAG_CONFIGURATION, "Failed to schedule ClientTransactionItem="
- + transactionItem + " owner=" + mOwner, e);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowProcessControllerMap.java b/services/core/java/com/android/server/wm/WindowProcessControllerMap.java
index 424b0436a008..ac675b8ba11c 100644
--- a/services/core/java/com/android/server/wm/WindowProcessControllerMap.java
+++ b/services/core/java/com/android/server/wm/WindowProcessControllerMap.java
@@ -72,9 +72,6 @@ final class WindowProcessControllerMap {
}
private void removeProcessFromUidMap(WindowProcessController proc) {
- if (proc == null) {
- return;
- }
final int uid = proc.mUid;
ArraySet<WindowProcessController> procSet = mUidMap.get(uid);
if (procSet != null) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastProcessedEventRecordTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastProcessedEventRecordTest.java
new file mode 100644
index 000000000000..7d8d9a57aaa1
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastProcessedEventRecordTest.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import static android.app.AppProtoEnums.BROADCAST_TYPE_FOREGROUND;
+import static android.app.AppProtoEnums.BROADCAST_TYPE_STICKY;
+import static android.os.Process.SYSTEM_UID;
+
+import static com.android.internal.util.FrameworkStatsLog.BROADCAST_PROCESSED;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.eq;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.internal.util.FrameworkStatsLog;
+import com.android.modules.utils.testing.ExtendedMockitoRule;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+@SmallTest
+public class BroadcastProcessedEventRecordTest {
+
+ private static final String ACTION = "action";
+ private static final String PROCESS_NAME = "process";
+ private static final int[] BROADCAST_TYPES =
+ new int[]{BROADCAST_TYPE_FOREGROUND, BROADCAST_TYPE_STICKY};
+
+ private BroadcastProcessedEventRecord mBroadcastProcessedEventRecord;
+
+ @Rule
+ public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(
+ this).mockStatic(FrameworkStatsLog.class).build();
+
+ @Before
+ public void setUp() {
+ mBroadcastProcessedEventRecord = createBroadcastProcessEventRecord();
+ }
+
+ @Test
+ public void addReceiverFinishDetails_withNewRecord_updatesBroadcastRecordEventTime() {
+ assertThat(mBroadcastProcessedEventRecord.getReceiverUidForTest()).isEqualTo(SYSTEM_UID);
+ assertThat(mBroadcastProcessedEventRecord.getSenderUidForTest()).isEqualTo(SYSTEM_UID);
+ assertThat(mBroadcastProcessedEventRecord.getIntentActionForTest()).isEqualTo(ACTION);
+ assertThat(mBroadcastProcessedEventRecord.getReceiverProcessNameForTest()).isEqualTo(
+ PROCESS_NAME);
+ assertThat(mBroadcastProcessedEventRecord.getBroadcastTypesForTest()).isEqualTo(
+ BROADCAST_TYPES);
+
+ mBroadcastProcessedEventRecord.addReceiverFinishTime(20);
+ verifyBroadcastProcessEventUpdateRecord(
+ /* numberOfReceivers= */ 1,
+ /* totalBroadcastFinishTimeMillis= */ 20,
+ /* maxReceiverFinishTimeMillis= */ 20);
+
+ mBroadcastProcessedEventRecord.addReceiverFinishTime(25);
+ verifyBroadcastProcessEventUpdateRecord(
+ /* numberOfReceivers= */ 2,
+ /* totalBroadcastFinishTimeMillis= */ 45,
+ /* maxReceiverFinishTimeMillis= */ 25);
+
+ mBroadcastProcessedEventRecord.addReceiverFinishTime(10);
+ verifyBroadcastProcessEventUpdateRecord(
+ /* numberOfReceivers= */ 3,
+ /* totalBroadcastFinishTimeMillis= */ 55,
+ /* maxReceiverFinishTimeMillis= */ 25);
+ }
+
+ @Test
+ public void logToStatsD_loggingSuccessful() {
+ mBroadcastProcessedEventRecord.addReceiverFinishTime(20);
+ mBroadcastProcessedEventRecord.logToStatsD();
+
+ ExtendedMockito.verify(() -> FrameworkStatsLog.write(eq(BROADCAST_PROCESSED),
+ eq(ACTION),
+ eq(SYSTEM_UID),
+ eq(SYSTEM_UID),
+ eq(1),
+ eq(PROCESS_NAME),
+ eq(20L),
+ eq(20L),
+ eq(BROADCAST_TYPES)));
+ }
+
+ @Test
+ public void logToStatsD_withTotalTimeLessThanTenMs_NoLogging() {
+ mBroadcastProcessedEventRecord.addReceiverFinishTime(8);
+ mBroadcastProcessedEventRecord.logToStatsD();
+
+ ExtendedMockito.verify(() -> FrameworkStatsLog.write(eq(BROADCAST_PROCESSED),
+ eq(ACTION),
+ eq(SYSTEM_UID),
+ eq(SYSTEM_UID),
+ eq(1),
+ eq(PROCESS_NAME),
+ eq(8L),
+ eq(8L),
+ eq(BROADCAST_TYPES)), Mockito.never());
+ }
+
+ private BroadcastProcessedEventRecord createBroadcastProcessEventRecord() {
+ return new BroadcastProcessedEventRecord()
+ .setBroadcastTypes(BROADCAST_TYPES)
+ .setIntentAction(ACTION)
+ .setReceiverProcessName(PROCESS_NAME)
+ .setReceiverUid(SYSTEM_UID)
+ .setSenderUid(SYSTEM_UID);
+ }
+
+ private void verifyBroadcastProcessEventUpdateRecord(
+ int numberOfReceivers,
+ long totalBroadcastFinishTimeMillis,
+ long maxReceiverFinishTimeMillis) {
+ assertThat(mBroadcastProcessedEventRecord.getNumberOfReceiversForTest())
+ .isEqualTo(numberOfReceivers);
+ assertThat(mBroadcastProcessedEventRecord.getTotalBroadcastFinishTimeMillisForTest())
+ .isEqualTo(totalBroadcastFinishTimeMillis);
+ assertThat(mBroadcastProcessedEventRecord.getMaxReceiverFinishTimeMillisForTest())
+ .isEqualTo(maxReceiverFinishTimeMillis);
+ }
+
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueImplTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueImplTest.java
index b32ce49d049d..6726088c6c61 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueImplTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueImplTest.java
@@ -87,6 +87,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
+import org.mockito.Mockito;
import java.io.PrintWriter;
import java.io.Writer;
@@ -1769,6 +1770,33 @@ public final class BroadcastQueueImplTest extends BaseBroadcastQueueTest {
}
@Test
+ public void testBroadcastProcessedEventRecord_broadcastDelivered_processedEventLogged()
+ throws Exception {
+ testBroadcastProcessedEventRecordLogged(
+ /* isAssumedDelivered= */ false,
+ /* isDelivered= */ true,
+ /* numberOfInvocations= */ 1);
+ }
+
+ @Test
+ public void testBroadcastProcessedEventRecord_broadcastDeliveryFailed_eventNotLogged()
+ throws Exception {
+ testBroadcastProcessedEventRecordLogged(
+ /* isAssumedDelivered= */ false,
+ /* isDelivered= */ false,
+ /* numberOfInvocations= */ 0);
+ }
+
+ @Test
+ public void testBroadcastProcessedEventRecord_broadcastAssumedDelivered_eventNotLogged()
+ throws Exception {
+ testBroadcastProcessedEventRecordLogged(
+ /* isAssumedDelivered= */ true,
+ /* isDelivered= */ true,
+ /* numberOfInvocations= */ 0);
+ }
+
+ @Test
public void testGetPreferredSchedulingGroup() throws Exception {
final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));
@@ -2310,6 +2338,28 @@ public final class BroadcastQueueImplTest extends BaseBroadcastQueueTest {
assertFalse(mImpl.isProcessFreezable(greenProcess));
}
+ @SuppressWarnings("GuardedBy")
+ private void testBroadcastProcessedEventRecordLogged(
+ boolean isAssumedDelivered,
+ boolean isDelivered,
+ int numberOfInvocations) throws Exception {
+ final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
+ final BroadcastOptions optionsTimeTick = BroadcastOptions.makeBasic();
+ optionsTimeTick.setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
+
+ final BroadcastRecord broadcastRecordSpy = Mockito.spy(
+ makeBroadcastRecord(timeTick, optionsTimeTick));
+ mImpl.enqueueBroadcastLocked(broadcastRecordSpy);
+
+ doReturn(isDelivered).when(broadcastRecordSpy).wasDelivered(anyInt());
+ doReturn(isAssumedDelivered).when(broadcastRecordSpy).isAssumedDelivered(anyInt());
+ waitForIdle();
+
+ verify(broadcastRecordSpy, times(numberOfInvocations)).updateBroadcastProcessedEventRecord(
+ any(), anyLong());
+ verify(broadcastRecordSpy).logBroadcastProcessedEventRecord();
+ }
+
BroadcastFilter makeRegisteredReceiver(ProcessRecord app, int priority) {
final IIntentReceiver receiver = mock(IIntentReceiver.class);
final ReceiverList receiverList = new ReceiverList(mAms, app, app.getPid(), app.info.uid,
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastRecordTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastRecordTest.java
index 8482fd609d05..3ea83debe2bf 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastRecordTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastRecordTest.java
@@ -30,14 +30,20 @@ import static com.android.server.am.BroadcastRecord.calculateDeferUntilActive;
import static com.android.server.am.BroadcastRecord.calculateUrgent;
import static com.android.server.am.BroadcastRecord.isReceiverEquals;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import android.app.BackgroundStartPrivileges;
import android.app.BroadcastOptions;
@@ -66,6 +72,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
@@ -93,6 +100,9 @@ public class BroadcastRecordTest {
private static final String PACKAGE2 = "pkg2";
private static final String PACKAGE3 = "pkg3";
+ private static final String PROCESS1 = "process1";
+ private static final String PROCESS2 = "process2";
+
private static final int SYSTEM_UID = android.os.Process.SYSTEM_UID;
private static final int APP_UID = android.os.Process.FIRST_APPLICATION_UID;
@@ -1005,6 +1015,142 @@ public class BroadcastRecordTest {
createResolveInfo(PACKAGE3, getAppId(3)))));
}
+
+ @Test
+ @DisableFlags(Flags.FLAG_LOG_BROADCAST_PROCESSED_EVENT)
+ public void testUpdateBroadcastProcessedEventRecord_flagDisabled() {
+ final ResolveInfo receiver = createResolveInfo(PACKAGE1, getAppId(1));
+ final BroadcastRecord record = createBroadcastRecord(
+ new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED),
+ List.of(receiver));
+
+ record.updateBroadcastProcessedEventRecord(receiver, 10);
+
+ assertThat(record.getBroadcastProcessedRecordsForTest()).isEmpty();
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_LOG_BROADCAST_PROCESSED_EVENT)
+ public void testUpdateBroadcastProcessedEventRecord_withNewReceiver_newBroadcastProcessedEventRecordCreated() {
+ final ResolveInfo receiver =
+ createResolveInfoWithProcessName(PACKAGE1, getAppId(1), PROCESS1);
+ final BroadcastRecord record = createBroadcastRecord(
+ new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED),
+ List.of(receiver));
+
+ record.updateBroadcastProcessedEventRecord(receiver, 10);
+
+ assertThat(record.getBroadcastProcessedRecordsForTest()).isNotEmpty();
+ final BroadcastProcessedEventRecord broadcastProcessedEventRecord =
+ record.getBroadcastProcessedRecordsForTest().get(
+ BroadcastRecord.getReceiverProcessName(receiver));
+
+ assertBroadcastProcessedEvent(
+ broadcastProcessedEventRecord,
+ 10001,
+ PROCESS1,
+ 1,
+ 2,
+ 10,
+ 10);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_LOG_BROADCAST_PROCESSED_EVENT)
+ public void testUpdateBroadcastProcessedEventRecord_withNewAndExistingReceiver_multipleBroadcastProcessedEventRecordCreated() {
+ final ResolveInfo receiver1 =
+ createResolveInfoWithProcessName(PACKAGE1, getAppId(1), PROCESS1);
+
+ final ResolveInfo receiver2 =
+ createResolveInfoWithProcessName(PACKAGE2, getAppId(2), PROCESS2);
+
+ final BroadcastRecord record = createBroadcastRecord(
+ new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED),
+ List.of(receiver1, receiver2));
+
+ record.updateBroadcastProcessedEventRecord(receiver1, 11);
+ record.updateBroadcastProcessedEventRecord(receiver2, 11);
+ record.updateBroadcastProcessedEventRecord(receiver1, 20);
+
+ assertThat(record.getBroadcastProcessedRecordsForTest().size()).isEqualTo(2);
+ final BroadcastProcessedEventRecord broadcastProcessedEventRecord1 =
+ record.getBroadcastProcessedRecordsForTest().get(
+ BroadcastRecord.getReceiverProcessName(receiver1));
+ final BroadcastProcessedEventRecord broadcastProcessedEventRecord2 =
+ record.getBroadcastProcessedRecordsForTest().get(
+ BroadcastRecord.getReceiverProcessName(receiver2));
+
+ assertBroadcastProcessedEvent(
+ broadcastProcessedEventRecord1,
+ 10001,
+ PROCESS1,
+ 2,
+ 1,
+ 31,
+ 20);
+ assertBroadcastProcessedEvent(
+ broadcastProcessedEventRecord2,
+ 10002,
+ PROCESS2,
+ 1,
+ 1,
+ 11,
+ 11);
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_LOG_BROADCAST_PROCESSED_EVENT)
+ public void testLogBroadcastProcessedEventRecord_flagDisabled() {
+ testLogBroadcastProcessedEventRecord(0);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_LOG_BROADCAST_PROCESSED_EVENT)
+ public void testLogBroadcastProcessedEventRecord_flagEnabled_allBroadcastProcessedEventLogged() {
+ testLogBroadcastProcessedEventRecord(1);
+ }
+
+ private void testLogBroadcastProcessedEventRecord(int times) {
+ final ResolveInfo receiver = createResolveInfo(PACKAGE1, getAppId(1));
+ final BroadcastRecord record = createBroadcastRecord(
+ new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED),
+ List.of(receiver));
+
+ final BroadcastProcessedEventRecord broadcastProcessedEventRecord = Mockito.mock(
+ BroadcastProcessedEventRecord.class);
+ record.getBroadcastProcessedRecordsForTest()
+ .put("process", broadcastProcessedEventRecord);
+ record.logBroadcastProcessedEventRecord();
+ doNothing().when(broadcastProcessedEventRecord).logToStatsD();
+
+ verify(broadcastProcessedEventRecord, times(times)).logToStatsD();
+ }
+
+ private void assertBroadcastProcessedEvent(
+ BroadcastProcessedEventRecord broadcastProcessedEventRecord,
+ int receiverUid,
+ String processName,
+ int numberOfReceivers,
+ int broadcastTypeLength,
+ long totalBroadcastFinishTimeMillis,
+ long maxReceiverFinishTimeMillis) {
+ assertNotNull(broadcastProcessedEventRecord);
+ assertThat(broadcastProcessedEventRecord.getReceiverUidForTest()).isEqualTo(receiverUid);
+ assertThat(broadcastProcessedEventRecord.getSenderUidForTest()).isEqualTo(0);
+ assertThat(broadcastProcessedEventRecord.getIntentActionForTest())
+ .isEqualTo(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+ assertThat(broadcastProcessedEventRecord.getReceiverProcessNameForTest())
+ .isEqualTo(processName);
+ assertThat(broadcastProcessedEventRecord.getBroadcastTypesForTest().length)
+ .isEqualTo(broadcastTypeLength);
+ assertThat(broadcastProcessedEventRecord.getNumberOfReceiversForTest())
+ .isEqualTo(numberOfReceivers);
+ assertThat(broadcastProcessedEventRecord.getTotalBroadcastFinishTimeMillisForTest())
+ .isEqualTo(totalBroadcastFinishTimeMillis);
+ assertThat(broadcastProcessedEventRecord.getMaxReceiverFinishTimeMillisForTest())
+ .isEqualTo(maxReceiverFinishTimeMillis);
+ }
+
private boolean[] calculateChangeState(List<Object> receivers) {
return BroadcastRecord.calculateChangeStateForReceivers(receivers,
LIMIT_PRIORITY_SCOPE, mPlatformCompat);
@@ -1049,6 +1195,16 @@ public class BroadcastRecordTest {
return createResolveInfo(PACKAGE1, getAppId(1), priority);
}
+ private static ResolveInfo createResolveInfoWithProcessName(
+ String packageName,
+ int uid,
+ String processName) {
+ final ResolveInfo resolveInfo = createResolveInfo(packageName, uid);
+ resolveInfo.activityInfo.processName = processName;
+
+ return resolveInfo;
+ }
+
private static ResolveInfo createResolveInfo(String packageName, int uid) {
return createResolveInfo(packageName, uid, 0);
}
diff --git a/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/TestApp/src/com/android/coretests/apps/testapp/Android.bp b/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/TestApp/src/com/android/coretests/apps/testapp/Android.bp
index ca5952b140c1..e4381007edc0 100644
--- a/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/TestApp/src/com/android/coretests/apps/testapp/Android.bp
+++ b/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/TestApp/src/com/android/coretests/apps/testapp/Android.bp
@@ -34,7 +34,6 @@ android_test_helper_app {
srcs: ["**/*.java"],
platform_apis: true,
- certificate: "platform",
dxflags: ["--multi-dex"],
optimize: {
enabled: false,
diff --git a/services/tests/servicestests/src/com/android/server/locales/LocaleManagerBackupRestoreTest.java b/services/tests/servicestests/src/com/android/server/locales/LocaleManagerBackupRestoreTest.java
index 50cfa753ebdb..57e9cf4bf48b 100644
--- a/services/tests/servicestests/src/com/android/server/locales/LocaleManagerBackupRestoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/locales/LocaleManagerBackupRestoreTest.java
@@ -95,8 +95,8 @@ public class LocaleManagerBackupRestoreTest {
private static final String TEST_LOCALES_XML_TAG = "locales";
private static final int DEFAULT_USER_ID = 0;
private static final int WORK_PROFILE_USER_ID = 10;
- private static final int DEFAULT_UID = Binder.getCallingUid() + 100;
- private static final int WORK_PROFILE_UID = Binder.getCallingUid() + 1000100;
+ private static final int DEFAULT_UID = 100;
+ private static final int WORK_PROFILE_UID = 1000100;
private static final long DEFAULT_CREATION_TIME_MILLIS = 1000;
private static final Duration RETENTION_PERIOD = Duration.ofDays(3);
private static final LocaleList DEFAULT_LOCALES =
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/OWNERS b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/OWNERS
index bb487fb52c9f..c8b8e4887b5e 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/OWNERS
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/OWNERS
@@ -1,4 +1,3 @@
aseemk@google.com
-bozhu@google.com
dementyev@google.com
robertberry@google.com
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 39a849a22622..8992c2e632b2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -724,6 +724,7 @@ public class ActivityRecordTests extends WindowTestsBase {
@Test
@EnableFlags(Flags.FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+ @DisableFlags(Flags.FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING_OPT_OUT)
@EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT})
public void testOrientation_allowFixedOrientationForCameraCompatInFreeformWindowing() {
final ActivityRecord activity = setupDisplayAndActivityForCameraCompat(
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 61ed0b53cdcf..4c81f738138a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -87,7 +87,7 @@ import static com.android.server.wm.TransitionSubject.assertThat;
import static com.android.window.flags.Flags.FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING;
import static com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE;
import static com.android.server.display.feature.flags.Flags.FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT;
-import static com.android.window.flags.Flags.FLAG_ENABLE_PERSISTING_DENSITY_SCALE_FOR_CONNECTED_DISPLAYS;
+import static com.android.window.flags.Flags.FLAG_ENABLE_PERSISTING_DISPLAY_SIZE_FOR_CONNECTED_DISPLAYS;
import static com.google.common.truth.Truth.assertThat;
@@ -2631,10 +2631,19 @@ public class DisplayContentTests extends WindowTestsBase {
final BooleanSupplier keyguardGoingAway = () -> keyguard.isKeyguardGoingAway(displayId);
final BooleanSupplier appVisible = activity::isVisibleRequested;
- // Begin locked and in AOD
+ // Begin unlocked.
+ keyguard.setKeyguardShown(displayId, false /* keyguard */, false /* aod */);
+ transitions.flush();
+
+ // Lock and go to AOD.
keyguard.setKeyguardShown(displayId, true /* keyguard */, true /* aod */);
assertFalse(keyguardGoingAway.getAsBoolean());
assertFalse(appVisible.getAsBoolean());
+ if (Flags.aodTransition()) {
+ assertThat(transitions.mLastTransit).flags().contains(TRANSIT_FLAG_AOD_APPEARING);
+ } else {
+ assertThat(transitions.mLastTransit).flags().doesNotContain(TRANSIT_FLAG_AOD_APPEARING);
+ }
transitions.flush();
// Start unlocking from AOD.
@@ -2654,14 +2663,7 @@ public class DisplayContentTests extends WindowTestsBase {
keyguard.setKeyguardShown(displayId, true /* keyguard */, false /* aod */);
assertTrue(keyguardGoingAway.getAsBoolean());
assertTrue(appVisible.getAsBoolean());
-
- if (Flags.aodTransition()) {
- assertThat(transitions.mLastTransit).flags()
- .containsExactly(TRANSIT_FLAG_AOD_APPEARING);
- } else {
- assertThat(transitions.mLastTransit).isNull();
- }
- transitions.flush();
+ assertThat(transitions.mLastTransit).isNull();
// Finish unlock
keyguard.setKeyguardShown(displayId, false /* keyguard */, false /* aod */);
@@ -2684,10 +2686,19 @@ public class DisplayContentTests extends WindowTestsBase {
final BooleanSupplier keyguardGoingAway = () -> keyguard.isKeyguardGoingAway(displayId);
final BooleanSupplier appVisible = activity::isVisibleRequested;
- // Begin locked and in AOD
+ // Begin unlocked.
+ keyguard.setKeyguardShown(displayId, false /* keyguard */, false /* aod */);
+ transitions.flush();
+
+ // Lock and go to AOD.
keyguard.setKeyguardShown(displayId, true /* keyguard */, true /* aod */);
assertFalse(keyguardGoingAway.getAsBoolean());
assertFalse(appVisible.getAsBoolean());
+ if (Flags.aodTransition()) {
+ assertThat(transitions.mLastTransit).flags().contains(TRANSIT_FLAG_AOD_APPEARING);
+ } else {
+ assertThat(transitions.mLastTransit).flags().doesNotContain(TRANSIT_FLAG_AOD_APPEARING);
+ }
transitions.flush();
// Start unlocking from AOD.
@@ -2705,14 +2716,7 @@ public class DisplayContentTests extends WindowTestsBase {
keyguard.setKeyguardShown(displayId, true /* keyguard */, false /* aod */);
assertTrue(keyguardGoingAway.getAsBoolean());
assertTrue(appVisible.getAsBoolean());
-
- if (Flags.aodTransition()) {
- assertThat(transitions.mLastTransit).flags()
- .containsExactly(TRANSIT_FLAG_AOD_APPEARING);
- } else {
- assertThat(transitions.mLastTransit).isNull();
- }
- transitions.flush();
+ assertThat(transitions.mLastTransit).isNull();
// Same API call a second time cancels the unlock, because AOD isn't changing.
keyguard.setKeyguardShown(displayId, true /* keyguard */, false /* aod */);
@@ -2921,7 +2925,7 @@ public class DisplayContentTests extends WindowTestsBase {
assertFalse(dc.mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(dc));
}
- @EnableFlags(FLAG_ENABLE_PERSISTING_DENSITY_SCALE_FOR_CONNECTED_DISPLAYS)
+ @EnableFlags(FLAG_ENABLE_PERSISTING_DISPLAY_SIZE_FOR_CONNECTED_DISPLAYS)
@Test
public void testForcedDensityRatioSetForExternalDisplays_persistDensityScaleFlagEnabled() {
final DisplayInfo displayInfo = new DisplayInfo(mDisplayInfo);
@@ -2951,7 +2955,7 @@ public class DisplayContentTests extends WindowTestsBase {
displayContent.mExternalDisplayForcedDensityRatio, 0.01);
}
- @EnableFlags(FLAG_ENABLE_PERSISTING_DENSITY_SCALE_FOR_CONNECTED_DISPLAYS)
+ @EnableFlags(FLAG_ENABLE_PERSISTING_DISPLAY_SIZE_FOR_CONNECTED_DISPLAYS)
@Test
public void testForcedDensityUpdateForExternalDisplays_persistDensityScaleFlagEnabled() {
final DisplayInfo displayInfo = new DisplayInfo(mDisplayInfo);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
index a57577a96f79..81e487a67725 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
@@ -274,7 +274,7 @@ public class DisplayWindowSettingsTests extends WindowTestsBase {
mSecondaryDisplay.mBaseDisplayDensity);
}
- @EnableFlags(Flags.FLAG_ENABLE_PERSISTING_DENSITY_SCALE_FOR_CONNECTED_DISPLAYS)
+ @EnableFlags(Flags.FLAG_ENABLE_PERSISTING_DISPLAY_SIZE_FOR_CONNECTED_DISPLAYS)
@Test
public void testSetForcedDensityRatio() {
mDisplayWindowSettings.setForcedDensity(mSecondaryDisplay.getDisplayInfo(),
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 4e09d6afe74b..33a48aadbd70 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -67,6 +67,7 @@ import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_POSITION_MU
import static com.android.server.wm.AppCompatUtils.computeAspectRatio;
import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
+import static com.android.window.flags.Flags.FLAG_ENABLE_SIZE_COMPAT_MODE_IMPROVEMENTS_FOR_CONNECTED_DISPLAYS;
import static com.google.common.truth.Truth.assertThat;
@@ -109,6 +110,7 @@ import android.provider.DeviceConfig;
import android.provider.DeviceConfig.Properties;
import android.view.DisplayCutout;
import android.view.DisplayInfo;
+import android.view.InputDevice;
import android.view.InsetsFrameProvider;
import android.view.InsetsSource;
import android.view.InsetsState;
@@ -561,6 +563,41 @@ public class SizeCompatTests extends WindowTestsBase {
assertDownScaled();
}
+ @EnableFlags(FLAG_ENABLE_SIZE_COMPAT_MODE_IMPROVEMENTS_FOR_CONNECTED_DISPLAYS)
+ @Test
+ public void testFixedMiscConfigurationWhenMovingToDisplay() {
+ setUpDisplaySizeWithApp(1000, 2500);
+
+ final DisplayContent newDisplay =
+ new TestDisplayContent.Builder(mAtm, 1000, 2000).build();
+ final InputDevice device = new InputDevice.Builder()
+ .setAssociatedDisplayId(newDisplay.mDisplayId)
+ .setSources(InputDevice.SOURCE_TOUCHSCREEN | InputDevice.SOURCE_TRACKBALL
+ | InputDevice.KEYBOARD_TYPE_ALPHABETIC)
+ .build();
+ final InputDevice[] devices = {device};
+ doReturn(true).when(newDisplay.mWmService.mInputManager)
+ .canDispatchToDisplay(device.getId(), newDisplay.mDisplayId);
+ doReturn(devices).when(newDisplay.mWmService.mInputManager).getInputDevices();
+ mTask.mWmService.mIsTouchDevice = true;
+ mTask.mWmService.displayReady();
+
+ prepareUnresizable(mActivity, 1.5f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
+
+ final Configuration originalConfiguration = mActivity.getConfiguration();
+ final int originalTouchscreen = originalConfiguration.touchscreen;
+ final int originalNavigation = originalConfiguration.navigation;
+ final int originalKeyboard = originalConfiguration.keyboard;
+
+ // Move the non-resizable activity to the new display.
+ mTask.reparent(newDisplay.getDefaultTaskDisplayArea(), true /* onTop */);
+
+ final Configuration newConfiguration = mActivity.getConfiguration();
+ assertEquals(originalTouchscreen, newConfiguration.touchscreen);
+ assertEquals(originalNavigation, newConfiguration.navigation);
+ assertEquals(originalKeyboard, newConfiguration.keyboard);
+ }
+
@Test
public void testFixedScreenBoundsWhenDisplaySizeChanged() {
setUpDisplaySizeWithApp(1000, 2500);
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 1c6652daf498..0dd0a42d44b4 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -3203,6 +3203,31 @@ interface ITelephony {
in List<String> satelliteCountryCodes, String satelliteAccessConfigurationFile);
/**
+ * This API can be used by only CTS to override the satellite access allowed state for
+ * a list of subscription IDs.
+ *
+ * @param subIdListStr The string representation of the list of subscription IDs,
+ * which are numbers separated by comma.
+ * @return {@code true} if the satellite access allowed state is set successfully,
+ * {@code false} otherwise.
+ */
+ boolean setSatelliteAccessAllowedForSubscriptions(in String subIdListStr);
+
+ /**
+ * This API can be used by only CTS to override satellite TN scanning support.
+ *
+ * @param reset {@code true} mean the overridden configs should not be used, {@code false}
+ * otherwise.
+ * @param concurrentTnScanningSupported Whether concurrent TN scanning is supported.
+ * @param tnScanningDuringSatelliteSessionAllowed Whether TN scanning is allowed during
+ * a satellite session.
+ * @return {@code true} if the TN scanning support is set successfully,
+ * {@code false} otherwise.
+ */
+ boolean setTnScanningSupport(in boolean reset, in boolean concurrentTnScanningSupported,
+ in boolean tnScanningDuringSatelliteSessionAllowed);
+
+ /**
* This API can be used in only testing to override oem-enabled satellite provision status.
*
* @param reset {@code true} mean the overriding status should not be used, {@code false}