summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AconfigFlags.bp9
-rw-r--r--android-sdk-flags/Android.bp13
-rw-r--r--core/api/current.txt29
-rw-r--r--core/api/system-current.txt4
-rw-r--r--core/api/test-current.txt11
-rw-r--r--core/java/android/app/BroadcastStickyCache.java215
-rw-r--r--core/java/android/app/ContextImpl.java21
-rw-r--r--core/java/android/app/IActivityManager.aidl10
-rw-r--r--core/java/android/app/Notification.java122
-rw-r--r--core/java/android/app/TEST_MAPPING4
-rw-r--r--core/java/android/app/WallpaperManager.java42
-rw-r--r--core/java/android/app/wallpaper/WallpaperDescription.java152
-rw-r--r--core/java/android/companion/CompanionDeviceManager.java13
-rw-r--r--core/java/android/companion/CompanionDeviceService.java8
-rw-r--r--core/java/android/content/ClipData.java28
-rw-r--r--core/java/android/content/Intent.java60
-rw-r--r--core/java/android/content/pm/dependencyinstaller/DependencyInstallerCallback.java7
-rw-r--r--core/java/android/content/pm/dependencyinstaller/IDependencyInstallerCallback.aidl4
-rw-r--r--core/java/android/content/pm/multiuser.aconfig11
-rw-r--r--core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java30
-rw-r--r--core/java/android/hardware/camera2/CameraManager.java23
-rw-r--r--core/java/android/hardware/camera2/TotalCaptureResult.java6
-rw-r--r--core/java/android/hardware/camera2/impl/CameraDeviceImpl.java68
-rw-r--r--core/java/android/hardware/camera2/impl/CameraMetadataNative.java12
-rw-r--r--core/java/android/hardware/camera2/impl/CameraOfflineSessionImpl.java5
-rw-r--r--core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java14
-rw-r--r--core/java/android/hardware/camera2/impl/PhysicalCaptureResultInfo.java19
-rw-r--r--core/java/android/os/Build.java51
-rw-r--r--core/java/android/os/CpuHeadroomParams.java36
-rw-r--r--core/java/android/os/GpuHeadroomParams.java35
-rw-r--r--core/java/android/os/GraphicsEnvironment.java5
-rw-r--r--core/java/android/os/UserManager.java2
-rw-r--r--core/java/android/permission/flags.aconfig18
-rw-r--r--core/java/android/provider/ContactsContract.java22
-rw-r--r--core/java/android/provider/Settings.java9
-rw-r--r--core/java/android/security/responsible_apis_flags.aconfig8
-rw-r--r--core/java/android/service/autofill/FillEventHistory.java29
-rw-r--r--core/java/android/widget/Button.java4
-rw-r--r--core/java/android/window/flags/lse_desktop_experience.aconfig21
-rw-r--r--core/java/com/android/internal/accessibility/AccessibilityShortcutController.java83
-rw-r--r--core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java18
-rw-r--r--core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java16
-rw-r--r--core/java/com/android/internal/widget/ConversationLayout.java3
-rw-r--r--core/java/com/android/internal/widget/MessagingGroup.java10
-rw-r--r--core/java/com/android/internal/widget/NotificationActionListLayout.java7
-rw-r--r--core/jni/Android.bp6
-rw-r--r--core/jni/AndroidRuntime.cpp2
-rw-r--r--core/jni/android_hardware_camera2_CameraDevice.cpp148
-rw-r--r--core/res/res/layout/notification_2025_conversation_face_pile_layout.xml54
-rw-r--r--core/res/res/layout/notification_2025_conversation_icon_container.xml104
-rw-r--r--core/res/res/layout/notification_2025_messaging_group.xml80
-rw-r--r--core/res/res/layout/notification_2025_template_collapsed_base.xml8
-rw-r--r--core/res/res/layout/notification_2025_template_collapsed_call.xml79
-rw-r--r--core/res/res/layout/notification_2025_template_collapsed_media.xml6
-rw-r--r--core/res/res/layout/notification_2025_template_collapsed_messaging.xml6
-rw-r--r--core/res/res/layout/notification_2025_template_conversation.xml159
-rw-r--r--core/res/res/layout/notification_2025_template_expanded_big_picture.xml93
-rw-r--r--core/res/res/layout/notification_2025_template_expanded_big_text.xml94
-rw-r--r--core/res/res/layout/notification_2025_template_expanded_call.xml109
-rw-r--r--core/res/res/layout/notification_2025_template_expanded_inbox.xml131
-rw-r--r--core/res/res/layout/notification_2025_template_expanded_media.xml103
-rw-r--r--core/res/res/layout/notification_2025_template_expanded_messaging.xml71
-rw-r--r--core/res/res/layout/notification_2025_template_expanded_progress.xml122
-rw-r--r--core/res/res/layout/side_fps_toast.xml4
-rw-r--r--core/res/res/values-af/strings.xml2
-rw-r--r--core/res/res/values-am/strings.xml2
-rw-r--r--core/res/res/values-ar/strings.xml2
-rw-r--r--core/res/res/values-as/strings.xml2
-rw-r--r--core/res/res/values-az/strings.xml2
-rw-r--r--core/res/res/values-b+sr+Latn/strings.xml2
-rw-r--r--core/res/res/values-be/strings.xml2
-rw-r--r--core/res/res/values-bg/strings.xml2
-rw-r--r--core/res/res/values-bn/strings.xml2
-rw-r--r--core/res/res/values-bs/strings.xml2
-rw-r--r--core/res/res/values-ca/strings.xml2
-rw-r--r--core/res/res/values-cs/strings.xml2
-rw-r--r--core/res/res/values-da/strings.xml2
-rw-r--r--core/res/res/values-de/strings.xml2
-rw-r--r--core/res/res/values-el/strings.xml2
-rw-r--r--core/res/res/values-en-rAU/strings.xml2
-rw-r--r--core/res/res/values-en-rCA/strings.xml2
-rw-r--r--core/res/res/values-en-rGB/strings.xml2
-rw-r--r--core/res/res/values-en-rIN/strings.xml2
-rw-r--r--core/res/res/values-es-rUS/strings.xml2
-rw-r--r--core/res/res/values-es/strings.xml2
-rw-r--r--core/res/res/values-et/strings.xml2
-rw-r--r--core/res/res/values-eu/strings.xml6
-rw-r--r--core/res/res/values-fa/strings.xml2
-rw-r--r--core/res/res/values-fi/strings.xml2
-rw-r--r--core/res/res/values-fr-rCA/strings.xml2
-rw-r--r--core/res/res/values-fr/strings.xml2
-rw-r--r--core/res/res/values-gl/strings.xml2
-rw-r--r--core/res/res/values-gu/strings.xml2
-rw-r--r--core/res/res/values-hi/strings.xml2
-rw-r--r--core/res/res/values-hr/strings.xml2
-rw-r--r--core/res/res/values-hu/strings.xml2
-rw-r--r--core/res/res/values-hy/strings.xml2
-rw-r--r--core/res/res/values-in/strings.xml2
-rw-r--r--core/res/res/values-is/strings.xml2
-rw-r--r--core/res/res/values-it/strings.xml18
-rw-r--r--core/res/res/values-iw/strings.xml2
-rw-r--r--core/res/res/values-ja/strings.xml2
-rw-r--r--core/res/res/values-ka/strings.xml2
-rw-r--r--core/res/res/values-kk/strings.xml10
-rw-r--r--core/res/res/values-km/strings.xml2
-rw-r--r--core/res/res/values-kn/strings.xml4
-rw-r--r--core/res/res/values-ko/strings.xml2
-rw-r--r--core/res/res/values-ky/strings.xml2
-rw-r--r--core/res/res/values-lo/strings.xml2
-rw-r--r--core/res/res/values-lt/strings.xml2
-rw-r--r--core/res/res/values-lv/strings.xml2
-rw-r--r--core/res/res/values-mk/strings.xml2
-rw-r--r--core/res/res/values-ml/strings.xml2
-rw-r--r--core/res/res/values-mn/strings.xml2
-rw-r--r--core/res/res/values-mr/strings.xml2
-rw-r--r--core/res/res/values-ms/strings.xml2
-rw-r--r--core/res/res/values-my/strings.xml2
-rw-r--r--core/res/res/values-nb/strings.xml2
-rw-r--r--core/res/res/values-ne/strings.xml4
-rw-r--r--core/res/res/values-nl/strings.xml2
-rw-r--r--core/res/res/values-or/strings.xml2
-rw-r--r--core/res/res/values-pa/strings.xml2
-rw-r--r--core/res/res/values-pl/strings.xml2
-rw-r--r--core/res/res/values-pt-rBR/strings.xml2
-rw-r--r--core/res/res/values-pt-rPT/strings.xml2
-rw-r--r--core/res/res/values-pt/strings.xml2
-rw-r--r--core/res/res/values-ro/strings.xml2
-rw-r--r--core/res/res/values-ru/strings.xml2
-rw-r--r--core/res/res/values-si/strings.xml2
-rw-r--r--core/res/res/values-sk/strings.xml2
-rw-r--r--core/res/res/values-sl/strings.xml2
-rw-r--r--core/res/res/values-sq/strings.xml2
-rw-r--r--core/res/res/values-sr/strings.xml2
-rw-r--r--core/res/res/values-sv/strings.xml2
-rw-r--r--core/res/res/values-sw/strings.xml2
-rw-r--r--core/res/res/values-ta/strings.xml2
-rw-r--r--core/res/res/values-te/strings.xml6
-rw-r--r--core/res/res/values-th/strings.xml2
-rw-r--r--core/res/res/values-tl/strings.xml2
-rw-r--r--core/res/res/values-tr/strings.xml2
-rw-r--r--core/res/res/values-uk/strings.xml2
-rw-r--r--core/res/res/values-ur/strings.xml2
-rw-r--r--core/res/res/values-uz/strings.xml2
-rw-r--r--core/res/res/values-vi/strings.xml2
-rw-r--r--core/res/res/values-zh-rCN/strings.xml2
-rw-r--r--core/res/res/values-zh-rHK/strings.xml2
-rw-r--r--core/res/res/values-zh-rTW/strings.xml2
-rw-r--r--core/res/res/values-zu/strings.xml2
-rw-r--r--core/res/res/values/attrs_manifest.xml2
-rw-r--r--core/res/res/values/config.xml3
-rw-r--r--core/res/res/values/dimens.xml29
-rw-r--r--core/res/res/values/public-staging.xml2
-rw-r--r--core/res/res/values/symbols.xml17
-rw-r--r--core/tests/coretests/src/android/app/wallpaper/WallpaperDescriptionTest.java180
-rw-r--r--core/tests/coretests/src/android/content/IntentTest.java113
-rw-r--r--core/tests/coretests/src/android/os/BuildTest.java97
-rw-r--r--core/tests/coretests/src/android/os/MessageQueueTest.java255
-rw-r--r--core/tests/coretests/src/android/window/OWNERS3
-rw-r--r--core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java125
-rw-r--r--core/tests/coretests/src/com/android/internal/accessibility/dialog/InvisibleToggleAccessibilityServiceTargetTest.java91
-rw-r--r--libs/WindowManager/Shell/res/layout/desktop_mode_app_header.xml10
-rw-r--r--libs/WindowManager/Shell/res/values-ar/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-bg/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-ca/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-cs/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-el/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-en-rAU/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-en-rCA/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-en-rGB/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-en-rIN/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-es-rUS/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-et/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-fa/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-hi/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-hy/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-it/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ja/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-lo/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-ml/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-nl/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-pl/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-pt-rPT/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-sl/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-sr/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-sv/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-th/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-tl/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-uz/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rHK/strings.xml2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxTransitionObserver.kt14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java23
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java76
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandler.kt9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandler.kt51
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt26
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt24
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListener.kt10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt73
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt27
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopUserRepositories.kt109
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/ToggleTaskSizeUtils.kt149
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandler.kt6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepository.kt25
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializer.kt6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt63
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java62
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java31
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java19
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java21
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java59
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java54
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java41
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageOrderOperator.kt19
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHeaderManageWindowsMenu.kt5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java100
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java55
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java25
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/DefaultWindowDecorViewHost.kt147
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/DefaultWindowDecorViewHostSupplier.kt37
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/WindowDecorViewHost.kt45
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/WindowDecorViewHostSupplier.kt36
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt4
-rw-r--r--libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/AndroidTestTemplate.xml2
-rw-r--r--libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/AndroidTestTemplate.xml2
-rw-r--r--libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/AndroidTestTemplate.xml2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/appcompat/AndroidTestTemplate.xml2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/bubble/AndroidTestTemplate.xml2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/AndroidTestTemplate.xml11
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/csuiteDefaultTemplate.xml2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipWithSourceRectHintTest.kt3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenEnterPipOnUserLeaveHintTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipAspectRatioChangeTest.kt3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipDragTest.kt3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipDragThenSnapTest.kt3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipPinchInTest.kt3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt35
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt35
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt12
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt8
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipToOtherOrientationTest.kt12
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/EnterPipTransition.kt8
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/PipTransition.kt10
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt9
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/transition/TransitionStateHolderTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java30
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxTransitionObserverTest.kt44
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt21
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt10
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandlerTest.kt10
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt36
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt8
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListenerTest.kt96
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt153
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt20
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt7
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandlerTest.kt9
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepositoryTest.kt9
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerTest.kt231
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java50
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java6
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java9
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java38
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java8
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/util/TransitionObserverTestUtils.kt46
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/CaptionWindowDecorationTests.kt3
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopHeaderManageWindowsMenuTest.kt20
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt23
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt9
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java83
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java5
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/viewhost/DefaultWindowDecorViewHostTest.kt221
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt6
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt17
-rw-r--r--media/java/android/media/MediaCas.java10
-rw-r--r--media/java/android/media/MediaRoute2Info.java104
-rw-r--r--media/java/android/media/quality/IMediaQualityManager.aidl60
-rw-r--r--media/java/android/media/quality/MediaQualityContract.java247
-rw-r--r--media/java/android/media/quality/MediaQualityManager.java62
-rw-r--r--media/java/android/media/tv/flags/media_tv.aconfig10
-rw-r--r--media/java/android/media/tv/tuner/Tuner.java10
-rw-r--r--media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java14
-rw-r--r--media/java/android/media/tv/tunerresourcemanager/aidl/android/media/tv/tunerresourcemanager/ITunerResourceManager.aidl11
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java3
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java13
-rw-r--r--packages/PackageInstaller/res/values-it/strings.xml2
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-af/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-am/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ar/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-as/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-az/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-b+sr+Latn/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-be/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-bg/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-bn/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-bs/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ca/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-cs/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-da/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-de/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-el/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-en-rAU/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-en-rGB/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-en-rIN/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-es-rUS/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-es/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-et/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-eu/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-fa/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-fi/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-fr-rCA/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-fr/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-gl/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-gu/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-hi/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-hr/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-hu/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-in/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-is/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-it/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-iw/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ka/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-kk/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-km/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ko/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ky/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-lo/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-lt/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-lv/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-mk/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ml/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-mn/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ms/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-my/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-nb/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ne/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-nl/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-or/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-pl/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-pt-rBR/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-pt/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ro/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ru/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-si/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-sk/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-sq/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-sr/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-sv/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-sw/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-th/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-tr/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-uk/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-vi/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-zh-rCN/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-zh-rHK/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-zh-rTW/strings.xml6
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-zu/strings.xml6
-rw-r--r--packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java2
-rw-r--r--packages/SettingsLib/RestrictedLockUtils/res/values-hi/strings.xml2
-rw-r--r--packages/SettingsLib/RestrictedLockUtils/res/values-hu/strings.xml2
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-af/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-am/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-ar/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-as/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-az/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-b+sr+Latn/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-be/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-bg/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-bn/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-bs/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-ca/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-cs/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-da/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-de/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-el/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-en-rAU/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-en-rGB/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-en-rIN/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-es-rUS/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-es/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-et/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-eu/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-fa/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-fi/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-fr-rCA/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-fr/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-gl/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-gu/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-hi/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-hr/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-hu/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-in/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-is/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-it/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-iw/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-ka/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-kk/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-km/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-ko/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-ky/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-lo/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-lt/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-lv/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-mk/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-ml/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-mn/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-ms/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-my/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-nb/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-ne/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-nl/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-or/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-pl/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-pt-rBR/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-pt/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-ro/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-ru/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-si/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-sk/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-sq/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-sr/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-sv/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-sw/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-th/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-tr/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-uk/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-vi/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-zh-rCN/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-zh-rHK/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-zh-rTW/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-zu/strings.xml22
-rw-r--r--packages/SettingsLib/Spa/build.gradle.kts2
-rw-r--r--packages/SettingsLib/Spa/gradle/libs.versions.toml2
-rw-r--r--packages/SettingsLib/Spa/gradle/wrapper/gradle-8.11.1-bin.zip (renamed from packages/SettingsLib/Spa/gradle/wrapper/gradle-8.10.2-bin.zip)bin136715430 -> 136920070 bytes
-rw-r--r--packages/SettingsLib/Spa/gradle/wrapper/gradle-wrapper.properties2
-rw-r--r--packages/SettingsLib/Spa/spa/build.gradle.kts6
-rw-r--r--packages/SettingsLib/res/values-af/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-am/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-ar/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-as/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-az/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-b+sr+Latn/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-be/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-bg/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-bn/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-bs/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-ca/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-cs/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-da/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-de/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-el/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-en-rAU/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-en-rCA/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-en-rGB/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-en-rIN/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-es-rUS/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-es/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-et/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-eu/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-fa/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-fi/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-fr-rCA/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-fr/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-gl/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-gu/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-hi/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-hr/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-hu/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-hy/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-in/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-is/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-it/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-iw/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-ja/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-ka/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-kk/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-km/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-kn/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-ko/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-ky/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-lo/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-lt/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-lv/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-mk/strings.xml11
-rw-r--r--packages/SettingsLib/res/values-ml/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-mn/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-mr/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-ms/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-my/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-nb/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-ne/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-nl/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-or/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-pa/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-pl/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-pt-rBR/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-pt-rPT/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-pt/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-ro/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-ru/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-si/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-sk/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-sl/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-sq/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-sr/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-sv/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-sw/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-ta/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-te/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-th/strings.xml13
-rw-r--r--packages/SettingsLib/res/values-tl/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-tr/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-uk/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-ur/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-uz/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-vi/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-zh-rCN/strings.xml11
-rw-r--r--packages/SettingsLib/res/values-zh-rHK/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-zh-rTW/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-zu/strings.xml9
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java3
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java1
-rw-r--r--packages/StatementService/src/com/android/statementservice/StatementServiceApplication.kt1
-rw-r--r--packages/StatementService/src/com/android/statementservice/domain/DomainVerificationUtils.kt39
-rw-r--r--packages/StatementService/src/com/android/statementservice/domain/DomainVerifier.kt8
-rw-r--r--packages/StatementService/src/com/android/statementservice/domain/VerifyStatus.kt17
-rw-r--r--packages/StatementService/src/com/android/statementservice/domain/worker/PeriodicUpdateWorker.kt94
-rw-r--r--packages/StatementService/src/com/android/statementservice/domain/worker/RetryRequestWorker.kt69
-rw-r--r--packages/StatementService/src/com/android/statementservice/domain/worker/UpdateVerifiedDomainsWorker.kt29
-rw-r--r--packages/SystemUI/TEST_MAPPING8
-rw-r--r--packages/SystemUI/aconfig/biometrics_framework.aconfig7
-rw-r--r--packages/SystemUI/aconfig/systemui.aconfig10
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt8
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt9
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResponsiveLazyHorizontalGrid.kt234
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt4
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt165
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt42
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt39
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt55
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SharedElement.kt113
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt23
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/ui/util/IntIndexedMap.kt73
-rw-r--r--packages/SystemUI/compose/scene/tests/AndroidManifest.xml3
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedSharedElementTest.kt283
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/SharedElementTest.kt57
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/ui/util/IntIndexMapTest.kt92
-rw-r--r--packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestTransition.kt90
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderClient.kt151
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt23
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/FakeCustomizationProviderClient.kt20
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogDelegateTest.kt (renamed from packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/fontscaling)22
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt1
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java19
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerPredictiveBackTest.kt (renamed from packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable)12
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModelTest.kt24
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt80
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractorImplTest.kt61
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/InputShortcutsSourceTest.kt42
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSourceTest.kt138
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt16
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt36
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt77
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/navigationbar/views/NavigationBarTest.java14
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/AbstractQSFragmentComposeViewModelTest.kt14
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelTest.kt27
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java18
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java33
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt309
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizerTest.kt22
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizerTest.kt23
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/AuthContextPlugin.kt85
-rw-r--r--packages/SystemUI/res/layout/controls_management.xml1
-rw-r--r--packages/SystemUI/res/layout/notification_2025_hybrid_conversation.xml6
-rw-r--r--packages/SystemUI/res/values-af/strings.xml25
-rw-r--r--packages/SystemUI/res/values-am/strings.xml25
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml35
-rw-r--r--packages/SystemUI/res/values-as/strings.xml25
-rw-r--r--packages/SystemUI/res/values-az/strings.xml25
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml27
-rw-r--r--packages/SystemUI/res/values-be/strings.xml25
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml27
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml25
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml25
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml29
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml27
-rw-r--r--packages/SystemUI/res/values-da/strings.xml25
-rw-r--r--packages/SystemUI/res/values-de/strings.xml25
-rw-r--r--packages/SystemUI/res/values-el/strings.xml27
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml27
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings.xml19
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml27
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml27
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml24
-rw-r--r--packages/SystemUI/res/values-es/strings.xml25
-rw-r--r--packages/SystemUI/res/values-et/strings.xml27
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml25
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml27
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml25
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml25
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml27
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml25
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml29
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml27
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml25
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml25
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml27
-rw-r--r--packages/SystemUI/res/values-in/strings.xml25
-rw-r--r--packages/SystemUI/res/values-is/strings.xml25
-rw-r--r--packages/SystemUI/res/values-it/strings.xml28
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml33
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml27
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml25
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml25
-rw-r--r--packages/SystemUI/res/values-km/strings.xml25
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml25
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml25
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml25
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml27
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml22
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml25
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml27
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml27
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml25
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml25
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml27
-rw-r--r--packages/SystemUI/res/values-my/strings.xml25
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml25
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml29
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml27
-rw-r--r--packages/SystemUI/res/values-or/strings.xml25
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml25
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml27
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml25
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml22
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml25
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml25
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml31
-rw-r--r--packages/SystemUI/res/values-si/strings.xml25
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml27
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml27
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml22
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml27
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml27
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml27
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml25
-rw-r--r--packages/SystemUI/res/values-te/strings.xml25
-rw-r--r--packages/SystemUI/res/values-th/strings.xml27
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml27
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml27
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml25
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml25
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml27
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml25
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml27
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml25
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml25
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml25
-rw-r--r--packages/SystemUI/res/values/dimens.xml13
-rw-r--r--packages/SystemUI/res/values/strings.xml16
-rw-r--r--packages/SystemUI/res/values/styles.xml5
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/plugins/AuthContextPlugins.kt41
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPatternView.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialView.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialViewBinder.kt28
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/KeyguardBouncerViewBinder.kt29
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModel.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt42
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/util/WidgetViewFactory.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt240
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt368
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlsManagementActivity.kt40
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt158
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt65
-rw-r--r--packages/SystemUI/src/com/android/systemui/display/DisplayModule.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractor.kt55
-rw-r--r--packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialAnimation.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutCategoriesUtils.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/InputShortcutsSource.kt33
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSource.kt83
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt57
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/Shortcut.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt33
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt30
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt58
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaSwitchingController.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/flags/QsInCompose.kt43
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractor.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfig.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotShelfView.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarOrchestrator.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt84
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt32
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarControllerImpl.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/domain/interactor/CollapsedStatusBarInteractor.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt41
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizer.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizer.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialog.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialogPlugin.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogComponent.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderTouchesViewBinder.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSlidersViewBinder.kt59
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderTouchesViewModel.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSlidersViewModel.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinder.kt44
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogPluginViewModel.kt28
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogViewModel.kt14
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaSwitchingControllerTest.java62
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractorKosmos.kt23
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt13
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapterKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/FakeStatusBarOrchestratorFactory.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarOrchestratorKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/AutoHideKosmos.kt17
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/touchpad/ui/gesture/FakeVelocityTracker.kt36
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/touchpad/ui/gesture/VelocityTrackerKosmos.kt21
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java4
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java3
-rw-r--r--services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java14
-rw-r--r--services/autofill/features.aconfig15
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java34
-rw-r--r--services/autofill/java/com/android/server/autofill/Session.java16
-rw-r--r--services/backup/flags.aconfig8
-rw-r--r--services/core/Android.bp3
-rw-r--r--services/core/java/com/android/server/BinaryTransparencyService.java170
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java4
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java45
-rw-r--r--services/core/java/com/android/server/am/BroadcastController.java44
-rw-r--r--services/core/java/com/android/server/am/BroadcastFilter.java6
-rw-r--r--services/core/java/com/android/server/am/SettingsToPropertiesMapper.java6
-rw-r--r--services/core/java/com/android/server/biometrics/biometrics.aconfig7
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecAtomWriter.java35
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java15
-rw-r--r--services/core/java/com/android/server/incident/PendingReports.java16
-rw-r--r--services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java21
-rw-r--r--services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java63
-rw-r--r--services/core/java/com/android/server/media/quality/MediaQualityService.java220
-rw-r--r--services/core/java/com/android/server/pm/BackgroundInstallControlCallbackHelper.java7
-rw-r--r--services/core/java/com/android/server/pm/InstallDependencyHelper.java142
-rw-r--r--services/core/java/com/android/server/pm/InstallPackageHelper.java9
-rw-r--r--services/core/java/com/android/server/pm/PackageAbiHelperImpl.java5
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java2
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java3
-rw-r--r--services/core/java/com/android/server/pm/ScanPackageUtils.java7
-rw-r--r--services/core/java/com/android/server/power/hint/adpf_flags.aconfig8
-rw-r--r--services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java2
-rw-r--r--services/core/java/com/android/server/security/advancedprotection/features/DisallowInstallUnknownSourcesAdvancedProtectionHook.java72
-rw-r--r--services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java30
-rw-r--r--services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java21
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java62
-rw-r--r--services/core/java/com/android/server/wm/AppCompatController.java18
-rw-r--r--services/core/java/com/android/server/wm/AppWarnings.java76
-rw-r--r--services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java54
-rw-r--r--services/core/java/com/android/server/wm/CameraStateMonitor.java47
-rw-r--r--services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java47
-rw-r--r--services/core/java/com/android/server/wm/OWNERS1
-rw-r--r--services/core/java/com/android/server/wm/PageSizeMismatchDialog.java72
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java17
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java10
-rw-r--r--services/java/com/android/server/SystemServer.java9
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java94
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/ApexManagerTest.java2
-rw-r--r--services/tests/security/intrusiondetection/Android.bp5
-rw-r--r--services/tests/security/intrusiondetection/AndroidManifest.xml4
-rw-r--r--services/tests/security/intrusiondetection/AndroidTest.xml1
-rw-r--r--services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/IntrusionDetectionServiceTest.java78
-rw-r--r--services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/TestApp/src/com/android/coretests/apps/testapp/Android.bp42
-rw-r--r--services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/TestApp/src/com/android/coretests/apps/testapp/AndroidManifest.xml24
-rw-r--r--services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/TestApp/src/com/android/coretests/apps/testapp/LocalIntrusionDetectionEventTransport.java58
-rw-r--r--services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/TestApp/src/com/android/coretests/apps/testapp/TestLoggingService.java40
-rw-r--r--services/tests/servicestests/Android.bp10
-rw-r--r--services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java81
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java12
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java72
-rw-r--r--services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java40
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java13
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/CameraStateMonitorTests.java58
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java4
-rw-r--r--services/usb/java/com/android/server/usb/UsbAlsaManager.java2
-rw-r--r--telephony/java/android/telephony/satellite/SatelliteManager.java40
-rw-r--r--telephony/java/android/telephony/satellite/SatelliteSessionStats.java228
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl2
-rw-r--r--tests/BinaryTransparencyHostTest/Android.bp2
-rw-r--r--tests/BinaryTransparencyHostTest/src/android/transparency/test/BinaryTransparencyHostTest.java9
-rw-r--r--tests/FlickerTests/ActivityEmbedding/AndroidTestTemplate.xml2
-rw-r--r--tests/FlickerTests/AppClose/AndroidTestTemplate.xml2
-rw-r--r--tests/FlickerTests/AppLaunch/AndroidTestTemplate.xml2
-rw-r--r--tests/FlickerTests/FlickerService/AndroidTestTemplate.xml2
-rw-r--r--tests/FlickerTests/IME/AndroidTestTemplate.xml2
-rw-r--r--tests/FlickerTests/Notification/AndroidTestTemplate.xml2
-rw-r--r--tests/FlickerTests/QuickSwitch/AndroidTestTemplate.xml2
-rw-r--r--tests/FlickerTests/Rotation/AndroidTestTemplate.xml2
-rw-r--r--tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/GestureHelper.java306
-rw-r--r--tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt4
-rw-r--r--tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt325
-rw-r--r--tests/broadcasts/unit/Android.bp44
-rw-r--r--tests/broadcasts/unit/AndroidManifest.xml27
-rw-r--r--tests/broadcasts/unit/AndroidTest.xml29
-rw-r--r--tests/broadcasts/unit/OWNERS2
-rw-r--r--tests/broadcasts/unit/TEST_MAPPING7
-rw-r--r--tests/broadcasts/unit/src/android/app/BroadcastStickyCacheTest.java231
868 files changed, 15947 insertions, 5268 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index e18470498f39..56831d70af3a 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -23,7 +23,6 @@ aconfig_declarations_group {
"aconfig_mediacodec_flags_java_lib",
"aconfig_settingslib_flags_java_lib",
"aconfig_trade_in_mode_flags_java_lib",
- "android-sdk-flags-java",
"android.adaptiveauth.flags-aconfig-java",
"android.app.appfunctions.flags-aconfig-java",
"android.app.assist.flags-aconfig-java",
@@ -63,6 +62,7 @@ aconfig_declarations_group {
"android.os.vibrator.flags-aconfig-java",
"android.permission.flags-aconfig-java",
"android.provider.flags-aconfig-java",
+ "android.sdk.flags-aconfig-java",
"android.security.flags-aconfig-java",
"android.server.app.flags-aconfig-java",
"android.service.autofill.flags-aconfig-java",
@@ -966,6 +966,13 @@ java_aconfig_library {
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+java_aconfig_library {
+ name: "android.app.flags-aconfig-java-host",
+ aconfig_declarations: "android.app.flags-aconfig",
+ host_supported: true,
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
// Broadcast Radio
aconfig_declarations {
name: "android.hardware.radio.flags-aconfig",
diff --git a/android-sdk-flags/Android.bp b/android-sdk-flags/Android.bp
index 79a0b9a4f273..d1df2ca69f50 100644
--- a/android-sdk-flags/Android.bp
+++ b/android-sdk-flags/Android.bp
@@ -17,14 +17,21 @@ package {
}
aconfig_declarations {
- name: "android-sdk-flags",
+ name: "android.sdk.flags-aconfig",
package: "android.sdk",
container: "system",
srcs: ["flags.aconfig"],
}
java_aconfig_library {
- name: "android-sdk-flags-java",
- aconfig_declarations: "android-sdk-flags",
+ name: "android.sdk.flags-aconfig-java",
+ aconfig_declarations: "android.sdk.flags-aconfig",
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
+java_aconfig_library {
+ name: "android.sdk.flags-aconfig-java-host",
+ aconfig_declarations: "android.sdk.flags-aconfig",
+ host_supported: true,
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
diff --git a/core/api/current.txt b/core/api/current.txt
index af7d6f1a5da1..dc7f0b2da0b8 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -1203,6 +1203,7 @@ package android {
field public static final int minResizeHeight = 16843670; // 0x1010396
field public static final int minResizeWidth = 16843669; // 0x1010395
field public static final int minSdkVersion = 16843276; // 0x101020c
+ field @FlaggedApi("android.content.pm.support_minor_versions_in_minsdkversion") public static final int minSdkVersionFull;
field public static final int minWidth = 16843071; // 0x101013f
field public static final int minimumHorizontalAngle = 16843901; // 0x101047d
field public static final int minimumVerticalAngle = 16843902; // 0x101047e
@@ -10089,10 +10090,10 @@ package android.companion {
method @FlaggedApi("android.companion.unpair_associated_device") @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean removeBond(int);
method public void requestNotificationAccess(android.content.ComponentName);
method @FlaggedApi("android.companion.association_tag") public void setAssociationTag(int, @NonNull String);
- method @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void startObservingDevicePresence(@NonNull String) throws android.companion.DeviceNotAssociatedException;
+ method @Deprecated @FlaggedApi("android.companion.device_presence") @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void startObservingDevicePresence(@NonNull String) throws android.companion.DeviceNotAssociatedException;
method @FlaggedApi("android.companion.device_presence") @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void startObservingDevicePresence(@NonNull android.companion.ObservingDevicePresenceRequest);
method public void startSystemDataTransfer(int, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.companion.CompanionException>) throws android.companion.DeviceNotAssociatedException;
- method @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void stopObservingDevicePresence(@NonNull String) throws android.companion.DeviceNotAssociatedException;
+ method @Deprecated @FlaggedApi("android.companion.device_presence") @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void stopObservingDevicePresence(@NonNull String) throws android.companion.DeviceNotAssociatedException;
method @FlaggedApi("android.companion.device_presence") @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void stopObservingDevicePresence(@NonNull android.companion.ObservingDevicePresenceRequest);
field public static final String EXTRA_ASSOCIATION = "android.companion.extra.ASSOCIATION";
field @Deprecated public static final String EXTRA_DEVICE = "android.companion.extra.DEVICE";
@@ -10120,9 +10121,9 @@ package android.companion {
method @RequiresPermission(android.Manifest.permission.DELIVER_COMPANION_MESSAGES) public final void detachSystemDataTransport(int) throws android.companion.DeviceNotAssociatedException;
method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
method @Deprecated @MainThread public void onDeviceAppeared(@NonNull String);
- method @MainThread public void onDeviceAppeared(@NonNull android.companion.AssociationInfo);
+ method @Deprecated @FlaggedApi("android.companion.device_presence") @MainThread public void onDeviceAppeared(@NonNull android.companion.AssociationInfo);
method @Deprecated @MainThread public void onDeviceDisappeared(@NonNull String);
- method @MainThread public void onDeviceDisappeared(@NonNull android.companion.AssociationInfo);
+ method @Deprecated @FlaggedApi("android.companion.device_presence") @MainThread public void onDeviceDisappeared(@NonNull android.companion.AssociationInfo);
method @FlaggedApi("android.companion.device_presence") @MainThread public void onDevicePresenceEvent(@NonNull android.companion.DevicePresenceEvent);
field public static final String SERVICE_INTERFACE = "android.companion.CompanionDeviceService";
}
@@ -24853,6 +24854,7 @@ package android.media {
method @NonNull public String getId();
method @NonNull public CharSequence getName();
method @FlaggedApi("com.android.media.flags.enable_built_in_speaker_route_suitability_statuses") public int getSuitabilityStatus();
+ method @FlaggedApi("com.android.media.flags.enable_mirroring_in_media_router_2") public int getSupportedRoutingTypes();
method public int getType();
method public int getVolume();
method public int getVolumeHandling();
@@ -24868,6 +24870,8 @@ package android.media {
field public static final String FEATURE_REMOTE_AUDIO_PLAYBACK = "android.media.route.feature.REMOTE_AUDIO_PLAYBACK";
field public static final String FEATURE_REMOTE_PLAYBACK = "android.media.route.feature.REMOTE_PLAYBACK";
field public static final String FEATURE_REMOTE_VIDEO_PLAYBACK = "android.media.route.feature.REMOTE_VIDEO_PLAYBACK";
+ field @FlaggedApi("com.android.media.flags.enable_mirroring_in_media_router_2") public static final int FLAG_ROUTING_TYPE_REMOTE = 4; // 0x4
+ field @FlaggedApi("com.android.media.flags.enable_mirroring_in_media_router_2") public static final int FLAG_ROUTING_TYPE_SYSTEM_AUDIO = 1; // 0x1
field public static final int PLAYBACK_VOLUME_FIXED = 0; // 0x0
field public static final int PLAYBACK_VOLUME_VARIABLE = 1; // 0x1
field @FlaggedApi("com.android.media.flags.enable_built_in_speaker_route_suitability_statuses") public static final int SUITABILITY_STATUS_NOT_SUITABLE_FOR_TRANSFER = 2; // 0x2
@@ -24918,6 +24922,7 @@ package android.media {
method @NonNull public android.media.MediaRoute2Info.Builder setExtras(@Nullable android.os.Bundle);
method @NonNull public android.media.MediaRoute2Info.Builder setIconUri(@Nullable android.net.Uri);
method @FlaggedApi("com.android.media.flags.enable_built_in_speaker_route_suitability_statuses") @NonNull public android.media.MediaRoute2Info.Builder setSuitabilityStatus(int);
+ method @FlaggedApi("com.android.media.flags.enable_mirroring_in_media_router_2") @NonNull public android.media.MediaRoute2Info.Builder setSupportedRoutingTypes(int);
method @NonNull public android.media.MediaRoute2Info.Builder setType(int);
method @NonNull public android.media.MediaRoute2Info.Builder setVisibilityPublic();
method @NonNull public android.media.MediaRoute2Info.Builder setVisibilityRestricted(@NonNull java.util.Set<java.lang.String>);
@@ -33612,14 +33617,12 @@ package android.os {
@FlaggedApi("android.os.cpu_gpu_headrooms") public final class CpuHeadroomParams {
ctor public CpuHeadroomParams();
method public int getCalculationType();
- method @IntRange(from=android.os.CpuHeadroomParams.CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN, to=android.os.CpuHeadroomParams.CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX) public long getCalculationWindowMillis();
+ method @IntRange(from=0x32, to=0x2710) public long getCalculationWindowMillis();
method public void setCalculationType(int);
- method public void setCalculationWindowMillis(@IntRange(from=android.os.CpuHeadroomParams.CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN, to=android.os.CpuHeadroomParams.CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX) int);
+ method public void setCalculationWindowMillis(@IntRange(from=0x32, to=0x2710) int);
method public void setTids(@NonNull int...);
field public static final int CPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1; // 0x1
field public static final int CPU_HEADROOM_CALCULATION_TYPE_MIN = 0; // 0x0
- field public static final int CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX = 10000; // 0x2710
- field public static final int CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN = 50; // 0x32
}
public final class CpuUsageInfo implements android.os.Parcelable {
@@ -33872,13 +33875,11 @@ package android.os {
@FlaggedApi("android.os.cpu_gpu_headrooms") public final class GpuHeadroomParams {
ctor public GpuHeadroomParams();
method public int getCalculationType();
- method @IntRange(from=android.os.GpuHeadroomParams.GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN, to=android.os.GpuHeadroomParams.GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX) public int getCalculationWindowMillis();
+ method @IntRange(from=0x32, to=0x2710) public int getCalculationWindowMillis();
method public void setCalculationType(int);
- method public void setCalculationWindowMillis(@IntRange(from=android.os.GpuHeadroomParams.GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN, to=android.os.GpuHeadroomParams.GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX) int);
+ method public void setCalculationWindowMillis(@IntRange(from=0x32, to=0x2710) int);
field public static final int GPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1; // 0x1
field public static final int GPU_HEADROOM_CALCULATION_TYPE_MIN = 0; // 0x0
- field public static final int GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX = 10000; // 0x2710
- field public static final int GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN = 50; // 0x32
}
public class Handler {
@@ -37615,6 +37616,10 @@ package android.provider {
field public static final String TERTIARY_PHONE_TYPE = "tertiary_phone_type";
}
+ @FlaggedApi("android.provider.new_default_account_api_enabled") public static class ContactsContract.LocalSimContactsWriteException extends java.lang.IllegalArgumentException {
+ ctor public ContactsContract.LocalSimContactsWriteException(@NonNull String);
+ }
+
public static final class ContactsContract.PhoneLookup implements android.provider.BaseColumns android.provider.ContactsContract.ContactNameColumns android.provider.ContactsContract.ContactOptionsColumns android.provider.ContactsContract.ContactsColumns android.provider.ContactsContract.PhoneLookupColumns {
field public static final android.net.Uri CONTENT_FILTER_URI;
field public static final android.net.Uri ENTERPRISE_CONTENT_FILTER_URI;
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 83699ac30939..77866f7542fe 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -7779,7 +7779,7 @@ package android.media {
}
public final class MediaCas implements java.lang.AutoCloseable {
- method @FlaggedApi("android.media.tv.flags.set_resource_holder_retain") @RequiresPermission("android.permission.TUNER_RESOURCE_ACCESS") public void setResourceHolderRetain(boolean);
+ method @FlaggedApi("android.media.tv.flags.set_resource_holder_retain") @RequiresPermission("android.permission.TUNER_RESOURCE_ACCESS") public void setResourceOwnershipRetention(boolean);
method @FlaggedApi("android.media.tv.flags.mediacas_update_client_profile_priority") @RequiresPermission("android.permission.TUNER_RESOURCE_ACCESS") public boolean updateResourcePriority(int, int);
}
@@ -8692,8 +8692,8 @@ package android.media.tv.tuner {
method public int setLnaEnabled(boolean);
method public int setMaxNumberOfFrontends(int, @IntRange(from=0) int);
method public void setOnTuneEventListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.tv.tuner.frontend.OnTuneEventListener);
- method @FlaggedApi("android.media.tv.flags.set_resource_holder_retain") @RequiresPermission("android.permission.TUNER_RESOURCE_ACCESS") public void setResourceHolderRetain(boolean);
method public void setResourceLostListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.tv.tuner.Tuner.OnResourceLostListener);
+ method @FlaggedApi("android.media.tv.flags.set_resource_holder_retain") @RequiresPermission("android.permission.TUNER_RESOURCE_ACCESS") public void setResourceOwnershipRetention(boolean);
method public void shareFrontendFromTuner(@NonNull android.media.tv.tuner.Tuner);
method public int transferOwner(@NonNull android.media.tv.tuner.Tuner);
method public int tune(@NonNull android.media.tv.tuner.frontend.FrontendSettings);
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 967f6194969e..3a62ac9e3c62 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -541,7 +541,9 @@ package android.app {
method @Nullable public android.graphics.Rect peekBitmapDimensions();
method @Nullable public android.graphics.Rect peekBitmapDimensions(int);
method @FlaggedApi("com.android.window.flags.multi_crop") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setBitmapWithCrops(@Nullable android.graphics.Bitmap, @NonNull java.util.Map<android.graphics.Point,android.graphics.Rect>, boolean, int) throws java.io.IOException;
+ method @FlaggedApi("android.app.live_wallpaper_content_handling") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setBitmapWithDescription(@Nullable android.graphics.Bitmap, @NonNull android.app.wallpaper.WallpaperDescription, boolean, int) throws java.io.IOException;
method @FlaggedApi("com.android.window.flags.multi_crop") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setStreamWithCrops(@NonNull java.io.InputStream, @NonNull java.util.Map<android.graphics.Point,android.graphics.Rect>, boolean, int) throws java.io.IOException;
+ method @FlaggedApi("android.app.live_wallpaper_content_handling") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setStreamWithDescription(@NonNull java.io.InputStream, @NonNull android.app.wallpaper.WallpaperDescription, boolean, int) throws java.io.IOException;
method public void setWallpaperZoomOut(@NonNull android.os.IBinder, float);
method public boolean shouldEnableWideColorGamut();
method public boolean wallpaperSupportsWcg(int);
@@ -907,6 +909,15 @@ package android.app.usage {
}
+package android.app.wallpaper {
+
+ public static final class WallpaperDescription.Builder {
+ method @NonNull public android.app.wallpaper.WallpaperDescription.Builder setCropHints(@NonNull java.util.Map<android.graphics.Point,android.graphics.Rect>);
+ method @NonNull public android.app.wallpaper.WallpaperDescription.Builder setCropHints(@NonNull android.util.SparseArray<android.graphics.Rect>);
+ }
+
+}
+
package android.appwidget {
public class AppWidgetManager {
diff --git a/core/java/android/app/BroadcastStickyCache.java b/core/java/android/app/BroadcastStickyCache.java
new file mode 100644
index 000000000000..fe2e10752355
--- /dev/null
+++ b/core/java/android/app/BroadcastStickyCache.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.app;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.content.Context.RegisterReceiverFlags;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.usb.UsbManager;
+import android.media.AudioManager;
+import android.net.ConnectivityManager;
+import android.net.TetheringManager;
+import android.net.nsd.NsdManager;
+import android.net.wifi.WifiManager;
+import android.net.wifi.p2p.WifiP2pManager;
+import android.os.IpcDataCache;
+import android.os.IpcDataCache.Config;
+import android.os.UpdateLock;
+import android.telephony.TelephonyManager;
+import android.util.ArrayMap;
+import android.view.WindowManagerPolicyConstants;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
+
+/** @hide */
+public class BroadcastStickyCache {
+
+ @VisibleForTesting
+ public static final String[] STICKY_BROADCAST_ACTIONS = {
+ AudioManager.ACTION_HDMI_AUDIO_PLUG,
+ AudioManager.ACTION_HEADSET_PLUG,
+ AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED,
+ AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED,
+ AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION,
+ AudioManager.RINGER_MODE_CHANGED_ACTION,
+ ConnectivityManager.CONNECTIVITY_ACTION,
+ Intent.ACTION_BATTERY_CHANGED,
+ Intent.ACTION_DEVICE_STORAGE_FULL,
+ Intent.ACTION_DEVICE_STORAGE_LOW,
+ Intent.ACTION_SIM_STATE_CHANGED,
+ NsdManager.ACTION_NSD_STATE_CHANGED,
+ TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED,
+ TetheringManager.ACTION_TETHER_STATE_CHANGED,
+ UpdateLock.UPDATE_LOCK_CHANGED,
+ UsbManager.ACTION_USB_STATE,
+ WifiManager.ACTION_WIFI_SCAN_AVAILABILITY_CHANGED,
+ WifiManager.NETWORK_STATE_CHANGED_ACTION,
+ WifiManager.SUPPLICANT_STATE_CHANGED_ACTION,
+ WifiManager.WIFI_STATE_CHANGED_ACTION,
+ WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION,
+ WindowManagerPolicyConstants.ACTION_HDMI_PLUGGED,
+ "android.net.conn.INET_CONDITION_ACTION" // ConnectivityManager.INET_CONDITION_ACTION
+ };
+
+ @VisibleForTesting
+ public static final ArrayMap<String, String> sActionApiNameMap = new ArrayMap<>();
+
+ private static final ArrayMap<String, IpcDataCache.Config> sActionConfigMap = new ArrayMap<>();
+
+ private static final ArrayMap<StickyBroadcastFilter, IpcDataCache<Void, Intent>>
+ sFilterCacheMap = new ArrayMap<>();
+
+ static {
+ sActionApiNameMap.put(AudioManager.ACTION_HDMI_AUDIO_PLUG, "hdmi_audio_plug");
+ sActionApiNameMap.put(AudioManager.ACTION_HEADSET_PLUG, "headset_plug");
+ sActionApiNameMap.put(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED,
+ "sco_audio_state_changed");
+ sActionApiNameMap.put(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED,
+ "action_sco_audio_state_updated");
+ sActionApiNameMap.put(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION,
+ "internal_ringer_mode_changed_action");
+ sActionApiNameMap.put(AudioManager.RINGER_MODE_CHANGED_ACTION,
+ "ringer_mode_changed");
+ sActionApiNameMap.put(ConnectivityManager.CONNECTIVITY_ACTION,
+ "connectivity_change");
+ sActionApiNameMap.put(Intent.ACTION_BATTERY_CHANGED, "battery_changed");
+ sActionApiNameMap.put(Intent.ACTION_DEVICE_STORAGE_FULL, "device_storage_full");
+ sActionApiNameMap.put(Intent.ACTION_DEVICE_STORAGE_LOW, "device_storage_low");
+ sActionApiNameMap.put(Intent.ACTION_SIM_STATE_CHANGED, "sim_state_changed");
+ sActionApiNameMap.put(NsdManager.ACTION_NSD_STATE_CHANGED, "nsd_state_changed");
+ sActionApiNameMap.put(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED,
+ "service_providers_updated");
+ sActionApiNameMap.put(TetheringManager.ACTION_TETHER_STATE_CHANGED,
+ "tether_state_changed");
+ sActionApiNameMap.put(UpdateLock.UPDATE_LOCK_CHANGED, "update_lock_changed");
+ sActionApiNameMap.put(UsbManager.ACTION_USB_STATE, "usb_state");
+ sActionApiNameMap.put(WifiManager.ACTION_WIFI_SCAN_AVAILABILITY_CHANGED,
+ "wifi_scan_availability_changed");
+ sActionApiNameMap.put(WifiManager.NETWORK_STATE_CHANGED_ACTION,
+ "network_state_change");
+ sActionApiNameMap.put(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION,
+ "supplicant_state_change");
+ sActionApiNameMap.put(WifiManager.WIFI_STATE_CHANGED_ACTION, "wifi_state_changed");
+ sActionApiNameMap.put(
+ WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION, "wifi_p2p_state_changed");
+ sActionApiNameMap.put(
+ WindowManagerPolicyConstants.ACTION_HDMI_PLUGGED, "hdmi_plugged");
+ sActionApiNameMap.put(
+ "android.net.conn.INET_CONDITION_ACTION", "inet_condition_action");
+ }
+
+ /**
+ * Checks whether we can use caching for the given filter.
+ */
+ public static boolean useCache(@Nullable IntentFilter filter) {
+ return Flags.useStickyBcastCache()
+ && filter != null
+ && filter.safeCountActions() == 1
+ && ArrayUtils.contains(STICKY_BROADCAST_ACTIONS, filter.getAction(0));
+ }
+
+ public static void invalidateCache(@NonNull String action) {
+ if (!Flags.useStickyBcastCache()
+ || !ArrayUtils.contains(STICKY_BROADCAST_ACTIONS, action)) {
+ return;
+ }
+ IpcDataCache.invalidateCache(IpcDataCache.MODULE_SYSTEM,
+ sActionApiNameMap.get(action));
+ }
+
+ public static void invalidateAllCaches() {
+ for (int i = sActionApiNameMap.size() - 1; i >= 0; i--) {
+ IpcDataCache.invalidateCache(IpcDataCache.MODULE_SYSTEM,
+ sActionApiNameMap.valueAt(i));
+ }
+ }
+
+ /**
+ * Returns the cached {@link Intent} based on the filter, if exits otherwise
+ * fetches the value from the service.
+ */
+ @Nullable
+ public static Intent getIntent(
+ @NonNull IApplicationThread applicationThread,
+ @NonNull String mBasePackageName,
+ @Nullable String attributionTag,
+ @NonNull IntentFilter filter,
+ @Nullable String broadcastPermission,
+ @UserIdInt int userId,
+ @RegisterReceiverFlags int flags) {
+ IpcDataCache<Void, Intent> intentDataCache = findIpcDataCache(filter);
+
+ if (intentDataCache == null) {
+ final String action = filter.getAction(0);
+ final StickyBroadcastFilter stickyBroadcastFilter =
+ new StickyBroadcastFilter(filter, action);
+ final Config config = getConfig(action);
+
+ intentDataCache =
+ new IpcDataCache<>(config,
+ (query) -> ActivityManager.getService().registerReceiverWithFeature(
+ applicationThread,
+ mBasePackageName,
+ attributionTag,
+ /* receiverId= */ "null",
+ /* receiver= */ null,
+ filter,
+ broadcastPermission,
+ userId,
+ flags));
+ sFilterCacheMap.put(stickyBroadcastFilter, intentDataCache);
+ }
+ return intentDataCache.query(null);
+ }
+
+ @VisibleForTesting
+ public static void clearCacheForTest() {
+ sFilterCacheMap.clear();
+ }
+
+ @Nullable
+ private static IpcDataCache<Void, Intent> findIpcDataCache(
+ @NonNull IntentFilter filter) {
+ for (int i = sFilterCacheMap.size() - 1; i >= 0; i--) {
+ StickyBroadcastFilter existingFilter = sFilterCacheMap.keyAt(i);
+ if (filter.getAction(0).equals(existingFilter.action())
+ && IntentFilter.filterEquals(existingFilter.filter(), filter)) {
+ return sFilterCacheMap.valueAt(i);
+ }
+ }
+ return null;
+ }
+
+ @NonNull
+ private static IpcDataCache.Config getConfig(@NonNull String action) {
+ if (!sActionConfigMap.containsKey(action)) {
+ // We only need 1 entry per cache but just to be on the safer side we are choosing 32
+ // although we don't expect more than 1.
+ sActionConfigMap.put(action,
+ new Config(32, IpcDataCache.MODULE_SYSTEM, sActionApiNameMap.get(action)));
+ }
+
+ return sActionConfigMap.get(action);
+ }
+
+ @VisibleForTesting
+ private record StickyBroadcastFilter(@NonNull IntentFilter filter, @NonNull String action) {
+ }
+}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index cd56957ed5d1..dcbdc2348fbc 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1922,10 +1922,23 @@ class ContextImpl extends Context {
}
}
try {
- final Intent intent = ActivityManager.getService().registerReceiverWithFeature(
- mMainThread.getApplicationThread(), mBasePackageName, getAttributionTag(),
- AppOpsManager.toReceiverId(receiver), rd, filter, broadcastPermission, userId,
- flags);
+ final Intent intent;
+ if (receiver == null && BroadcastStickyCache.useCache(filter)) {
+ intent = BroadcastStickyCache.getIntent(
+ mMainThread.getApplicationThread(),
+ mBasePackageName,
+ getAttributionTag(),
+ filter,
+ broadcastPermission,
+ userId,
+ flags);
+ } else {
+ intent = ActivityManager.getService().registerReceiverWithFeature(
+ mMainThread.getApplicationThread(), mBasePackageName, getAttributionTag(),
+ AppOpsManager.toReceiverId(receiver), rd, filter, broadcastPermission,
+ userId, flags);
+ }
+
if (intent != null) {
intent.setExtrasClassLoader(getClassLoader());
// TODO: determine at registration time if caller is
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 0668958b2d5c..50486611a5a9 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -1028,4 +1028,14 @@ interface IActivityManager {
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.DEVICE_POWER)")
void noteAppRestrictionEnabled(in String packageName, int uid, int restrictionType,
boolean enabled, int reason, in String subReason, int source, long threshold);
+
+ /**
+ * Creates and returns a new IntentCreatorToken that keeps the creatorUid and refreshes key
+ * fields of the intent passed in.
+ *
+ * @param intent The intent with key fields out of sync of the IntentCreatorToken it contains.
+ * @hide
+ */
+ @EnforcePermission("INTERACT_ACROSS_USERS_FULL")
+ IBinder refreshIntentCreatorToken(in Intent intent);
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 7fcae45ea452..0268b5ba2ae3 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -817,18 +817,18 @@ public class Notification implements Parcelable
R.layout.notification_2025_template_expanded_base,
R.layout.notification_2025_template_heads_up_base,
R.layout.notification_2025_template_header,
+ R.layout.notification_2025_template_conversation,
+ R.layout.notification_2025_template_collapsed_call,
+ R.layout.notification_2025_template_expanded_call,
R.layout.notification_2025_template_collapsed_messaging,
+ R.layout.notification_2025_template_expanded_messaging,
R.layout.notification_2025_template_collapsed_media,
- R.layout.notification_template_material_big_picture,
- R.layout.notification_template_material_big_text,
- R.layout.notification_template_material_inbox,
- R.layout.notification_template_material_big_messaging,
- R.layout.notification_template_material_conversation,
- R.layout.notification_template_material_big_media,
- R.layout.notification_template_material_call,
- R.layout.notification_template_material_big_call,
- R.layout.notification_template_header -> true;
- case R.layout.notification_template_material_progress -> Flags.apiRichOngoing();
+ R.layout.notification_2025_template_expanded_media,
+ R.layout.notification_2025_template_expanded_big_picture,
+ R.layout.notification_2025_template_expanded_big_text,
+ R.layout.notification_2025_template_expanded_inbox -> true;
+ case R.layout.notification_2025_template_expanded_progress
+ -> Flags.apiRichOngoing();
default -> false;
};
}
@@ -5964,7 +5964,7 @@ public class Notification implements Parcelable
private static void setHeaderlessVerticalMargins(RemoteViews contentView,
StandardTemplateParams p, boolean hasSecondLine) {
- if (!p.mHeaderless) {
+ if (Flags.notificationsRedesignTemplates() || !p.mHeaderless) {
return;
}
int marginDimen = hasSecondLine
@@ -6445,10 +6445,13 @@ public class Notification implements Parcelable
// Clear view padding to allow buttons to start on the left edge.
// This must be done before 'setEmphasizedMode' which sets top/bottom margins.
big.setViewPadding(R.id.actions, 0, 0, 0, 0);
- // Add an optional indent that will make buttons start at the correct column when
- // there is enough space to do so (and fall back to the left edge if not).
- big.setInt(R.id.actions, "setCollapsibleIndentDimen",
- R.dimen.call_notification_collapsible_indent);
+ if (!Flags.notificationsRedesignTemplates()) {
+ // Add an optional indent that will make buttons start at the correct column
+ // when there is enough space to do so (and fall back to the left edge if not).
+ // This is handled directly in NotificationActionListLayout in the new design.
+ big.setInt(R.id.actions, "setCollapsibleIndentDimen",
+ R.dimen.call_notification_collapsible_indent);
+ }
if (evenlyDividedCallStyleActionLayout()) {
if (CallStyle.DEBUG_NEW_ACTION_LAYOUT) {
Log.d(TAG, "setting evenly divided mode on action list");
@@ -7561,15 +7564,27 @@ public class Notification implements Parcelable
}
private int getBigPictureLayoutResource() {
- return R.layout.notification_template_material_big_picture;
+ if (Flags.notificationsRedesignTemplates()) {
+ return R.layout.notification_2025_template_expanded_big_picture;
+ } else {
+ return R.layout.notification_template_material_big_picture;
+ }
}
private int getBigTextLayoutResource() {
- return R.layout.notification_template_material_big_text;
+ if (Flags.notificationsRedesignTemplates()) {
+ return R.layout.notification_2025_template_expanded_big_text;
+ } else {
+ return R.layout.notification_template_material_big_text;
+ }
}
private int getInboxLayoutResource() {
- return R.layout.notification_template_material_inbox;
+ if (Flags.notificationsRedesignTemplates()) {
+ return R.layout.notification_2025_template_expanded_inbox;
+ } else {
+ return R.layout.notification_template_material_inbox;
+ }
}
private int getCollapsedMessagingLayoutResource() {
@@ -7581,7 +7596,11 @@ public class Notification implements Parcelable
}
private int getExpandedMessagingLayoutResource() {
- return R.layout.notification_template_material_big_messaging;
+ if (Flags.notificationsRedesignTemplates()) {
+ return R.layout.notification_2025_template_expanded_messaging;
+ } else {
+ return R.layout.notification_template_material_big_messaging;
+ }
}
private int getCollapsedMediaLayoutResource() {
@@ -7592,12 +7611,44 @@ public class Notification implements Parcelable
}
}
+ private int getExpandedMediaLayoutResource() {
+ if (Flags.notificationsRedesignTemplates()) {
+ return R.layout.notification_2025_template_expanded_media;
+ } else {
+ return R.layout.notification_template_material_big_media;
+ }
+ }
+
private int getConversationLayoutResource() {
- return R.layout.notification_template_material_conversation;
+ if (Flags.notificationsRedesignTemplates()) {
+ return R.layout.notification_2025_template_conversation;
+ } else {
+ return R.layout.notification_template_material_conversation;
+ }
+ }
+
+ private int getCollapsedCallLayoutResource() {
+ if (Flags.notificationsRedesignTemplates()) {
+ return R.layout.notification_2025_template_collapsed_call;
+ } else {
+ return R.layout.notification_template_material_call;
+ }
+ }
+
+ private int getExpandedCallLayoutResource() {
+ if (Flags.notificationsRedesignTemplates()) {
+ return R.layout.notification_2025_template_expanded_call;
+ } else {
+ return R.layout.notification_template_material_big_call;
+ }
}
private int getProgressLayoutResource() {
- return R.layout.notification_template_material_progress;
+ if (Flags.notificationsRedesignTemplates()) {
+ return R.layout.notification_2025_template_expanded_progress;
+ } else {
+ return R.layout.notification_template_material_progress;
+ }
}
private int getActionLayoutResource() {
@@ -10521,7 +10572,7 @@ public class Notification implements Parcelable
.fillTextsFrom(mBuilder);
TemplateBindResult result = new TemplateBindResult();
RemoteViews template = mBuilder.applyStandardTemplate(
- R.layout.notification_template_material_big_media, p , result);
+ mBuilder.getExpandedMediaLayoutResource(), p , result);
for (int i = 0; i < MAX_MEDIA_BUTTONS; i++) {
if (i < actionCount) {
@@ -10944,10 +10995,10 @@ public class Notification implements Parcelable
final RemoteViews contentView;
if (isCollapsed) {
contentView = mBuilder.applyStandardTemplate(
- R.layout.notification_template_material_call, p, null /* result */);
+ mBuilder.getCollapsedCallLayoutResource(), p, null /* result */);
} else {
contentView = mBuilder.applyStandardTemplateWithActions(
- R.layout.notification_template_material_big_call, p, null /* result */);
+ mBuilder.getExpandedCallLayoutResource(), p, null /* result */);
}
// Bind some extra conversation-specific header fields.
@@ -14798,12 +14849,23 @@ public class Notification implements Parcelable
} else {
mBackgroundColor = rawColor;
}
- mPrimaryTextColor = ContrastColorUtil.findAlphaToMeetContrast(
- ContrastColorUtil.resolvePrimaryColor(ctx, mBackgroundColor, nightMode),
- mBackgroundColor, 4.5);
- mSecondaryTextColor = ContrastColorUtil.findAlphaToMeetContrast(
- ContrastColorUtil.resolveSecondaryColor(ctx, mBackgroundColor, nightMode),
- mBackgroundColor, 4.5);
+ if (Flags.uiRichOngoing()) {
+ boolean isBgDark = Notification.Builder.isColorDark(mBackgroundColor);
+ int onSurfaceColorExtreme = isBgDark ? Color.WHITE : Color.BLACK;
+ mPrimaryTextColor = ContrastColorUtil.ensureContrast(
+ ColorUtils.blendARGB(mBackgroundColor, onSurfaceColorExtreme, 0.9f),
+ mBackgroundColor, isBgDark, 4.5);
+ mSecondaryTextColor = ContrastColorUtil.ensureContrast(
+ ColorUtils.blendARGB(mBackgroundColor, onSurfaceColorExtreme, 0.8f),
+ mBackgroundColor, isBgDark, 4.5);
+ } else {
+ mPrimaryTextColor = ContrastColorUtil.findAlphaToMeetContrast(
+ ContrastColorUtil.resolvePrimaryColor(ctx, mBackgroundColor, nightMode),
+ mBackgroundColor, 4.5);
+ mSecondaryTextColor = ContrastColorUtil.findAlphaToMeetContrast(
+ ContrastColorUtil.resolveSecondaryColor(ctx,
+ mBackgroundColor, nightMode), mBackgroundColor, 4.5);
+ }
mContrastColor = mPrimaryTextColor;
mPrimaryAccentColor = mPrimaryTextColor;
mSecondaryAccentColor = mSecondaryTextColor;
diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING
index 5ed1f4e35533..637187e01160 100644
--- a/core/java/android/app/TEST_MAPPING
+++ b/core/java/android/app/TEST_MAPPING
@@ -177,6 +177,10 @@
{
"file_patterns": ["(/|^)AppOpsManager.java"],
"name": "CtsAppOpsTestCases"
+ },
+ {
+ "file_patterns": ["(/|^)BroadcastStickyCache.java"],
+ "name": "BroadcastUnitTests"
}
]
}
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index abb2dd465576..a8671cf74619 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -2491,6 +2491,27 @@ public class WallpaperManager {
return result.getInt(EXTRA_NEW_WALLPAPER_ID, 0);
}
+ /**
+ * Version of setBitmap that allows specification of wallpaper metadata including how the
+ * wallpaper will be positioned for different display sizes.
+ *
+ * @param fullImage A bitmap that will supply the wallpaper imagery.
+ * @param description Wallpaper metadata including desired cropping
+ * @param allowBackup {@code true} if the OS is permitted to back up this wallpaper
+ * image for restore to a future device; {@code false} otherwise.
+ * @param which Flags indicating which wallpaper(s) to configure with the new imagery.
+ * @hide
+ */
+ @FlaggedApi(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+ @TestApi
+ @RequiresPermission(android.Manifest.permission.SET_WALLPAPER)
+ public int setBitmapWithDescription(@Nullable Bitmap fullImage,
+ @NonNull WallpaperDescription description, boolean allowBackup,
+ @SetWallpaperFlags int which) throws IOException {
+ return setBitmapWithCrops(fullImage, description.getCropHints(), allowBackup, which,
+ mContext.getUserId());
+ }
+
private final void validateRect(Rect rect) {
if (rect != null && rect.isEmpty()) {
throw new IllegalArgumentException("visibleCrop rectangle must be valid and non-empty");
@@ -2700,6 +2721,27 @@ public class WallpaperManager {
}
/**
+ * Version of setStream that allows specification of wallpaper metadata including how the
+ * wallpaper will be positioned for different display sizes.
+ *
+ * @param bitmapData A stream containing the raw data to install as a wallpaper. This
+ * data can be in any format handled by {@link BitmapRegionDecoder}.
+ * @param description Wallpaper metadata including desired cropping
+ * @param allowBackup {@code true} if the OS is permitted to back up this wallpaper
+ * image for restore to a future device; {@code false} otherwise.
+ * @param which Flags indicating which wallpaper(s) to configure with the new imagery.
+ * @hide
+ */
+ @FlaggedApi(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+ @TestApi
+ @RequiresPermission(android.Manifest.permission.SET_WALLPAPER)
+ public int setStreamWithDescription(@NonNull InputStream bitmapData,
+ @NonNull WallpaperDescription description, boolean allowBackup,
+ @SetWallpaperFlags int which) throws IOException {
+ return setStreamWithCrops(bitmapData, description.getCropHints(), allowBackup, which);
+ }
+
+ /**
* Return whether any users are currently set to use the wallpaper
* with the given resource ID. That is, their wallpaper has been
* set through {@link #setResource(int)} with the same resource id.
diff --git a/core/java/android/app/wallpaper/WallpaperDescription.java b/core/java/android/app/wallpaper/WallpaperDescription.java
index 4a142bb5287a..3ee00ca3d941 100644
--- a/core/java/android/app/wallpaper/WallpaperDescription.java
+++ b/core/java/android/app/wallpaper/WallpaperDescription.java
@@ -19,8 +19,14 @@ package android.app.wallpaper;
import static android.app.Flags.FLAG_LIVE_WALLPAPER_CONTENT_HANDLING;
import android.annotation.FlaggedApi;
+import android.annotation.SuppressLint;
+import android.annotation.TestApi;
import android.app.WallpaperInfo;
+import android.app.WallpaperManager;
+import android.app.WallpaperManager.ScreenOrientation;
import android.content.ComponentName;
+import android.graphics.Point;
+import android.graphics.Rect;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
@@ -29,6 +35,8 @@ import android.text.Html;
import android.text.Spanned;
import android.text.SpannedString;
import android.util.Log;
+import android.util.Pair;
+import android.util.SparseArray;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -43,6 +51,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
/**
@@ -71,12 +80,15 @@ public final class WallpaperDescription implements Parcelable {
@Nullable private final Uri mContextUri;
@Nullable private final CharSequence mContextDescription;
@NonNull private final PersistableBundle mContent;
+ @NonNull private final SparseArray<Rect> mCropHints;
+ private final float mSampleSize;
private WallpaperDescription(@Nullable ComponentName component,
@Nullable String id, @Nullable Uri thumbnail, @Nullable CharSequence title,
@Nullable List<CharSequence> description, @Nullable Uri contextUri,
@Nullable CharSequence contextDescription,
- @Nullable PersistableBundle content) {
+ @Nullable PersistableBundle content, @NonNull SparseArray<Rect> cropHints,
+ float sampleSize) {
this.mComponent = component;
this.mId = id;
this.mThumbnail = thumbnail;
@@ -85,6 +97,8 @@ public final class WallpaperDescription implements Parcelable {
this.mContextUri = contextUri;
this.mContextDescription = contextDescription;
this.mContent = (content != null) ? content : new PersistableBundle();
+ this.mCropHints = cropHints;
+ this.mSampleSize = sampleSize;
}
/** @return the component for this wallpaper, or {@code null} for a static wallpaper */
@@ -134,6 +148,24 @@ public final class WallpaperDescription implements Parcelable {
return mContent;
}
+ /**
+ * @return the cropping for the current image as described in
+ * {@link Builder#setCropHints(SparseArray)}
+ * @hide
+ */
+ @NonNull
+ public SparseArray<Rect> getCropHints() {
+ return mCropHints;
+ }
+
+ /**
+ * @return the subsamling size as described in {@link Builder#setSampleSize(float)}.
+ * @hide
+ */
+ public float getSampleSize() {
+ return mSampleSize;
+ }
+
////// Comparison overrides
@Override
@@ -163,9 +195,23 @@ public final class WallpaperDescription implements Parcelable {
if (mContextDescription != null) {
out.attribute(null, "contextdescription", toHtml(mContextDescription));
}
+
+ for (Pair<Integer, String> pair : screenDimensionPairs()) {
+ @ScreenOrientation int orientation = pair.first;
+ String attrName = pair.second;
+ Rect cropHint = mCropHints.get(orientation);
+ if (cropHint == null) continue;
+ out.attributeInt(null, "cropLeft" + attrName, cropHint.left);
+ out.attributeInt(null, "cropTop" + attrName, cropHint.top);
+ out.attributeInt(null, "cropRight" + attrName, cropHint.right);
+ out.attributeInt(null, "cropBottom" + attrName, cropHint.bottom);
+ }
+ out.attributeFloat(null, "sampleSize", mSampleSize);
+
out.startTag(null, XML_TAG_DESCRIPTION);
for (CharSequence s : mDescription) out.attribute(null, "descriptionline", toHtml(s));
out.endTag(null, XML_TAG_DESCRIPTION);
+
try {
out.startTag(null, XML_TAG_CONTENT);
mContent.saveToXml(out);
@@ -194,6 +240,19 @@ public final class WallpaperDescription implements Parcelable {
CharSequence contextDescription = fromHtml(
in.getAttributeValue(null, "contextdescription"));
+ SparseArray<Rect> cropHints = new SparseArray<>();
+ screenDimensionPairs().forEach(pair -> {
+ @ScreenOrientation int orientation = pair.first;
+ String attrName = pair.second;
+ Rect crop = new Rect(
+ in.getAttributeInt(null, "cropLeft" + attrName, 0),
+ in.getAttributeInt(null, "cropTop" + attrName, 0),
+ in.getAttributeInt(null, "cropRight" + attrName, 0),
+ in.getAttributeInt(null, "cropBottom" + attrName, 0));
+ if (!crop.isEmpty()) cropHints.put(orientation, crop);
+ });
+ float sampleSize = in.getAttributeFloat(null, "sampleSize", 1f);
+
List<CharSequence> description = new ArrayList<>();
PersistableBundle content = null;
int type;
@@ -213,7 +272,7 @@ public final class WallpaperDescription implements Parcelable {
}
return new WallpaperDescription(componentName, id, thumbnail, title, description,
- contextUri, contextDescription, content);
+ contextUri, contextDescription, content, cropHints, sampleSize);
}
private static String toHtml(@NonNull CharSequence c) {
@@ -253,6 +312,13 @@ public final class WallpaperDescription implements Parcelable {
mContextUri = Uri.CREATOR.createFromParcel(in);
mContextDescription = in.readCharSequence();
mContent = PersistableBundle.CREATOR.createFromParcel(in);
+ mCropHints = new SparseArray<>();
+ screenDimensionPairs().forEach(pair -> {
+ int orientation = pair.first;
+ Rect crop = in.readTypedObject(Rect.CREATOR);
+ if (crop != null) mCropHints.put(orientation, crop);
+ });
+ mSampleSize = in.readFloat();
}
@NonNull
@@ -283,6 +349,11 @@ public final class WallpaperDescription implements Parcelable {
Uri.writeToParcel(dest, mContextUri);
dest.writeCharSequence(mContextDescription);
dest.writePersistableBundle(mContent);
+ screenDimensionPairs().forEach(pair -> {
+ int orientation = pair.first;
+ dest.writeTypedObject(mCropHints.get(orientation), flags);
+ });
+ dest.writeFloat(mSampleSize);
}
////// Builder
@@ -293,9 +364,17 @@ public final class WallpaperDescription implements Parcelable {
*/
@NonNull
public Builder toBuilder() {
- return new Builder().setComponent(mComponent).setId(mId).setThumbnail(mThumbnail).setTitle(
- mTitle).setDescription(mDescription).setContextUri(
- mContextUri).setContextDescription(mContextDescription).setContent(mContent);
+ return new Builder()
+ .setComponent(mComponent)
+ .setId(mId)
+ .setThumbnail(mThumbnail)
+ .setTitle(mTitle)
+ .setDescription(mDescription)
+ .setContextUri(mContextUri)
+ .setContextDescription(mContextDescription)
+ .setContent(mContent)
+ .setCropHints(mCropHints)
+ .setSampleSize(mSampleSize);
}
/** Builder for the immutable {@link WallpaperDescription} class */
@@ -308,6 +387,9 @@ public final class WallpaperDescription implements Parcelable {
@Nullable private Uri mContextUri;
@Nullable private CharSequence mContextDescription;
@NonNull private PersistableBundle mContent = new PersistableBundle();
+ @NonNull
+ private SparseArray<Rect> mCropHints = new SparseArray<>();
+ private float mSampleSize = 1f;
/** Creates a new, empty {@link Builder}. */
public Builder() {}
@@ -416,11 +498,69 @@ public final class WallpaperDescription implements Parcelable {
return this;
}
+ /**
+ * Defines which part of the source wallpaper image is in the stored crop file.
+ *
+ * @param cropHints map from screen dimensions to a sub-region of the image to display
+ * for those dimensions. The {@code Rect} sub-region may have a larger
+ * width/height ratio than the screen dimensions to apply a horizontal
+ * parallax effect. If the map is empty or some entries are missing, the
+ * system will apply a default strategy to position the wallpaper for
+ * any unspecified screen dimensions.
+ * @hide
+ */
+ @NonNull
+ @TestApi
+ @SuppressLint("MissingGetterMatchingBuilder")
+ public Builder setCropHints(@NonNull Map<Point, Rect> cropHints) {
+ mCropHints = new SparseArray<>();
+ cropHints.forEach(
+ (point, rect) -> mCropHints.put(WallpaperManager.getOrientation(point), rect));
+ return this;
+ }
+
+ /**
+ * Defines which part of the source wallpaper image is in the stored crop file.
+ *
+ * @param cropHints map from {@link ScreenOrientation} to a sub-region of the image to
+ * display for that screen orientation.
+ * @hide
+ */
+ @NonNull
+ @TestApi
+ @SuppressLint("MissingGetterMatchingBuilder")
+ public Builder setCropHints(@NonNull SparseArray<Rect> cropHints) {
+ mCropHints = cropHints;
+ return this;
+ }
+
+ /**
+ * How much the crop is sub-sampled. A value > 1 means that the image quality was reduced.
+ * This is the ratio between the cropHint height and the actual stored crop file height.
+ * height.
+ *
+ * @param sampleSize Sub-sampling value
+ * @hide
+ */
+ @NonNull
+ public Builder setSampleSize(float sampleSize) {
+ mSampleSize = sampleSize;
+ return this;
+ }
+
/** Creates and returns the {@link WallpaperDescription} represented by this builder. */
@NonNull
public WallpaperDescription build() {
return new WallpaperDescription(mComponent, mId, mThumbnail, mTitle, mDescription,
- mContextUri, mContextDescription, mContent);
+ mContextUri, mContextDescription, mContent, mCropHints, mSampleSize);
}
}
+
+ private static List<Pair<Integer, String>> screenDimensionPairs() {
+ return List.of(
+ new Pair<>(WallpaperManager.ORIENTATION_PORTRAIT, "Portrait"),
+ new Pair<>(WallpaperManager.ORIENTATION_LANDSCAPE, "Landscape"),
+ new Pair<>(WallpaperManager.ORIENTATION_SQUARE_PORTRAIT, "SquarePortrait"),
+ new Pair<>(WallpaperManager.ORIENTATION_SQUARE_LANDSCAPE, "SquareLandscape"));
+ }
}
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index 4472c3d13d7c..04668479d8e3 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -1229,7 +1229,6 @@ public final class CompanionDeviceManager {
}
}
- // TODO(b/315163162) Add @Deprecated keyword after 24Q2 cut.
/**
* Register to receive callbacks whenever the associated device comes in and out of range.
*
@@ -1261,7 +1260,12 @@ public final class CompanionDeviceManager {
*
* @throws DeviceNotAssociatedException if the given device was not previously associated
* with this app.
+ *
+ * @deprecated use {@link #startObservingDevicePresence(ObservingDevicePresenceRequest)}
+ * instead.
*/
+ @FlaggedApi(Flags.FLAG_DEVICE_PRESENCE)
+ @Deprecated
@RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE)
public void startObservingDevicePresence(@NonNull String deviceAddress)
throws DeviceNotAssociatedException {
@@ -1288,7 +1292,7 @@ public final class CompanionDeviceManager {
callingUid, callingPid);
}
}
- // TODO(b/315163162) Add @Deprecated keyword after 24Q2 cut.
+
/**
* Unregister for receiving callbacks whenever the associated device comes in and out of range.
*
@@ -1305,7 +1309,12 @@ public final class CompanionDeviceManager {
*
* @throws DeviceNotAssociatedException if the given device was not previously associated
* with this app.
+ *
+ * @deprecated use {@link #stopObservingDevicePresence(ObservingDevicePresenceRequest)}
+ * instead.
*/
+ @FlaggedApi(Flags.FLAG_DEVICE_PRESENCE)
+ @Deprecated
@RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE)
public void stopObservingDevicePresence(@NonNull String deviceAddress)
throws DeviceNotAssociatedException {
diff --git a/core/java/android/companion/CompanionDeviceService.java b/core/java/android/companion/CompanionDeviceService.java
index db080fcc7702..316d129bd6b9 100644
--- a/core/java/android/companion/CompanionDeviceService.java
+++ b/core/java/android/companion/CompanionDeviceService.java
@@ -247,12 +247,14 @@ public abstract class CompanionDeviceService extends Service {
.detachSystemDataTransport(associationId);
}
- // TODO(b/315163162) Add @Deprecated keyword after 24Q2 cut.
/**
* Called by the system when an associated device is nearby or connected.
*
* @param associationInfo A record for the companion device.
+ * @deprecated use {@link #onDevicePresenceEvent(DevicePresenceEvent)}} instead.
*/
+ @FlaggedApi(Flags.FLAG_DEVICE_PRESENCE)
+ @Deprecated
@MainThread
public void onDeviceAppeared(@NonNull AssociationInfo associationInfo) {
if (!associationInfo.isSelfManaged()) {
@@ -260,12 +262,14 @@ public abstract class CompanionDeviceService extends Service {
}
}
- // TODO(b/315163162) Add @Deprecated keyword after 24Q2 cut.
/**
* Called by the system when an associated device is out of range or disconnected.
*
* @param associationInfo A record for the companion device.
+ * @deprecated use {@link #onDevicePresenceEvent(DevicePresenceEvent)}} instead.
*/
+ @FlaggedApi(Flags.FLAG_DEVICE_PRESENCE)
+ @Deprecated
@MainThread
public void onDeviceDisappeared(@NonNull AssociationInfo associationInfo) {
if (!associationInfo.isSelfManaged()) {
diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java
index cc57dc05d6b1..e271cf4f60ec 100644
--- a/core/java/android/content/ClipData.java
+++ b/core/java/android/content/ClipData.java
@@ -946,6 +946,34 @@ public class ClipData implements Parcelable {
}
/**
+ * Make a clone of ClipData that only contains URIs. This reduces the size of data transfer over
+ * IPC and only retains important information for the purpose of verifying creator token of an
+ * Intent.
+ * @return a copy of ClipData with only URIs remained.
+ * @hide
+ */
+ public ClipData cloneOnlyUriItems() {
+ ArrayList<Item> items = null;
+ final int N = mItems.size();
+ for (int i = 0; i < N; i++) {
+ Item item = mItems.get(i);
+ if (item.getUri() != null) {
+ if (items == null) {
+ items = new ArrayList<>(N);
+ }
+ items.add(new Item(item.getUri()));
+ } else if (item.getIntent() != null) {
+ if (items == null) {
+ items = new ArrayList<>(N);
+ }
+ items.add(new Item(item.getIntent().cloneForCreatorToken()));
+ }
+ }
+ if (items == null || items.isEmpty()) return null;
+ return new ClipData(new ClipDescription("", new String[0]), items);
+ }
+
+ /**
* Create a new ClipData holding data of the type
* {@link ClipDescription#MIMETYPE_TEXT_PLAIN}.
*
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 02eed1a7553f..d7660172a2f1 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -7970,6 +7970,24 @@ public class Intent implements Parcelable, Cloneable {
}
/**
+ * Make a copy of all members important to identify an intent with its creator token.
+ * @hide
+ */
+ public @NonNull Intent cloneForCreatorToken() {
+ Intent clone = new Intent()
+ .setAction(this.mAction)
+ .setDataAndType(this.mData, this.mType)
+ .setPackage(this.mPackage)
+ .setComponent(this.mComponent)
+ .setFlags(this.mFlags & IMMUTABLE_FLAGS);
+ if (this.mClipData != null) {
+ clone.setClipData(this.mClipData.cloneOnlyUriItems());
+ }
+ clone.mCreatorTokenInfo = this.mCreatorTokenInfo;
+ return clone;
+ }
+
+ /**
* Create an intent with a given action. All other fields (data, type,
* class) are null. Note that the action <em>must</em> be in a
* namespace because Intents are used globally in the system -- for
@@ -11684,7 +11702,7 @@ public class Intent implements Parcelable, Cloneable {
Log.w(TAG, "Failure filling in extras", e);
}
}
- mCreatorTokenInfo = other.mCreatorTokenInfo;
+ fillInCreatorTokenInfo(other.mCreatorTokenInfo, changes);
if (mayHaveCopiedUris && mContentUserHint == UserHandle.USER_CURRENT
&& other.mContentUserHint != UserHandle.USER_CURRENT) {
mContentUserHint = other.mContentUserHint;
@@ -11692,6 +11710,45 @@ public class Intent implements Parcelable, Cloneable {
return changes;
}
+ // keep original creator token and merge nested intent keys.
+ private void fillInCreatorTokenInfo(CreatorTokenInfo otherCreatorTokenInfo, int changes) {
+ if (otherCreatorTokenInfo != null && otherCreatorTokenInfo.mNestedIntentKeys != null) {
+ if (mCreatorTokenInfo == null) {
+ mCreatorTokenInfo = new CreatorTokenInfo();
+ }
+ ArraySet<NestedIntentKey> otherNestedIntentKeys =
+ otherCreatorTokenInfo.mNestedIntentKeys;
+ if (mCreatorTokenInfo.mNestedIntentKeys == null) {
+ mCreatorTokenInfo.mNestedIntentKeys = new ArraySet<>(otherNestedIntentKeys);
+ } else {
+ ArraySet<NestedIntentKey> otherKeys;
+ if ((changes & FILL_IN_CLIP_DATA) == 0) {
+ // If clip data is Not filled in from other, do not merge clip data keys.
+ otherKeys = new ArraySet<>();
+ int N = otherNestedIntentKeys.size();
+ for (int i = 0; i < N; i++) {
+ NestedIntentKey key = otherNestedIntentKeys.valueAt(i);
+ if (key.mType != NestedIntentKey.NESTED_INTENT_KEY_TYPE_CLIP_DATA) {
+ otherKeys.add(key);
+ }
+ }
+ } else {
+ // If clip data is filled in from other, remove clip data keys from this
+ // creatorTokenInfo and then merge every key from the others.
+ int N = mCreatorTokenInfo.mNestedIntentKeys.size();
+ for (int i = N - 1; i >= 0; i--) {
+ NestedIntentKey key = mCreatorTokenInfo.mNestedIntentKeys.valueAt(i);
+ if (key.mType == NestedIntentKey.NESTED_INTENT_KEY_TYPE_CLIP_DATA) {
+ mCreatorTokenInfo.mNestedIntentKeys.removeAt(i);
+ }
+ }
+ otherKeys = otherNestedIntentKeys;
+ }
+ mCreatorTokenInfo.mNestedIntentKeys.addAll(otherKeys);
+ }
+ }
+ }
+
/**
* Merge the extras data in this intent with that of other supplied intent using the
* strategy specified using {@code extrasMerger}.
@@ -12228,6 +12285,7 @@ public class Intent implements Parcelable, Cloneable {
private IBinder mCreatorToken;
// Stores all extra keys whose values are intents for a top level intent.
private ArraySet<NestedIntentKey> mNestedIntentKeys;
+
}
/**
diff --git a/core/java/android/content/pm/dependencyinstaller/DependencyInstallerCallback.java b/core/java/android/content/pm/dependencyinstaller/DependencyInstallerCallback.java
index ba089f7fd33e..35e5c443e4b2 100644
--- a/core/java/android/content/pm/dependencyinstaller/DependencyInstallerCallback.java
+++ b/core/java/android/content/pm/dependencyinstaller/DependencyInstallerCallback.java
@@ -53,7 +53,14 @@ public final class DependencyInstallerCallback implements Parcelable {
* Callback to indicate that all the requested dependencies have been resolved and their
* sessions created. See {@link DependencyInstallerService#onDependenciesRequired}.
*
+ * The system will wait for the sessions to be installed before resuming the original session
+ * which requested dependency installation.
+ *
+ * If any of the session fails to install, the system may fail the original session. The caller
+ * is expected to handle clean up of any other pending sessions remanining.
+ *
* @param sessionIds the install session IDs for all requested dependencies
+ * @throws IllegalArgumentException if session id doesn't exist or has already failed.
*/
public void onAllDependenciesResolved(@NonNull int[] sessionIds) {
try {
diff --git a/core/java/android/content/pm/dependencyinstaller/IDependencyInstallerCallback.aidl b/core/java/android/content/pm/dependencyinstaller/IDependencyInstallerCallback.aidl
index 92d1d9e118e6..e4cf55d3ce5f 100644
--- a/core/java/android/content/pm/dependencyinstaller/IDependencyInstallerCallback.aidl
+++ b/core/java/android/content/pm/dependencyinstaller/IDependencyInstallerCallback.aidl
@@ -24,7 +24,7 @@ import java.util.List;
*
* {@hide}
*/
-oneway interface IDependencyInstallerCallback {
+interface IDependencyInstallerCallback {
/**
* Callback to indicate that all the requested dependencies have been resolved and have been
* committed for installation. See {@link DependencyInstallerService#onDependenciesRequired}.
@@ -38,4 +38,4 @@ oneway interface IDependencyInstallerCallback {
* and any associated sessions have been abandoned.
*/
void onFailureToResolveAllDependencies();
-} \ No newline at end of file
+}
diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig
index 833260a15c45..d351ebc22026 100644
--- a/core/java/android/content/pm/multiuser.aconfig
+++ b/core/java/android/content/pm/multiuser.aconfig
@@ -363,6 +363,17 @@ flag {
is_fixed_read_only: true
}
+flag {
+ name: "cache_user_restrictions_read_only"
+ namespace: "multiuser"
+ description: "Cache hasUserRestriction to avoid unnecessary binder calls"
+ bug: "350419621"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+ is_fixed_read_only: true
+}
+
# This flag guards the private space feature and all its implementations excluding the APIs. APIs are guarded by android.os.Flags.allow_private_profile.
flag {
name: "enable_private_space_features"
diff --git a/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java b/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
index 153dd9a93490..e30f871b68eb 100644
--- a/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
@@ -330,6 +330,36 @@ public class FrameworkParsingPackageUtils {
}
/**
+ * Check if a package is compatible with this platform with regards to its
+ * its minSdkVersionFull.
+ *
+ * @param minSdkVersionFullString A string representation of a major.minor version,
+ * e.g. "12.34"
+ * @param platformMinSdkVersionFull The major and minor version of the platform, i.e. the value
+ * of Build.VERSION.SDK_INT_FULL
+ * @param input A ParseInput object to report success or failure
+ */
+ public static ParseResult<Void> verifyMinSdkVersionFull(@NonNull String minSdkVersionFullString,
+ int platformMinSdkVersionFull, @NonNull ParseInput input) {
+ int minSdkVersionFull;
+ try {
+ minSdkVersionFull = Build.parseFullVersion(minSdkVersionFullString);
+ } catch (IllegalStateException e) {
+ return input.error(PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ e.getMessage());
+ }
+ if (minSdkVersionFull <= platformMinSdkVersionFull) {
+ return input.success(null);
+ }
+ return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK,
+ "Requires newer sdk version "
+ + Build.fullVersionToString(minSdkVersionFull)
+ + " (current version is "
+ + Build.fullVersionToString(platformMinSdkVersionFull)
+ + ")");
+ }
+
+ /**
* Computes the targetSdkVersion to use at runtime. If the package is not compatible with this
* platform, populates {@code outError[0]} with an error message.
* <p>
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 266efb7b759c..aba2345f28d8 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -1699,17 +1699,18 @@ public final class CameraManager {
}
if (context != null) {
- final ActivityManager activityManager =
- context.getSystemService(ActivityManager.class);
- for (ActivityManager.AppTask appTask : activityManager.getAppTasks()) {
- final TaskInfo taskInfo = appTask.getTaskInfo();
- final int freeformCameraCompatMode =
- taskInfo.appCompatTaskInfo.cameraCompatTaskInfo.freeformCameraCompatMode;
- if (freeformCameraCompatMode != 0
- && taskInfo.topActivity != null
- && taskInfo.topActivity.getPackageName().equals(packageName)) {
- // WindowManager has requested rotation override.
- return getRotationOverrideForCompatFreeform(freeformCameraCompatMode);
+ final ActivityManager activityManager = context.getSystemService(ActivityManager.class);
+ if (activityManager != null) {
+ for (ActivityManager.AppTask appTask : activityManager.getAppTasks()) {
+ final TaskInfo taskInfo = appTask.getTaskInfo();
+ final int freeformCameraCompatMode = taskInfo.appCompatTaskInfo
+ .cameraCompatTaskInfo.freeformCameraCompatMode;
+ if (freeformCameraCompatMode != 0
+ && taskInfo.topActivity != null
+ && taskInfo.topActivity.getPackageName().equals(packageName)) {
+ // WindowManager has requested rotation override.
+ return getRotationOverrideForCompatFreeform(freeformCameraCompatMode);
+ }
}
}
}
diff --git a/core/java/android/hardware/camera2/TotalCaptureResult.java b/core/java/android/hardware/camera2/TotalCaptureResult.java
index 7e42f43056e1..29eaab8eebcc 100644
--- a/core/java/android/hardware/camera2/TotalCaptureResult.java
+++ b/core/java/android/hardware/camera2/TotalCaptureResult.java
@@ -86,7 +86,8 @@ public final class TotalCaptureResult extends CaptureResult {
mPhysicalCaptureResults = new HashMap<String, TotalCaptureResult>();
for (PhysicalCaptureResultInfo onePhysicalResult : physicalResults) {
TotalCaptureResult physicalResult = new TotalCaptureResult(
- onePhysicalResult.getCameraId(), onePhysicalResult.getCameraMetadata(),
+ onePhysicalResult.getCameraId(),
+ onePhysicalResult.getCameraMetadata(),
parent, extras, /*partials*/null, sessionId, new PhysicalCaptureResultInfo[0]);
mPhysicalCaptureResults.put(onePhysicalResult.getCameraId(),
physicalResult);
@@ -115,7 +116,8 @@ public final class TotalCaptureResult extends CaptureResult {
mPhysicalCaptureResults = new HashMap<String, TotalCaptureResult>();
for (PhysicalCaptureResultInfo onePhysicalResult : physicalResults) {
TotalCaptureResult physicalResult = new TotalCaptureResult(
- onePhysicalResult.getCameraId(), onePhysicalResult.getCameraMetadata(),
+ onePhysicalResult.getCameraId(),
+ onePhysicalResult.getCameraMetadata(),
parent, requestId, frameNumber, /*partials*/null, sessionId,
new PhysicalCaptureResultInfo[0]);
mPhysicalCaptureResults.put(onePhysicalResult.getCameraId(),
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index ea70abb55b48..34c0f7b19da9 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -34,6 +34,7 @@ import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraExtensionCharacteristics;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
+import android.hardware.camera2.CameraMetadataInfo;
import android.hardware.camera2.CameraOfflineSession;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
@@ -59,6 +60,8 @@ import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.os.SystemClock;
@@ -129,6 +132,8 @@ public class CameraDeviceImpl extends CameraDevice
final Object mInterfaceLock = new Object(); // access from this class and Session only!
private final CameraDeviceCallbacks mCallbacks = new CameraDeviceCallbacks();
+ private long mFMQReader; // native fmq reader ptr
+
private final StateCallback mDeviceCallback;
private volatile StateCallbackKK mSessionStateCallback;
private final Executor mDeviceExecutor;
@@ -476,6 +481,9 @@ public class CameraDeviceImpl extends CameraDevice
if (mInError) return;
mRemoteDevice = new ICameraDeviceUserWrapper(remoteDevice);
+ Parcel resultParcel = Parcel.obtain();
+ mRemoteDevice.getCaptureResultMetadataQueue().writeToParcel(resultParcel, 0);
+ mFMQReader = nativeCreateFMQReader(resultParcel);
IBinder remoteDeviceBinder = remoteDevice.asBinder();
// For legacy camera device, remoteDevice is in the same process, and
@@ -1682,6 +1690,7 @@ public class CameraDeviceImpl extends CameraDevice
if (mRemoteDevice != null || mInError) {
mDeviceExecutor.execute(mCallOnClosed);
}
+ nativeClose(mFMQReader);
mRemoteDevice = null;
}
@@ -2416,27 +2425,61 @@ public class CameraDeviceImpl extends CameraDevice
}
}
}
+ private PhysicalCaptureResultInfo[] readMetadata(
+ PhysicalCaptureResultInfo[] srcPhysicalResults) {
+ PhysicalCaptureResultInfo[] retVal =
+ new PhysicalCaptureResultInfo[srcPhysicalResults.length];
+ int i = 0;
+ long fmqSize = 0;
+ for (PhysicalCaptureResultInfo srcPhysicalResult : srcPhysicalResults) {
+ CameraMetadataNative physicalCameraMetadata = null;
+ if (srcPhysicalResult.getCameraMetadataInfo().getTag() ==
+ CameraMetadataInfo.fmqSize) {
+ fmqSize = srcPhysicalResult.getCameraMetadataInfo().getFmqSize();
+ physicalCameraMetadata =
+ new CameraMetadataNative(nativeReadResultMetadata(mFMQReader, fmqSize));
+ } else {
+ physicalCameraMetadata = srcPhysicalResult.getCameraMetadata();
+ }
+ PhysicalCaptureResultInfo physicalResultInfo =
+ new PhysicalCaptureResultInfo(
+ srcPhysicalResult.getCameraId(), physicalCameraMetadata);
+ retVal[i] = physicalResultInfo;
+ i++;
+ }
+ return retVal;
+ }
@Override
- public void onResultReceived(CameraMetadataNative result,
+ public void onResultReceived(CameraMetadataInfo resultInfo,
CaptureResultExtras resultExtras, PhysicalCaptureResultInfo physicalResults[])
throws RemoteException {
int requestId = resultExtras.getRequestId();
long frameNumber = resultExtras.getFrameNumber();
-
- if (DEBUG) {
- Log.v(TAG, "Received result frame " + frameNumber + " for id "
- + requestId);
- }
-
synchronized(mInterfaceLock) {
if (mRemoteDevice == null) return; // Camera already closed
-
+ PhysicalCaptureResultInfo savedPhysicalResults[] = physicalResults;
+ CameraMetadataNative result;
+ if (resultInfo.getTag() == CameraMetadataInfo.fmqSize) {
+ CameraMetadataNative fmqMetadata =
+ new CameraMetadataNative(
+ nativeReadResultMetadata(mFMQReader, resultInfo.getFmqSize()));
+ result = fmqMetadata;
+ } else {
+ result = resultInfo.getMetadata();
+ }
+ physicalResults = readMetadata(savedPhysicalResults);
+ if (DEBUG) {
+ Log.v(TAG, "Received result frame " + frameNumber + " for id "
+ + requestId);
+ }
// Redirect device callback to the offline session in case we are in the middle
// of an offline switch
if (mOfflineSessionImpl != null) {
- mOfflineSessionImpl.getCallbacks().onResultReceived(result, resultExtras,
+ CameraMetadataInfo resultInfoOffline = CameraMetadataInfo.metadata(result);
+ mOfflineSessionImpl.getCallbacks().onResultReceived(resultInfoOffline,
+ resultExtras,
physicalResults);
return;
}
@@ -2824,6 +2867,11 @@ public class CameraDeviceImpl extends CameraDevice
}
}
+ private static native long nativeCreateFMQReader(Parcel resultQueue);
+ //TODO: Investigate adding FastNative b/62791857
+ private static native long nativeReadResultMetadata(long ptr, long metadataSize);
+ private static native void nativeClose(long ptr);
+
@Override
public @CAMERA_AUDIO_RESTRICTION int getCameraAudioRestriction() throws CameraAccessException {
synchronized(mInterfaceLock) {
@@ -2870,4 +2918,4 @@ public class CameraDeviceImpl extends CameraDevice
}
}
}
-}
+} \ No newline at end of file
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index c0a5928a369b..d7b6f116e452 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -391,6 +391,18 @@ public class CameraMetadataNative implements Parcelable {
}
/**
+ * Take ownership of native metadata
+ */
+ public CameraMetadataNative(long metadataPtr) {
+ super();
+ mMetadataPtr = metadataPtr;
+ if (mMetadataPtr == 0) {
+ throw new OutOfMemoryError("Failed to allocate native CameraMetadata");
+ }
+ updateNativeAllocation();
+ }
+
+ /**
* Move the contents from {@code other} into a new camera metadata instance.</p>
*
* <p>After this call, {@code other} will become empty.</p>
diff --git a/core/java/android/hardware/camera2/impl/CameraOfflineSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraOfflineSessionImpl.java
index 1769c4638805..e660d6aba854 100644
--- a/core/java/android/hardware/camera2/impl/CameraOfflineSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraOfflineSessionImpl.java
@@ -28,6 +28,7 @@ import android.hardware.camera2.CameraOfflineSession.CameraOfflineSessionCallbac
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.CameraMetadataInfo;
import android.hardware.camera2.ICameraDeviceCallbacks;
import android.hardware.camera2.ICameraOfflineSession;
import android.hardware.camera2.TotalCaptureResult;
@@ -291,10 +292,10 @@ public class CameraOfflineSessionImpl extends CameraOfflineSession
}
@Override
- public void onResultReceived(CameraMetadataNative result,
+ public void onResultReceived(CameraMetadataInfo resultInfo,
CaptureResultExtras resultExtras, PhysicalCaptureResultInfo physicalResults[])
throws RemoteException {
-
+ CameraMetadataNative result = resultInfo.getMetadata();
int requestId = resultExtras.getRequestId();
long frameNumber = resultExtras.getFrameNumber();
diff --git a/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java b/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java
index 831c75ec5d33..a79e084b7f41 100644
--- a/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java
+++ b/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java
@@ -26,6 +26,7 @@ import android.hardware.camera2.params.OutputConfiguration;
import android.hardware.camera2.params.SessionConfiguration;
import android.hardware.camera2.utils.ExceptionUtils;
import android.hardware.camera2.utils.SubmitInfo;
+import android.hardware.common.fmq.MQDescriptor;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
@@ -313,4 +314,15 @@ public class ICameraDeviceUserWrapper {
throw ExceptionUtils.throwAsPublicException(e);
}
}
-}
+
+ public MQDescriptor<Byte, Byte> getCaptureResultMetadataQueue() throws CameraAccessException {
+ try {
+ return mRemoteDevice.getCaptureResultMetadataQueue();
+ } catch (ServiceSpecificException e) {
+ throw ExceptionUtils.throwAsPublicException(e);
+ } catch (RemoteException e) {
+ throw ExceptionUtils.throwAsPublicException(e);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/core/java/android/hardware/camera2/impl/PhysicalCaptureResultInfo.java b/core/java/android/hardware/camera2/impl/PhysicalCaptureResultInfo.java
index 09619d0f5c7e..77296d1c1877 100644
--- a/core/java/android/hardware/camera2/impl/PhysicalCaptureResultInfo.java
+++ b/core/java/android/hardware/camera2/impl/PhysicalCaptureResultInfo.java
@@ -15,6 +15,7 @@
*/
package android.hardware.camera2.impl;
+import android.hardware.camera2.CameraMetadataInfo;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.os.Parcel;
@@ -25,7 +26,7 @@ import android.os.Parcelable;
*/
public class PhysicalCaptureResultInfo implements Parcelable {
private String cameraId;
- private CameraMetadataNative cameraMetadata;
+ private CameraMetadataInfo cameraMetadataInfo;
public static final @android.annotation.NonNull Parcelable.Creator<PhysicalCaptureResultInfo> CREATOR =
new Parcelable.Creator<PhysicalCaptureResultInfo>() {
@@ -46,7 +47,7 @@ public class PhysicalCaptureResultInfo implements Parcelable {
public PhysicalCaptureResultInfo(String cameraId, CameraMetadataNative cameraMetadata) {
this.cameraId = cameraId;
- this.cameraMetadata = cameraMetadata;
+ this.cameraMetadataInfo = CameraMetadataInfo.metadata(cameraMetadata);
}
@Override
@@ -57,13 +58,12 @@ public class PhysicalCaptureResultInfo implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(cameraId);
- cameraMetadata.writeToParcel(dest, flags);
+ cameraMetadataInfo.writeToParcel(dest, flags);
}
public void readFromParcel(Parcel in) {
cameraId = in.readString();
- cameraMetadata = new CameraMetadataNative();
- cameraMetadata.readFromParcel(in);
+ cameraMetadataInfo = CameraMetadataInfo.CREATOR.createFromParcel(in);
}
public String getCameraId() {
@@ -71,6 +71,11 @@ public class PhysicalCaptureResultInfo implements Parcelable {
}
public CameraMetadataNative getCameraMetadata() {
- return cameraMetadata;
+ return cameraMetadataInfo.getMetadata();
}
-}
+
+ public CameraMetadataInfo getCameraMetadataInfo() {
+ return cameraMetadataInfo;
+ }
+
+} \ No newline at end of file
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index c2e9260879a8..9b39c62ad03e 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -1546,6 +1546,57 @@ public class Build {
}
/**
+ * Convert a major.minor version String like "36.1" to an int that
+ * represents both major and minor version.
+ *
+ * @param version the String to parse
+ * @return an int encoding the major and minor version
+ * @throws IllegalArgumentException if the string could not be converted into an int
+ *
+ * @hide
+ */
+ @SuppressWarnings("FlaggedApi") // SDK_INT_MULTIPLIER is defined in this file
+ public static @SdkIntFull int parseFullVersion(@NonNull String version) {
+ int index = version.indexOf('.');
+ int major;
+ int minor = 0;
+ try {
+ if (index == -1) {
+ major = Integer.parseInt(version);
+ } else {
+ major = Integer.parseInt(version.substring(0, index));
+ minor = Integer.parseInt(version.substring(index + 1));
+ }
+ if (major < 0 || minor < 0) {
+ throw new NumberFormatException();
+ }
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("failed to parse '" + version
+ + "' as a major.minor version code");
+ }
+ return major * VERSION_CODES_FULL.SDK_INT_MULTIPLIER + minor;
+ }
+
+ /**
+ * Convert an int representing a major.minor version like SDK_INT_FULL to a
+ * human readable string. The returned string is only intended for debug
+ * and error messages.
+ *
+ * @param version the int to convert to a string
+ * @return a String representing the same major.minor version as the int passed in
+ * @throws IllegalArgumentException if {@code version} is negative
+ *
+ * @hide
+ */
+ public static String fullVersionToString(@SdkIntFull int version) {
+ if (version < 0) {
+ throw new IllegalArgumentException("failed to convert '" + version
+ + "' to string: not a valid major.minor version code");
+ }
+ return String.format("%d.%d", getMajorSdkVersion(version), getMinorSdkVersion(version));
+ }
+
+ /**
* The vendor API for 2024 Q2
*
* <p>For Android 14-QPR3 and later, the vendor API level is completely decoupled from the SDK
diff --git a/core/java/android/os/CpuHeadroomParams.java b/core/java/android/os/CpuHeadroomParams.java
index 8e78b7e355f9..072c012d6db9 100644
--- a/core/java/android/os/CpuHeadroomParams.java
+++ b/core/java/android/os/CpuHeadroomParams.java
@@ -56,15 +56,9 @@ public final class CpuHeadroomParams {
*/
public static final int CPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1;
- /**
- * Minimum CPU headroom calculation window size.
- */
- public static final int CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN = 50;
-
- /**
- * Maximum CPU headroom calculation window size.
- */
- public static final int CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX = 10000;
+ private static final int CALCULATION_WINDOW_MILLIS_MIN = 50;
+ private static final int CALCULATION_WINDOW_MILLIS_MAX = 10000;
+ private static final int MAX_TID_COUNT = 5;
/**
* Sets the headroom calculation type.
@@ -99,20 +93,18 @@ public final class CpuHeadroomParams {
* Sets the headroom calculation window size in milliseconds.
* <p>
*
- * @param windowMillis the window size in milliseconds, ranged from
- * [{@link #CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN},
- * {@link #CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX}]. The smaller
- * the value, the larger fluctuation in value should be expected. The
- * default value can be retrieved from the
+ * @param windowMillis the window size in milliseconds ranges from [50, 10000]. The smaller the
+ * window size, the larger fluctuation in the headroom value should be
+ * expected. The default value can be retrieved from the
* {@link #getCalculationWindowMillis}. The device will try to use the
* closest feasible window size to this param.
* @throws IllegalArgumentException if the window size is not in allowed range.
*/
public void setCalculationWindowMillis(
- @IntRange(from = CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN, to =
- CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX) int windowMillis) {
- if (windowMillis < CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN
- || windowMillis > CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX) {
+ @IntRange(from = CALCULATION_WINDOW_MILLIS_MIN, to =
+ CALCULATION_WINDOW_MILLIS_MAX) int windowMillis) {
+ if (windowMillis < CALCULATION_WINDOW_MILLIS_MIN
+ || windowMillis > CALCULATION_WINDOW_MILLIS_MAX) {
throw new IllegalArgumentException("Invalid calculation window: " + windowMillis);
}
mInternal.calculationWindowMillis = windowMillis;
@@ -121,10 +113,10 @@ public final class CpuHeadroomParams {
/**
* Gets the headroom calculation window size in milliseconds.
* <p>
- * This will return the default value chosen by the device if not set.
+ * This will return the default value chosen by the device if the params is not set.
*/
- public @IntRange(from = CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN, to =
- CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX) long getCalculationWindowMillis() {
+ public @IntRange(from = CALCULATION_WINDOW_MILLIS_MIN, to =
+ CALCULATION_WINDOW_MILLIS_MAX) long getCalculationWindowMillis() {
return mInternal.calculationWindowMillis;
}
@@ -141,7 +133,7 @@ public final class CpuHeadroomParams {
* positive.
*/
public void setTids(@NonNull int... tids) {
- if (tids.length == 0 || tids.length > 5) {
+ if (tids.length == 0 || tids.length > MAX_TID_COUNT) {
throw new IllegalArgumentException("Invalid number of TIDs: " + tids.length);
}
for (int tid : tids) {
diff --git a/core/java/android/os/GpuHeadroomParams.java b/core/java/android/os/GpuHeadroomParams.java
index 4dc98264e57b..126ee8cce3d0 100644
--- a/core/java/android/os/GpuHeadroomParams.java
+++ b/core/java/android/os/GpuHeadroomParams.java
@@ -54,15 +54,8 @@ public final class GpuHeadroomParams {
*/
public static final int GPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1;
- /**
- * Minimum GPU headroom calculation window size.
- */
- public static final int GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN = 50;
-
- /**
- * Maximum GPU headroom calculation window size.
- */
- public static final int GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX = 10000;
+ private static final int CALCULATION_WINDOW_MILLIS_MIN = 50;
+ private static final int CALCULATION_WINDOW_MILLIS_MAX = 10000;
/**
* Sets the headroom calculation type.
@@ -82,7 +75,7 @@ public final class GpuHeadroomParams {
/**
* Gets the headroom calculation type.
- * Default to {@link #GPU_HEADROOM_CALCULATION_TYPE_MIN} if not set.
+ * Default to {@link #GPU_HEADROOM_CALCULATION_TYPE_MIN} if the params is not set.
*/
public @GpuHeadroomCalculationType int getCalculationType() {
@GpuHeadroomCalculationType int validatedType = switch ((int) mInternal.calculationType) {
@@ -97,20 +90,18 @@ public final class GpuHeadroomParams {
* Sets the headroom calculation window size in milliseconds.
* <p>
*
- * @param windowMillis the window size in milliseconds, ranged from
- * [{@link #GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN},
- * {@link #GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX}]. The smaller
- * the value, the larger fluctuation in value should be expected. The
- * default value can be retrieved from the
- * {@link #getCalculationWindowMillis}. If the device will try to use the
+ * @param windowMillis the window size in milliseconds ranges from [50, 10000]. The smaller the
+ * window size, the larger fluctuation in the headroom value should be
+ * expected. The default value can be retrieved from the
+ * {@link #getCalculationWindowMillis}. The device will try to use the
* closest feasible window size to this param.
* @throws IllegalArgumentException if the window is invalid.
*/
public void setCalculationWindowMillis(
- @IntRange(from = GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN, to =
- GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX) int windowMillis) {
- if (windowMillis < GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN
- || windowMillis > GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX) {
+ @IntRange(from = CALCULATION_WINDOW_MILLIS_MIN, to =
+ CALCULATION_WINDOW_MILLIS_MAX) int windowMillis) {
+ if (windowMillis < CALCULATION_WINDOW_MILLIS_MIN
+ || windowMillis > CALCULATION_WINDOW_MILLIS_MAX) {
throw new IllegalArgumentException("Invalid calculation window: " + windowMillis);
}
mInternal.calculationWindowMillis = windowMillis;
@@ -121,8 +112,8 @@ public final class GpuHeadroomParams {
* <p>
* This will return the default value chosen by the device if not set.
*/
- public @IntRange(from = GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN, to =
- GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX) int getCalculationWindowMillis() {
+ public @IntRange(from = CALCULATION_WINDOW_MILLIS_MIN, to =
+ CALCULATION_WINDOW_MILLIS_MAX) int getCalculationWindowMillis() {
return mInternal.calculationWindowMillis;
}
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index 94768d111ca4..8f6a50843ddb 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -98,6 +98,7 @@ public class GraphicsEnvironment {
private static final int VULKAN_1_1 = 0x00401000;
private static final int VULKAN_1_2 = 0x00402000;
private static final int VULKAN_1_3 = 0x00403000;
+ private static final int VULKAN_1_4 = 0x00404000;
// Values for UPDATABLE_DRIVER_ALL_APPS
// 0: Default (Invalid values fallback to default as well)
@@ -179,6 +180,10 @@ public class GraphicsEnvironment {
private int getVulkanVersion(PackageManager pm) {
// PackageManager doesn't have an API to retrieve the version of a specific feature, and we
// need to avoid retrieving all system features here and looping through them.
+ if (pm.hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, VULKAN_1_4)) {
+ return VULKAN_1_4;
+ }
+
if (pm.hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, VULKAN_1_3)) {
return VULKAN_1_3;
}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index a1ede5fee3f3..7e73a5d04866 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -3846,7 +3846,7 @@ public class UserManager {
}
/**
- * Return the time when the context user was unlocked elapsed milliseconds since boot,
+ * Return the time when the calling user was unlocked elapsed milliseconds since boot,
* or 0 if not unlocked.
*
* @hide
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index a7195834e6bb..b5139b5b7ef6 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -445,3 +445,21 @@ flag {
description: "Enable the Wallet role within profiles"
bug: "356107987"
}
+
+flag {
+ name: "text_classifier_choice_api_enabled"
+ is_fixed_read_only: true
+ is_exported: true
+ namespace: "permissions"
+ description: "API change to enable getTextClassifier by type"
+ bug: "377229653"
+}
+
+flag {
+ name: "updatable_text_classifier_for_otp_detection_enabled"
+ is_fixed_read_only: true
+ is_exported: true
+ namespace: "permissions"
+ description: "Enables text classifier for OTP detection that is updatable from mainline module"
+ bug: "377229653"
+}
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 99ff38b43adc..8e379e82a5fb 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -10859,6 +10859,28 @@ public final class ContactsContract {
"vnd.android.cursor.item/contact_metadata_sync_state";
}
+ /**
+ * This exception is thrown when an attempt is made to perform a write operation
+ * on a contact or contact group targeting a local account or a SIM account,
+ * and the operation is not permitted under the current conditions.
+ * The local account can be retrieved using {@link RawContacts#getLocalAccountName(Context)}
+ * and {@link RawContacts#getLocalAccountType(Context)}.
+ * SIM accounts can be retrieved using {@link SimContacts#getSimAccounts(ContentResolver)}.
+ *
+ * <p>Local and SIM accounts have limitations that may prevent write operations
+ * due to their nature, underlying implementation, or the current system state.
+ * For example, the SIM card may be full, read-only, or not present.
+ *
+ * <p>The specific conditions under which write operations are permitted on
+ * local or SIM accounts can vary.
+ */
+ @FlaggedApi(Flags.FLAG_NEW_DEFAULT_ACCOUNT_API_ENABLED)
+ public static class LocalSimContactsWriteException extends IllegalArgumentException {
+ public LocalSimContactsWriteException(@NonNull String s) {
+ super(s);
+ }
+ }
+
private static Bundle nullSafeCall(@NonNull ContentResolver resolver, @NonNull Uri uri,
@NonNull String method, @Nullable String arg, @Nullable Bundle extras) {
try (ContentProviderClient client = resolver.acquireContentProviderClient(uri)) {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index d5b525884ac1..8d054f4b1750 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6374,6 +6374,14 @@ public final class Settings {
public static final String LOCALE_PREFERENCES = "locale_preferences";
/**
+ * User can change the region from region settings. This records user's preferred region.
+ *
+ * E.g. : if user's locale is en-US, this will record US
+ * @hide
+ */
+ public static final String PREFERRED_REGION = "preferred_region";
+
+ /**
* Setting to enable camera flash notification feature.
* <ul>
* <li> 0 = Off
@@ -6547,6 +6555,7 @@ public final class Settings {
PRIVATE_SETTINGS.add(DEFAULT_DEVICE_FONT_SCALE);
PRIVATE_SETTINGS.add(MOUSE_REVERSE_VERTICAL_SCROLLING);
PRIVATE_SETTINGS.add(MOUSE_SWAP_PRIMARY_BUTTON);
+ PRIVATE_SETTINGS.add(PREFERRED_REGION);
}
/**
diff --git a/core/java/android/security/responsible_apis_flags.aconfig b/core/java/android/security/responsible_apis_flags.aconfig
index a5c837b88fa4..2007a5f43f41 100644
--- a/core/java/android/security/responsible_apis_flags.aconfig
+++ b/core/java/android/security/responsible_apis_flags.aconfig
@@ -96,6 +96,14 @@ flag {
}
flag {
+ name: "prevent_intent_redirect_show_toast_if_nested_keys_not_collected"
+ namespace: "responsible_apis"
+ description: "Prevent intent redirect attacks by showing a toast if not yet collected"
+ bug: "361143368"
+ is_fixed_read_only: true
+}
+
+flag {
name: "prevent_intent_redirect_throw_exception_if_nested_keys_not_collected"
namespace: "responsible_apis"
description: "Prevent intent redirect attacks by throwing exception if the intent does not collect nested keys"
diff --git a/core/java/android/service/autofill/FillEventHistory.java b/core/java/android/service/autofill/FillEventHistory.java
index 14a14e69f208..fba8e42cc673 100644
--- a/core/java/android/service/autofill/FillEventHistory.java
+++ b/core/java/android/service/autofill/FillEventHistory.java
@@ -170,6 +170,9 @@ public final class FillEventHistory implements Parcelable {
}
parcel.writeInt(event.mSaveDialogNotShowReason);
parcel.writeInt(event.mUiType);
+ if (Flags.addLastFocusedIdToFillEventHistory()) {
+ parcel.writeParcelable(event.mFocusedId, 0);
+ }
}
}
}
@@ -375,6 +378,8 @@ public final class FillEventHistory implements Parcelable {
@UiType
private final int mUiType;
+ @Nullable private final AutofillId mFocusedId;
+
/**
* Returns the type of the event.
*
@@ -388,7 +393,7 @@ public final class FillEventHistory implements Parcelable {
@FlaggedApi(FLAG_AUTOFILL_W_METRICS)
@Nullable
public AutofillId getFocusedId() {
- return null;
+ return mFocusedId;
}
/**
@@ -624,6 +629,7 @@ public final class FillEventHistory implements Parcelable {
* @param manuallyFilledDatasetIds The ids of datasets that had values matching the
* respective entry on {@code manuallyFilledFieldIds}.
* @param detectedFieldClassifications the field classification matches.
+ * @param focusedId the field which was focused at the time of event trigger
*
* @throws IllegalArgumentException If the length of {@code changedFieldIds} and
* {@code changedDatasetIds} doesn't match.
@@ -640,11 +646,12 @@ public final class FillEventHistory implements Parcelable {
@Nullable ArrayList<AutofillId> manuallyFilledFieldIds,
@Nullable ArrayList<ArrayList<String>> manuallyFilledDatasetIds,
@Nullable AutofillId[] detectedFieldIds,
- @Nullable FieldClassification[] detectedFieldClassifications) {
+ @Nullable FieldClassification[] detectedFieldClassifications,
+ @Nullable AutofillId focusedId) {
this(eventType, datasetId, clientState, selectedDatasetIds, ignoredDatasetIds,
changedFieldIds, changedDatasetIds, manuallyFilledFieldIds,
manuallyFilledDatasetIds, detectedFieldIds, detectedFieldClassifications,
- NO_SAVE_UI_REASON_NONE);
+ NO_SAVE_UI_REASON_NONE, focusedId);
}
/**
@@ -665,6 +672,7 @@ public final class FillEventHistory implements Parcelable {
* respective entry on {@code manuallyFilledFieldIds}.
* @param detectedFieldClassifications the field classification matches.
* @param saveDialogNotShowReason The reason why a save dialog was not shown.
+ * @param focusedId the field which was focused at the time of event trigger
*
* @throws IllegalArgumentException If the length of {@code changedFieldIds} and
* {@code changedDatasetIds} doesn't match.
@@ -682,11 +690,12 @@ public final class FillEventHistory implements Parcelable {
@Nullable ArrayList<ArrayList<String>> manuallyFilledDatasetIds,
@Nullable AutofillId[] detectedFieldIds,
@Nullable FieldClassification[] detectedFieldClassifications,
- int saveDialogNotShowReason) {
+ int saveDialogNotShowReason,
+ @Nullable AutofillId focusedId) {
this(eventType, datasetId, clientState, selectedDatasetIds, ignoredDatasetIds,
changedFieldIds, changedDatasetIds, manuallyFilledFieldIds,
manuallyFilledDatasetIds, detectedFieldIds, detectedFieldClassifications,
- saveDialogNotShowReason, UI_TYPE_UNKNOWN);
+ saveDialogNotShowReason, UI_TYPE_UNKNOWN, focusedId);
}
/**
@@ -708,6 +717,7 @@ public final class FillEventHistory implements Parcelable {
* @param detectedFieldClassifications the field classification matches.
* @param saveDialogNotShowReason The reason why a save dialog was not shown.
* @param uiType The ui presentation type for fill suggestion.
+ * @param focusedId the field which was focused at the time of event trigger
*
* @throws IllegalArgumentException If the length of {@code changedFieldIds} and
* {@code changedDatasetIds} doesn't match.
@@ -725,7 +735,7 @@ public final class FillEventHistory implements Parcelable {
@Nullable ArrayList<ArrayList<String>> manuallyFilledDatasetIds,
@Nullable AutofillId[] detectedFieldIds,
@Nullable FieldClassification[] detectedFieldClassifications,
- int saveDialogNotShowReason, int uiType) {
+ int saveDialogNotShowReason, int uiType, @Nullable AutofillId focusedId) {
mEventType = Preconditions.checkArgumentInRange(eventType, 0,
TYPE_VIEW_REQUESTED_AUTOFILL, "eventType");
mDatasetId = datasetId;
@@ -756,6 +766,7 @@ public final class FillEventHistory implements Parcelable {
NO_SAVE_UI_REASON_NONE, NO_SAVE_UI_REASON_DATASET_MATCH,
"saveDialogNotShowReason");
mUiType = uiType;
+ mFocusedId = focusedId;
}
@Override
@@ -852,13 +863,17 @@ public final class FillEventHistory implements Parcelable {
: null;
final int saveDialogNotShowReason = parcel.readInt();
final int uiType = parcel.readInt();
+ AutofillId focusedId = null;
+ if (Flags.addLastFocusedIdToFillEventHistory()) {
+ focusedId = parcel.readParcelable(null, AutofillId.class);
+ }
selection.addEvent(new Event(eventType, datasetId, clientState,
selectedDatasetIds, ignoredDatasets,
changedFieldIds, changedDatasetIds,
manuallyFilledFieldIds, manuallyFilledDatasetIds,
detectedFieldIds, detectedFieldClassifications,
- saveDialogNotShowReason, uiType));
+ saveDialogNotShowReason, uiType, focusedId));
}
return selection;
}
diff --git a/core/java/android/widget/Button.java b/core/java/android/widget/Button.java
index 0bf6380eb904..eb3b76873a8f 100644
--- a/core/java/android/widget/Button.java
+++ b/core/java/android/widget/Button.java
@@ -134,6 +134,7 @@ public class Button extends TextView {
// 1. app target sdk is 36 or above.
// 2. feature flag rolled-out.
// 3. device is a watch.
+ // 4. button uses Theme.DeviceDefault.
// getButtonDefaultStyleAttr and getButtonDefaultStyleRes works together to alter the UI
// while considering the conditions above.
// Their results are mutual exclusive. i.e. when conditions above are all true,
@@ -229,6 +230,7 @@ public class Button extends TextView {
private static boolean useWearMaterial3Style(Context context) {
return Flags.useWearMaterial3Ui() && CompatChanges.isChangeEnabled(WEAR_MATERIAL3_BUTTON)
- && context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
+ && context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)
+ && context.getThemeResId() == com.android.internal.R.style.Theme_DeviceDefault;
}
}
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index 8019e6791cf1..65e5679034c8 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -58,10 +58,13 @@ flag {
}
flag {
- name: "enable_desktop_windowing_scvh_cache"
+ name: "enable_desktop_windowing_scvh_cache_bug_fix"
namespace: "lse_desktop_experience"
description: "Enables a SurfaceControlViewHost cache for window decorations"
- bug: "345146928"
+ bug: "360452034"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
}
flag {
@@ -242,13 +245,6 @@ flag {
}
flag {
- name: "enable_desktop_windowing_app_handle_education_integration"
- namespace: "lse_desktop_experience"
- description: "Enables desktop windowing app handle education and integrates new APIs"
- bug: "380272815"
-}
-
-flag {
name: "enable_desktop_windowing_transitions"
namespace: "lse_desktop_experience"
description: "Enables desktop windowing transition & motion polish changes"
@@ -304,6 +300,13 @@ flag {
}
flag {
+ name: "enable_desktop_windowing_app_to_web_education_integration"
+ namespace: "lse_desktop_experience"
+ description: "Enables desktop windowing App-to-Web education and integrates new APIs"
+ bug: "380272815"
+}
+
+flag {
name: "enable_minimize_button"
namespace: "lse_desktop_experience"
description: "Adds a minimize button the the caption bar"
diff --git a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
index e8831ec2743e..e2be1f57b1fb 100644
--- a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
+++ b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
@@ -360,43 +360,44 @@ public class AccessibilityShortcutController {
// Avoid non-a11y users accidentally turning shortcut on without reading this carefully.
// Put "don't turn on" as the primary action.
- final AlertDialog alertDialog = mFrameworkObjectProvider.getAlertDialogBuilder(
- // Use SystemUI context so we pick up any theme set in a vendor overlay
- mFrameworkObjectProvider.getSystemUiContext())
- .setTitle(getShortcutWarningTitle(targets))
- .setMessage(getShortcutWarningMessage(targets))
- .setCancelable(false)
- .setNegativeButton(R.string.accessibility_shortcut_on,
- (DialogInterface d, int which) -> enableDefaultHardwareShortcut(userId))
- .setPositiveButton(R.string.accessibility_shortcut_off,
- (DialogInterface d, int which) -> {
- Set<String> targetServices =
- ShortcutUtils.getShortcutTargetsFromSettings(
- mContext,
- HARDWARE,
+ final AlertDialog alertDialog =
+ mFrameworkObjectProvider
+ .getAlertDialogBuilder(
+ // Use SystemUI context so we pick up any theme set in a vendor
+ // overlay
+ mFrameworkObjectProvider.getSystemUiContext())
+ .setTitle(getShortcutWarningTitle(targets))
+ .setMessage(getShortcutWarningMessage(targets))
+ .setCancelable(false)
+ .setNegativeButton(
+ R.string.accessibility_shortcut_on,
+ (DialogInterface d, int which) ->
+ enableDefaultHardwareShortcut(userId))
+ .setPositiveButton(
+ R.string.accessibility_shortcut_off,
+ (DialogInterface d, int which) -> {
+ Set<String> targetServices =
+ ShortcutUtils.getShortcutTargetsFromSettings(
+ mContext, HARDWARE, userId);
+ am.enableShortcutsForTargets(
+ false, HARDWARE, targetServices, userId);
+ // If canceled, treat as if the dialog has never been shown
+ Settings.Secure.putIntForUser(
+ mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ DialogStatus.NOT_SHOWN,
userId);
- if (Flags.migrateEnableShortcuts()) {
- am.enableShortcutsForTargets(
- false, HARDWARE, targetServices, userId);
- } else {
- Settings.Secure.putStringForUser(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, "",
- userId);
- ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
- mContext, targetServices, userId);
- }
- // If canceled, treat as if the dialog has never been shown
- Settings.Secure.putIntForUser(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
- DialogStatus.NOT_SHOWN, userId);
- })
- .setOnCancelListener((DialogInterface d) -> {
- // If canceled, treat as if the dialog has never been shown
- Settings.Secure.putIntForUser(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
- DialogStatus.NOT_SHOWN, userId);
- })
- .create();
+ })
+ .setOnCancelListener(
+ (DialogInterface d) -> {
+ // If canceled, treat as if the dialog has never been shown
+ Settings.Secure.putIntForUser(
+ mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ DialogStatus.NOT_SHOWN,
+ userId);
+ })
+ .create();
return alertDialog;
}
@@ -531,14 +532,8 @@ public class AccessibilityShortcutController {
// Default service is invalid, so nothing we can do here.
return;
}
- if (Flags.migrateEnableShortcuts()) {
- accessibilityManager.enableShortcutsForTargets(true, HARDWARE,
- Set.of(defaultServiceComponent.flattenToString()), userId);
- } else {
- Settings.Secure.putStringForUser(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
- defaultServiceComponent.flattenToString(), userId);
- }
+ accessibilityManager.enableShortcutsForTargets(true, HARDWARE,
+ Set.of(defaultServiceComponent.flattenToString()), userId);
}
private boolean performTtsPrompt(AlertDialog alertDialog) {
diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java
index a753110edd51..f0582d063c71 100644
--- a/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java
+++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java
@@ -19,8 +19,6 @@ package com.android.internal.accessibility.dialog;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
-import static com.android.internal.accessibility.util.ShortcutUtils.optInValueToSettings;
-import static com.android.internal.accessibility.util.ShortcutUtils.optOutValueFromSettings;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -31,7 +29,6 @@ import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.view.View;
import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.Flags;
import com.android.internal.accessibility.common.ShortcutConstants;
import com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType;
@@ -118,18 +115,9 @@ public abstract class AccessibilityTarget implements TargetOperations, OnTargetS
@Override
public void onCheckedChanged(boolean isChecked) {
setShortcutEnabled(isChecked);
- if (Flags.migrateEnableShortcuts()) {
- final AccessibilityManager am =
- getContext().getSystemService(AccessibilityManager.class);
- am.enableShortcutsForTargets(
- isChecked, getShortcutType(), Set.of(mId), UserHandle.myUserId());
- } else {
- if (isChecked) {
- optInValueToSettings(getContext(), getShortcutType(), getId());
- } else {
- optOutValueFromSettings(getContext(), getShortcutType(), getId());
- }
- }
+ final AccessibilityManager am = getContext().getSystemService(AccessibilityManager.class);
+ am.enableShortcutsForTargets(
+ isChecked, getShortcutType(), Set.of(mId), UserHandle.myUserId());
}
public void setStateDescription(CharSequence stateDescription) {
diff --git a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
index 0f93e6e8109b..c160b42f8b6b 100644
--- a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
@@ -29,6 +29,7 @@ import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_
import static android.os.Build.VERSION_CODES.DONUT;
import static android.os.Build.VERSION_CODES.O;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
+import static android.sdk.Flags.majorMinorVersioningScheme;
import static com.android.internal.pm.pkg.parsing.ParsingUtils.parseKnownActivityEmbeddingCerts;
@@ -1689,6 +1690,21 @@ public class ParsingPackageUtils {
targetCode = minCode;
}
+ if (majorMinorVersioningScheme()) {
+ val = sa.peekValue(R.styleable.AndroidManifestUsesSdk_minSdkVersionFull);
+ if (val != null) {
+ if (val.type == TypedValue.TYPE_STRING && val.string != null) {
+ String minSdkVersionFullString = val.string.toString();
+ ParseResult<Void> minSdkVersionFullResult =
+ FrameworkParsingPackageUtils.verifyMinSdkVersionFull(
+ minSdkVersionFullString, Build.VERSION.SDK_INT_FULL, input);
+ if (minSdkVersionFullResult.isError()) {
+ return input.error(minSdkVersionFullResult);
+ }
+ }
+ }
+ }
+
if (isApkInApex) {
val = sa.peekValue(R.styleable.AndroidManifestUsesSdk_maxSdkVersion);
if (val != null) {
diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java
index 2bfbf843b2ab..4b90420a75ee 100644
--- a/core/java/com/android/internal/widget/ConversationLayout.java
+++ b/core/java/com/android/internal/widget/ConversationLayout.java
@@ -16,6 +16,7 @@
package com.android.internal.widget;
+import static android.app.Flags.notificationsRedesignTemplates;
import static android.widget.flags.Flags.conversationLayoutUseMaximumChildHeight;
import static com.android.internal.widget.MessagingGroup.IMAGE_DISPLAY_LOCATION_EXTERNAL;
@@ -692,7 +693,7 @@ public class ConversationLayout extends FrameLayout
}
private void updateActionListPadding() {
- if (mActions != null) {
+ if (!notificationsRedesignTemplates() && mActions != null) {
mActions.setCollapsibleIndentDimen(R.dimen.call_notification_collapsible_indent);
}
}
diff --git a/core/java/com/android/internal/widget/MessagingGroup.java b/core/java/com/android/internal/widget/MessagingGroup.java
index 97a2d3beda90..4305ba753e46 100644
--- a/core/java/com/android/internal/widget/MessagingGroup.java
+++ b/core/java/com/android/internal/widget/MessagingGroup.java
@@ -261,7 +261,7 @@ public class MessagingGroup extends NotificationOptimizedLinearLayout implements
MessagingGroup createdGroup = sInstancePool.acquire();
if (createdGroup == null) {
createdGroup = (MessagingGroup) LayoutInflater.from(layout.getContext()).inflate(
- R.layout.notification_template_messaging_group, layout,
+ getMessagingGroupLayoutResource(), layout,
false);
createdGroup.addOnLayoutChangeListener(MessagingLayout.MESSAGING_PROPERTY_ANIMATOR);
}
@@ -269,6 +269,14 @@ public class MessagingGroup extends NotificationOptimizedLinearLayout implements
return createdGroup;
}
+ private static int getMessagingGroupLayoutResource() {
+ if (Flags.notificationsRedesignTemplates()) {
+ return R.layout.notification_2025_messaging_group;
+ } else {
+ return R.layout.notification_template_messaging_group;
+ }
+ }
+
public void removeMessage(MessagingMessage messagingMessage,
ArrayList<MessagingLinearLayout.MessagingChild> toRecycle) {
View view = messagingMessage.getView();
diff --git a/core/java/com/android/internal/widget/NotificationActionListLayout.java b/core/java/com/android/internal/widget/NotificationActionListLayout.java
index 301dc392c125..cac2024f548d 100644
--- a/core/java/com/android/internal/widget/NotificationActionListLayout.java
+++ b/core/java/com/android/internal/widget/NotificationActionListLayout.java
@@ -20,6 +20,7 @@ import static android.app.Notification.CallStyle.DEBUG_NEW_ACTION_LAYOUT;
import static android.app.Flags.evenlyDividedCallStyleActionLayout;
import android.annotation.DimenRes;
+import android.app.Flags;
import android.app.Notification;
import android.content.Context;
import android.content.res.TypedArray;
@@ -58,7 +59,7 @@ public class NotificationActionListLayout extends LinearLayout {
private int mEmphasizedPaddingBottom;
private int mEmphasizedHeight;
private int mRegularHeight;
- @DimenRes private int mCollapsibleIndentDimen = R.dimen.notification_actions_padding_start;
+ @DimenRes private int mCollapsibleIndentDimen;
int mNumNotGoneChildren;
int mNumPriorityChildren;
@@ -73,6 +74,10 @@ public class NotificationActionListLayout extends LinearLayout {
public NotificationActionListLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
+ mCollapsibleIndentDimen = Flags.notificationsRedesignTemplates()
+ ? R.dimen.notification_2025_actions_margin_start
+ : R.dimen.notification_actions_padding_start;
+
int[] attrIds = { android.R.attr.gravity };
TypedArray ta = context.obtainStyledAttributes(attrs, attrIds, defStyleAttr, defStyleRes);
mGravity = ta.getInt(0, 0);
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 5c03c5cca66d..e22d9587093b 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -214,6 +214,7 @@ cc_library_shared_for_libandroid_runtime {
"android_media_ToneGenerator.cpp",
"android_hardware_Camera.cpp",
"android_hardware_camera2_CameraMetadata.cpp",
+ "android_hardware_camera2_CameraDevice.cpp",
"android_hardware_camera2_DngCreator.cpp",
"android_hardware_camera2_impl_CameraExtensionJpegProcessor.cpp",
"android_hardware_camera2_utils_SurfaceUtils.cpp",
@@ -304,7 +305,12 @@ cc_library_shared_for_libandroid_runtime {
"av-types-aidl-cpp",
"android.hardware.camera.device@3.2",
"camera_platform_flags_c_lib",
+ "android.hardware.common.fmq-V1-cpp",
+ "android.hardware.common-V2-cpp",
+ "android.hardware.common.fmq-V1-ndk",
+ "android.hardware.common-V2-ndk",
"libandroid_net",
+ "libfmq",
"libbattery",
"libnetdutils",
"libmemtrack",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 00a62977de43..ac187b08f0f1 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -77,6 +77,7 @@ extern int register_android_opengl_jni_GLES32(JNIEnv* env);
extern int register_android_hardware_Camera(JNIEnv *env);
extern int register_android_hardware_camera2_CameraMetadata(JNIEnv *env);
+extern int register_android_hardware_camera2_CameraDevice(JNIEnv *env);
extern int register_android_hardware_camera2_DngCreator(JNIEnv *env);
extern int register_android_hardware_camera2_impl_CameraExtensionJpegProcessor(JNIEnv* env);
extern int register_android_hardware_camera2_utils_SurfaceUtils(JNIEnv* env);
@@ -1623,6 +1624,7 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_com_android_internal_util_VirtualRefBasePtr),
REG_JNI(register_android_hardware_Camera),
REG_JNI(register_android_hardware_camera2_CameraMetadata),
+ REG_JNI(register_android_hardware_camera2_CameraDevice),
REG_JNI(register_android_hardware_camera2_DngCreator),
REG_JNI(register_android_hardware_camera2_impl_CameraExtensionJpegProcessor),
REG_JNI(register_android_hardware_camera2_utils_SurfaceUtils),
diff --git a/core/jni/android_hardware_camera2_CameraDevice.cpp b/core/jni/android_hardware_camera2_CameraDevice.cpp
new file mode 100644
index 000000000000..493c7073416c
--- /dev/null
+++ b/core/jni/android_hardware_camera2_CameraDevice.cpp
@@ -0,0 +1,148 @@
+/*
+**
+** Copyright 2024, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+// #define LOG_NDEBUG 0
+
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+
+#include <memory>
+#define LOG_TAG "CameraDevice-JNI"
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <utils/Trace.h>
+#include <vector>
+
+#include "jni.h"
+#include <nativehelper/JNIHelp.h>
+#include "android_os_Parcel.h"
+#include "core_jni_helpers.h"
+#include <android/binder_parcel_jni.h>
+#include <android/hardware/camera2/ICameraDeviceUser.h>
+#include <aidl/android/hardware/common/fmq/MQDescriptor.h>
+#include <aidl/android/hardware/common/fmq/SynchronizedReadWrite.h>
+#include <fmq/AidlMessageQueue.h>
+#include <camera/CameraMetadata.h>
+
+using namespace android;
+
+using ::android::AidlMessageQueue;
+using ResultMetadataQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
+
+class FMQReader {
+ public:
+ FMQReader(MQDescriptor<int8_t, SynchronizedReadWrite> &resultMQ) {
+ mCaptureResultMetadataQueue = std::make_shared<ResultMetadataQueue>(resultMQ);
+ }
+ std::shared_ptr<CameraMetadata> readOneResultMetadata(long metadataSize);
+ private:
+ std::shared_ptr<ResultMetadataQueue> mCaptureResultMetadataQueue = nullptr;
+};
+
+std::shared_ptr<CameraMetadata> FMQReader::readOneResultMetadata(long metadataSize) {
+ ATRACE_CALL();
+ if (metadataSize == 0) {
+ return nullptr;
+ }
+ auto metadataVec = std::make_unique<int8_t []>(metadataSize);
+ bool read = mCaptureResultMetadataQueue->read(metadataVec.get(), metadataSize);
+ if (!read) {
+ ALOGE("%s capture metadata could't be read from fmq", __FUNCTION__);
+ return nullptr;
+ }
+
+ // Takes ownership of metadataVec, this doesn't copy
+ std::shared_ptr<CameraMetadata> retVal =
+ std::make_shared<CameraMetadata>(
+ reinterpret_cast<camera_metadata_t *>(metadataVec.release()));
+ return retVal;
+}
+
+extern "C" {
+
+static jlong CameraDevice_createFMQReader(JNIEnv *env, jclass thiz,
+ jobject resultParcel) {
+ AParcel *resultAParcel = AParcel_fromJavaParcel(env, resultParcel);
+ if (resultAParcel == nullptr) {
+ ALOGE("%s: Error creating result parcel", __FUNCTION__);
+ return 0;
+ }
+ AParcel_setDataPosition(resultAParcel, 0);
+
+ MQDescriptor<int8_t, SynchronizedReadWrite> resultMQ;
+ if (resultMQ.readFromParcel(resultAParcel) != OK) {
+ ALOGE("%s: read from result parcel failed", __FUNCTION__);
+ return 0;
+ }
+ return reinterpret_cast<jlong>(new std::shared_ptr<FMQReader>(
+ new FMQReader(resultMQ)));
+}
+
+static std::shared_ptr<FMQReader>* FMQReader_getSharedPtr(jlong fmqReaderLongPtr) {
+ return reinterpret_cast<std::shared_ptr<FMQReader>* >(fmqReaderLongPtr);
+}
+
+static jlong CameraDevice_readResultMetadata(JNIEnv *env, jclass thiz, jlong ptr,
+ jlong metadataSize) {
+ ALOGV("%s", __FUNCTION__);
+
+ FMQReader *fmqReader = FMQReader_getSharedPtr(ptr)->get();
+ auto metadataSp = fmqReader->readOneResultMetadata(metadataSize);
+ auto retVal = new std::shared_ptr<CameraMetadata>(metadataSp);
+ return reinterpret_cast<jlong>(retVal);
+}
+
+static void CameraDevice_close(JNIEnv *env, jclass thiz, jlong ptr) {
+ ALOGV("%s", __FUNCTION__);
+
+ auto fmqPtr = FMQReader_getSharedPtr(ptr);
+ if (fmqPtr != nullptr) {
+ delete fmqPtr;
+ }
+}
+
+}
+
+//-------------------------------------------------
+#define CAMERA_DEVICE_CLASS_NAME "android/hardware/camera2/impl/CameraDeviceImpl"
+static const JNINativeMethod gCameraDeviceMethods[] = {
+// static methods
+ { "nativeCreateFMQReader",
+ "(Landroid/os/Parcel;)J",
+ (void *)CameraDevice_createFMQReader},
+ { "nativeReadResultMetadata",
+ "(JJ)J",
+ (void *)CameraDevice_readResultMetadata},
+ { "nativeClose",
+ "(J)V",
+ (void*)CameraDevice_close},
+// instance methods
+};
+
+
+// Get all the required offsets in java class and register native functions
+int register_android_hardware_camera2_CameraDevice(JNIEnv *env)
+{
+ // Register native functions
+ return RegisterMethodsOrDie(env,
+ CAMERA_DEVICE_CLASS_NAME,
+ gCameraDeviceMethods,
+ NELEM(gCameraDeviceMethods));
+}
+
+extern "C" {
+
+} // extern "C" \ No newline at end of file
diff --git a/core/res/res/layout/notification_2025_conversation_face_pile_layout.xml b/core/res/res/layout/notification_2025_conversation_face_pile_layout.xml
new file mode 100644
index 000000000000..b25adaabf8e8
--- /dev/null
+++ b/core/res/res/layout/notification_2025_conversation_face_pile_layout.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations underthe License
+ -->
+
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/conversation_face_pile"
+ android:layout_width="@dimen/conversation_avatar_size"
+ android:layout_height="@dimen/conversation_avatar_size"
+ android:forceHasOverlappingRendering="false"
+ >
+ <ImageView
+ android:id="@+id/conversation_face_pile_top"
+ android:layout_width="@dimen/messaging_avatar_size"
+ android:layout_height="@dimen/messaging_avatar_size"
+ android:scaleType="centerCrop"
+ android:layout_gravity="end|top"
+ android:background="@drawable/notification_icon_circle"
+ android:clipToOutline="true"
+ />
+ <FrameLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="start|bottom">
+ <ImageView
+ android:id="@+id/conversation_face_pile_bottom_background"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/conversation_badge_background"
+ />
+ <ImageView
+ android:id="@+id/conversation_face_pile_bottom"
+ android:layout_width="@dimen/messaging_avatar_size"
+ android:layout_height="@dimen/messaging_avatar_size"
+ android:scaleType="centerCrop"
+ android:layout_gravity="center"
+ android:background="@drawable/notification_icon_circle"
+ android:clipToOutline="true"
+ />
+ </FrameLayout>
+</FrameLayout>
diff --git a/core/res/res/layout/notification_2025_conversation_icon_container.xml b/core/res/res/layout/notification_2025_conversation_icon_container.xml
new file mode 100644
index 000000000000..90befd911bdf
--- /dev/null
+++ b/core/res/res/layout/notification_2025_conversation_icon_container.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/conversation_icon_container"
+ android:layout_width="@dimen/conversation_content_start"
+ android:layout_height="wrap_content"
+ android:gravity="start|top"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:paddingTop="20dp"
+ android:paddingBottom="16dp"
+ android:importantForAccessibility="no"
+ >
+
+ <FrameLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:layout_gravity="top|center_horizontal"
+ >
+
+ <!-- Big icon: 48x48, 12dp padding top, 16dp padding sides -->
+ <com.android.internal.widget.CachingIconView
+ android:id="@+id/conversation_icon"
+ android:layout_width="@dimen/conversation_avatar_size"
+ android:layout_height="@dimen/conversation_avatar_size"
+ android:layout_marginLeft="@dimen/conversation_badge_protrusion"
+ android:layout_marginRight="@dimen/conversation_badge_protrusion"
+ android:layout_marginBottom="@dimen/conversation_badge_protrusion"
+ android:background="@drawable/notification_icon_circle"
+ android:clipToOutline="true"
+ android:scaleType="centerCrop"
+ android:importantForAccessibility="no"
+ />
+
+ <ViewStub
+ android:layout="@layout/notification_2025_conversation_face_pile_layout"
+ android:layout_width="@dimen/conversation_avatar_size"
+ android:layout_height="@dimen/conversation_avatar_size"
+ android:layout_marginLeft="@dimen/conversation_badge_protrusion"
+ android:layout_marginRight="@dimen/conversation_badge_protrusion"
+ android:layout_marginBottom="@dimen/conversation_badge_protrusion"
+ android:id="@+id/conversation_face_pile"
+ />
+
+ <FrameLayout
+ android:id="@+id/conversation_icon_badge"
+ android:layout_width="@dimen/conversation_icon_size_badged"
+ android:layout_height="@dimen/conversation_icon_size_badged"
+ android:layout_gravity="end|bottom"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ >
+
+ <com.android.internal.widget.CachingIconView
+ android:id="@+id/conversation_icon_badge_bg"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:src="@drawable/conversation_badge_background"
+ android:forceHasOverlappingRendering="false"
+ android:scaleType="center"
+ />
+
+ <com.android.internal.widget.NotificationRowIconView
+ android:id="@+id/icon"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_margin="4dp"
+ android:layout_gravity="center"
+ android:forceHasOverlappingRendering="false"
+ />
+
+ <com.android.internal.widget.CachingIconView
+ android:id="@+id/conversation_icon_badge_ring"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:src="@drawable/conversation_badge_ring"
+ android:visibility="gone"
+ android:forceHasOverlappingRendering="false"
+ android:clipToPadding="false"
+ android:scaleType="center"
+ />
+ </FrameLayout>
+ </FrameLayout>
+</FrameLayout>
diff --git a/core/res/res/layout/notification_2025_messaging_group.xml b/core/res/res/layout/notification_2025_messaging_group.xml
new file mode 100644
index 000000000000..c1b491fc4b0e
--- /dev/null
+++ b/core/res/res/layout/notification_2025_messaging_group.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<!-- extends LinearLayout -->
+<com.android.internal.widget.MessagingGroup
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/status_bar_latest_event_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal" >
+ <FrameLayout
+ android:id="@+id/message_icon_container"
+ android:layout_width="@dimen/conversation_content_start"
+ android:layout_height="wrap_content">
+ <ImageView
+ android:layout_gravity="top|center_horizontal"
+ android:id="@+id/message_icon"
+ android:layout_width="@dimen/messaging_avatar_size"
+ android:layout_height="@dimen/messaging_avatar_size"
+ android:background="@drawable/notification_icon_circle"
+ android:clipToOutline="true"
+ android:scaleType="centerCrop"
+ android:importantForAccessibility="no" />
+ </FrameLayout>
+ <com.android.internal.widget.RemeasuringLinearLayout
+ android:id="@+id/messaging_group_content_container"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:baselineAligned="true"
+ android:orientation="vertical">
+ <com.android.internal.widget.ImageFloatingTextView
+ android:id="@+id/message_name"
+ style="@style/Widget.DeviceDefault.Notification.MessagingName"
+ android:layout_width="wrap_content"
+ android:textAlignment="viewStart"
+ />
+ <com.android.internal.widget.MessagingLinearLayout
+ android:id="@+id/group_message_container"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/notification_text_margin_top"
+ android:spacing="2dp" />
+ </com.android.internal.widget.RemeasuringLinearLayout>
+ <FrameLayout
+ android:id="@+id/messaging_group_icon_container"
+ android:layout_width="@dimen/messaging_avatar_size"
+ android:layout_height="@dimen/messaging_avatar_size"
+ android:layout_marginStart="12dp"
+ android:visibility="gone"/>
+ <FrameLayout
+ android:id="@+id/messaging_group_sending_progress_container"
+ android:layout_width="@dimen/messaging_group_sending_progress_size"
+ android:layout_height="@dimen/messaging_avatar_size"
+ android:layout_marginStart="12dp"
+ android:layout_gravity="top"
+ android:visibility="gone">
+ <ProgressBar
+ android:id="@+id/messaging_group_sending_progress"
+ android:layout_height="@dimen/messaging_group_sending_progress_size"
+ android:layout_width="@dimen/messaging_group_sending_progress_size"
+ android:layout_gravity="center"
+ android:indeterminate="true"
+ style="?android:attr/progressBarStyleSmall" />
+ </FrameLayout>
+</com.android.internal.widget.MessagingGroup>
diff --git a/core/res/res/layout/notification_2025_template_collapsed_base.xml b/core/res/res/layout/notification_2025_template_collapsed_base.xml
index a790e5da20de..09c02c9994f4 100644
--- a/core/res/res/layout/notification_2025_template_collapsed_base.xml
+++ b/core/res/res/layout/notification_2025_template_collapsed_base.xml
@@ -20,7 +20,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:minHeight="@dimen/notification_headerless_min_height"
+ android:minHeight="@dimen/notification_2025_min_height"
android:tag="base"
>
@@ -72,8 +72,8 @@
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
- android:layout_marginBottom="@dimen/notification_headerless_margin_twoline"
- android:layout_marginTop="@dimen/notification_headerless_margin_twoline"
+ android:layout_marginBottom="@dimen/notification_2025_margin"
+ android:layout_marginTop="@dimen/notification_2025_margin"
android:orientation="vertical"
>
@@ -81,7 +81,7 @@
android:id="@+id/notification_top_line"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:minHeight="@dimen/notification_headerless_line_height"
+ android:minHeight="@dimen/notification_2025_content_min_height"
android:clipChildren="false"
android:theme="@style/Theme.DeviceDefault.Notification"
>
diff --git a/core/res/res/layout/notification_2025_template_collapsed_call.xml b/core/res/res/layout/notification_2025_template_collapsed_call.xml
new file mode 100644
index 000000000000..614444d6b2f0
--- /dev/null
+++ b/core/res/res/layout/notification_2025_template_collapsed_call.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<!-- Extends FrameLayout -->
+<com.android.internal.widget.CallLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/status_bar_latest_event_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipChildren="false"
+ android:tag="call"
+ android:theme="@style/Theme.DeviceDefault.Notification"
+ >
+
+ <!-- CallLayout shares visual appearance with ConversationLayout, so shares layouts -->
+ <include layout="@layout/notification_2025_conversation_icon_container" />
+
+ <LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/notification_2025_min_height"
+ android:orientation="horizontal"
+ >
+
+ <LinearLayout
+ android:id="@+id/notification_main_column"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_marginStart="@dimen/conversation_content_start"
+ android:orientation="vertical"
+ android:paddingBottom="@dimen/notification_2025_margin"
+ >
+
+ <include
+ layout="@layout/notification_template_conversation_header"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ />
+
+ <include layout="@layout/notification_template_text"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/notification_text_height"
+ />
+
+ </LinearLayout>
+
+ <FrameLayout
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:minWidth="@dimen/notification_content_margin_end"
+ >
+
+ <include
+ layout="@layout/notification_expand_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ />
+
+ </FrameLayout>
+
+ </LinearLayout>
+
+</com.android.internal.widget.CallLayout>
diff --git a/core/res/res/layout/notification_2025_template_collapsed_media.xml b/core/res/res/layout/notification_2025_template_collapsed_media.xml
index 427c4e42e40c..f539105368e7 100644
--- a/core/res/res/layout/notification_2025_template_collapsed_media.xml
+++ b/core/res/res/layout/notification_2025_template_collapsed_media.xml
@@ -23,7 +23,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:minHeight="@dimen/notification_min_height"
+ android:minHeight="@dimen/notification_2025_min_height"
android:tag="media"
>
@@ -74,8 +74,8 @@
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
- android:layout_marginBottom="@dimen/notification_headerless_margin_twoline"
- android:layout_marginTop="@dimen/notification_headerless_margin_twoline"
+ android:layout_marginBottom="@dimen/notification_2025_margin"
+ android:layout_marginTop="@dimen/notification_2025_margin"
android:orientation="vertical"
>
diff --git a/core/res/res/layout/notification_2025_template_collapsed_messaging.xml b/core/res/res/layout/notification_2025_template_collapsed_messaging.xml
index f0e4c0f272fb..ddf3ebceaa46 100644
--- a/core/res/res/layout/notification_2025_template_collapsed_messaging.xml
+++ b/core/res/res/layout/notification_2025_template_collapsed_messaging.xml
@@ -38,7 +38,7 @@
<com.android.internal.widget.NotificationMaxHeightFrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:minHeight="@dimen/notification_min_height"
+ android:minHeight="@dimen/notification_2025_min_height"
android:clipChildren="false"
>
@@ -98,8 +98,8 @@
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
- android:layout_marginBottom="@dimen/notification_headerless_margin_twoline"
- android:layout_marginTop="@dimen/notification_headerless_margin_twoline"
+ android:layout_marginBottom="@dimen/notification_2025_margin"
+ android:layout_marginTop="@dimen/notification_2025_margin"
android:layout_marginStart="@dimen/notification_2025_content_margin_start"
android:clipChildren="false"
android:orientation="vertical"
diff --git a/core/res/res/layout/notification_2025_template_conversation.xml b/core/res/res/layout/notification_2025_template_conversation.xml
new file mode 100644
index 000000000000..0c4c7fba90b1
--- /dev/null
+++ b/core/res/res/layout/notification_2025_template_conversation.xml
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<!-- extends FrameLayout -->
+<com.android.internal.widget.ConversationLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/status_bar_latest_event_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipChildren="false"
+ android:tag="conversation"
+ android:theme="@style/Theme.DeviceDefault.Notification"
+ >
+
+ <include layout="@layout/notification_2025_conversation_icon_container" />
+
+ <!-- Wraps entire "expandable" notification -->
+ <com.android.internal.widget.RemeasuringLinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top"
+ android:clipToPadding="false"
+ android:clipChildren="false"
+ android:orientation="vertical"
+ >
+ <!-- LinearLayout for Expand Button-->
+ <com.android.internal.widget.RemeasuringLinearLayout
+ android:id="@+id/expand_button_and_content_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="start|top"
+ android:orientation="horizontal"
+ android:clipChildren="false"
+ android:clipToPadding="false">
+ <!--TODO: move this into a separate layout and share logic with the header to bring back app opps etc-->
+ <com.android.internal.widget.RemeasuringLinearLayout
+ android:id="@+id/notification_action_list_margin_target"
+ android:layout_width="0dp"
+ android:orientation="vertical"
+ android:layout_height="wrap_content"
+ android:layout_weight="1">
+
+ <!-- Header -->
+
+ <!-- Use layout_marginStart instead of paddingStart to work around strange
+ measurement behavior on lower display densities. -->
+ <include
+ layout="@layout/notification_template_conversation_header"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="2dp"
+ android:layout_marginStart="@dimen/conversation_content_start"
+ />
+
+ <!-- Messages -->
+ <com.android.internal.widget.MessagingLinearLayout
+ android:id="@+id/notification_messaging"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/notification_text_size"
+ android:spacing="@dimen/notification_messaging_spacing"
+ android:clipToPadding="false"
+ android:clipChildren="false"
+ />
+ </com.android.internal.widget.RemeasuringLinearLayout>
+
+ <!-- This is where the expand button container will be placed when collapsed-->
+ </com.android.internal.widget.RemeasuringLinearLayout>
+
+ <include layout="@layout/notification_template_smart_reply_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/notification_content_margin"
+ android:layout_marginStart="@dimen/conversation_content_start"
+ android:layout_marginEnd="@dimen/notification_content_margin_end" />
+ <include layout="@layout/notification_material_action_list" />
+ </com.android.internal.widget.RemeasuringLinearLayout>
+
+ <!--expand_button_a11y_container ensures talkback focus order is correct when view is expanded.
+ The -1px of marginTop and 1px of paddingTop make sure expand_button_a11y_container is prior to
+ its sibling view in accessibility focus order.
+ {see android.view.ViewGroup.addChildrenForAccessibility()}
+ expand_button_container will be moved under expand_button_and_content_container when collapsed,
+ this dynamic movement ensures message can flow under expand button when expanded-->
+ <FrameLayout
+ android:id="@+id/expand_button_a11y_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="end|top"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:layout_marginTop="-1px"
+ android:paddingTop="1px"
+ >
+ <!--expand_button_container is dynamically placed between here and at the end of the
+ layout. It starts here since only FrameLayout layout params have gravity-->
+ <LinearLayout
+ android:id="@+id/expand_button_container"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_gravity="end|top"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:orientation="vertical">
+ <include layout="@layout/notification_close_button"
+ android:layout_width="@dimen/notification_close_button_size"
+ android:layout_height="@dimen/notification_close_button_size"
+ android:layout_gravity="end"
+ android:layout_marginEnd="20dp"
+ />
+ <!--expand_button_touch_container makes sure that we can nicely center the expand
+ content in the collapsed layout while the parent makes sure that we're never laid out
+ bigger than the messaging content.-->
+ <LinearLayout
+ android:id="@+id/expand_button_touch_container"
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/conversation_expand_button_height"
+ android:orientation="horizontal"
+ android:layout_gravity="end|top"
+ android:paddingEnd="0dp"
+ android:clipToPadding="false"
+ android:clipChildren="false"
+ >
+ <!-- Images -->
+ <com.android.internal.widget.MessagingLinearLayout
+ android:id="@+id/conversation_image_message_container"
+ android:forceHasOverlappingRendering="false"
+ android:layout_width="40dp"
+ android:layout_height="40dp"
+ android:layout_marginStart="@dimen/conversation_image_start_margin"
+ android:spacing="0dp"
+ android:layout_gravity="center"
+ android:clipToPadding="false"
+ android:clipChildren="false"
+ />
+ <include layout="@layout/notification_expand_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ />
+ </LinearLayout>
+ </LinearLayout>
+ </FrameLayout>
+</com.android.internal.widget.ConversationLayout>
diff --git a/core/res/res/layout/notification_2025_template_expanded_big_picture.xml b/core/res/res/layout/notification_2025_template_expanded_big_picture.xml
new file mode 100644
index 000000000000..18bafe068fcb
--- /dev/null
+++ b/core/res/res/layout/notification_2025_template_expanded_big_picture.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/status_bar_latest_event_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:tag="bigPicture"
+ android:clipChildren="false"
+ >
+
+ <include layout="@layout/notification_2025_template_header" />
+
+ <include layout="@layout/notification_template_right_icon" />
+
+ <LinearLayout
+ android:id="@+id/notification_action_list_margin_target"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="top"
+ android:layout_marginTop="@dimen/notification_content_margin_top"
+ android:clipToPadding="false"
+ android:orientation="vertical"
+ >
+
+ <LinearLayout
+ android:id="@+id/notification_main_column"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+ android:layout_marginEnd="@dimen/notification_content_margin_end"
+ android:orientation="vertical"
+ >
+
+ <include layout="@layout/notification_template_part_line1" />
+
+ <include
+ layout="@layout/notification_template_progress"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/notification_progress_bar_height"
+ android:layout_marginTop="@dimen/notification_progress_margin_top"
+ />
+
+ <include layout="@layout/notification_template_text_multiline" />
+ </LinearLayout>
+
+ <com.android.internal.widget.BigPictureNotificationImageView
+ android:id="@+id/big_picture"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:adjustViewBounds="true"
+ android:layout_weight="1"
+ android:layout_marginTop="13dp"
+ android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+ android:layout_marginEnd="@dimen/notification_content_margin_end"
+ android:background="@drawable/notification_big_picture_outline"
+ android:clipToOutline="true"
+ android:scaleType="centerCrop"
+ />
+
+ <ViewStub
+ android:layout="@layout/notification_material_reply_text"
+ android:id="@+id/notification_2025_reply_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
+
+ <include
+ layout="@layout/notification_template_smart_reply_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+ android:layout_marginEnd="@dimen/notification_content_margin_end"
+ android:layout_marginTop="@dimen/notification_content_margin"
+ />
+
+ <include layout="@layout/notification_material_action_list" />
+ </LinearLayout>
+</FrameLayout>
diff --git a/core/res/res/layout/notification_2025_template_expanded_big_text.xml b/core/res/res/layout/notification_2025_template_expanded_big_text.xml
new file mode 100644
index 000000000000..9ff141b7c946
--- /dev/null
+++ b/core/res/res/layout/notification_2025_template_expanded_big_text.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/status_bar_latest_event_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipChildren="false"
+ android:tag="bigText"
+ >
+
+ <include layout="@layout/notification_2025_template_header" />
+
+ <com.android.internal.widget.RemeasuringLinearLayout
+ android:id="@+id/notification_action_list_margin_target"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top"
+ android:layout_marginTop="@dimen/notification_content_margin_top"
+ android:layout_marginBottom="@dimen/notification_content_margin"
+ android:clipToPadding="false"
+ android:orientation="vertical"
+ >
+
+ <com.android.internal.widget.RemeasuringLinearLayout
+ android:id="@+id/notification_main_column"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top"
+ android:paddingStart="@dimen/notification_2025_content_margin_start"
+ android:paddingEnd="@dimen/notification_content_margin_end"
+ android:clipToPadding="false"
+ android:orientation="vertical"
+ android:layout_weight="1"
+ >
+
+ <include layout="@layout/notification_template_part_line1" />
+
+ <include
+ layout="@layout/notification_template_progress"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/notification_progress_bar_height"
+ android:layout_marginTop="@dimen/notification_progress_margin_top"
+ android:layout_marginBottom="6dp"
+ />
+
+ <com.android.internal.widget.ImageFloatingTextView
+ android:id="@+id/big_text"
+ style="@style/Widget.DeviceDefault.Notification.Text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/notification_text_margin_top"
+ android:singleLine="false"
+ android:gravity="top"
+ android:visibility="gone"
+ android:textAlignment="viewStart"
+ />
+ </com.android.internal.widget.RemeasuringLinearLayout>
+
+ <ViewStub
+ android:layout="@layout/notification_material_reply_text"
+ android:id="@+id/notification_2025_reply_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
+
+ <include
+ layout="@layout/notification_template_smart_reply_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+ android:layout_marginEnd="@dimen/notification_content_margin_end"
+ android:layout_marginTop="@dimen/notification_content_margin"
+ />
+
+ <include layout="@layout/notification_material_action_list" />
+ </com.android.internal.widget.RemeasuringLinearLayout>
+
+ <include layout="@layout/notification_template_right_icon" />
+</FrameLayout>
diff --git a/core/res/res/layout/notification_2025_template_expanded_call.xml b/core/res/res/layout/notification_2025_template_expanded_call.xml
new file mode 100644
index 000000000000..3ff71b78835d
--- /dev/null
+++ b/core/res/res/layout/notification_2025_template_expanded_call.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<!-- Extends FrameLayout -->
+<com.android.internal.widget.CallLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/status_bar_latest_event_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipChildren="false"
+ android:tag="call"
+ android:theme="@style/Theme.DeviceDefault.Notification"
+ >
+
+ <!-- CallLayout shares visual appearance with ConversationLayout, so shares layouts -->
+ <include layout="@layout/notification_2025_conversation_icon_container" />
+
+ <LinearLayout
+ android:id="@+id/notification_action_list_margin_target"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/notification_content_margin"
+ android:orientation="vertical"
+ >
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ >
+
+ <LinearLayout
+ android:id="@+id/notification_main_column"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_marginStart="@dimen/conversation_content_start"
+ android:orientation="vertical"
+ android:minHeight="68dp"
+ >
+
+ <include
+ layout="@layout/notification_template_conversation_header"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ />
+
+ <include layout="@layout/notification_template_text_multiline" />
+
+ <include
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/notification_progress_bar_height"
+ android:layout_marginTop="@dimen/notification_progress_margin_top"
+ layout="@layout/notification_template_progress"
+ />
+ </LinearLayout>
+
+ <FrameLayout
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:minWidth="@dimen/notification_content_margin_end"
+ >
+
+ <include
+ layout="@layout/notification_expand_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ />
+
+ </FrameLayout>
+
+ </LinearLayout>
+
+ <ViewStub
+ android:layout="@layout/notification_material_reply_text"
+ android:id="@+id/notification_material_reply_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
+
+ <include
+ layout="@layout/notification_template_smart_reply_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/notification_content_margin_start"
+ android:layout_marginEnd="@dimen/notification_content_margin_end"
+ android:layout_marginTop="@dimen/notification_content_margin"
+ />
+
+ <include layout="@layout/notification_material_action_list" />
+
+ </LinearLayout>
+
+</com.android.internal.widget.CallLayout>
diff --git a/core/res/res/layout/notification_2025_template_expanded_inbox.xml b/core/res/res/layout/notification_2025_template_expanded_inbox.xml
new file mode 100644
index 000000000000..9fb44ccccfa0
--- /dev/null
+++ b/core/res/res/layout/notification_2025_template_expanded_inbox.xml
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/status_bar_latest_event_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:tag="inbox"
+ android:clipChildren="false"
+ >
+ <include layout="@layout/notification_2025_template_header" />
+ <LinearLayout
+ android:id="@+id/notification_action_list_margin_target"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="top"
+ android:layout_marginTop="@dimen/notification_content_margin_top"
+ android:clipToPadding="false"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:id="@+id/notification_main_column"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top"
+ android:paddingStart="@dimen/notification_2025_content_margin_start"
+ android:paddingEnd="@dimen/notification_content_margin_end"
+ android:layout_weight="1"
+ android:clipToPadding="false"
+ android:orientation="vertical"
+ >
+ <include layout="@layout/notification_template_part_line1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+ <include layout="@layout/notification_template_progress"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/notification_progress_bar_height"
+ android:layout_marginTop="@dimen/notification_progress_margin_top"
+ android:layout_marginBottom="2dp"/>
+ <TextView android:id="@+id/inbox_text0"
+ style="@style/Widget.DeviceDefault.Notification.Text"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:visibility="gone"
+ android:layout_weight="1"
+ />
+ <TextView android:id="@+id/inbox_text1"
+ style="@style/Widget.DeviceDefault.Notification.Text"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:visibility="gone"
+ android:layout_weight="1"
+ />
+ <TextView android:id="@+id/inbox_text2"
+ style="@style/Widget.DeviceDefault.Notification.Text"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:visibility="gone"
+ android:layout_weight="1"
+ />
+ <TextView android:id="@+id/inbox_text3"
+ style="@style/Widget.DeviceDefault.Notification.Text"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:visibility="gone"
+ android:layout_weight="1"
+ />
+ <TextView android:id="@+id/inbox_text4"
+ style="@style/Widget.DeviceDefault.Notification.Text"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:visibility="gone"
+ android:layout_weight="1"
+ />
+ <TextView android:id="@+id/inbox_text5"
+ style="@style/Widget.DeviceDefault.Notification.Text"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:visibility="gone"
+ android:layout_weight="1"
+ />
+ <TextView android:id="@+id/inbox_text6"
+ style="@style/Widget.DeviceDefault.Notification.Text"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:visibility="gone"
+ android:layout_weight="1"
+ />
+ </LinearLayout>
+ <ViewStub android:layout="@layout/notification_material_reply_text"
+ android:id="@+id/notification_2025_reply_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+ <include layout="@layout/notification_template_smart_reply_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+ android:layout_marginEnd="@dimen/notification_content_margin_end"
+ android:layout_marginTop="@dimen/notification_content_margin" />
+ <include layout="@layout/notification_material_action_list" />
+ </LinearLayout>
+ <include layout="@layout/notification_template_right_icon" />
+</FrameLayout>
diff --git a/core/res/res/layout/notification_2025_template_expanded_media.xml b/core/res/res/layout/notification_2025_template_expanded_media.xml
new file mode 100644
index 000000000000..578a0b2b6d0b
--- /dev/null
+++ b/core/res/res/layout/notification_2025_template_expanded_media.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<!-- Note: This is the expanded version of the old media style notification (different from UMO). -->
+
+<!-- extends FrameLayout -->
+<com.android.internal.widget.MediaNotificationView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/status_bar_latest_event_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:tag="bigMediaNarrow"
+ >
+
+ <include layout="@layout/notification_2025_template_header" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:id="@+id/notification_media_content"
+ >
+
+ <LinearLayout
+ android:id="@+id/notification_main_column"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/notification_content_margin_top"
+ android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+ android:layout_marginEnd="@dimen/notification_content_margin_end"
+ android:orientation="vertical"
+ >
+ <include layout="@layout/notification_template_part_line1"/>
+ <include layout="@layout/notification_template_text"/>
+ </LinearLayout>
+
+ <!-- this FrameLayout's minHeight serves as a padding for the content above -->
+ <FrameLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/notification_2025_media_actions_margin_start"
+ android:minHeight="@dimen/notification_content_margin"
+ >
+
+ <!-- Nesting in FrameLayout is required to ensure that the marginStart actually applies
+ at the start instead of always the left, given that the media_actions LinearLayout
+ has layoutDirection="ltr". -->
+ <LinearLayout
+ android:id="@+id/media_actions"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/media_notification_actions_padding_bottom"
+ android:gravity="top"
+ android:orientation="horizontal"
+ android:layoutDirection="ltr"
+ >
+
+ <include
+ layout="@layout/notification_material_media_action"
+ android:id="@+id/action0"
+ />
+
+ <include
+ layout="@layout/notification_material_media_action"
+ android:id="@+id/action1"
+ />
+
+ <include
+ layout="@layout/notification_material_media_action"
+ android:id="@+id/action2"
+ />
+
+ <include
+ layout="@layout/notification_material_media_action"
+ android:id="@+id/action3"
+ />
+
+ <include
+ layout="@layout/notification_material_media_action"
+ android:id="@+id/action4"
+ />
+ </LinearLayout>
+
+ </FrameLayout>
+
+ </LinearLayout>
+
+ <include layout="@layout/notification_template_right_icon" />
+
+</com.android.internal.widget.MediaNotificationView>
diff --git a/core/res/res/layout/notification_2025_template_expanded_messaging.xml b/core/res/res/layout/notification_2025_template_expanded_messaging.xml
new file mode 100644
index 000000000000..5b5872657a43
--- /dev/null
+++ b/core/res/res/layout/notification_2025_template_expanded_messaging.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<!-- extends FrameLayout -->
+<com.android.internal.widget.MessagingLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/status_bar_latest_event_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipToPadding="false"
+ android:clipChildren="false"
+ android:tag="messaging"
+ >
+
+ <include layout="@layout/notification_2025_template_header"/>
+
+ <com.android.internal.widget.RemeasuringLinearLayout
+ android:id="@+id/notification_action_list_margin_target"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top"
+ android:layout_marginTop="@dimen/notification_content_margin_top"
+ android:clipChildren="false"
+ android:orientation="vertical">
+
+ <com.android.internal.widget.RemeasuringLinearLayout
+ android:id="@+id/notification_main_column"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top"
+ android:layout_weight="1"
+ android:layout_marginEnd="@dimen/notification_content_margin_end"
+ android:orientation="vertical"
+ android:clipChildren="false"
+ >
+ <com.android.internal.widget.MessagingLinearLayout
+ android:id="@+id/notification_messaging"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipChildren="false"
+ android:spacing="@dimen/notification_messaging_spacing" />
+ </com.android.internal.widget.RemeasuringLinearLayout>
+
+ <include layout="@layout/notification_template_smart_reply_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/notification_content_margin"
+ android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+ android:layout_marginEnd="@dimen/notification_content_margin_end" />
+
+ <include layout="@layout/notification_material_action_list" />
+
+ </com.android.internal.widget.RemeasuringLinearLayout>
+
+ <include layout="@layout/notification_template_right_icon" />
+
+</com.android.internal.widget.MessagingLayout>
diff --git a/core/res/res/layout/notification_2025_template_expanded_progress.xml b/core/res/res/layout/notification_2025_template_expanded_progress.xml
new file mode 100644
index 000000000000..afa4bc6dd7f8
--- /dev/null
+++ b/core/res/res/layout/notification_2025_template_expanded_progress.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/status_bar_latest_event_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:clipChildren="false"
+ android:tag="progress"
+ >
+
+ <LinearLayout
+ android:id="@+id/notification_action_list_margin_target"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/notification_content_margin"
+ android:orientation="vertical"
+ >
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_gravity="top"
+ >
+
+ <include layout="@layout/notification_2025_template_header" />
+
+ <LinearLayout
+ android:id="@+id/notification_main_column"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+ android:layout_marginEnd="@dimen/notification_content_margin_end"
+ android:layout_marginTop="@dimen/notification_content_margin_top"
+ android:orientation="vertical"
+ >
+
+ <include layout="@layout/notification_template_part_line1" />
+
+ <include layout="@layout/notification_template_text_multiline" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical"
+ android:layout_marginTop="@dimen/notification_progress_margin_top"
+ android:orientation="horizontal">
+
+ <com.android.internal.widget.CachingIconView
+ android:id="@+id/notification_progress_start_icon"
+ android:layout_width="@dimen/notification_progress_icon_size"
+ android:layout_height="@dimen/notification_progress_icon_size"
+ android:background="@drawable/notification_progress_icon_background"
+ android:clipToOutline="true"
+ android:importantForAccessibility="no"
+ android:layout_marginEnd="@dimen/notification_progress_margin_horizontal"
+ android:scaleType="centerCrop"
+ android:maxDrawableWidth="@dimen/notification_progress_icon_size"
+ android:maxDrawableHeight="@dimen/notification_progress_icon_size"
+ />
+
+
+ <include
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="@dimen/notification_progress_tracker_height"
+ layout="@layout/notification_template_notification_progress_bar"
+ />
+
+ <com.android.internal.widget.CachingIconView
+ android:id="@+id/notification_progress_end_icon"
+ android:layout_width="@dimen/notification_progress_icon_size"
+ android:layout_height="@dimen/notification_progress_icon_size"
+ android:background="@drawable/notification_progress_icon_background"
+ android:clipToOutline="true"
+ android:importantForAccessibility="no"
+ android:scaleType="centerCrop"
+ android:layout_marginStart="@dimen/notification_progress_margin_horizontal"
+ android:maxDrawableWidth="@dimen/notification_progress_icon_size"
+ android:maxDrawableHeight="@dimen/notification_progress_icon_size"
+ />
+ </LinearLayout>
+ </LinearLayout>
+
+ <include layout="@layout/notification_template_right_icon" />
+ </FrameLayout>
+
+ <ViewStub
+ android:layout="@layout/notification_material_reply_text"
+ android:id="@+id/notification_2025_reply_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
+
+ <include
+ layout="@layout/notification_template_smart_reply_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+ android:layout_marginEnd="@dimen/notification_content_margin_end"
+ android:layout_marginTop="@dimen/notification_content_margin"
+ />
+
+ <include layout="@layout/notification_material_action_list" />
+ </LinearLayout>
+</FrameLayout> \ No newline at end of file
diff --git a/core/res/res/layout/side_fps_toast.xml b/core/res/res/layout/side_fps_toast.xml
index 78299ab0ea99..7bb6fcfa2ae0 100644
--- a/core/res/res/layout/side_fps_toast.xml
+++ b/core/res/res/layout/side_fps_toast.xml
@@ -25,7 +25,7 @@
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="6"
- android:paddingBottom="10dp"
+ android:paddingBottom="16dp"
android:text="@string/fp_power_button_enrollment_title"
android:textColor="@color/side_fps_text_color"
android:paddingLeft="20dp"/>
@@ -37,7 +37,7 @@
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="3"
- android:paddingBottom="10dp"
+ android:paddingBottom="16dp"
android:text="@string/fp_power_button_enrollment_button_text"
style="?android:attr/buttonBarNegativeButtonStyle"
android:textColor="@color/side_fps_button_color"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index a4499efae37d..b0545eba0042 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> tot <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Enige kalender"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> demp sekere klanke"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Daar is \'n interne probleem met jou toestel en dit sal dalk onstabiel wees totdat jy \'n fabriekterugstelling doen."</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 225f04d53ad0..e56f79afbe92 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"፣ "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"ከ<xliff:g id="START">%1$s</xliff:g> እስከ <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ማንኛውም ቀን መቁጠሪያ"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> አንዳንድ ድምጾችን እየዘጋ ነው"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"መሣሪያዎ ላይ የውስጣዊ ችግር አለ፣ የፋብሪካ ውሂብ ዳግም እስኪያስጀምሩት ድረስ ላይረጋጋ ይችላል።"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 484d22047fcf..ebffb4da6e50 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1951,6 +1951,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"، "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"من <xliff:g id="START">%1$s</xliff:g> إلى <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"من <xliff:g id="START">%1$s</xliff:g> إلى <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"أي تقويم"</string>
<string name="muted_by" msgid="91464083490094950">"يعمل <xliff:g id="THIRD_PARTY">%1$s</xliff:g> على كتم بعض الأصوات."</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"حدثت مشكلة داخلية في جهازك، وقد لا يستقر وضعه حتى إجراء إعادة الضبط على الإعدادات الأصلية."</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index fdddc70e56d3..f80352ee6c6f 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>ৰ পৰা <xliff:g id="END">%2$s</xliff:g>লৈ"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"যিকোনো কেলেণ্ডাৰ"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>এ কিছুমান ধ্বনি মিউট কৰি আছে"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"আপোনাৰ ডিভাইচত এটা আভ্যন্তৰীণ সমস্যা আছে আৰু আপুনি ফেক্টৰী ডেটা ৰিছেট নকৰালৈকে ই সুস্থিৰভাৱে কাম নকৰিব পাৰে।"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 003c0dbc6f26..57e2ddd41cdf 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"İstənilən təqvim"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> bəzi səsləri səssiz rejimə salır"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Cihazınızın daxili problemi var və istehsalçı sıfırlanması olmayana qədər qeyri-stabil ola bilər."</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 5a848bafc7eb..26ded97f11dc 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1948,6 +1948,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Bilo koji kalendar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> isključuje neke zvuke"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Došlo je do internog problema u vezi sa uređajem i možda će biti nestabilan dok ne obavite resetovanje na fabrička podešavanja."</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index ce98a5ff7473..4d8543731125 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1949,6 +1949,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Любы каляндар"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> выключае некаторыя гукі"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"На вашай прыладзе ўзнікла ўнутраная праблема, і яна можа працаваць нестабільна, пакуль вы не зробіце скід да заводскіх налад."</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index aad5d48f80cd..226447ab7c74 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"От <xliff:g id="START">%1$s</xliff:g> до <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Всички календари"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> заглушава някои звуци"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Възникна вътрешен проблем с устройството ви. То може да е нестабилно, докато не възстановите фабричните настройки."</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index d52f6e91f45b..521b0926e97f 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> থেকে <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"যেকোনও ক্যালেন্ডার"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> কিছু সাউন্ডকে মিউট করে দিচ্ছে"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"আপনার ডিভাইসে একটি অভ্যন্তরীন সমস্যা হয়েছে, এবং আপনি যতক্ষণ না পর্যন্ত এটিকে ফ্যাক্টরি ডেটা রিসেট করছেন ততক্ষণ এটি ঠিকভাবে কাজ নাও করতে পারে৷"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index b74b13966405..e22d838ec000 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -1948,6 +1948,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Bilo koji kalendar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> isključuje neke zvukove"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Postoji problem u vašem uređaju i može biti nestabilan dok ga ne vratite na fabričke postavke."</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 7500122e6d94..6b3c9bf21ea0 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1948,6 +1948,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"De <xliff:g id="START">%1$s</xliff:g> a <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Qualsevol calendari"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> està silenciant alguns sons"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"S\'ha produït un error intern al dispositiu i és possible que funcioni de manera inestable fins que restableixis les dades de fàbrica."</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 277d359e5fd0..b0760fee8506 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1949,6 +1949,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"V libovolném kalendáři"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> vypíná určité zvuky"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"V zařízení došlo k internímu problému. Dokud neprovedete obnovení továrních dat, může být nestabilní."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 9db6076ee6fa..f4fa796268b4 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> til <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Alle kalendere"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> slår nogle lyde fra"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Der er et internt problem med enheden, og den vil muligvis være ustabil, indtil du gendanner fabriksdataene."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 9561b3f8a3c5..5bf7933331f1 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> bis <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Alle Kalender"</string>
<string name="muted_by" msgid="91464083490094950">"Einige Töne werden von <xliff:g id="THIRD_PARTY">%1$s</xliff:g> stummgeschaltet"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Es liegt ein internes Problem mit deinem Gerät vor. Möglicherweise verhält es sich instabil, bis du es auf die Werkseinstellungen zurücksetzt."</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 551fe701e7dd..8289ff77ffb1 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> έως <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Οποιοδήποτε ημερολόγιο"</string>
<string name="muted_by" msgid="91464083490094950">"Το τρίτο μέρος <xliff:g id="THIRD_PARTY">%1$s</xliff:g> θέτει ορισμένους ήχους σε σίγαση"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Υπάρχει ένα εσωτερικό πρόβλημα με τη συσκευή σας και ενδέχεται να είναι ασταθής μέχρι την επαναφορά των εργοστασιακών ρυθμίσεων."</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 5cedb1fa6655..0390acffcd62 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> to <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Any calendar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> is muting some sounds"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index b09a79a63039..5373b1ee5437 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> to <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Any calendar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> is muting some sounds"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 4e728ff0f814..d4bdad02f36e 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> to <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Any calendar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> is muting some sounds"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 578e4795f2b4..3eda31b6fd6d 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> to <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Any calendar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> is muting some sounds"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index da3c4c4c27eb..de3945a90736 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1948,6 +1948,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"De <xliff:g id="START">%1$s</xliff:g> a <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Cualquier calendario"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> silencia algunos sonidos"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Existe un problema interno con el dispositivo, de modo que el dispositivo puede estar inestable hasta que restablezcas la configuración de fábrica."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 37bf70e9bbd1..e9ac320ab888 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1948,6 +1948,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"De <xliff:g id="START">%1$s</xliff:g> a <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Cualquier calendario"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> silencia algunos sonidos"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Se ha producido un problema interno en el dispositivo y es posible que este no sea estable hasta que restablezcas el estado de fábrica."</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 0d79e8aa0333..69a3dd36cdc9 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> kuni <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Mis tahes kalender"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> vaigistab teatud helid"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Seadmes ilmnes sisemine probleem ja seade võib olla ebastabiilne seni, kuni lähtestate seadme tehase andmetele."</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index b96f9eb97c21..e4f4bbd590de 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Edozein egutegi"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> soinu batzuk isilarazten ari da"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Barneko arazo bat dago zure gailuan eta agian ezegonkor egongo da jatorrizko datuak berrezartzen dituzun arte."</string>
@@ -2438,7 +2440,7 @@
<string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Satelite bidezko SOS komunikazioa ez da bateragarria"</string>
<string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Satelite bidezko SOS komunikazioa ez da bateragarria gailu honekin"</string>
<string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Satelite bidezko SOS komunikazioa ez dago konfiguratuta"</string>
- <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Ziurtatu Internetera konektatuta zaudela eta saiatu konfiguratzen berriro"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Ziurtatu Internetera konektatuta zaudela eta saiatu berriro konfiguratzen"</string>
<string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Satelite bidezko SOS komunikazioa ez dago erabilgarri"</string>
<string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Satelite bidezko SOS komunikazioa ez dago erabilgarri herrialde edo lurralde honetan"</string>
<string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Satelite bidezko SOS komunikazioa ez dago konfiguratuta"</string>
@@ -2450,7 +2452,7 @@
<string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Satelite bidezko mezularitza ez da bateragarria"</string>
<string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Satelite bidezko mezularitza ez da bateragarria gailu honekin"</string>
<string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Satelite bidezko mezularitza ez dago konfiguratuta"</string>
- <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Ziurtatu Internetera konektatuta zaudela eta saiatu konfiguratzen berriro"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Ziurtatu Internetera konektatuta zaudela eta saiatu berriro konfiguratzen"</string>
<string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Satelite bidezko mezularitza ez dago erabilgarri"</string>
<string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Satelite bidezko mezularitza ez dago erabilgarri herrialde edo lurralde honetan"</string>
<string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Satelite bidezko mezularitza ez dago konfiguratuta"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 7627ff37d2bc..b87fe90df46c 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"، "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"‫<xliff:g id="START">%1$s</xliff:g> تا <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"هر تقویمی"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> درحال قطع کردن بعضی از صداهاست"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"دستگاهتان یک مشکل داخلی دارد، و ممکن است تا زمانی که بازنشانی داده‌های کارخانه انجام نگیرد، بی‌ثبات بماند."</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 78fb2a07f756..867d32f55586 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Kaikki kalenterit"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> mykistää joitakin ääniä"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Laitteellasi on sisäinen ongelma, joka aiheuttaa epävakautta. Voit korjata tilanteen palauttamalla tehdasasetukset."</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 163d70d49230..3683248e73d7 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1948,6 +1948,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"De <xliff:g id="START">%1$s</xliff:g> à <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"N\'importe quel agenda"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> désactive certains sons"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Un problème interne est survenu avec votre appareil. Il se peut qu\'il soit instable jusqu\'à ce que vous le réinitialisiez à ses paramètres par défaut."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 75b8e3125da0..9f752db403c0 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1948,6 +1948,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"De <xliff:g id="START">%1$s</xliff:g> à <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Tous les agendas"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> coupe certains sons"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Un problème interne lié à votre appareil est survenu. Ce dernier risque d\'être instable jusqu\'à ce que vous rétablissiez la configuration d\'usine."</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 70a7ec9c7a19..766fdbf2802f 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"De <xliff:g id="START">%1$s</xliff:g> a <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Calquera calendario"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> está silenciando algúns sons"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Produciuse un erro interno no teu dispositivo e quizais funcione de maneira inestable ata o restablecemento dos datos de fábrica."</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 1535e4f5d463..ab32a7a3a06b 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>થી <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"કોઈપણ કૅલેન્ડર"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> અમુક અવાજોને મ્યૂટ કરે છે"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"તમારા ઉપકરણમાં આંતરિક સમસ્યા છે અને જ્યાં સુધી તમે ફેક્ટરી ડેટા ફરીથી સેટ કરશો નહીં ત્યાં સુધી તે અસ્થિર રહી શકે છે."</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index c5825fe097db..3a07058e3bdd 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> से <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"किसी भी कैलेंडर के इवेंट के लिए"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> कुछ आवाज़ें म्‍यूट कर रहा है"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"आपके डिवाइस में कोई अंदरूनी समस्या है और यह तब तक ठीक नहीं होगी जब तक आप फ़ैक्‍टरी डेटा रीसेट नहीं करते."</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 954f4cb1842c..010f09970a4e 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1948,6 +1948,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Bilo koji kalendar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> isključuje neke zvukove"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Na vašem uređaju postoji interni problem i možda neće biti stabilan dok ga ne vratite na tvorničko stanje."</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 58a5cbdbc2ab..baace739145a 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Bármilyen naptár"</string>
<string name="muted_by" msgid="91464083490094950">"A(z) <xliff:g id="THIRD_PARTY">%1$s</xliff:g> lenémít néhány hangot"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Belső probléma van az eszközzel, és instabil lehet, amíg vissza nem állítja a gyári adatokat."</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index f457c42d9cd4..e8c6280c5f08 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Ցանկացած օրացույց"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>-ն անջատում է որոշ ձայներ"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Սարքում ներքին խնդիր է առաջացել և այն կարող է կրկնվել, մինչև չվերականգնեք գործարանային կարգավորումները:"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 88764c4112b8..0384ce5e9130 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> hingga <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Kalender mana saja"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> mematikan beberapa suara"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Ada masalah dengan perangkat. Hal ini mungkin membuat perangkat jadi tidak stabil dan perlu dikembalikan ke setelan pabrik."</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 8e92ed1532c1..b63ea1cbea7a 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> til <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Öll dagatöl"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> þaggar í einhverjum hljóðum"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Innra vandamál kom upp í tækinu og það kann að vera óstöðugt þangað til þú núllstillir það."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 49f1f21131e2..43cee8a03b51 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -169,7 +169,7 @@
<string name="scNullCipherIssueActionGotIt" msgid="8747796640866585787">"Ok"</string>
<string name="fcComplete" msgid="1080909484660507044">"Codice funzione completo."</string>
<string name="fcError" msgid="5325116502080221346">"Problema di connessione o codice funzione non valido."</string>
- <string name="httpErrorOk" msgid="6206751415788256357">"OK"</string>
+ <string name="httpErrorOk" msgid="6206751415788256357">"Ok"</string>
<string name="httpError" msgid="3406003584150566720">"Si è verificato un errore di rete."</string>
<string name="httpErrorLookup" msgid="3099834738227549349">"Impossibile trovare l\'URL."</string>
<string name="httpErrorUnsupportedAuthScheme" msgid="3976195595501606787">"Schema di autenticazione del sito non supportato."</string>
@@ -1167,7 +1167,7 @@
<string name="VideoView_error_title" msgid="5750686717225068016">"Problemi video"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3782449246085134720">"Questo video non è valido per lo streaming su questo dispositivo."</string>
<string name="VideoView_error_text_unknown" msgid="7658683339707607138">"Impossibile riprodurre il video."</string>
- <string name="VideoView_error_button" msgid="5138809446603764272">"OK"</string>
+ <string name="VideoView_error_button" msgid="5138809446603764272">"Ok"</string>
<string name="relative_time" msgid="8572030016028033243">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="noon" msgid="8365974533050605886">"mezzogiorno"</string>
<string name="Noon" msgid="6902418443846838189">"Mezzogiorno"</string>
@@ -1206,7 +1206,7 @@
<string name="app_running_notification_text" msgid="5120815883400228566">"Tocca per ulteriori informazioni o per interrompere l\'app."</string>
<string name="ok" msgid="2646370155170753815">"Ok"</string>
<string name="cancel" msgid="6908697720451760115">"Annulla"</string>
- <string name="yes" msgid="9069828999585032361">"OK"</string>
+ <string name="yes" msgid="9069828999585032361">"Ok"</string>
<string name="no" msgid="5122037903299899715">"Annulla"</string>
<string name="dialog_alert_title" msgid="651856561974090712">"Attenzione"</string>
<string name="loading" msgid="3138021523725055037">"Caricamento…"</string>
@@ -1265,7 +1265,7 @@
<string name="anr_activity_process" msgid="3477362583767128667">"L\'app <xliff:g id="ACTIVITY">%1$s</xliff:g> non risponde"</string>
<string name="anr_application_process" msgid="4978772139461676184">"L\'app <xliff:g id="APPLICATION">%1$s</xliff:g> non risponde"</string>
<string name="anr_process" msgid="1664277165911816067">"Il processo <xliff:g id="PROCESS">%1$s</xliff:g> non risponde"</string>
- <string name="force_close" msgid="9035203496368973803">"OK"</string>
+ <string name="force_close" msgid="9035203496368973803">"Ok"</string>
<string name="report" msgid="2149194372340349521">"Segnala"</string>
<string name="wait" msgid="7765985809494033348">"Attendi"</string>
<string name="webpage_unresponsive" msgid="7850879412195273433">"La pagina non risponde più.\n\nVuoi chiuderla?"</string>
@@ -1395,7 +1395,7 @@
<string name="perms_description_app" msgid="2747752389870161996">"Fornito da <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="no_permissions" msgid="5729199278862516390">"Nessuna autorizzazione richiesta"</string>
<string name="perm_costs_money" msgid="749054595022779685">"potrebbe comportare dei costi"</string>
- <string name="dlg_ok" msgid="5103447663504839312">"OK"</string>
+ <string name="dlg_ok" msgid="5103447663504839312">"Ok"</string>
<string name="usb_charging_notification_title" msgid="1674124518282666955">"Dispositivo in carica tramite USB"</string>
<string name="usb_supplying_notification_title" msgid="5378546632408101811">"Dispositivo collegato in carica tramite USB"</string>
<string name="usb_mtp_notification_title" msgid="1065989144124499810">"Trasferimento file tramite USB attivato"</string>
@@ -1892,7 +1892,7 @@
<string name="restr_pin_try_later" msgid="5897719962541636727">"Riprova più tardi"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Visualizzazione a schermo intero"</string>
<string name="immersive_cling_description" msgid="2896205051090870978">"Per uscire, scorri verso il basso dalla parte superiore dello schermo"</string>
- <string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
+ <string name="immersive_cling_positive" msgid="7047498036346489883">"Ok"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Ruota per migliorare l\'anteprima"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Apri <xliff:g id="NAME">%s</xliff:g> a schermo intero per migliorare la visualizzazione"</string>
<string name="done_label" msgid="7283767013231718521">"Fine"</string>
@@ -1914,7 +1914,7 @@
<string name="package_installed_device_owner" msgid="8684974629306529138">"Installato dall\'amministratore.\nVai alle impostazioni per visualizzare le autorizzazioni concesse"</string>
<string name="package_updated_device_owner" msgid="7560272363805506941">"Aggiornato dall\'amministratore"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Eliminato dall\'amministratore"</string>
- <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
+ <string name="confirm_battery_saver" msgid="5247976246208245754">"Ok"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Il risparmio energetico attiva il tema scuro e limita o disattiva l\'attività in background, nonché alcuni effetti visivi, funzionalità e connessioni di rete."</string>
<string name="battery_saver_description" msgid="8518809702138617167">"Il risparmio energetico attiva il tema scuro e limita o disattiva l\'attività in background, nonché alcuni effetti visivi, funzionalità e connessioni di rete."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Per contribuire a ridurre l\'utilizzo dei dati, la funzionalità Risparmio dati impedisce ad alcune app di inviare o ricevere dati in background. Un\'app in uso può accedere ai dati, ma potrebbe farlo con meno frequenza. Per esempio, è possibile che le immagini non vengano visualizzate finché non le tocchi."</string>
@@ -1948,6 +1948,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"Da <xliff:g id="START">%1$s</xliff:g> a <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Qualsiasi calendario"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> sta disattivando alcuni suoni"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Si è verificato un problema interno con il dispositivo, che potrebbe essere instabile fino al ripristino dei dati di fabbrica."</string>
@@ -2150,7 +2152,7 @@
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Questa notifica è stata posizionata più in basso. Tocca per dare un feedback."</string>
<string name="nas_upgrade_notification_title" msgid="8436359459300146555">"Notifiche avanzate"</string>
<string name="nas_upgrade_notification_content" msgid="5157550369837103337">"Ora le risposte e le azioni suggerite vengono fornite dalle notifiche avanzate. Le notifiche adattive Android non sono più supportate."</string>
- <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Ok"</string>
<string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Disattiva"</string>
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Scopri di più"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Le notifiche adattive Android sono state sostituite dalle notifiche avanzate in Android 12. Questa funzionalità mostra risposte e azioni suggerite e organizza le tue notifiche.\n\nLe notifiche avanzate possono accedere ai contenuti di una notifica, incluse le informazioni personali, come i nomi dei contatti e i messaggi. Questa funzionalità può anche ignorare le notifiche o rispondervi, ad esempio accettando le telefonate, e controllare la modalità Non disturbare."</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 0e8f472cb107..0b70b9474310 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1948,6 +1948,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"‫<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"‫<xliff:g id="START">%1$s</xliff:g> עד <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"כל יומן"</string>
<string name="muted_by" msgid="91464083490094950">"חלק מהצלילים מושתקים על ידי <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"קיימת בעיה פנימית במכשיר שלך, וייתכן שהוא לא יתפקד כראוי עד שיבוצע איפוס לנתוני היצרן."</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 6eabd4afaf3d..b6a2b241d50c 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"、 "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>~<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>~<xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"すべてのカレンダー"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> により一部の音はミュートに設定"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"デバイスで内部的な問題が発生しました。データが初期化されるまで不安定になる可能性があります。"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 4ffa312f7c53..1554714570ec 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ნებისმიერი კალენდარი"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ზოგიერთ ხმას ადუმებს"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"ფიქსირდება თქვენი მ ოწყობილობის შიდა პრობლემა და შეიძლება არასტაბილური იყოს, სანამ ქარხნულ მონაცემების არ განაახლებთ."</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 6355d86a8ac9..f2a6b089ca6c 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Кез келген күнтізбе"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> кейбір дыбыстарды өшіруде"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
@@ -2442,9 +2444,9 @@
<string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Satellite SOS функциясы қолжетімді емес"</string>
<string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Satellite SOS функциясы бұл елде немесе аймақта қолжетімді емес."</string>
<string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Satellite SOS функциясы реттелмеген"</string>
- <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Жерсерік арқылы хабар алмасу үшін, Google Messages сіздің әдепкі хабар алмасу қолданбаңыз болуы керек."</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Жерсерік арқылы хабар алмасу үшін Google Messages сіздің әдепкі хабар алмасу қолданбаңыз болуы керек."</string>
<string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Satellite SOS функциясы қолжетімді емес"</string>
- <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Satellite SOS функциясының бұл елде немесе аймақта қолжетімді екенін тексеру үшін, локация параметрлерін қосыңыз."</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Satellite SOS функциясының бұл елде немесе аймақта қолжетімді екенін тексеру үшін локация параметрлерін қосыңыз."</string>
<string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Жерсерік арқылы хабар алмасу функциясы қолжетімді"</string>
<string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Мобильдік немесе Wi-Fi желісі жоқ болған жағдайда, жерсерік арқылы хабар алмаса аласыз. Google Messages сіздің әдепкі хабар алмасу қолданбаңыз болуы керек."</string>
<string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Жерсерік арқылы хабар алмасу функциясына қолдау көрсетілмейді"</string>
@@ -2454,9 +2456,9 @@
<string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Жерсерік арқылы хабар алмасу функциясы қолжетімді емес"</string>
<string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Жерсерік арқылы хабар алмасу функциясы бұл елде немесе аймақта қолжетімді емес."</string>
<string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Жерсерік арқылы хабар алмасу функциясы реттелмеген"</string>
- <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Жерсерік арқылы хабар алмасу үшін, Google Messages сіздің әдепкі хабар алмасу қолданбаңыз болуы керек."</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Жерсерік арқылы хабар алмасу үшін Google Messages сіздің әдепкі хабар алмасу қолданбаңыз болуы керек."</string>
<string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Жерсерік арқылы хабар алмасу функциясы қолжетімді емес"</string>
- <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Жерсерік арқылы хабар алмасу функциясының бұл елде немесе аймақта қолжетімді екенін тексеру үшін, локация параметрлерін қосыңыз."</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Жерсерік арқылы хабар алмасу функциясының бұл елде немесе аймақта қолжетімді екенін тексеру үшін локация параметрлерін қосыңыз."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Саусақ ізімен ашу функциясын қайта реттеу"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> бұдан былай танылмайды."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> және <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> бұдан былай танылмайды."</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 4163be41f7fd..287677ef7c5a 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> ដល់ <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ប្រតិទិនណាមួយ"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> កំពុង​បិទសំឡេង​មួយចំនួន"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"មានបញ្ហាខាងក្នុងឧបករណ៍របស់អ្នក ហើយវាអ្នកមិនមានស្ថេរភាព រហូតទាល់តែអ្នកកំណត់ដូចដើមវិញទាំងស្រុង។"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 234ba66a5bc3..de44b8740376 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -1387,7 +1387,7 @@
<string name="carrier_app_notification_title" msgid="5815477368072060250">"ಹೊಸ ಸಿಮ್ ಸೇರಿಸಲಾಗಿದೆ"</string>
<string name="carrier_app_notification_text" msgid="6567057546341958637">"ಇದನ್ನು ಸ್ಥಾಪಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="time_picker_dialog_title" msgid="9053376764985220821">"ಸಮಯವನ್ನು ಹೊಂದಿಸಿ"</string>
- <string name="date_picker_dialog_title" msgid="5030520449243071926">"ದಿನಾಂಕವನ್ನು ಹೊಂದಿಸಿ"</string>
+ <string name="date_picker_dialog_title" msgid="5030520449243071926">"ದಿನಾಂಕವನ್ನು ಸೆಟ್ ಮಾಡಿ"</string>
<string name="date_time_set" msgid="4603445265164486816">"ಹೊಂದಿಸು"</string>
<string name="date_time_done" msgid="8363155889402873463">"ಆಯಿತು"</string>
<string name="perms_new_perm_prefix" msgid="6984556020395757087"><font size="12" fgcolor="#ff33b5e5">"ಹೊಸ: "</font></string>
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> ನಿಂದ <xliff:g id="END">%2$s</xliff:g> ವರೆಗೆ"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ಯಾವುದೇ ಕ್ಯಾಲೆಂಡರ್"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ಧ್ವನಿ ಮ್ಯೂಟ್ ಮಾಡುತ್ತಿದ್ದಾರೆ"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಆಂತರಿಕ ಸಮಸ್ಯೆಯಿದೆ ಹಾಗೂ ನೀವು ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾವನ್ನು ರೀಸೆಟ್ ಮಾಡುವವರೆಗೂ ಅದು ಅಸ್ಥಿರವಾಗಬಹುದು."</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 59af8fb584ce..7116c6e8c42e 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>~<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>~<xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"모든 캘린더"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>(이)가 일부 소리를 음소거함"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"사용 중인 기기 내부에 문제가 발생했습니다. 초기화할 때까지 불안정할 수 있습니다."</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index cbb0a13963b3..63b5b3991a63 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>, <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Бардык жылнаамалар"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> айрым үндөрдү өчүрүүдө"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Түзмөгүңүздө ички көйгөй бар жана ал баштапкы абалга кайтарылмайынча туруктуу иштебей коюшу мүмкүн."</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 5af4a84c7caf..8a4da89d3a37 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> ຫາ <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ປະ​ຕິ​ທິນ​ໃດ​ກໍໄດ້"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ປິດສຽງບາງຢ່າງໄວ້"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"ມີ​ບັນ​ຫາ​ພາຍ​ໃນ​ກັບ​ອຸ​ປະ​ກອນ​ຂອງ​ທ່ານ, ແລະ​ມັນ​ອາດ​ຈະ​ບໍ່​ສະ​ຖຽນ​ຈົນ​ກວ່າ​ທ່ານ​ຕັ້ງ​ເປັນ​ຂໍ້​ມູນ​ໂຮງ​ງານ​ຄືນ​ແລ້ວ."</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index cb7cc896d42f..e6cc84564301 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1949,6 +1949,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Bet kuris kalendorius"</string>
<string name="muted_by" msgid="91464083490094950">"„<xliff:g id="THIRD_PARTY">%1$s</xliff:g>“ nutildo kai kuriuos garsus"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Iškilo vidinė su jūsų įrenginiu susijusi problema, todėl įrenginys gali veikti nestabiliai, kol neatkursite gamyklinių duomenų."</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index b72fb074ab14..515aaae297de 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1948,6 +1948,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"no <xliff:g id="START">%1$s</xliff:g> līdz <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Jebkurš kalendārs"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> izslēdz noteiktas skaņas"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Jūsu ierīcē ir radusies iekšēja problēma, un ierīce var darboties nestabili. Lai to labotu, veiciet rūpnīcas datu atiestatīšanu."</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 0b0e3ef81cca..1a13752ae5a0 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> до <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Кој било календар"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> исклучи некои звуци"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Настана внатрешен проблем со уредот и може да биде нестабилен сè додека не ресетирате на фабричките податоци."</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index fe5974b3df24..3291e22c8c98 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> മുതൽ <xliff:g id="END">%2$s</xliff:g> വരെ"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"എല്ലാ കലണ്ടറിലും"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ചില ശബ്‌ദങ്ങൾ മ്യൂട്ട് ചെയ്യുന്നു"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"നിങ്ങളുടെ ഉപകരണത്തിൽ ഒരു ആന്തരിക പ്രശ്‌നമുണ്ട്, ഫാക്‌ടറി വിവര പുനഃസജ്ജീകരണം ചെയ്യുന്നതുവരെ ഇതു അസ്ഥിരമായിരിക്കാനിടയുണ്ട്."</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 376a03350b23..f608c23b9a5c 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>-с <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Дурын календарь"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> зарим дууны дууг хааж байна"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Таны төхөөрөмжид дотоод алдаа байна.Та төхөөрөмжөө үйлдвэрээс гарсан төлөвт шилжүүлэх хүртэл таны төхөөрөмж чинь тогтворгүй байж болох юм."</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index e640f729d093..b9c955ee5f49 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> ते <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"कोणतेही कॅलेंडर"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> काही ध्‍वनी म्‍यूट करत आहे"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"आपल्‍या डिव्‍हाइसमध्‍ये अंतर्गत समस्‍या आहे आणि तुमचा फॅक्‍टरी डेटा रीसेट होईपर्यंत ती अस्‍थिर असू शकते."</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 3946ac1df42f..01e070fa1f31 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> hingga <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Sebarang kalendar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> meredamkan sesetengah bunyi"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Terdapat masalah dalaman dengan peranti anda. Peranti mungkin tidak stabil sehingga anda membuat tetapan semula data kilang."</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index fc0072557cb0..e957ea2977d8 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"၊ "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> မှ <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"မည်သည့်ပြက္ခဒိန်မဆို"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> သည် အချို့အသံကို ပိတ်နေသည်"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"သင့်ကိရိယာအတွင်းပိုင်းတွင် ပြဿနာရှိနေပြီး၊ မူလစက်ရုံထုတ်အခြေအနေအဖြစ် ပြန်လည်ရယူနိုင်သည်အထိ အခြေအနေမတည်ငြိမ်နိုင်ပါ။"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index c1095d3978ef..b2eaf959f01d 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> til <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Hvilken som helst kalender"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> slår av noen lyder"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Det har oppstått et internt problem på enheten din, og den kan være ustabil til du tilbakestiller den til fabrikkdata."</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index beda131e3de4..2eee141c099e 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1105,7 +1105,7 @@
<string name="permlab_addVoicemail" msgid="4770245808840814471">"भ्वाइसमेल थप गर्नुहोस्"</string>
<string name="permdesc_addVoicemail" msgid="5470312139820074324">"तपाईँको भ्वाइसमेल इनबक्समा सन्देश थप्नको लागि एपलाई अनुमति दिन्छ।"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ले तपाईंको क्लिपबोर्डमा रहेको जानकारी पेस्ट गरेको छ"</string>
- <string name="more_item_label" msgid="7419249600215749115">"बढी"</string>
+ <string name="more_item_label" msgid="7419249600215749115">"थप"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"मेनु+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
<string name="menu_ctrl_shortcut_label" msgid="131911133027196485">"Ctrl+"</string>
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> देखि <xliff:g id="END">%2$s</xliff:g> सम्म"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"कुनै पनि पात्रो"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ले केही ध्वनिहरू म्युट गर्दै छ"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"तपाईंको यन्त्रसँग आन्तरिक समस्या छ, र तपाईंले फ्याक्ट्री डाटा रिसेट नगर्दासम्म यो अस्थिर रहन्छ।"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 48c8be196bc0..5a452239d1e6 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> tot <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Elke agenda"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> zet sommige geluiden uit"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Er is een intern probleem met je apparaat. Het apparaat kan instabiel zijn totdat u het apparaat terugzet naar de fabrieksinstellingen."</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index a99afa5a0a2f..afcb3d8f072f 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>ରୁ <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ଯେକୌଣସି କ୍ୟାଲେଣ୍ଡର୍‌"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> କିଛି ସାଉଣ୍ଡକୁ ମ୍ୟୁଟ୍ କରୁଛି"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"ଆପଣଙ୍କ ଡିଭାଇସ୍‍ରେ ଏକ ସମସ୍ୟା ରହିଛି ଏବଂ ଆପଣ ଫ୍ୟାକ୍ଟୋରୀ ଡାଟା ରିସେଟ୍‍ ନକରିବା ପର୍ଯ୍ୟନ୍ତ ଏହା ଅସ୍ଥିର ରହିପାରେ।"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index b46301744701..8422b93f8aa1 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> ਤੋਂ <xliff:g id="END">%2$s</xliff:g> ਤੱਕ"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ਕੋਈ ਵੀ ਕੈਲੰਡਰ"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ਕੁਝ ਧੁਨੀਆਂ ਨੂੰ ਮਿਊਟ ਕਰ ਰਹੀ ਹੈ"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨਾਲ ਇੱਕ ਅੰਦਰੂਨੀ ਸਮੱਸਿਆ ਹੈ ਅਤੇ ਇਹ ਅਸਥਿਰ ਹੋ ਸਕਦੀ ਹੈ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈੱਟ ਨਹੀਂ ਕਰਦੇ।"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 4f34fc5ed84e..4eccff5d1688 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1949,6 +1949,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"Od <xliff:g id="START">%1$s</xliff:g> do <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Dowolny kalendarz"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> wycisza niektóre dźwięki"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"W Twoim urządzeniu wystąpił problem wewnętrzny. Może być ono niestabilne, dopóki nie przywrócisz danych fabrycznych."</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index a2192767258a..173be307d973 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1948,6 +1948,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> a <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> a <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Qualquer agenda"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> está silenciando alguns sons"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Há um problema interno com seu dispositivo. Ele pode ficar instável até que você faça a redefinição para configuração original."</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index a898121434e5..605e94e6181d 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1948,6 +1948,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Qualquer calendário"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> está a desativar alguns sons."</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Existe um problema interno no seu dispositivo e pode ficar instável até efetuar uma reposição de dados de fábrica."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index a2192767258a..173be307d973 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1948,6 +1948,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> a <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> a <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Qualquer agenda"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> está silenciando alguns sons"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Há um problema interno com seu dispositivo. Ele pode ficar instável até que você faça a redefinição para configuração original."</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 8b7a29683d8e..b709475a46cd 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1948,6 +1948,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Orice calendar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> dezactivează anumite sunete"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"A apărut o problemă internă pe dispozitiv, iar acesta poate fi instabil până la revenirea la setările din fabrică."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 386830e83e66..b3f75cad48d4 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1949,6 +1949,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Любой календарь"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> приглушает некоторые звуки."</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Произошла внутренняя ошибка, и устройство может работать нестабильно, пока вы не выполните сброс настроек."</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index e969a8ed523f..2dee88c73046 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="END">%2$s</xliff:g> සිට <xliff:g id="START">%1$s</xliff:g> දක්වා"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ඕනෑම දින දර්ශනයක්"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> සමහර ශබ්ද නිහඬ කරමින්"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"ඔබේ උපාංගය සමගින් ගැටලුවක් ඇති අතර, ඔබේ කර්මාන්තශාලා දත්ත යළි සකසන තෙක් එය අස්ථායි විය හැකිය."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index d211d8c481f7..177a55b9e24a 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1949,6 +1949,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Ľubovoľný kalendár"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> vypína niektoré zvuky"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Vo vašom zariadení došlo k internému problému. Môže byť nestabilné, kým neobnovíte jeho výrobné nastavenia."</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index ca854340fc43..28ca6986867b 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1949,6 +1949,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> do <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Kateri koli koledar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> izklaplja nekatere zvoke"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Vaša naprava ima notranjo napako in bo morda nestabilna, dokler je ne ponastavite na tovarniške nastavitve."</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 45cf31a9b0e8..7b4bc795b9bf 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Çdo kalendar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> po çaktivizon disa tinguj"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Ka një problem të brendshëm me pajisjen tënde. Ajo mund të jetë e paqëndrueshme derisa të rivendosësh të dhënat në gjendje fabrike."</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 5a3bae0012bc..fe499c78832f 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1948,6 +1948,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Било који календар"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> искључује неке звуке"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Дошло је до интерног проблема у вези са уређајем и можда ће бити нестабилан док не обавите ресетовање на фабричка подешавања."</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index fde90235e6ee..e037046d990b 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> till <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Alla kalendrar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> stänger av vissa ljud"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Ett internt problem har uppstått i enheten, och det kan hända att problemet kvarstår tills du återställer standardinställningarna."</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 2a62c87d16d9..dde0637f843a 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> hadi <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Kalenda yoyote"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> inazima baadhi ya sauti"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Kuna hitilafu ya ndani ya kifaa chako, na huenda kisiwe thabiti mpaka urejeshe mipangilio ya kiwandani."</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 6ff96c00ea8d..42cf38b0712b 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> முதல் <xliff:g id="END">%2$s</xliff:g> வரை"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ஏதேனும் கேலெண்டர்"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> சில ஒலிகளை முடக்குகிறது"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"சாதனத்தில் அகச் சிக்கல் இருக்கிறது, அதனை ஆரம்பநிலைக்கு மீட்டமைக்கும் வரை நிலையற்று இயங்கலாம்."</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 68fce1f8175a..c867d558f740 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> నుండి <xliff:g id="END">%2$s</xliff:g> వరకు"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ఏదైనా క్యాలెండర్"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> కొన్ని ధ్వనులను మ్యూట్ చేస్తోంది"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"మీ పరికరంతో అంతర్గత సమస్య ఏర్పడింది మరియు మీరు ఫ్యాక్టరీ డేటా రీసెట్ చేసే వరకు అస్థిరంగా ఉంటుంది."</string>
@@ -2442,7 +2444,7 @@
<string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"ఎమర్జెన్సీ శాటిలైట్ సహాయం అందుబాటులో లేదు"</string>
<string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"ఈ దేశంలో లేదా ప్రాంతంలో ఎమర్జెన్సీ శాటిలైట్ సహాయం అందుబాటులో లేదు"</string>
<string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"ఎమర్జెన్సీ శాటిలైట్ సహాయం సెటప్ చేయలేదు"</string>
- <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"శాటిలైట్ ద్వారా మెసేజ్ చేయడానికి, Google Messagesను మీ ఆటోమేటిక్ సెట్టింగ్ మెసేజింగ్ యాప్‌గా సెట్ చేయండి"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"శాటిలైట్ ద్వారా మెసేజ్ చేయడానికి, Google Messagesను మీ ఆటోమేటిక్ మెసేజింగ్ యాప్‌గా సెట్ చేయండి"</string>
<string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"ఎమర్జెన్సీ శాటిలైట్ సహాయం అందుబాటులో లేదు"</string>
<string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"ఈ దేశంలో లేదా ప్రాంతంలో ఎమర్జెన్సీ శాటిలైట్ సహాయం అందుబాటులో ఉందో లేదో చెక్ చేయడానికి, లొకేషన్ సెట్టింగ్‌లను ఆన్ చేయండి"</string>
<string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"శాటిలైట్ మెసేజింగ్ అందుబాటులో ఉంది"</string>
@@ -2454,7 +2456,7 @@
<string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"శాటిలైట్ మెసేజింగ్ అందుబాటులో లేదు"</string>
<string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"ఈ దేశంలో లేదా ప్రాంతంలో శాటిలైట్ మెసేజింగ్ అందుబాటులో లేదు"</string>
<string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"శాటిలైట్ మెసేజింగ్‌ను సెటప్ చేయలేదు"</string>
- <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"శాటిలైట్ ద్వారా మెసేజ్ చేయడానికి, Google Messagesను మీ ఆటోమేటిక్ సెట్టింగ్ మెసేజింగ్ యాప్‌గా సెట్ చేయండి"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"శాటిలైట్ ద్వారా మెసేజ్ చేయడానికి, Google Messagesను మీ ఆటోమేటిక్ మెసేజింగ్ యాప్‌గా సెట్ చేయండి"</string>
<string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"శాటిలైట్ మెసేజింగ్ అందుబాటులో లేదు"</string>
<string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"ఈ దేశంలో లేదా ప్రాంతంలో శాటిలైట్ మెసేజింగ్ అందుబాటులో ఉందో లేదో చెక్ చేయడానికి, లొకేషన్ సెట్టింగ్‌లను ఆన్ చేయండి"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"వేలిముద్ర అన్‌లాక్‌ను మళ్లీ సెటప్ చేయండి"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 178a76d3a404..7af9fb9c8d26 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>ถึง<xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ปฏิทินทั้งหมด"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> กำลังปิดเสียงบางรายการ"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"อุปกรณ์ของคุณเกิดปัญหาภายในเครื่อง อุปกรณ์อาจทำงานไม่เสถียรจนกว่าคุณจะรีเซ็ตข้อมูลเป็นค่าเริ่มต้น"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 8e3c5e7433a7..5de981ca825b 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>, <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> patungong <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Anumang kalendaryo"</string>
<string name="muted_by" msgid="91464083490094950">"Minu-mute ng <xliff:g id="THIRD_PARTY">%1$s</xliff:g> ang ilang tunog"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"May internal na problema sa iyong device, at maaaring hindi ito maging stable hanggang sa i-reset mo ang factory data."</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 98b1dd3ef245..28eb125382e6 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Tüm takvimler"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> bazı sesleri kapatıyor"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Cihazınızla ilgili dahili bir sorun oluştu ve fabrika verilerine sıfırlama işlemi gerçekleştirilene kadar kararsız çalışabilir."</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index d5e6bd81ffcc..ae2cab56a96b 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1949,6 +1949,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"З усіх календарів"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> вимикає деякі звуки"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Через внутрішню помилку ваш пристрій може працювати нестабільно. Відновіть заводські налаштування."</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index b26b1c102abc..6a96bc21be70 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"، "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> تا <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"کوئی بھی کیلنڈر"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> کچھ آوازوں کو خاموش کر رہا ہے"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"آپ کے آلہ میں ایک داخلی مسئلہ ہے اور جب تک آپ فیکٹری ڈیٹا کو دوبارہ ترتیب نہیں دے دیتے ہیں، ہوسکتا ہے کہ یہ غیر مستحکم رہے۔"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 97e044887d7e..42b236aae2e8 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Har qanday taqvim"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ayrim tovushlarni ovozsiz qilgan"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Qurilmangiz bilan bog‘liq ichki muammo mavjud. U zavod sozlamalari tiklanmaguncha barqaror ishlamasligi mumkin."</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 1ebff32f7d20..ae3976333295 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> đến <xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Bất kỳ lịch nào"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> đang tắt một số âm thanh"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Đã xảy ra sự cố nội bộ với thiết bị của bạn và thiết bị có thể sẽ không ổn định cho tới khi bạn thiết lập lại dữ liệu ban đầu."</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 64c2f70be73e..fbab421da8f2 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"、 "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>到<xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"所有日历"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>正在将某些音效设为静音"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"您的设备内部出现了问题。如果不将设备恢复出厂设置,设备运行可能会不稳定。"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 53c5d155cd27..43da71ecf3a0 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"、 "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>至<xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"任何日曆"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>正將某些音效設為靜音"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"你裝置的系統發生問題,回復原廠設定後即可解決該問題。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index cbd6bd2fb48f..628fda71c9d5 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"、 "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>到<xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"任何日曆"</string>
<string name="muted_by" msgid="91464083490094950">"「<xliff:g id="THIRD_PARTY">%1$s</xliff:g>」正在關閉部分音效"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"你的裝置發生內部問題,必須將裝置恢復原廠設定才能解除不穩定狀態。"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index f498fe24267c..878275a8064a 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1947,6 +1947,8 @@
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>, <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"U-<xliff:g id="START">%1$s</xliff:g> ukuya ku-<xliff:g id="END">%2$s</xliff:g>"</string>
+ <!-- no translation found for zen_mode_trigger_summary_combined (6492381546327807669) -->
+ <skip />
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Noma iyiphi ikhalenda"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ithulisa eminye imisindo"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Kukhona inkinga yangaphakathi ngedivayisi yakho, futhi ingase ibe engazinzile kuze kube yilapho usetha kabusha yonke idatha."</string>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index cdf184c9c944..08cb4de03536 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -2572,6 +2572,8 @@
against a development branch, in which case it will only work against
the development builds. -->
<attr name="minSdkVersion" format="integer|string" />
+ <!-- @FlaggedApi(android.content.pm.Flags.FLAG_SUPPORT_MINOR_VERSIONS_IN_MINSDKVERSION) -->
+ <attr name="minSdkVersionFull" format="string" />
<!-- This is the SDK version number that the application is targeting.
It is able to run on older versions (down to minSdkVersion), but
was explicitly tested to work with the version specified here.
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 73d696ba3567..0d13ca83ec59 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2779,6 +2779,9 @@
If empty, logs "other" for all. -->
<string-array name="config_loggable_dream_prefixes"></string-array>
+ <!-- Whether to enable glanceable hub features on this device. -->
+ <bool name="config_glanceableHubEnabled">false</bool>
+
<!-- ComponentName of a dream to show whenever the system would otherwise have
gone to sleep. When the PowerManager is asked to go to sleep, it will instead
try to start this dream if possible. The dream should typically call startDozing()
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index c8df662eed6d..f53acbfac71d 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -255,6 +255,19 @@
This represents 16dp for the left margin + 40dp for the icon + 16dp for the right margin -->
<dimen name="notification_2025_content_margin_start">72dp</dimen>
+ <!-- The margin on the start of the media actions, selected to ensure that action icons which
+ are visually 12x12 in a 24x24 drawable will align correctly with the text. This means that
+ stock media action icons will align, but icons may be visually up to 20x20 and remain in-spec,
+ in which case they will protrude into the start column slightly.
+ 72dp (content margin) - 8dp (media action padding) - 6dp (visual padding within drawable) -->
+ <dimen name="notification_2025_media_actions_margin_start">58dp</dimen>
+
+ <!-- The margin on the start of notification actions (2025 redesign version), to align them to
+ the rest of the notification content. Note that this can be set to 0 if the actions would not
+ fit with it included.
+ 72dp (content margin) - 12dp (action padding) - 4dp (button inset) -->
+ <dimen name="notification_2025_actions_margin_start">56dp</dimen>
+
<!-- The margin on the end of most content views (ignores the expander) -->
<dimen name="notification_content_margin_end">16dp</dimen>
@@ -377,6 +390,9 @@
<!-- the size of the notification close button -->
<dimen name="notification_close_button_size">16dp</dimen>
+ <!-- Margin for all notification content -->
+ <dimen name="notification_2025_margin">16dp</dimen>
+
<!-- Vertical margin for the headerless notification content, when content has 1 line -->
<!-- 16 * 2 (margins) + 24 (1 line) = 56 (notification) -->
<dimen name="notification_headerless_margin_oneline">16dp</dimen>
@@ -388,10 +404,19 @@
<!-- The height of each of the 1 or 2 lines in the headerless notification template -->
<dimen name="notification_headerless_line_height">24dp</dimen>
- <!-- vertical margin for the headerless notification content -->
+ <!-- The minimum height of the notification content (even when there's only one line of text) -->
+ <dimen name="notification_2025_content_min_height">40dp</dimen>
+
+ <!-- Height of a headerless notification with one or two lines -->
+ <!-- 16 * 2 (margins) + 40 (min content height) = 72 (notification) -->
+ <dimen name="notification_2025_min_height">72dp</dimen>
+
+ <!-- Height of a headerless notification with one line -->
+ <!-- 16 * 2 (margins) + 24 (1 line) = 56 (notification) -->
<dimen name="notification_headerless_min_height">56dp</dimen>
- <!-- Height of a small notification in the status bar -->
+ <!-- Height of a small two-line notification -->
+ <!-- 20 * 2 (margins) + 24 * 2 (2 lines) = 88 (notification) -->
<dimen name="notification_min_height">88dp</dimen>
<!-- The width of the big icons in notifications. -->
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index e75371d6bf46..76ff56559adf 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -135,6 +135,8 @@
<public name="pageSizeCompat" />
<!-- @FlaggedApi(android.nfc.Flags.FLAG_NFC_ASSOCIATED_ROLE_SERVICES) -->
<public name="shareRolePriority"/>
+ <!-- @FlaggedApi(android.content.pm.Flags.FLAG_SUPPORT_MINOR_VERSIONS_IN_MINSDKVERSION) -->
+ <public name="minSdkVersionFull"/>
</staging-public-group>
<staging-public-group type="id" first-id="0x01b60000">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 2f82011726ec..748f4b38468b 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2054,6 +2054,7 @@
<java-symbol type="bool" name="config_allowTheaterModeWakeFromDock" />
<java-symbol type="bool" name="config_allowTheaterModeWakeFromWindowLayout" />
<java-symbol type="bool" name="config_keepDreamingWhenUnplugging" />
+ <java-symbol type="bool" name="config_glanceableHubEnabled" />
<java-symbol type="integer" name="config_keyguardDrawnTimeout" />
<java-symbol type="bool" name="config_goToSleepOnButtonPressTheaterMode" />
<java-symbol type="bool" name="config_supportLongPressPowerWhenNonInteractive" />
@@ -2395,6 +2396,12 @@
<java-symbol type="layout" name="notification_2025_template_header" />
<java-symbol type="layout" name="notification_2025_template_collapsed_messaging" />
<java-symbol type="layout" name="notification_2025_template_collapsed_media" />
+ <java-symbol type="layout" name="notification_2025_template_expanded_big_picture" />
+ <java-symbol type="layout" name="notification_2025_template_expanded_inbox" />
+ <java-symbol type="layout" name="notification_2025_template_expanded_media" />
+ <java-symbol type="layout" name="notification_2025_template_expanded_big_text" />
+ <java-symbol type="layout" name="notification_2025_template_expanded_messaging" />
+ <java-symbol type="layout" name="notification_2025_template_expanded_progress" />
<java-symbol type="layout" name="notification_template_material_base" />
<java-symbol type="layout" name="notification_template_material_heads_up_base" />
<java-symbol type="layout" name="notification_template_material_compact_heads_up_base" />
@@ -2406,6 +2413,8 @@
<java-symbol type="layout" name="notification_template_material_big_media" />
<java-symbol type="layout" name="notification_template_material_big_text" />
<java-symbol type="layout" name="notification_template_material_progress" />
+ <java-symbol type="layout" name="notification_template_material_messaging" />
+ <java-symbol type="layout" name="notification_template_material_big_messaging" />
<java-symbol type="layout" name="notification_template_header" />
<java-symbol type="layout" name="notification_material_media_action" />
<java-symbol type="color" name="notification_progress_background_color" />
@@ -3345,8 +3354,6 @@
<java-symbol type="bool" name="config_strongAuthRequiredOnBoot" />
<java-symbol type="layout" name="app_anr_dialog" />
- <java-symbol type="layout" name="notification_template_material_messaging" />
- <java-symbol type="layout" name="notification_template_material_big_messaging" />
<java-symbol type="id" name="aerr_wait" />
@@ -3448,6 +3455,8 @@
<!-- Notifications: CallStyle -->
<java-symbol type="layout" name="notification_template_material_call" />
<java-symbol type="layout" name="notification_template_material_big_call" />
+ <java-symbol type="layout" name="notification_2025_template_collapsed_call" />
+ <java-symbol type="layout" name="notification_2025_template_expanded_call" />
<java-symbol type="string" name="call_notification_answer_action" />
<java-symbol type="string" name="call_notification_answer_video_action" />
<java-symbol type="string" name="call_notification_decline_action" />
@@ -3472,6 +3481,7 @@
<java-symbol type="bool" name="config_supportPreRebootSecurityLogs" />
+ <java-symbol type="dimen" name="notification_2025_actions_margin_start"/>
<java-symbol type="id" name="notification_action_list_margin_target" />
<java-symbol type="dimen" name="notification_actions_padding_start"/>
<java-symbol type="dimen" name="notification_actions_collapsed_priority_width"/>
@@ -4099,6 +4109,7 @@
<java-symbol type="layout" name="notification_template_messaging_text_message" />
<java-symbol type="layout" name="notification_template_messaging_image_message" />
<java-symbol type="layout" name="notification_template_messaging_group" />
+ <java-symbol type="layout" name="notification_2025_messaging_group" />
<java-symbol type="id" name="message_text" />
<java-symbol type="id" name="message_name" />
<java-symbol type="id" name="message_icon" />
@@ -4629,9 +4640,11 @@
<java-symbol type="dimen" name="conversation_icon_container_top_padding" />
<java-symbol type="dimen" name="conversation_icon_container_top_padding_small_avatar" />
<java-symbol type="layout" name="notification_template_material_conversation" />
+ <java-symbol type="layout" name="notification_2025_template_conversation" />
<java-symbol type="dimen" name="button_padding_horizontal_material" />
<java-symbol type="dimen" name="button_inset_horizontal_material" />
<java-symbol type="layout" name="conversation_face_pile_layout" />
+ <java-symbol type="layout" name="notification_2025_conversation_face_pile_layout" />
<java-symbol type="string" name="unread_convo_overflow" />
<java-symbol type="drawable" name="conversation_badge_background" />
<java-symbol type="drawable" name="conversation_badge_ring" />
diff --git a/core/tests/coretests/src/android/app/wallpaper/WallpaperDescriptionTest.java b/core/tests/coretests/src/android/app/wallpaper/WallpaperDescriptionTest.java
index 01c2abf2781b..a22eae3d19d9 100644
--- a/core/tests/coretests/src/android/app/wallpaper/WallpaperDescriptionTest.java
+++ b/core/tests/coretests/src/android/app/wallpaper/WallpaperDescriptionTest.java
@@ -15,13 +15,20 @@
*/
package android.app.wallpaper;
+import static android.app.WallpaperManager.ORIENTATION_LANDSCAPE;
+import static android.app.WallpaperManager.ORIENTATION_PORTRAIT;
+import static android.app.WallpaperManager.ORIENTATION_SQUARE_LANDSCAPE;
+import static android.app.WallpaperManager.ORIENTATION_SQUARE_PORTRAIT;
+
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import android.content.ComponentName;
+import android.graphics.Rect;
import android.net.Uri;
import android.os.Parcel;
import android.os.PersistableBundle;
+import android.util.SparseArray;
import android.util.Xml;
import com.android.modules.utils.TypedXmlPullParser;
@@ -41,17 +48,20 @@ import java.util.List;
@RunWith(JUnit4.class)
public class WallpaperDescriptionTest {
- private static final String TAG = "WallpaperDescriptionTest";
+ private static final Rect DEFAULT_CROP_PORTRAIT = new Rect(1, 2, 3, 4);
+ private static final Rect DEFAULT_CROP_LANDSCAPE = new Rect(5, 6, 7, 8);
+ private static final Rect DEFAULT_CROP_SQUARE_PORTRAIT = new Rect(9, 10, 11, 12);
+ private static final Rect DEFAULT_CROP_SQUARE_LANDSCAPE = new Rect(13, 14, 15, 16);
private final ComponentName mTestComponent = new ComponentName("fakePackage", "fakeClass");
@Test
public void equals_ignoresIrrelevantFields() {
String id = "fakeId";
- WallpaperDescription desc1 = new WallpaperDescription.Builder().setComponent(
- mTestComponent).setId(id).setTitle("fake one").build();
- WallpaperDescription desc2 = new WallpaperDescription.Builder().setComponent(
- mTestComponent).setId(id).setTitle("fake different").build();
+ WallpaperDescription desc1 = new WallpaperDescription.Builder()
+ .setComponent(mTestComponent).setId(id).setTitle("fake one").build();
+ WallpaperDescription desc2 = new WallpaperDescription.Builder()
+ .setComponent(mTestComponent).setId(id).setTitle("fake different").build();
assertThat(desc1).isEqualTo(desc2);
}
@@ -72,13 +82,21 @@ public class WallpaperDescriptionTest {
final Uri thumbnail = Uri.parse("http://www.bogus.com/thumbnail");
final List<CharSequence> description = List.of("line1", "line2");
final Uri contextUri = Uri.parse("http://www.bogus.com/contextUri");
- final PersistableBundle content = new PersistableBundle();
- content.putString("ckey", "cvalue");
+ final PersistableBundle content = makeDefaultContent();
+ final SparseArray<Rect> cropHints = makeDefaultCropHints();
+ final float sampleSize = 0.9f;
WallpaperDescription source = new WallpaperDescription.Builder()
- .setComponent(mTestComponent).setId("fakeId").setThumbnail(thumbnail)
- .setTitle("Fake title").setDescription(description)
- .setContextUri(contextUri).setContextDescription("Context description")
- .setContent(content).build();
+ .setComponent(mTestComponent)
+ .setId("fakeId")
+ .setThumbnail(thumbnail)
+ .setTitle("Fake title")
+ .setDescription(description)
+ .setContextUri(contextUri)
+ .setContextDescription("Context description")
+ .setContent(content)
+ .setCropHints(cropHints)
+ .setSampleSize(sampleSize)
+ .build();
ByteArrayOutputStream ostream = new ByteArrayOutputStream();
TypedXmlSerializer serializer = Xml.newBinarySerializer();
@@ -122,6 +140,57 @@ public class WallpaperDescriptionTest {
assertThat(destination.getContent()).isNotNull();
assertThat(destination.getContent().getString("ckey")).isEqualTo(
source.getContent().getString("ckey"));
+ assertThat(destination.getCropHints()).isNotNull();
+ assertThat(destination.getCropHints().get(ORIENTATION_PORTRAIT)).isEqualTo(
+ DEFAULT_CROP_PORTRAIT);
+ assertThat(destination.getCropHints().get(ORIENTATION_LANDSCAPE)).isEqualTo(
+ DEFAULT_CROP_LANDSCAPE);
+ assertThat(destination.getCropHints().get(ORIENTATION_SQUARE_PORTRAIT)).isEqualTo(
+ DEFAULT_CROP_SQUARE_PORTRAIT);
+ assertThat(destination.getCropHints().get(ORIENTATION_SQUARE_LANDSCAPE)).isEqualTo(
+ DEFAULT_CROP_SQUARE_LANDSCAPE);
+ assertThat(destination.getSampleSize()).isEqualTo(sampleSize);
+ }
+
+ @Test
+ public void xml_roundTripSucceeds_withNulls() throws IOException, XmlPullParserException {
+ WallpaperDescription source = new WallpaperDescription.Builder().build();
+
+ ByteArrayOutputStream ostream = new ByteArrayOutputStream();
+ TypedXmlSerializer serializer = Xml.newBinarySerializer();
+ serializer.setOutput(ostream, StandardCharsets.UTF_8.name());
+ serializer.startDocument(null, true);
+ serializer.startTag(null, "test");
+ source.saveToXml(serializer);
+ serializer.endTag(null, "test");
+ serializer.endDocument();
+ ostream.close();
+
+ WallpaperDescription destination = null;
+ ByteArrayInputStream istream = new ByteArrayInputStream(ostream.toByteArray());
+ TypedXmlPullParser parser = Xml.newBinaryPullParser();
+ parser.setInput(istream, StandardCharsets.UTF_8.name());
+ int type;
+ do {
+ type = parser.next();
+ if (type == XmlPullParser.START_TAG && "test".equals(parser.getName())) {
+ destination = WallpaperDescription.restoreFromXml(parser);
+ }
+ } while (type != XmlPullParser.END_DOCUMENT);
+
+ assertThat(destination).isNotNull();
+ assertThat(destination.getComponent()).isEqualTo(source.getComponent());
+ assertThat(destination.getId()).isEqualTo(source.getId());
+ assertThat(destination.getThumbnail()).isEqualTo(source.getThumbnail());
+ assertThat(destination.getTitle()).isNull();
+ assertThat(destination.getDescription()).hasSize(0);
+ assertThat(destination.getContextUri()).isEqualTo(source.getContextUri());
+ assertThat(destination.getContextDescription()).isNull();
+ assertThat(destination.getContent()).isNotNull();
+ assertThat(destination.getContent().keySet()).isEmpty();
+ assertThat(destination.getCropHints()).isNotNull();
+ assertThat(destination.getCropHints().size()).isEqualTo(0);
+ assertThat(destination.getSampleSize()).isEqualTo(source.getSampleSize());
}
@Test
@@ -129,13 +198,21 @@ public class WallpaperDescriptionTest {
final Uri thumbnail = Uri.parse("http://www.bogus.com/thumbnail");
final List<CharSequence> description = List.of("line1", "line2");
final Uri contextUri = Uri.parse("http://www.bogus.com/contextUri");
- final PersistableBundle content = new PersistableBundle();
- content.putString("ckey", "cvalue");
- WallpaperDescription source = new WallpaperDescription.Builder().setComponent(
- mTestComponent).setId("fakeId").setThumbnail(thumbnail).setTitle(
- "Fake title").setDescription(description).setContextUri(
- contextUri).setContextDescription("Context description").setContent(
- content).build();
+ final PersistableBundle content = makeDefaultContent();
+ final SparseArray<Rect> cropHints = makeDefaultCropHints();
+ final float sampleSize = 0.9f;
+ WallpaperDescription source = new WallpaperDescription.Builder()
+ .setComponent(mTestComponent)
+ .setId("fakeId")
+ .setThumbnail(thumbnail)
+ .setTitle("Fake title")
+ .setDescription(description)
+ .setContextUri(contextUri)
+ .setContextDescription("Context description")
+ .setContent(content)
+ .setCropHints(cropHints)
+ .setSampleSize(sampleSize)
+ .build();
Parcel parcel = Parcel.obtain();
source.writeToParcel(parcel, 0);
@@ -162,6 +239,16 @@ public class WallpaperDescriptionTest {
assertThat(destination.getContent()).isNotNull();
assertThat(destination.getContent().getString("ckey")).isEqualTo(
source.getContent().getString("ckey"));
+ assertThat(destination.getCropHints()).isNotNull();
+ assertThat(destination.getCropHints().get(ORIENTATION_PORTRAIT)).isEqualTo(
+ DEFAULT_CROP_PORTRAIT);
+ assertThat(destination.getCropHints().get(ORIENTATION_LANDSCAPE)).isEqualTo(
+ DEFAULT_CROP_LANDSCAPE);
+ assertThat(destination.getCropHints().get(ORIENTATION_SQUARE_PORTRAIT)).isEqualTo(
+ DEFAULT_CROP_SQUARE_PORTRAIT);
+ assertThat(destination.getCropHints().get(ORIENTATION_SQUARE_LANDSCAPE)).isEqualTo(
+ DEFAULT_CROP_SQUARE_LANDSCAPE);
+ assertThat(destination.getSampleSize()).isEqualTo(sampleSize);
}
@Test
@@ -178,17 +265,14 @@ public class WallpaperDescriptionTest {
assertThat(destination.getId()).isEqualTo(source.getId());
assertThat(destination.getThumbnail()).isEqualTo(source.getThumbnail());
assertThat(destination.getTitle()).isNull();
- assertThat(destination.getDescription()).hasSize(source.getDescription().size());
- for (int i = 0; i < destination.getDescription().size(); i++) {
- CharSequence strDest = destination.getDescription().get(i);
- CharSequence strSrc = source.getDescription().get(i);
- assertWithMessage("description string mismatch")
- .that(CharSequence.compare(strDest, strSrc)).isEqualTo(0);
- }
+ assertThat(destination.getDescription()).hasSize(0);
assertThat(destination.getContextUri()).isEqualTo(source.getContextUri());
assertThat(destination.getContextDescription()).isNull();
assertThat(destination.getContent()).isNotNull();
assertThat(destination.getContent().keySet()).isEmpty();
+ assertThat(destination.getCropHints()).isNotNull();
+ assertThat(destination.getCropHints().size()).isEqualTo(0);
+ assertThat(destination.getSampleSize()).isEqualTo(source.getSampleSize());
}
@Test
@@ -197,14 +281,22 @@ public class WallpaperDescriptionTest {
final Uri thumbnail = Uri.parse("http://www.bogus.com/thumbnail");
final List<CharSequence> description = List.of("line1", "line2");
final Uri contextUri = Uri.parse("http://www.bogus.com/contextUri");
- final PersistableBundle content = new PersistableBundle();
- content.putString("ckey", "cvalue");
+ final PersistableBundle content = makeDefaultContent();
+ final SparseArray<Rect> cropHints = makeDefaultCropHints();
+ final float sampleSize = 1.1f;
final String destinationId = "destinationId";
- WallpaperDescription source = new WallpaperDescription.Builder().setComponent(
- mTestComponent).setId(sourceId).setThumbnail(thumbnail).setTitle(
- "Fake title").setDescription(description).setContextUri(
- contextUri).setContextDescription("Context description").setContent(
- content).build();
+ WallpaperDescription source = new WallpaperDescription.Builder()
+ .setComponent(mTestComponent)
+ .setId(sourceId)
+ .setThumbnail(thumbnail)
+ .setTitle("Fake title")
+ .setDescription(description)
+ .setContextUri(contextUri)
+ .setContextDescription("Context description")
+ .setContent(content)
+ .setCropHints(cropHints)
+ .setSampleSize(sampleSize)
+ .build();
WallpaperDescription destination = source.toBuilder().setId(destinationId).build();
@@ -227,5 +319,29 @@ public class WallpaperDescriptionTest {
assertThat(destination.getContent()).isNotNull();
assertThat(destination.getContent().getString("ckey")).isEqualTo(
source.getContent().getString("ckey"));
+ assertThat(destination.getCropHints().get(ORIENTATION_PORTRAIT)).isEqualTo(
+ DEFAULT_CROP_PORTRAIT);
+ assertThat(destination.getCropHints().get(ORIENTATION_LANDSCAPE)).isEqualTo(
+ DEFAULT_CROP_LANDSCAPE);
+ assertThat(destination.getCropHints().get(ORIENTATION_SQUARE_PORTRAIT)).isEqualTo(
+ DEFAULT_CROP_SQUARE_PORTRAIT);
+ assertThat(destination.getCropHints().get(ORIENTATION_SQUARE_LANDSCAPE)).isEqualTo(
+ DEFAULT_CROP_SQUARE_LANDSCAPE);
+ assertThat(destination.getSampleSize()).isEqualTo(sampleSize);
+ }
+
+ private static PersistableBundle makeDefaultContent() {
+ final PersistableBundle content = new PersistableBundle();
+ content.putString("ckey", "cvalue");
+ return content;
+ }
+
+ private static SparseArray<Rect> makeDefaultCropHints() {
+ final SparseArray<Rect> cropHints = new SparseArray<>();
+ cropHints.put(ORIENTATION_PORTRAIT, DEFAULT_CROP_PORTRAIT);
+ cropHints.put(ORIENTATION_LANDSCAPE, DEFAULT_CROP_LANDSCAPE);
+ cropHints.put(ORIENTATION_SQUARE_PORTRAIT, DEFAULT_CROP_SQUARE_PORTRAIT);
+ cropHints.put(ORIENTATION_SQUARE_LANDSCAPE, DEFAULT_CROP_SQUARE_LANDSCAPE);
+ return cropHints;
}
}
diff --git a/core/tests/coretests/src/android/content/IntentTest.java b/core/tests/coretests/src/android/content/IntentTest.java
index 7bc4abd935b6..fdfb0c34cdeb 100644
--- a/core/tests/coretests/src/android/content/IntentTest.java
+++ b/core/tests/coretests/src/android/content/IntentTest.java
@@ -19,8 +19,9 @@ package android.content;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
-import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
@@ -29,6 +30,7 @@ import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.security.Flags;
+import android.util.ArraySet;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -40,6 +42,7 @@ import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Set;
/**
* Build/Install/Run:
@@ -51,7 +54,6 @@ import java.util.List;
public class IntentTest {
private static final String TEST_ACTION = "android.content.IntentTest_test";
private static final String TEST_EXTRA_NAME = "testExtraName";
- private static final Uri TEST_URI = Uri.parse("content://com.example/people");
@Rule
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
@@ -129,4 +131,111 @@ public class IntentTest {
}
}
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_PREVENT_INTENT_REDIRECT)
+ public void testFillInCreatorTokenInfo() {
+ // case 1: intent does not have creatorTokenInfo; fillinIntent contains creatorTokenInfo
+ Intent intent = new Intent();
+ Intent fillInIntent = new Intent();
+ fillInIntent.setCreatorToken(new Binder());
+ fillInIntent.putExtra("extraKey", new Intent());
+
+ fillInIntent.collectExtraIntentKeys();
+ intent.fillIn(fillInIntent, 0);
+
+ // extra intent keys are merged
+ assertThat(intent.getExtraIntentKeys()).isEqualTo(fillInIntent.getExtraIntentKeys());
+ // but creator token is not overwritten.
+ assertThat(intent.getCreatorToken()).isNull();
+
+
+ // case 2: Both intent and fillInIntent contains creatorToken, intent's creatorToken is not
+ // overwritten.
+ intent = new Intent();
+ IBinder creatorToken = new Binder();
+ intent.setCreatorToken(creatorToken);
+ fillInIntent = new Intent();
+ fillInIntent.setCreatorToken(new Binder());
+
+ intent.fillIn(fillInIntent, 0);
+
+ assertThat(intent.getCreatorToken()).isEqualTo(creatorToken);
+
+
+ // case 3: Contains duplicate extra keys
+ intent = new Intent();
+ intent.putExtra("key1", new Intent());
+ intent.putExtra("key2", new Intent());
+ fillInIntent = new Intent();
+ fillInIntent.putExtra("key1", new Intent());
+ fillInIntent.putExtra("key3", new Intent());
+
+ intent.collectExtraIntentKeys();
+ Set originalIntentKeys = new ArraySet<>(intent.getExtraIntentKeys());
+
+ fillInIntent.collectExtraIntentKeys();
+ intent.fillIn(fillInIntent, 0);
+
+ assertThat(intent.getExtraIntentKeys()).hasSize(3);
+ assertTrue(intent.getExtraIntentKeys().containsAll(originalIntentKeys));
+ assertTrue(intent.getExtraIntentKeys().containsAll(fillInIntent.getExtraIntentKeys()));
+
+
+ // case 4: Both contains a mixture of extras and clip data. NOT force to fill in clip data.
+ intent = new Intent();
+ ClipData clipData = ClipData.newIntent("clip", new Intent());
+ clipData.addItem(new ClipData.Item(new Intent()));
+ intent.setClipData(clipData);
+ intent.putExtra("key1", new Intent());
+ intent.putExtra("key2", new Intent());
+ fillInIntent = new Intent();
+ ClipData fillInClipData = ClipData.newIntent("clip", new Intent());
+ fillInClipData.addItem(new ClipData.Item(new Intent()));
+ fillInClipData.addItem(new ClipData.Item(new Intent()));
+ fillInIntent.setClipData(fillInClipData);
+ fillInIntent.putExtra("key1", new Intent());
+ fillInIntent.putExtra("key3", new Intent());
+
+ intent.collectExtraIntentKeys();
+ originalIntentKeys = new ArraySet<>(intent.getExtraIntentKeys());
+ fillInIntent.collectExtraIntentKeys();
+ intent.fillIn(fillInIntent, 0);
+
+ // size is 5 ( 3 extras merged from both + 2 clip data in the original.
+ assertThat(intent.getExtraIntentKeys()).hasSize(5);
+ // all keys from original are kept.
+ assertTrue(intent.getExtraIntentKeys().containsAll(originalIntentKeys));
+ // Not all keys from fillInIntent are kept - clip data keys are dropped.
+ assertFalse(intent.getExtraIntentKeys().containsAll(fillInIntent.getExtraIntentKeys()));
+
+
+ // case 5: Both contains a mixture of extras and clip data. Force to fill in clip data.
+ intent = new Intent();
+ clipData = ClipData.newIntent("clip", new Intent());
+ clipData.addItem(new ClipData.Item(new Intent()));
+ clipData.addItem(new ClipData.Item(new Intent()));
+ clipData.addItem(new ClipData.Item(new Intent()));
+ intent.setClipData(clipData);
+ intent.putExtra("key1", new Intent());
+ intent.putExtra("key2", new Intent());
+ fillInIntent = new Intent();
+ fillInClipData = ClipData.newIntent("clip", new Intent());
+ fillInClipData.addItem(new ClipData.Item(new Intent()));
+ fillInClipData.addItem(new ClipData.Item(new Intent()));
+ fillInIntent.setClipData(fillInClipData);
+ fillInIntent.putExtra("key1", new Intent());
+ fillInIntent.putExtra("key3", new Intent());
+
+ intent.collectExtraIntentKeys();
+ originalIntentKeys = new ArraySet<>(intent.getExtraIntentKeys());
+ fillInIntent.collectExtraIntentKeys();
+ intent.fillIn(fillInIntent, Intent.FILL_IN_CLIP_DATA);
+
+ // size is 6 ( 3 extras merged from both + 3 clip data in the fillInIntent.
+ assertThat(intent.getExtraIntentKeys()).hasSize(6);
+ // all keys from fillInIntent are kept.
+ assertTrue(intent.getExtraIntentKeys().containsAll(fillInIntent.getExtraIntentKeys()));
+ // Not all keys from intent are kept - clip data keys are dropped.
+ assertFalse(intent.getExtraIntentKeys().containsAll(originalIntentKeys));
+ }
}
diff --git a/core/tests/coretests/src/android/os/BuildTest.java b/core/tests/coretests/src/android/os/BuildTest.java
index e8c701ef2615..2a67716aa215 100644
--- a/core/tests/coretests/src/android/os/BuildTest.java
+++ b/core/tests/coretests/src/android/os/BuildTest.java
@@ -16,8 +16,10 @@
package android.os;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import android.platform.test.flag.junit.SetFlagsRule;
@@ -103,4 +105,99 @@ public class BuildTest {
mSetFlagsRule.disableFlags(Flags.FLAG_ANDROID_OS_BUILD_VANILLA_ICE_CREAM);
assertFalse(Flags.androidOsBuildVanillaIceCream());
}
+
+ @Test
+ public void testParseFullVersionCorrectInputMajorDotMinor() throws Exception {
+ int version = Build.parseFullVersion("12.34");
+ assertEquals(12, Build.getMajorSdkVersion(version));
+ assertEquals(34, Build.getMinorSdkVersion(version));
+ }
+
+ @Test
+ public void testParseFullVersionCorrectInputOmitDotMinor() throws Exception {
+ int version = Build.parseFullVersion("1234");
+ assertEquals(1234, Build.getMajorSdkVersion(version));
+ assertEquals(0, Build.getMinorSdkVersion(version));
+ }
+
+ @Test
+ public void testParseFullVersionCorrectInputCurDevelopment() throws Exception {
+ int version = Build.parseFullVersion(Integer.toString(Build.VERSION_CODES.CUR_DEVELOPMENT));
+ assertEquals(Build.VERSION_CODES.CUR_DEVELOPMENT, Build.getMajorSdkVersion(version));
+ assertEquals(0, Build.getMinorSdkVersion(version));
+ }
+
+ @Test
+ public void testParseFullVersionIncorrectInputEmptyString() throws Exception {
+ assertThrows(IllegalArgumentException.class, () -> {
+ Build.parseFullVersion("");
+ });
+ }
+
+ @Test
+ public void testParseFullVersionIncorrectInputNoNumbersInString() throws Exception {
+ assertThrows(IllegalArgumentException.class, () -> {
+ Build.parseFullVersion("foobar");
+ });
+ }
+
+ @Test
+ public void testParseFullVersionIncorrectInputUnexpectedPatchVersion() throws Exception {
+ assertThrows(IllegalArgumentException.class, () -> {
+ Build.parseFullVersion("1.2.3");
+ });
+ }
+
+ @Test
+ public void testParseFullVersionIncorrectInputLeadingDotMissingMajorVersion() throws Exception {
+ assertThrows(IllegalArgumentException.class, () -> {
+ Build.parseFullVersion(".1234");
+ });
+ }
+
+ @Test
+ public void testParseFullVersionIncorrectInputTrailingDotMissingMinorVersion()
+ throws Exception {
+ assertThrows(IllegalArgumentException.class, () -> {
+ Build.parseFullVersion("1234.");
+ });
+ }
+
+ @Test
+ public void testParseFullVersionIncorrectInputNegativeMajorVersion() throws Exception {
+ assertThrows(IllegalArgumentException.class, () -> {
+ Build.parseFullVersion("-12.34");
+ });
+ }
+
+ @Test
+ public void testParseFullVersionIncorrectInputNegativeMinorVersion() throws Exception {
+ assertThrows(IllegalArgumentException.class, () -> {
+ Build.parseFullVersion("12.-34");
+ });
+ }
+
+ @Test
+ public void testFullVersionToStringCorrectInput() throws Exception {
+ assertEquals("0.0", Build.fullVersionToString(0));
+ assertEquals("1.0", Build.fullVersionToString(1 * 100000 + 0));
+ assertEquals("1.1", Build.fullVersionToString(1 * 100000 + 1));
+ assertEquals("12.34", Build.fullVersionToString(12 * 100000 + 34));
+ }
+
+ @Test
+ public void testFullVersionToStringSameStringAfterRoundTripViaParseFullVersion()
+ throws Exception {
+ String s = "12.34";
+ int major = Build.getMajorSdkVersion(Build.parseFullVersion(s));
+ int minor = Build.getMinorSdkVersion(Build.parseFullVersion(s));
+ assertEquals(s, Build.fullVersionToString(major * 100000 + minor));
+ }
+
+ @Test
+ public void testFullVersionToStringIncorrectInputNegativeVersion() throws Exception {
+ assertThrows(IllegalArgumentException.class, () -> {
+ Build.fullVersionToString(-1);
+ });
+ }
}
diff --git a/core/tests/coretests/src/android/os/MessageQueueTest.java b/core/tests/coretests/src/android/os/MessageQueueTest.java
index 549e66658b85..30f6636766d5 100644
--- a/core/tests/coretests/src/android/os/MessageQueueTest.java
+++ b/core/tests/coretests/src/android/os/MessageQueueTest.java
@@ -26,262 +26,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-@Suppress // Failing.
@RunWith(AndroidJUnit4.class)
public class MessageQueueTest {
- @Rule
- public final RavenwoodRule mRavenwood = new RavenwoodRule();
- private static class BaseTestHandler extends TestHandlerThread {
- Handler mHandler;
- int mLastMessage;
- int mCount;
-
- public BaseTestHandler() {
- }
-
- public void go() {
- mHandler = new Handler() {
- public void handleMessage(Message msg) {
- BaseTestHandler.this.handleMessage(msg);
- }
- };
- }
-
- public void handleMessage(Message msg) {
- if (!msg.isInUse()) {
- failure(new RuntimeException(
- "msg.isInuse is false, should always be true, #" + msg.what));
- }
- if (mCount <= mLastMessage) {
- if (msg.what != mCount) {
- failure(new RuntimeException(
- "Expected message #" + mCount
- + ", received #" + msg.what));
- } else if (mCount == mLastMessage) {
- success();
- }
- mCount++;
- } else {
- failure(new RuntimeException(
- "Message received after done, #" + msg.what));
- }
- }
- }
-
- @Test
- @MediumTest
- public void testMessageOrder() throws Exception {
- TestHandlerThread tester = new BaseTestHandler() {
- public void go() {
- super.go();
- long now = SystemClock.uptimeMillis() + 200;
- mLastMessage = 4;
- mCount = 0;
- mHandler.sendMessageAtTime(mHandler.obtainMessage(2), now + 1);
- mHandler.sendMessageAtTime(mHandler.obtainMessage(3), now + 2);
- mHandler.sendMessageAtTime(mHandler.obtainMessage(4), now + 2);
- mHandler.sendMessageAtTime(mHandler.obtainMessage(0), now + 0);
- mHandler.sendMessageAtTime(mHandler.obtainMessage(1), now + 0);
- }
- };
-
- tester.doTest(1000);
- }
-
- @Test
- @MediumTest
- public void testAtFrontOfQueue() throws Exception {
- TestHandlerThread tester = new BaseTestHandler() {
- public void go() {
- super.go();
- long now = SystemClock.uptimeMillis() + 200;
- mLastMessage = 3;
- mCount = 0;
- mHandler.sendMessageAtTime(mHandler.obtainMessage(3), now);
- mHandler.sendMessageAtFrontOfQueue(mHandler.obtainMessage(2));
- mHandler.sendMessageAtFrontOfQueue(mHandler.obtainMessage(0));
- }
-
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- if (msg.what == 0) {
- mHandler.sendMessageAtFrontOfQueue(mHandler.obtainMessage(1));
- }
- }
- };
-
- tester.doTest(1000);
- }
-
- private static class TestFieldIntegrityHandler extends TestHandlerThread {
- Handler mHandler;
- int mLastMessage;
- int mCount;
-
- public TestFieldIntegrityHandler() {
- }
-
- public void go() {
- mHandler = new Handler() {
- public void handleMessage(Message msg) {
- TestFieldIntegrityHandler.this.handleMessage(msg);
- }
- };
- }
-
- public void handleMessage(Message msg) {
- if (!msg.isInUse()) {
- failure(new RuntimeException(
- "msg.isInuse is false, should always be true, #" + msg.what));
- }
- if (mCount <= mLastMessage) {
- if (msg.what != mCount) {
- failure(new RuntimeException(
- "Expected message #" + mCount
- + ", received #" + msg.what));
- } else if (mCount == mLastMessage) {
- success();
- }
- mCount++;
- } else {
- failure(new RuntimeException(
- "Message received after done, #" + msg.what));
- }
- }
- }
-
- @Test
- @MediumTest
- public void testFieldIntegrity() throws Exception {
-
- TestHandlerThread tester = new TestFieldIntegrityHandler() {
- Bundle mBundle;
-
- public void go() {
- super.go();
- mLastMessage = 1;
- mCount = 0;
- mHandler.sendMessage(mHandler.obtainMessage(0));
- }
-
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- if (msg.what == 0) {
- msg.flags = Message.FLAGS_TO_CLEAR_ON_COPY_FROM;
- msg.what = 1;
- msg.arg1 = 456;
- msg.arg2 = 789;
- msg.obj = this;
- msg.replyTo = null;
- mBundle = new Bundle();
- msg.data = mBundle;
- msg.data.putString("key", "value");
-
- Message newMsg = mHandler.obtainMessage();
- newMsg.copyFrom(msg);
- if (newMsg.isInUse() != false) {
- failure(new RuntimeException(
- "newMsg.isInUse is true should be false after copyFrom"));
- }
- if (newMsg.flags != 0) {
- failure(new RuntimeException(String.format(
- "newMsg.flags is %d should be 0 after copyFrom", newMsg.flags)));
- }
- if (newMsg.what != 1) {
- failure(new RuntimeException(String.format(
- "newMsg.what is %d should be %d after copyFrom", newMsg.what, 1)));
- }
- if (newMsg.arg1 != 456) {
- failure(new RuntimeException(String.format(
- "newMsg.arg1 is %d should be %d after copyFrom", msg.arg1, 456)));
- }
- if (newMsg.arg2 != 789) {
- failure(new RuntimeException(String.format(
- "newMsg.arg2 is %d should be %d after copyFrom", msg.arg2, 789)));
- }
- if (newMsg.obj != this) {
- failure(new RuntimeException(
- "newMsg.obj should be 'this' after copyFrom"));
- }
- if (newMsg.replyTo != null) {
- failure(new RuntimeException(
- "newMsg.replyTo should be null after copyFrom"));
- }
- if (newMsg.data == mBundle) {
- failure(new RuntimeException(
- "newMsg.data should NOT be mBundle after copyFrom"));
- }
- if (!newMsg.data.getString("key").equals(mBundle.getString("key"))) {
- failure(new RuntimeException(String.format(
- "newMsg.data.getString(\"key\") is %s and does not equal" +
- " mBundle.getString(\"key\") which is %s after copyFrom",
- newMsg.data.getString("key"), mBundle.getString("key"))));
- }
- if (newMsg.when != 0) {
- failure(new RuntimeException(String.format(
- "newMsg.when is %d should be 0 after copyFrom", newMsg.when)));
- }
- if (newMsg.target != mHandler) {
- failure(new RuntimeException(
- "newMsg.target is NOT mHandler after copyFrom"));
- }
- if (newMsg.callback != null) {
- failure(new RuntimeException(
- "newMsg.callback is NOT null after copyFrom"));
- }
-
- mHandler.sendMessage(newMsg);
- } else if (msg.what == 1) {
- if (msg.isInUse() != true) {
- failure(new RuntimeException(String.format(
- "msg.isInUse is false should be true after when processing %d",
- msg.what)));
- }
- if (msg.arg1 != 456) {
- failure(new RuntimeException(String.format(
- "msg.arg1 is %d should be %d when processing # %d",
- msg.arg1, 456, msg.what)));
- }
- if (msg.arg2 != 789) {
- failure(new RuntimeException(String.format(
- "msg.arg2 is %d should be %d when processing # %d",
- msg.arg2, 789, msg.what)));
- }
- if (msg.obj != this) {
- failure(new RuntimeException(String.format(
- "msg.obj should be 'this' when processing # %d", msg.what)));
- }
- if (msg.replyTo != null) {
- failure(new RuntimeException(String.format(
- "msg.replyTo should be null when processing # %d", msg.what)));
- }
- if (!msg.data.getString("key").equals(mBundle.getString("key"))) {
- failure(new RuntimeException(String.format(
- "msg.data.getString(\"key\") is %s and does not equal" +
- " mBundle.getString(\"key\") which is %s when processing # %d",
- msg.data.getString("key"), mBundle.getString("key"), msg.what)));
- }
- if (msg.when != 0) {
- failure(new RuntimeException(String.format(
- "msg.when is %d should be 0 when processing # %d",
- msg.when, msg.what)));
- }
- if (msg.target != null) {
- failure(new RuntimeException(String.format(
- "msg.target is NOT null when processing # %d", msg.what)));
- }
- if (msg.callback != null) {
- failure(new RuntimeException(String.format(
- "msg.callback is NOT null when processing # %d", msg.what)));
- }
- } else {
- failure(new RuntimeException(String.format(
- "Unexpected msg.what is %d" + msg.what)));
- }
- }
- };
-
- tester.doTest(1000);
- }
}
diff --git a/core/tests/coretests/src/android/window/OWNERS b/core/tests/coretests/src/android/window/OWNERS
index 6c80cf9e5945..b3fcea2907a1 100644
--- a/core/tests/coretests/src/android/window/OWNERS
+++ b/core/tests/coretests/src/android/window/OWNERS
@@ -1,2 +1,3 @@
include /services/core/java/com/android/server/wm/OWNERS
-charlesccchen@google.com
+
+# Bug component: 1519745 = per-file WindowContext*,WindowMetrics*,WindowProvider*,WindowTokenClient* \ No newline at end of file
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
index f78bc9294357..a6466c58dfda 100644
--- a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
+++ b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
@@ -16,7 +16,6 @@
package com.android.internal.accessibility;
-import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
import static android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN;
import static android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN;
import static android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
@@ -64,7 +63,6 @@ import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
-import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
@@ -423,7 +421,6 @@ public class AccessibilityShortcutControllerTest {
}
@Test
- @EnableFlags(Flags.FLAG_MIGRATE_ENABLE_SHORTCUTS)
public void testClickingDisableButtonInDialog_shouldClearShortcutId() throws Exception {
configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
configureValidShortcutService();
@@ -446,58 +443,6 @@ public class AccessibilityShortcutControllerTest {
}
@Test
- @DisableFlags(Flags.FLAG_MIGRATE_ENABLE_SHORTCUTS)
- public void testClickingDisableButtonInDialog_shouldClearShortcutId_old() throws Exception {
- configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
- configureValidShortcutService();
- Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
- AccessibilityShortcutController.DialogStatus.NOT_SHOWN);
- getController().performAccessibilityShortcut();
-
- ArgumentCaptor<DialogInterface.OnClickListener> captor =
- ArgumentCaptor.forClass(DialogInterface.OnClickListener.class);
- verify(mAlertDialogBuilder).setPositiveButton(eq(R.string.accessibility_shortcut_off),
- captor.capture());
- captor.getValue().onClick(null, DialogInterface.BUTTON_POSITIVE);
-
- assertThat(
- Settings.Secure.getString(mContentResolver, ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)
- ).isEmpty();
- assertThat(Settings.Secure.getInt(
- mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN)).isEqualTo(
- AccessibilityShortcutController.DialogStatus.NOT_SHOWN);
- }
-
- @Test
- @EnableFlags(Flags.FLAG_UPDATE_ALWAYS_ON_A11Y_SERVICE)
- @DisableFlags(Flags.FLAG_MIGRATE_ENABLE_SHORTCUTS)
- public void turnOffVolumeShortcutForAlwaysOnA11yService_shouldTurnOffA11yService()
- throws Exception {
- configureApplicationTargetSdkVersion(Build.VERSION_CODES.R);
- turnOffVolumeKeyShortcutForA11yService(/* alwaysOnService= */ true);
-
- assertThat(
- Settings.Secure.getString(mContentResolver, ENABLED_ACCESSIBILITY_SERVICES)
- ).isEmpty();
- }
-
- @Test
- @EnableFlags(Flags.FLAG_UPDATE_ALWAYS_ON_A11Y_SERVICE)
- @DisableFlags(Flags.FLAG_MIGRATE_ENABLE_SHORTCUTS)
- public void turnOffVolumeShortcutForAlwaysOnA11yService_hasOtherTypesShortcut_shouldNotTurnOffA11yService()
- throws Exception {
- configureApplicationTargetSdkVersion(Build.VERSION_CODES.R);
- Settings.Secure.putString(
- mContentResolver, ACCESSIBILITY_BUTTON_TARGETS, SERVICE_NAME_STRING);
-
- turnOffVolumeKeyShortcutForA11yService(/* alwaysOnService= */ true);
-
- assertThat(
- Settings.Secure.getString(mContentResolver, ENABLED_ACCESSIBILITY_SERVICES)
- ).isEqualTo(SERVICE_NAME_STRING);
- }
-
- @Test
public void turnOffVolumeShortcutForStandardA11yService_shouldNotTurnOffA11yService()
throws Exception {
turnOffVolumeKeyShortcutForA11yService(/* alwaysOnService= */ false);
@@ -530,7 +475,6 @@ public class AccessibilityShortcutControllerTest {
}
@Test
- @EnableFlags(Flags.FLAG_MIGRATE_ENABLE_SHORTCUTS)
public void testTurnOnDefaultA11yServiceInDialog_defaultServiceShortcutTurnsOn()
throws Exception {
configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
@@ -554,30 +498,6 @@ public class AccessibilityShortcutControllerTest {
}
@Test
- @DisableFlags(Flags.FLAG_MIGRATE_ENABLE_SHORTCUTS)
- public void testTurnOnDefaultA11yServiceInDialog_defaultServiceShortcutTurnsOn_old()
- throws Exception {
- configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
- configureDefaultAccessibilityService();
- Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
- AccessibilityShortcutController.DialogStatus.NOT_SHOWN);
- getController().performAccessibilityShortcut();
-
- ArgumentCaptor<DialogInterface.OnClickListener> captor =
- ArgumentCaptor.forClass(DialogInterface.OnClickListener.class);
- verify(mAlertDialogBuilder).setNegativeButton(eq(R.string.accessibility_shortcut_on),
- captor.capture());
- captor.getValue().onClick(null, DialogInterface.BUTTON_NEGATIVE);
-
- assertThat(Settings.Secure.getString(mContentResolver,
- ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)).isEqualTo(SERVICE_NAME_STRING);
- assertThat(Settings.Secure.getInt(
- mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN)).isEqualTo(
- AccessibilityShortcutController.DialogStatus.SHOWN);
- }
-
- @Test
- @EnableFlags(Flags.FLAG_MIGRATE_ENABLE_SHORTCUTS)
public void testTurnOffDefaultA11yServiceInDialog_defaultServiceShortcutTurnsOff()
throws Exception {
configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
@@ -601,29 +521,6 @@ public class AccessibilityShortcutControllerTest {
}
@Test
- @DisableFlags(Flags.FLAG_MIGRATE_ENABLE_SHORTCUTS)
- public void testTurnOffDefaultA11yServiceInDialog_defaultServiceShortcutTurnsOff_old()
- throws Exception {
- configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
- configureDefaultAccessibilityService();
- Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
- AccessibilityShortcutController.DialogStatus.NOT_SHOWN);
- getController().performAccessibilityShortcut();
-
- ArgumentCaptor<DialogInterface.OnClickListener> captor =
- ArgumentCaptor.forClass(DialogInterface.OnClickListener.class);
- verify(mAlertDialogBuilder).setPositiveButton(eq(R.string.accessibility_shortcut_off),
- captor.capture());
- captor.getValue().onClick(null, DialogInterface.BUTTON_POSITIVE);
-
- assertThat(Settings.Secure.getString(mContentResolver,
- ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)).isEmpty();
- assertThat(Settings.Secure.getInt(
- mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN)).isEqualTo(
- AccessibilityShortcutController.DialogStatus.NOT_SHOWN);
- }
-
- @Test
public void testOnAccessibilityShortcut_afterDialogShown_shouldCallServer() throws Exception {
configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
configureValidShortcutService();
@@ -638,9 +535,7 @@ public class AccessibilityShortcutControllerTest {
}
@Test
- @EnableFlags({
- Flags.FLAG_MIGRATE_ENABLE_SHORTCUTS,
- Flags.FLAG_RESTORE_A11Y_SHORTCUT_TARGET_SERVICE})
+ @EnableFlags(Flags.FLAG_RESTORE_A11Y_SHORTCUT_TARGET_SERVICE)
public void testOnAccessibilityShortcut_settingNull_dialogShown_enablesDefaultShortcut()
throws Exception {
configureDefaultAccessibilityService();
@@ -658,24 +553,6 @@ public class AccessibilityShortcutControllerTest {
}
@Test
- @EnableFlags(Flags.FLAG_RESTORE_A11Y_SHORTCUT_TARGET_SERVICE)
- @DisableFlags(Flags.FLAG_MIGRATE_ENABLE_SHORTCUTS)
- public void testOnAccessibilityShortcut_settingNull_dialogShown_writesDefaultSetting()
- throws Exception {
- configureDefaultAccessibilityService();
- Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
- AccessibilityShortcutController.DialogStatus.SHOWN);
- // Setting is only `null` during SUW.
- Settings.Secure.putString(mContentResolver, ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, null);
- getController().performAccessibilityShortcut();
-
- assertThat(Settings.Secure.getString(mContentResolver,
- ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)).isEqualTo(SERVICE_NAME_STRING);
- verify(mAccessibilityManagerService).performAccessibilityShortcut(
- Display.DEFAULT_DISPLAY, HARDWARE, null);
- }
-
- @Test
public void getFrameworkFeatureMap_shouldBeUnmodifiable() {
final Map<ComponentName, AccessibilityShortcutController.FrameworkFeatureInfo>
frameworkFeatureMap =
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/dialog/InvisibleToggleAccessibilityServiceTargetTest.java b/core/tests/coretests/src/com/android/internal/accessibility/dialog/InvisibleToggleAccessibilityServiceTargetTest.java
index 5339d915c8a4..acf7dbcaa5fe 100644
--- a/core/tests/coretests/src/com/android/internal/accessibility/dialog/InvisibleToggleAccessibilityServiceTargetTest.java
+++ b/core/tests/coretests/src/com/android/internal/accessibility/dialog/InvisibleToggleAccessibilityServiceTargetTest.java
@@ -33,12 +33,7 @@ import android.content.pm.ParceledListSlice;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
-import android.platform.test.annotations.DisableFlags;
-import android.platform.test.annotations.EnableFlags;
-import android.platform.test.flag.junit.SetFlagsRule;
-import android.provider.Settings;
import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.Flags;
import android.view.accessibility.IAccessibilityManager;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -68,8 +63,6 @@ import java.util.List;
@RunWith(AndroidJUnit4.class)
public class InvisibleToggleAccessibilityServiceTargetTest {
@Rule
- public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
- @Rule
public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
@Mock
private IAccessibilityManager mAccessibilityManagerService;
@@ -117,7 +110,6 @@ public class InvisibleToggleAccessibilityServiceTargetTest {
}
@Test
- @EnableFlags(Flags.FLAG_MIGRATE_ENABLE_SHORTCUTS)
public void onCheckedChanged_true_callA11yManagerToUpdateShortcuts() throws Exception {
mSut.onCheckedChanged(true);
@@ -130,7 +122,6 @@ public class InvisibleToggleAccessibilityServiceTargetTest {
}
@Test
- @EnableFlags(Flags.FLAG_MIGRATE_ENABLE_SHORTCUTS)
public void onCheckedChanged_false_callA11yManagerToUpdateShortcuts() throws Exception {
mSut.onCheckedChanged(false);
verify(mAccessibilityManagerService).enableShortcutsForTargets(
@@ -140,86 +131,4 @@ public class InvisibleToggleAccessibilityServiceTargetTest {
anyInt());
assertThat(mListCaptor.getValue()).containsExactly(ALWAYS_ON_SERVICE_COMPONENT_NAME);
}
-
- @Test
- @DisableFlags(Flags.FLAG_MIGRATE_ENABLE_SHORTCUTS)
- public void onCheckedChanged_turnOnShortcut_hasOtherShortcut_serviceKeepsOn() {
- enableA11yService(/* enable= */ true);
- addShortcutForA11yService(
- Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, /* add= */ false);
- addShortcutForA11yService(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, /* add= */ true);
-
- mSut.onCheckedChanged(/* isChecked= */ true);
-
- assertA11yServiceState(/* enabled= */ true);
- }
-
- @Test
- @DisableFlags(Flags.FLAG_MIGRATE_ENABLE_SHORTCUTS)
- public void onCheckedChanged_turnOnShortcut_noOtherShortcut_shouldTurnOnService() {
- enableA11yService(/* enable= */ false);
- addShortcutForA11yService(
- Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, /* add= */ false);
- addShortcutForA11yService(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, /* add= */ false);
-
- mSut.onCheckedChanged(/* isChecked= */ true);
-
- assertA11yServiceState(/* enabled= */ true);
- }
-
- @Test
- @DisableFlags(Flags.FLAG_MIGRATE_ENABLE_SHORTCUTS)
- public void onCheckedChanged_turnOffShortcut_hasOtherShortcut_serviceKeepsOn() {
- enableA11yService(/* enable= */ true);
- addShortcutForA11yService(
- Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, /* add= */ true);
- addShortcutForA11yService(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, /* add= */ true);
-
- mSut.onCheckedChanged(/* isChecked= */ false);
-
- assertA11yServiceState(/* enabled= */ true);
- }
-
- @Test
- @DisableFlags(Flags.FLAG_MIGRATE_ENABLE_SHORTCUTS)
- public void onCheckedChanged_turnOffShortcut_noOtherShortcut_shouldTurnOffService() {
- enableA11yService(/* enable= */ true);
- addShortcutForA11yService(
- Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, /* add= */ true);
- addShortcutForA11yService(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, /* add= */ false);
-
- mSut.onCheckedChanged(/* isChecked= */ false);
-
- assertA11yServiceState(/* enabled= */ false);
- }
-
- private void enableA11yService(boolean enable) {
- Settings.Secure.putString(
- mContextSpy.getContentResolver(),
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
- enable ? ALWAYS_ON_SERVICE_COMPONENT_NAME : "");
- }
-
- private void addShortcutForA11yService(String shortcutKey, boolean add) {
- Settings.Secure.putString(
- mContextSpy.getContentResolver(),
- shortcutKey,
- add ? ALWAYS_ON_SERVICE_COMPONENT_NAME : "");
- }
-
- private void assertA11yServiceState(boolean enabled) {
- if (enabled) {
- assertThat(
- Settings.Secure.getString(
- mContextSpy.getContentResolver(),
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES)
- ).contains(ALWAYS_ON_SERVICE_COMPONENT_NAME);
- } else {
- assertThat(
- Settings.Secure.getString(
- mContextSpy.getContentResolver(),
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES)
- ).doesNotContain(ALWAYS_ON_SERVICE_COMPONENT_NAME);
- }
- }
}
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_app_header.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_app_header.xml
index 3dbf7542ac6e..fcf74e3c1936 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_app_header.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_app_header.xml
@@ -46,15 +46,19 @@
<TextView
android:id="@+id/application_name"
android:layout_width="0dp"
- android:layout_height="20dp"
- android:maxWidth="86dp"
+ android:layout_height="wrap_content"
+ android:maxWidth="130dp"
android:textAppearance="@android:style/TextAppearance.Material.Title"
android:textSize="14sp"
android:textFontWeight="500"
- android:lineHeight="20dp"
+ android:lineHeight="20sp"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:layout_marginStart="8dp"
+ android:singleLine="true"
+ android:ellipsize="none"
+ android:requiresFadingEdge="horizontal"
+ android:fadingEdgeLength="28dp"
android:clickable="false"
android:focusable="false"
tools:text="Gmail"/>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index 46ab090e310e..b72d25519e4f 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"إغلاق القائمة"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"فتح القائمة"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"تكبير الشاشة إلى أقصى حدّ"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"تغيير الحجم"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"لا يمكن نقل التطبيق إلى هنا"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"مجسَّم"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"استعادة"</string>
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 10a33bb6aca7..c2d4d8b0613e 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite meni"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otvorite meni"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Povećaj ekran"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Promeni veličinu"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacija ne može da se premesti ovde"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Imerzivne"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Vrati"</string>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index d7da3aef02bb..7e804843dfce 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Затваряне на менюто"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Отваряне на менюто"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Увеличаване на екрана"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Преоразмеряване"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Приложението не може да бъде преместено тук"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Реалистично"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Възстановяване"</string>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index 4249373e0a3d..786ed769e7b7 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Tanca el menú"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Obre el menú"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximitza la pantalla"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Canvia la mida"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"L\'aplicació no es pot moure aquí"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersiu"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaura"</string>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index a12534372135..99e9a8350822 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Zavřít nabídku"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otevřít nabídku"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximalizovat obrazovku"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Změnit velikost"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikaci sem nelze přesunout"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Pohlcující"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Obnovit"</string>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index 85a44f6d760d..879347adf406 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Κλείσιμο μενού"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Άνοιγμα μενού"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Μεγιστοποίηση οθόνης"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Αλλαγή μεγέθους"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Δεν είναι δυνατή η μετακίνηση της εφαρμογής εδώ"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Καθηλωτικό"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Επαναφορά"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index 3e30ff048c6d..358e31476242 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Open menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Resize"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersive"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restore"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index 0d7189bd16b3..923f30b9a5ba 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Close Menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Open Menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximize Screen"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Resize"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersive"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restore"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index 3e30ff048c6d..358e31476242 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Open menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Resize"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersive"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restore"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index 3e30ff048c6d..358e31476242 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Open menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Resize"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersive"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restore"</string>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index 6a1a2e5a4d39..7a2e8cffffcf 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Cerrar menú"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir el menú"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar pantalla"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Cambiar el tamaño"</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-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index f0d1d4e60392..9a15f90ac27e 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Sule menüü"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Ava menüü"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Kuva täisekraanil"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Suuruse muutmine"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Rakendust ei saa siia teisaldada"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Kaasahaarav"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Taasta"</string>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index d10a02d75c18..eb50ba7c9477 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"بستن منو"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"باز کردن منو"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"بزرگ کردن صفحه"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"تغییر اندازه"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"برنامه را نمی‌توان به اینجا منتقل کرد"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"فراگیر"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"بازیابی"</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index 0eab10c34606..696650a11eb9 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"मेन्यू बंद करें"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"मेन्यू खोलें"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"स्क्रीन को बड़ा करें"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"साइज़ बदलें"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ऐप्लिकेशन को यहां मूव नहीं किया जा सकता"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"इमर्सिव"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"वापस लाएं"</string>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index 59a95f0c1393..7266942434c0 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Փակել ընտրացանկը"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Բացել ընտրացանկը"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ծավալել էկրանը"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Փոխել չափը"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Հավելվածը հնարավոր չէ տեղափոխել այստեղ"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Ներկայության էֆեկտով"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Վերականգնել"</string>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index b75c041afdab..8ea5c44006d6 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -79,7 +79,7 @@
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Le nuove conversazioni vengono mostrate come icone mobili o bolle. Tocca per aprire la bolla. Trascinala per spostarla."</string>
<string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"Controlla le bolle quando vuoi"</string>
<string name="bubbles_user_education_manage" msgid="3460756219946517198">"Tocca Gestisci per disattivare le bolle dall\'app"</string>
- <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
+ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Ok"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nessuna bolla recente"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Le bolle recenti e ignorate appariranno qui"</string>
<string name="bubble_bar_education_stack_title" msgid="2486903590422497245">"Chatta utilizzando le bolle"</string>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index 2960a19cef0a..8cc737216af4 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"メニューを閉じる"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"メニューを開く"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"画面の最大化"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"サイズ変更"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"アプリはここに移動できません"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"没入モード"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"復元"</string>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index 9710e69a0418..fab0cb245cfd 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"ປິດເມນູ"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"ເປີດເມນູ"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ປັບຈໍໃຫຍ່ສຸດ"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ປັບຂະໜາດ"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ບໍ່ສາມາດຍ້າຍແອັບມາບ່ອນນີ້ໄດ້"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ສົມຈິງ"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ກູ້ຄືນ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index 7e20ee1fc36b..c2e747c590d8 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"മെനു അടയ്ക്കുക"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"മെനു തുറക്കുക"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"സ്‌ക്രീൻ വലുതാക്കുക"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"വലുപ്പം മാറ്റുക"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ആപ്പ് ഇവിടേക്ക് നീക്കാനാകില്ല"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ഇമേഴ്‌സീവ്"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"പുനഃസ്ഥാപിക്കുക"</string>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index b28b69080051..886ef7936665 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Menu sluiten"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menu openen"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Scherm maximaliseren"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Formaat aanpassen"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Kan de app niet hierheen verplaatsen"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersief"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Herstellen"</string>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index e82916b89033..fa0e7c318f7e 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Zamknij menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otwórz menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksymalizuj ekran"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Zmień rozmiar"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Nie można przenieść aplikacji tutaj"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Tryb immersyjny"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Przywróć"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index e0e91e715ed0..28dc7b0d228e 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar ecrã"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Redimensionar"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Não é possível mover a app para aqui"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Envolvente"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaurar"</string>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index 063e47c80d5f..55452bd0e854 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Zapri meni"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Odpri meni"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimiraj zaslon"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Spremeni velikost"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacije ni mogoče premakniti sem"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Poglobljeno"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Obnovi"</string>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index f74e460226b6..af8ac6898e83 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Затворите мени"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Отворите мени"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Повећај екран"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Промени величину"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Апликација не може да се премести овде"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Имерзивне"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Врати"</string>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index 7a5549eb5f59..0c3c18c70040 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Stäng menyn"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Öppna menyn"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximera skärmen"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Ändra storlek"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Det går inte att flytta appen hit"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Uppslukande"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Återställ"</string>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index fe7556156e78..7be7373e03a9 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"ปิดเมนู"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"เปิดเมนู"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ขยายหน้าจอให้ใหญ่สุด"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ปรับขนาด"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ย้ายแอปมาที่นี่ไม่ได้"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"สมจริง"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"คืนค่า"</string>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index d9fb13bb0b6f..22b0174c0252 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Isara ang Menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Buksan ang Menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"I-maximize ang Screen"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"I-resize"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Hindi mailipat dito ang app"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersive"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"I-restore"</string>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index 3417fef84de5..c64b84373b17 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -133,8 +133,7 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Menyuni yopish"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menyuni ochish"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ekranni yoyish"</string>
- <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Oʻlchamini oʻzgartirish"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Ilova bu yerga surilmaydi"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersiv"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Tiklash"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index e1ecd44eb69f..f3202a120492 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -125,7 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"選取"</string>
<string name="screenshot_text" msgid="1477704010087786671">"螢幕截圖"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"在瀏覽器中開啟"</string>
- <string name="open_in_app_text" msgid="2874590745116268525">"在應用程式中開啟"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"喺應用程式入面打開"</string>
<string name="new_window_text" msgid="6318648868380652280">"新視窗"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"管理視窗"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"變更長寬比"</string>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index b82496e45415..3b53c3fbe03f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -274,8 +274,11 @@ public class BubbleController implements ConfigurationChangeListener,
private final DragAndDropController mDragAndDropController;
/** Used to send bubble events to launcher. */
private Bubbles.BubbleStateListener mBubbleStateListener;
- /** Used to track previous navigation mode to detect switch to buttons navigation. */
- private boolean mIsPrevNavModeGestures;
+ /**
+ * Used to track previous navigation mode to detect switch to buttons navigation. Set to
+ * true to switch the bubble bar to the opposite side for 3 nav buttons mode on device boot.
+ */
+ private boolean mIsPrevNavModeGestures = true;
/** Used to send updates to the views from {@link #mBubbleDataListener}. */
private BubbleViewCallback mBubbleViewCallback;
@@ -357,7 +360,6 @@ public class BubbleController implements ConfigurationChangeListener,
}
};
mExpandedViewManager = BubbleExpandedViewManager.fromBubbleController(this);
- mIsPrevNavModeGestures = ContextUtils.isGestureNavigationMode(mContext);
}
private void registerOneHandedState(OneHandedController oneHanded) {
@@ -593,9 +595,9 @@ public class BubbleController implements ConfigurationChangeListener,
if (mBubbleStateListener != null) {
boolean isCurrentNavModeGestures = ContextUtils.isGestureNavigationMode(mContext);
if (mIsPrevNavModeGestures && !isCurrentNavModeGestures) {
- BubbleBarLocation navButtonsLocation = ContextUtils.isRtl(mContext)
+ BubbleBarLocation bubbleBarLocation = ContextUtils.isRtl(mContext)
? BubbleBarLocation.RIGHT : BubbleBarLocation.LEFT;
- mBubblePositioner.setBubbleBarLocation(navButtonsLocation);
+ mBubblePositioner.setBubbleBarLocation(bubbleBarLocation);
}
mIsPrevNavModeGestures = isCurrentNavModeGestures;
BubbleBarUpdate update = mBubbleData.getInitialStateForBubbleBar();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
index c99d9ba862c1..9d4b4bbb33de 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
@@ -54,6 +54,7 @@ import com.android.wm.shell.compatui.api.CompatUIEvent;
import com.android.wm.shell.compatui.api.CompatUIHandler;
import com.android.wm.shell.compatui.api.CompatUIInfo;
import com.android.wm.shell.compatui.impl.CompatUIEvents.SizeCompatRestartButtonClicked;
+import com.android.wm.shell.desktopmode.DesktopUserRepositories;
import com.android.wm.shell.sysui.KeyguardChangeListener;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
@@ -65,6 +66,7 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
+import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -194,7 +196,7 @@ public class CompatUIController implements OnDisplaysChangedListener,
private final CompatUIStatusManager mCompatUIStatusManager;
@NonNull
- private final IntPredicate mInDesktopModePredicate;
+ private final Optional<DesktopUserRepositories> mDesktopUserRepositories;
public CompatUIController(@NonNull Context context,
@NonNull ShellInit shellInit,
@@ -210,7 +212,7 @@ public class CompatUIController implements OnDisplaysChangedListener,
@NonNull CompatUIShellCommandHandler compatUIShellCommandHandler,
@NonNull AccessibilityManager accessibilityManager,
@NonNull CompatUIStatusManager compatUIStatusManager,
- @NonNull IntPredicate isDesktopModeEnablePredicate) {
+ @NonNull Optional<DesktopUserRepositories> desktopUserRepositories) {
mContext = context;
mShellController = shellController;
mDisplayController = displayController;
@@ -226,7 +228,7 @@ public class CompatUIController implements OnDisplaysChangedListener,
mDisappearTimeSupplier = flags -> accessibilityManager.getRecommendedTimeoutMillis(
DISAPPEAR_DELAY_MS, flags);
mCompatUIStatusManager = compatUIStatusManager;
- mInDesktopModePredicate = isDesktopModeEnablePredicate;
+ mDesktopUserRepositories = desktopUserRepositories;
shellInit.addInitCallback(this::onInit, this);
}
@@ -267,7 +269,6 @@ public class CompatUIController implements OnDisplaysChangedListener,
updateActiveTaskInfo(taskInfo);
}
-
// We're showing the first reachability education so we ignore incoming TaskInfo
// until the education flow has completed or we double tap. The double-tap
// basically cancel all the onboarding flow. We don't have to ignore events in case
@@ -865,7 +866,11 @@ public class CompatUIController implements OnDisplaysChangedListener,
}
private boolean isInDesktopMode(@Nullable TaskInfo taskInfo) {
- return taskInfo != null && Flags.skipCompatUiEducationInDesktopMode()
- && mInDesktopModePredicate.test(taskInfo.displayId);
+ if (mDesktopUserRepositories.isEmpty() || taskInfo == null) {
+ return false;
+ }
+ boolean isDesktopModeShowing = mDesktopUserRepositories.get().getCurrent()
+ .getVisibleTaskCount(taskInfo.displayId) > 0;
+ return Flags.skipCompatUiEducationInDesktopMode() && isDesktopModeShowing;
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxTransitionObserver.kt
index b50716ad07a3..8b830e769c70 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxTransitionObserver.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxTransitionObserver.kt
@@ -22,6 +22,7 @@ import android.view.SurfaceControl
import android.window.TransitionInfo
import com.android.internal.protolog.ProtoLog
import com.android.window.flags.Flags.appCompatRefactoring
+import com.android.wm.shell.common.transition.TransitionStateHolder
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_APP_COMPAT
import com.android.wm.shell.shared.TransitionUtil.isClosingType
import com.android.wm.shell.sysui.ShellInit
@@ -33,7 +34,8 @@ import com.android.wm.shell.transition.Transitions
class LetterboxTransitionObserver(
shellInit: ShellInit,
private val transitions: Transitions,
- private val letterboxController: LetterboxController
+ private val letterboxController: LetterboxController,
+ private val transitionStateHolder: TransitionStateHolder
) : Transitions.TransitionObserver {
companion object {
@@ -71,11 +73,11 @@ class LetterboxTransitionObserver(
change.endAbsBounds.height()
)
with(letterboxController) {
- if (isClosingType(change.mode)) {
- destroyLetterboxSurface(
- key,
- startTransaction
- )
+ // TODO(b/380274087) Handle return to home from a recents transition.
+ if (isClosingType(change.mode) &&
+ !transitionStateHolder.isRecentsTransitionRunning()) {
+ // For the other types of close we need to check the recents.
+ destroyLetterboxSurface(key, finishTransaction)
} else {
val isTopActivityLetterboxed = ti.appCompatTaskInfo.isTopActivityLetterboxed
if (isTopActivityLetterboxed) {
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 cb9c20e9b7ec..47084e17d029 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
@@ -87,8 +87,8 @@ import com.android.wm.shell.compatui.impl.DefaultCompatUIHandler;
import com.android.wm.shell.compatui.impl.DefaultCompatUIRepository;
import com.android.wm.shell.compatui.impl.DefaultComponentIdGenerator;
import com.android.wm.shell.desktopmode.DesktopMode;
-import com.android.wm.shell.desktopmode.DesktopRepository;
import com.android.wm.shell.desktopmode.DesktopTasksController;
+import com.android.wm.shell.desktopmode.DesktopUserRepositories;
import com.android.wm.shell.displayareahelper.DisplayAreaHelper;
import com.android.wm.shell.displayareahelper.DisplayAreaHelperController;
import com.android.wm.shell.freeform.FreeformComponents;
@@ -138,7 +138,6 @@ import dagger.Module;
import dagger.Provides;
import java.util.Optional;
-import java.util.function.IntPredicate;
/**
* Provides basic dependencies from {@link com.android.wm.shell}, these dependencies are only
@@ -267,7 +266,7 @@ public abstract class WMShellBaseModule {
Lazy<CompatUIShellCommandHandler> compatUIShellCommandHandler,
Lazy<AccessibilityManager> accessibilityManager,
CompatUIRepository compatUIRepository,
- Optional<DesktopRepository> desktopRepository,
+ Optional<DesktopUserRepositories> desktopUserRepositories,
@NonNull CompatUIState compatUIState,
@NonNull CompatUIComponentIdGenerator componentIdGenerator,
@NonNull CompatUIComponentFactory compatUIComponentFactory,
@@ -280,10 +279,6 @@ public abstract class WMShellBaseModule {
new DefaultCompatUIHandler(compatUIRepository, compatUIState,
componentIdGenerator, compatUIComponentFactory, mainExecutor));
}
- final IntPredicate inDesktopModePredicate =
- desktopRepository.<IntPredicate>map(modeTaskRepository -> displayId ->
- modeTaskRepository.getVisibleTaskCount(displayId) > 0)
- .orElseGet(() -> displayId -> false);
return Optional.of(
new CompatUIController(
context,
@@ -300,7 +295,7 @@ public abstract class WMShellBaseModule {
compatUIShellCommandHandler.get(),
accessibilityManager.get(),
compatUIStatusManager,
- inDesktopModePredicate));
+ desktopUserRepositories));
}
@WMSingleton
@@ -704,14 +699,14 @@ public abstract class WMShellBaseModule {
ShellCommandHandler shellCommandHandler,
TaskStackListenerImpl taskStackListener,
ActivityTaskManager activityTaskManager,
- Optional<DesktopRepository> desktopRepository,
+ Optional<DesktopUserRepositories> desktopUserRepositories,
TaskStackTransitionObserver taskStackTransitionObserver,
@ShellMainThread ShellExecutor mainExecutor
) {
return Optional.ofNullable(
RecentTasksController.create(context, shellInit, shellController,
shellCommandHandler, taskStackListener, activityTaskManager,
- desktopRepository, taskStackTransitionObserver, mainExecutor));
+ desktopUserRepositories, taskStackTransitionObserver, mainExecutor));
}
@BindsOptionalOf
@@ -1002,16 +997,16 @@ public abstract class WMShellBaseModule {
@BindsOptionalOf
@DynamicOverride
- abstract DesktopRepository optionalDesktopRepository();
+ abstract DesktopUserRepositories optionalDesktopUserRepositories();
@WMSingleton
@Provides
- static Optional<DesktopRepository> provideDesktopRepository(Context context,
- @DynamicOverride Optional<Lazy<DesktopRepository>> desktopRepository) {
+ static Optional<DesktopUserRepositories> provideDesktopUserRepositories(Context context,
+ @DynamicOverride Optional<Lazy<DesktopUserRepositories>> desktopUserRepositories) {
// Use optional-of-lazy for the dependency that this provider relies on.
// Lazy ensures that this provider will not be the cause the dependency is created
// when it will not be returned due to the condition below.
- return desktopRepository.flatMap((lazy) -> {
+ return desktopUserRepositories.flatMap((lazy) -> {
if (DesktopModeStatus.canEnterDesktopMode(context)) {
return Optional.of(lazy.get());
}
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 974535385334..0bf3d9b4515f 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
@@ -68,6 +68,7 @@ import com.android.wm.shell.common.MultiInstanceHelper;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.TaskStackListenerImpl;
+import com.android.wm.shell.common.transition.TransitionStateHolder;
import com.android.wm.shell.compatui.letterbox.LetterboxCommandHandler;
import com.android.wm.shell.compatui.letterbox.LetterboxController;
import com.android.wm.shell.compatui.letterbox.LetterboxTransitionObserver;
@@ -91,6 +92,7 @@ import com.android.wm.shell.desktopmode.DesktopTaskChangeListener;
import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.desktopmode.DesktopTasksLimiter;
import com.android.wm.shell.desktopmode.DesktopTasksTransitionObserver;
+import com.android.wm.shell.desktopmode.DesktopUserRepositories;
import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler;
import com.android.wm.shell.desktopmode.EnterDesktopTaskTransitionHandler;
import com.android.wm.shell.desktopmode.ExitDesktopTaskTransitionHandler;
@@ -150,6 +152,8 @@ import com.android.wm.shell.windowdecor.CaptionWindowDecorViewModel;
import com.android.wm.shell.windowdecor.DesktopModeWindowDecorViewModel;
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer;
+import com.android.wm.shell.windowdecor.common.viewhost.DefaultWindowDecorViewHostSupplier;
+import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHostSupplier;
import com.android.wm.shell.windowdecor.education.DesktopWindowingEducationPromoController;
import com.android.wm.shell.windowdecor.education.DesktopWindowingEducationTooltipController;
import com.android.wm.shell.windowdecor.tiling.DesktopTilingDecorViewModel;
@@ -337,6 +341,13 @@ public abstract class WMShellModule {
return new AdditionalSystemViewContainer.Factory();
}
+ @WMSingleton
+ @Provides
+ static WindowDecorViewHostSupplier provideWindowDecorViewHostSupplier(
+ @ShellMainThread @NonNull CoroutineScope mainScope) {
+ return new DefaultWindowDecorViewHostSupplier(mainScope);
+ }
+
//
// Freeform
//
@@ -362,7 +373,7 @@ public abstract class WMShellModule {
Context context,
ShellInit shellInit,
ShellTaskOrganizer shellTaskOrganizer,
- Optional<DesktopRepository> desktopRepository,
+ Optional<DesktopUserRepositories> desktopUserRepositories,
Optional<DesktopTasksController> desktopTasksController,
LaunchAdjacentController launchAdjacentController,
WindowDecorViewModel windowDecorViewModel,
@@ -374,7 +385,7 @@ public abstract class WMShellModule {
context,
init,
shellTaskOrganizer,
- desktopRepository,
+ desktopUserRepositories,
desktopTasksController,
launchAdjacentController,
windowDecorViewModel,
@@ -690,7 +701,7 @@ public abstract class WMShellModule {
DesktopModeDragAndDropTransitionHandler desktopModeDragAndDropTransitionHandler,
ToggleResizeDesktopTaskTransitionHandler toggleResizeDesktopTaskTransitionHandler,
DragToDesktopTransitionHandler dragToDesktopTransitionHandler,
- @DynamicOverride DesktopRepository desktopRepository,
+ @DynamicOverride DesktopUserRepositories desktopUserRepositories,
Optional<DesktopImmersiveController> desktopImmersiveController,
DesktopModeLoggerTransitionObserver desktopModeLoggerTransitionObserver,
LaunchAdjacentController launchAdjacentController,
@@ -726,7 +737,7 @@ public abstract class WMShellModule {
toggleResizeDesktopTaskTransitionHandler,
dragToDesktopTransitionHandler,
desktopImmersiveController.get(),
- desktopRepository,
+ desktopUserRepositories,
recentsTransitionHandler,
multiInstanceHelper,
mainExecutor,
@@ -749,7 +760,7 @@ public abstract class WMShellModule {
ShellTaskOrganizer shellTaskOrganizer,
ToggleResizeDesktopTaskTransitionHandler toggleResizeDesktopTaskTransitionHandler,
ReturnToDragStartAnimator returnToDragStartAnimator,
- @DynamicOverride DesktopRepository desktopRepository,
+ @DynamicOverride DesktopUserRepositories desktopUserRepositories,
DesktopModeEventLogger desktopModeEventLogger) {
return new DesktopTilingDecorViewModel(
context,
@@ -760,7 +771,7 @@ public abstract class WMShellModule {
shellTaskOrganizer,
toggleResizeDesktopTaskTransitionHandler,
returnToDragStartAnimator,
- desktopRepository,
+ desktopUserRepositories,
desktopModeEventLogger
);
}
@@ -768,10 +779,10 @@ public abstract class WMShellModule {
@WMSingleton
@Provides
static Optional<TaskChangeListener> provideDesktopTaskChangeListener(
- Context context, @DynamicOverride DesktopRepository desktopRepository) {
+ Context context, @DynamicOverride DesktopUserRepositories desktopUserRepositories) {
if (ENABLE_WINDOWING_TRANSITION_HANDLERS_OBSERVERS.isTrue()
&& DesktopModeStatus.canEnterDesktopMode(context)) {
- return Optional.of(new DesktopTaskChangeListener(desktopRepository));
+ return Optional.of(new DesktopTaskChangeListener(desktopUserRepositories));
}
return Optional.empty();
}
@@ -781,7 +792,7 @@ public abstract class WMShellModule {
static Optional<DesktopTasksLimiter> provideDesktopTasksLimiter(
Context context,
Transitions transitions,
- @DynamicOverride DesktopRepository desktopRepository,
+ @DynamicOverride DesktopUserRepositories desktopUserRepositories,
ShellTaskOrganizer shellTaskOrganizer,
InteractionJankMonitor interactionJankMonitor,
@ShellMainThread Handler handler) {
@@ -794,7 +805,7 @@ public abstract class WMShellModule {
return Optional.of(
new DesktopTasksLimiter(
transitions,
- desktopRepository,
+ desktopUserRepositories,
shellTaskOrganizer,
maxTaskLimit,
interactionJankMonitor,
@@ -808,7 +819,7 @@ public abstract class WMShellModule {
Context context,
ShellInit shellInit,
Transitions transitions,
- @DynamicOverride DesktopRepository desktopRepository,
+ @DynamicOverride DesktopUserRepositories desktopUserRepositories,
DisplayController displayController,
ShellTaskOrganizer shellTaskOrganizer,
ShellCommandHandler shellCommandHandler) {
@@ -817,7 +828,7 @@ public abstract class WMShellModule {
new DesktopImmersiveController(
shellInit,
transitions,
- desktopRepository,
+ desktopUserRepositories,
displayController,
shellTaskOrganizer,
shellCommandHandler));
@@ -856,14 +867,16 @@ public abstract class WMShellModule {
InputManager inputManager,
ShellTaskOrganizer shellTaskOrganizer,
FocusTransitionObserver focusTransitionObserver,
- @ShellMainThread ShellExecutor mainExecutor) {
+ @ShellMainThread ShellExecutor mainExecutor,
+ DisplayController displayController) {
if (DesktopModeStatus.canEnterDesktopMode(context) && useKeyGestureEventHandler()
&& manageKeyGestures()
&& (Flags.enableMoveToNextDisplayShortcut()
|| Flags.enableTaskResizingKeyboardShortcuts())) {
return Optional.of(new DesktopModeKeyGestureHandler(context,
desktopModeWindowDecorViewModel, desktopTasksController,
- inputManager, shellTaskOrganizer, focusTransitionObserver, mainExecutor));
+ inputManager, shellTaskOrganizer, focusTransitionObserver,
+ mainExecutor, displayController));
}
return Optional.empty();
}
@@ -880,7 +893,7 @@ public abstract class WMShellModule {
ShellCommandHandler shellCommandHandler,
IWindowManager windowManager,
ShellTaskOrganizer taskOrganizer,
- @DynamicOverride DesktopRepository desktopRepository,
+ @DynamicOverride DesktopUserRepositories desktopUserRepositories,
DisplayController displayController,
ShellController shellController,
DisplayInsetsController displayInsetsController,
@@ -907,7 +920,7 @@ public abstract class WMShellModule {
}
return Optional.of(new DesktopModeWindowDecorViewModel(context, shellExecutor, mainHandler,
mainChoreographer, bgExecutor, shellInit, shellCommandHandler, windowManager,
- taskOrganizer, desktopRepository, displayController, shellController,
+ taskOrganizer, desktopUserRepositories, displayController, shellController,
displayInsetsController, syncQueue, transitions, desktopTasksController,
desktopImmersiveController.get(),
rootTaskDisplayAreaOrganizer, interactionJankMonitor, genericLinksParser,
@@ -925,7 +938,7 @@ public abstract class WMShellModule {
@ShellAnimationThread ShellExecutor animExecutor,
ShellInit shellInit,
Transitions transitions,
- @DynamicOverride DesktopRepository desktopRepository) {
+ @DynamicOverride DesktopUserRepositories desktopUserRepositories) {
if (!DesktopModeStatus.canEnterDesktopMode(context)
|| !ENABLE_DESKTOP_WINDOWING_MODALS_POLICY.isTrue()
|| !Flags.enableDesktopSystemDialogsTransitions()) {
@@ -934,7 +947,7 @@ public abstract class WMShellModule {
return Optional.of(
new SystemModalsTransitionHandler(
context, mainExecutor, animExecutor, shellInit, transitions,
- desktopRepository));
+ desktopUserRepositories));
}
@WMSingleton
@@ -993,16 +1006,17 @@ public abstract class WMShellModule {
@WMSingleton
@Provides
@DynamicOverride
- static DesktopRepository provideDesktopRepository(
+ static DesktopUserRepositories provideDesktopUserRepositories(
Context context,
ShellInit shellInit,
DesktopPersistentRepository desktopPersistentRepository,
DesktopRepositoryInitializer desktopRepositoryInitializer,
- @ShellMainThread CoroutineScope mainScope
+ @ShellMainThread CoroutineScope mainScope,
+ UserManager userManager
) {
- return new DesktopRepository(context, shellInit, desktopPersistentRepository,
+ return new DesktopUserRepositories(context, shellInit, desktopPersistentRepository,
desktopRepositoryInitializer,
- mainScope);
+ mainScope, userManager);
}
@WMSingleton
@@ -1013,7 +1027,7 @@ public abstract class WMShellModule {
ShellTaskOrganizer shellTaskOrganizer,
TaskStackListenerImpl taskStackListener,
ToggleResizeDesktopTaskTransitionHandler toggleResizeDesktopTaskTransitionHandler,
- @DynamicOverride DesktopRepository desktopRepository) {
+ @DynamicOverride DesktopUserRepositories desktopUserRepositories) {
if (DesktopModeStatus.canEnterDesktopMode(context)) {
return Optional.of(
new DesktopActivityOrientationChangeHandler(
@@ -1022,7 +1036,7 @@ public abstract class WMShellModule {
shellTaskOrganizer,
taskStackListener,
toggleResizeDesktopTaskTransitionHandler,
- desktopRepository));
+ desktopUserRepositories));
}
return Optional.empty();
}
@@ -1031,12 +1045,12 @@ public abstract class WMShellModule {
@Provides
static Optional<DesktopTasksTransitionObserver> provideDesktopTasksTransitionObserver(
Context context,
- Optional<DesktopRepository> desktopRepository,
+ Optional<DesktopUserRepositories> desktopUserRepositories,
Transitions transitions,
ShellTaskOrganizer shellTaskOrganizer,
Optional<DesktopMixedTransitionHandler> desktopMixedTransitionHandler,
ShellInit shellInit) {
- return desktopRepository.flatMap(
+ return desktopUserRepositories.flatMap(
repository ->
Optional.of(
new DesktopTasksTransitionObserver(
@@ -1053,7 +1067,7 @@ public abstract class WMShellModule {
static Optional<DesktopMixedTransitionHandler> provideDesktopMixedTransitionHandler(
Context context,
Transitions transitions,
- @DynamicOverride DesktopRepository desktopRepository,
+ @DynamicOverride DesktopUserRepositories desktopUserRepositories,
FreeformTaskTransitionHandler freeformTaskTransitionHandler,
CloseDesktopTaskTransitionHandler closeDesktopTaskTransitionHandler,
Optional<DesktopImmersiveController> desktopImmersiveController,
@@ -1071,7 +1085,7 @@ public abstract class WMShellModule {
new DesktopMixedTransitionHandler(
context,
transitions,
- desktopRepository,
+ desktopUserRepositories,
freeformTaskTransitionHandler,
closeDesktopTaskTransitionHandler,
desktopImmersiveController.get(),
@@ -1316,9 +1330,11 @@ public abstract class WMShellModule {
static LetterboxTransitionObserver provideLetterboxTransitionObserver(
@NonNull ShellInit shellInit,
@NonNull Transitions transitions,
- @NonNull LetterboxController letterboxController
+ @NonNull LetterboxController letterboxController,
+ @NonNull TransitionStateHolder transitionStateHolder
) {
- return new LetterboxTransitionObserver(shellInit, transitions, letterboxController);
+ return new LetterboxTransitionObserver(shellInit, transitions, letterboxController,
+ transitionStateHolder);
}
@WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java
index 3cd5df3121c1..cfdfe3d52011 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java
@@ -42,7 +42,7 @@ import com.android.wm.shell.common.pip.PipUiEventLogger;
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.DesktopRepository;
+import com.android.wm.shell.desktopmode.DesktopUserRepositories;
import com.android.wm.shell.onehanded.OneHandedController;
import com.android.wm.shell.pip.PipAnimationController;
import com.android.wm.shell.pip.PipParamsChangedForwarder;
@@ -171,7 +171,7 @@ public abstract class Pip1Module {
PipParamsChangedForwarder pipParamsChangedForwarder,
Optional<SplitScreenController> splitScreenControllerOptional,
Optional<PipPerfHintController> pipPerfHintControllerOptional,
- Optional<DesktopRepository> desktopRepositoryOptional,
+ Optional<DesktopUserRepositories> desktopUserRepositoriesOptional,
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
DisplayController displayController,
PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer,
@@ -181,7 +181,7 @@ public abstract class Pip1Module {
pipBoundsAlgorithm, menuPhoneController, pipAnimationController,
pipSurfaceTransactionHelper, pipTransitionController, pipParamsChangedForwarder,
splitScreenControllerOptional, pipPerfHintControllerOptional,
- desktopRepositoryOptional, rootTaskDisplayAreaOrganizer, displayController,
+ desktopUserRepositoriesOptional, rootTaskDisplayAreaOrganizer, displayController,
pipUiEventLogger, shellTaskOrganizer, mainExecutor);
}
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 3508ecee6d51..3a9961917f79 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.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayInsetsController;
@@ -38,6 +39,7 @@ import com.android.wm.shell.common.pip.PipUtils;
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.pip2.phone.PhonePipMenuController;
import com.android.wm.shell.pip2.phone.PipController;
import com.android.wm.shell.pip2.phone.PipMotionHelper;
@@ -128,8 +130,11 @@ public abstract class Pip2Module {
static PipScheduler providePipScheduler(Context context,
PipBoundsState pipBoundsState,
@ShellMainThread ShellExecutor mainExecutor,
- PipTransitionState pipTransitionState) {
- return new PipScheduler(context, pipBoundsState, mainExecutor, pipTransitionState);
+ PipTransitionState pipTransitionState,
+ Optional<DesktopUserRepositories> desktopUserRepositoriesOptional,
+ RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) {
+ return new PipScheduler(context, pipBoundsState, mainExecutor, pipTransitionState,
+ desktopUserRepositoriesOptional, rootTaskDisplayAreaOrganizer);
}
@WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandler.kt
index 606aa6cd3353..c0bf40b9c461 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandler.kt
@@ -39,7 +39,7 @@ class DesktopActivityOrientationChangeHandler(
private val shellTaskOrganizer: ShellTaskOrganizer,
private val taskStackListener: TaskStackListenerImpl,
private val resizeHandler: ToggleResizeDesktopTaskTransitionHandler,
- private val taskRepository: DesktopRepository,
+ private val desktopUserRepositories: DesktopUserRepositories,
) {
init {
@@ -81,7 +81,9 @@ class DesktopActivityOrientationChangeHandler(
) {
if (!Flags.respectOrientationChangeForUnresizeable()) return
val task = shellTaskOrganizer.getRunningTaskInfo(taskId) ?: return
- if (!isDesktopModeShowing(task.displayId) || !task.isFreeform || task.isResizeable) return
+ val taskRepository = desktopUserRepositories.current
+ val isDesktopModeShowing = taskRepository.getVisibleTaskCount(task.displayId) > 0
+ if (!isDesktopModeShowing || !task.isFreeform || task.isResizeable) return
val taskBounds = task.configuration.windowConfiguration.bounds
val taskHeight = taskBounds.height()
@@ -106,7 +108,4 @@ class DesktopActivityOrientationChangeHandler(
resizeHandler.startTransition(wct)
}
}
-
- private fun isDesktopModeShowing(displayId: Int): Boolean =
- taskRepository.getVisibleTaskCount(displayId) > 0
} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt
index dd95273dd4f3..79be698773da 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt
@@ -50,7 +50,7 @@ import java.io.PrintWriter
class DesktopImmersiveController(
shellInit: ShellInit,
private val transitions: Transitions,
- private val desktopRepository: DesktopRepository,
+ private val desktopUserRepositories: DesktopUserRepositories,
private val displayController: DisplayController,
private val shellTaskOrganizer: ShellTaskOrganizer,
private val shellCommandHandler: ShellCommandHandler,
@@ -60,14 +60,14 @@ class DesktopImmersiveController(
constructor(
shellInit: ShellInit,
transitions: Transitions,
- desktopRepository: DesktopRepository,
+ desktopUserRepositories: DesktopUserRepositories,
displayController: DisplayController,
shellTaskOrganizer: ShellTaskOrganizer,
shellCommandHandler: ShellCommandHandler,
) : this(
shellInit,
transitions,
- desktopRepository,
+ desktopUserRepositories,
displayController,
shellTaskOrganizer,
shellCommandHandler,
@@ -177,8 +177,9 @@ class DesktopImmersiveController(
reason: ExitReason,
): ExitResult {
if (!Flags.enableFullyImmersiveInDesktop()) return ExitResult.NoExit
- val immersiveTask = desktopRepository.getTaskInFullImmersiveState(displayId)
- ?: return ExitResult.NoExit
+ val immersiveTask =
+ desktopUserRepositories.current.getTaskInFullImmersiveState(displayId)
+ ?: return ExitResult.NoExit
if (immersiveTask == excludeTaskId) {
return ExitResult.NoExit
}
@@ -210,7 +211,7 @@ class DesktopImmersiveController(
reason: ExitReason,
): ExitResult {
if (!Flags.enableFullyImmersiveInDesktop()) return ExitResult.NoExit
- if (desktopRepository.isTaskInFullImmersiveState(taskInfo.taskId)) {
+ if (desktopUserRepositories.current.isTaskInFullImmersiveState(taskInfo.taskId)) {
// A full immersive task is being minimized, make sure the immersive state is broken
// (i.e. resize back to max bounds).
wct.setBounds(taskInfo.token, getExitDestinationBounds(taskInfo))
@@ -377,6 +378,7 @@ class DesktopImmersiveController(
startTransaction: SurfaceControl.Transaction,
finishTransaction: SurfaceControl.Transaction,
) {
+ val desktopRepository: DesktopRepository = desktopUserRepositories.current
// Check if this is a pending external exit transition.
val pendingExit = pendingExternalExitTransitions
.firstOrNull { pendingExit -> pendingExit.transition == transition }
@@ -412,6 +414,7 @@ class DesktopImmersiveController(
}
val startBounds = immersiveChange.startAbsBounds
logV("Direct move for task#%d in %s direction verified", state.taskId, state.direction)
+
when (state.direction) {
Direction.ENTER -> {
desktopRepository.setTaskInFullImmersiveState(
@@ -484,7 +487,8 @@ class DesktopImmersiveController(
val displayLayout = displayController.getDisplayLayout(taskInfo.displayId)
?: error("Expected non-null display layout for displayId: ${taskInfo.displayId}")
return if (Flags.enableRestoreToPreviousSizeFromDesktopImmersive()) {
- desktopRepository.removeBoundsBeforeFullImmersive(taskInfo.taskId)
+ desktopUserRepositories.current
+ .removeBoundsBeforeFullImmersive(taskInfo.taskId)
?: if (ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS.isTrue()) {
calculateInitialBounds(displayLayout, taskInfo)
} else {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt
index 82c2ebc7ec77..96bbd58949bd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt
@@ -49,7 +49,7 @@ import com.android.wm.shell.transition.Transitions.TransitionFinishCallback
class DesktopMixedTransitionHandler(
private val context: Context,
private val transitions: Transitions,
- private val desktopRepository: DesktopRepository,
+ private val desktopUserRepositories: DesktopUserRepositories,
private val freeformTaskTransitionHandler: FreeformTaskTransitionHandler,
private val closeDesktopTaskTransitionHandler: CloseDesktopTaskTransitionHandler,
private val desktopImmersiveController: DesktopImmersiveController,
@@ -405,7 +405,7 @@ class DesktopMixedTransitionHandler(
private fun isLastDesktopTask(change: TransitionInfo.Change): Boolean =
change.taskInfo?.let {
- desktopRepository.getExpandedTaskCount(it.displayId) == 1
+ desktopUserRepositories.getProfile(it.userId).getExpandedTaskCount(it.displayId) == 1
} ?: false
private fun findCloseDesktopTaskChange(info: TransitionInfo): TransitionInfo.Change? {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandler.kt
index 2b0724d64d0e..250e1779aac3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandler.kt
@@ -31,7 +31,8 @@ import android.content.Context
import com.android.hardware.input.Flags.manageKeyGestures
import com.android.window.flags.Flags.enableTaskResizingKeyboardShortcuts
import com.android.wm.shell.common.ShellExecutor
-import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
+import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.desktopmode.common.ToggleTaskSizeInteraction
import com.android.wm.shell.transition.FocusTransitionObserver
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
import com.android.wm.shell.shared.annotations.ShellMainThread
@@ -48,7 +49,8 @@ class DesktopModeKeyGestureHandler(
private val shellTaskOrganizer: ShellTaskOrganizer,
private val focusTransitionObserver: FocusTransitionObserver,
@ShellMainThread private val mainExecutor: ShellExecutor,
- ) : KeyGestureEventHandler {
+ private val displayController: DisplayController,
+) : KeyGestureEventHandler {
init {
inputManager.registerKeyGestureEventHandler(this)
@@ -72,35 +74,44 @@ class DesktopModeKeyGestureHandler(
KeyGestureEvent.KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW -> {
logV("Key gesture SNAP_LEFT_FREEFORM_WINDOW is handled")
getGloballyFocusedFreeformTask()?.let {
- desktopModeWindowDecorViewModel.get().onSnapResize(
- it.taskId,
- true,
- DesktopModeEventLogger.Companion.InputMethod.KEYBOARD,
- /* fromMenu= */ false
- )
+ mainExecutor.execute {
+ desktopModeWindowDecorViewModel.get().onSnapResize(
+ it.taskId,
+ true,
+ DesktopModeEventLogger.Companion.InputMethod.KEYBOARD,
+ /* fromMenu= */ false
+ )
+ }
}
return true
}
KeyGestureEvent.KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW -> {
logV("Key gesture SNAP_RIGHT_FREEFORM_WINDOW is handled")
getGloballyFocusedFreeformTask()?.let {
- desktopModeWindowDecorViewModel.get().onSnapResize(
- it.taskId,
- false,
- DesktopModeEventLogger.Companion.InputMethod.KEYBOARD,
- /* fromMenu= */ false
- )
+ mainExecutor.execute {
+ desktopModeWindowDecorViewModel.get().onSnapResize(
+ it.taskId,
+ false,
+ DesktopModeEventLogger.Companion.InputMethod.KEYBOARD,
+ /* fromMenu= */ false
+ )
+ }
}
return true
}
KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_MAXIMIZE_FREEFORM_WINDOW -> {
logV("Key gesture TOGGLE_MAXIMIZE_FREEFORM_WINDOW is handled")
- getGloballyFocusedFreeformTask()?.let {
- desktopTasksController.get().toggleDesktopTaskSize(
- it,
- ResizeTrigger.MAXIMIZE_MENU,
- DesktopModeEventLogger.Companion.InputMethod.KEYBOARD,
- )
+ getGloballyFocusedFreeformTask()?.let { taskInfo ->
+ mainExecutor.execute {
+ desktopTasksController.get().toggleDesktopTaskSize(
+ taskInfo,
+ ToggleTaskSizeInteraction(
+ isMaximized = isTaskMaximized(taskInfo, displayController),
+ source = ToggleTaskSizeInteraction.Source.KEYBOARD_SHORTCUT,
+ inputMethod = DesktopModeEventLogger.Companion.InputMethod.KEYBOARD
+ )
+ )
+ }
}
return true
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt
index 2c432bcb55ab..38219984d651 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt
@@ -103,8 +103,12 @@ class DesktopModeUiEventLogger(
DESKTOP_WINDOW_CORNER_DRAG_RESIZE(1722),
@UiEvent(doc = "Tap on the window header maximize button in desktop windowing mode")
DESKTOP_WINDOW_MAXIMIZE_BUTTON_TAP(1723),
+ @UiEvent(doc = "Tap on the window header restore button in desktop windowing mode")
+ DESKTOP_WINDOW_RESTORE_BUTTON_TAP(2017),
@UiEvent(doc = "Double tap on window header to maximize it in desktop windowing mode")
DESKTOP_WINDOW_HEADER_DOUBLE_TAP_TO_MAXIMIZE(1724),
+ @UiEvent(doc = "Double tap on window header to restore from maximize in desktop windowing")
+ DESKTOP_WINDOW_HEADER_DOUBLE_TAP_TO_RESTORE(2018),
@UiEvent(doc = "Tap on the window Handle to open the Handle Menu")
DESKTOP_WINDOW_APP_HANDLE_TAP(1998),
@UiEvent(doc = "Tap on the desktop mode option under app handle menu")
@@ -136,7 +140,11 @@ class DesktopModeUiEventLogger(
@UiEvent(doc = "Tap on the tile to left option in the maximize button menu")
DESKTOP_WINDOW_MAXIMIZE_BUTTON_MENU_TAP_TO_TILE_TO_LEFT(2012),
@UiEvent(doc = "Tap on the tile to right option in the maximize button menu")
- DESKTOP_WINDOW_MAXIMIZE_BUTTON_MENU_TAP_TO_TILE_TO_RIGHT(2013);
+ DESKTOP_WINDOW_MAXIMIZE_BUTTON_MENU_TAP_TO_TILE_TO_RIGHT(2013),
+ @UiEvent(doc = "Moving the desktop window by dragging the header")
+ DESKTOP_WINDOW_MOVE_BY_HEADER_DRAG(2021),
+ @UiEvent(doc = "Double tap on the window header to refocus a desktop window")
+ DESKTOP_WINDOW_HEADER_TAP_TO_REFOCUS(2022);
override fun getId(): Int = mId
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
index c7cf31081c8b..42c3b1ccd1a7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
@@ -28,6 +28,7 @@ import android.content.res.Configuration.ORIENTATION_PORTRAIT
import android.graphics.Rect
import android.os.SystemProperties
import android.util.Size
+import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.DisplayLayout
val DESKTOP_MODE_INITIAL_BOUNDS_SCALE: Float =
@@ -211,6 +212,31 @@ fun calculateAspectRatio(taskInfo: RunningTaskInfo): Float {
minOf(appBounds.height(), appBounds.width()).toFloat()
}
+/** Returns whether the task is maximized. */
+fun isTaskMaximized(
+ taskInfo: RunningTaskInfo,
+ displayController: DisplayController
+): Boolean {
+ val displayLayout = displayController.getDisplayLayout(taskInfo.displayId)
+ ?: error("Could not get display layout for display=${taskInfo.displayId}")
+ val stableBounds = Rect()
+ displayLayout.getStableBounds(stableBounds)
+ return isTaskMaximized(taskInfo, stableBounds)
+}
+
+/** Returns whether the task is maximized. */
+fun isTaskMaximized(
+ taskInfo: RunningTaskInfo,
+ stableBounds: Rect
+): Boolean {
+ val currentTaskBounds = taskInfo.configuration.windowConfiguration.bounds
+ return if (taskInfo.isResizeable) {
+ isTaskBoundsEqual(currentTaskBounds, stableBounds)
+ } else {
+ isTaskWidthOrHeightEqual(currentTaskBounds, stableBounds)
+ }
+}
+
/** Returns true if task's width or height is maximized else returns false. */
fun isTaskWidthOrHeightEqual(taskBounds: Rect, stableBounds: Rect): Boolean {
return taskBounds.width() == stableBounds.width() ||
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 7fcb7678f6af..ca3dc2d5426e 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
@@ -16,7 +16,7 @@
package com.android.wm.shell.desktopmode
-import android.content.Context
+import android.content.pm.UserInfo
import android.graphics.Rect
import android.graphics.Region
import android.util.ArrayMap
@@ -30,11 +30,8 @@ import androidx.core.util.keyIterator
import androidx.core.util.valueIterator
import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.desktopmode.persistence.DesktopPersistentRepository
-import com.android.wm.shell.desktopmode.persistence.DesktopRepositoryInitializer
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
import com.android.wm.shell.shared.annotations.ShellMainThread
-import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
-import com.android.wm.shell.sysui.ShellInit
import java.io.PrintWriter
import java.util.concurrent.Executor
import java.util.function.Consumer
@@ -43,13 +40,10 @@ import kotlinx.coroutines.launch
/** Tracks desktop data for Android Desktop Windowing. */
class DesktopRepository (
- private val context: Context,
- shellInit: ShellInit,
private val persistentRepository: DesktopPersistentRepository,
- private val repositoryInitializer: DesktopRepositoryInitializer,
@ShellMainThread private val mainCoroutineScope: CoroutineScope,
+ val userId: Int,
){
-
/**
* Task data tracked per desktop.
*
@@ -117,16 +111,6 @@ class DesktopRepository (
this[displayId] ?: DesktopTaskData().also { this[displayId] = it }
}
- init {
- if (DesktopModeStatus.canEnterDesktopMode(context)) {
- shellInit.addInitCallback(::initRepoFromPersistentStorage, this)
- }
- }
-
- private fun initRepoFromPersistentStorage() {
- repositoryInitializer.initialize(this)
- }
-
/** Adds [activeTasksListener] to be notified of updates to active tasks. */
fun addActiveTaskListener(activeTasksListener: ActiveTasksListener) {
activeTasksListeners.add(activeTasksListener)
@@ -276,6 +260,8 @@ class DesktopRepository (
* the set of visible tasks on that display and notifies listeners.
*/
fun updateTask(displayId: Int, taskId: Int, isVisible: Boolean) {
+ logD("updateTask taskId=%d, displayId=%d, isVisible=%b", taskId, displayId, isVisible)
+
if (isVisible) {
// If task is visible, remove it from any other display besides [displayId].
removeVisibleTask(taskId, excludedDisplayId = displayId)
@@ -495,6 +481,7 @@ class DesktopRepository (
persistentRepository.addOrUpdateDesktop(
// Use display id as desktop id for now since only once desktop per display
// is supported.
+ userId = userId,
desktopId = displayId,
visibleTasks = desktopTaskDataByDisplayIdCopy.visibleTasks,
minimizedTasks = desktopTaskDataByDisplayIdCopy.minimizedTasks,
@@ -529,6 +516,7 @@ class DesktopRepository (
)
pw.println("${innerPrefix}minimizedTasks=${data.minimizedTasks.toDumpString()}")
pw.println("${innerPrefix}fullImmersiveTaskId=${data.fullImmersiveTaskId}")
+ pw.println("${innerPrefix}wallpaperActivityToken=${wallpaperActivityToken}")
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListener.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListener.kt
index 94ac2e665f61..80d8bfba99d2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListener.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListener.kt
@@ -23,10 +23,12 @@ import com.android.wm.shell.freeform.TaskChangeListener
/** Manages tasks handling specific to Android Desktop Mode. */
class DesktopTaskChangeListener(
- private val desktopRepository: DesktopRepository,
+ private val desktopUserRepositories: DesktopUserRepositories,
) : TaskChangeListener {
override fun onTaskOpening(taskInfo: RunningTaskInfo) {
+ val desktopRepository: DesktopRepository =
+ desktopUserRepositories.getProfile(taskInfo.userId)
if (!isFreeformTask(taskInfo) && desktopRepository.isActiveTask(taskInfo.taskId)) {
desktopRepository.removeFreeformTask(taskInfo.displayId, taskInfo.taskId)
return
@@ -37,6 +39,8 @@ class DesktopTaskChangeListener(
}
override fun onTaskChanging(taskInfo: RunningTaskInfo) {
+ val desktopRepository: DesktopRepository =
+ desktopUserRepositories.getProfile(taskInfo.userId)
if (!desktopRepository.isActiveTask(taskInfo.taskId)) return
// Case 1: Freeform task is changed in Desktop Mode.
@@ -61,6 +65,8 @@ class DesktopTaskChangeListener(
}
override fun onTaskMovingToFront(taskInfo: RunningTaskInfo) {
+ val desktopRepository: DesktopRepository =
+ desktopUserRepositories.getProfile(taskInfo.userId)
if (!desktopRepository.isActiveTask(taskInfo.taskId)) return
if (!isFreeformTask(taskInfo)) {
desktopRepository.removeFreeformTask(taskInfo.displayId, taskInfo.taskId)
@@ -74,6 +80,8 @@ class DesktopTaskChangeListener(
}
override fun onTaskClosing(taskInfo: RunningTaskInfo) {
+ val desktopRepository: DesktopRepository =
+ desktopUserRepositories.getProfile(taskInfo.userId)
if (!desktopRepository.isActiveTask(taskInfo.taskId)) return
// TODO: b/370038902 - Handle Activity#finishAndRemoveTask.
if (!DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION.isTrue() ||
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 c479ab382acb..5cb94f870a2d 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
@@ -84,6 +84,7 @@ import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.common.SingleInstanceRemoteListener
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.compatui.isTopActivityExemptFromDesktopWindowing
+import com.android.wm.shell.desktopmode.common.ToggleTaskSizeInteraction
import com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.DragStartState
import com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType
import com.android.wm.shell.desktopmode.DesktopRepository.VisibleTasksListener
@@ -158,7 +159,7 @@ class DesktopTasksController(
private val toggleResizeDesktopTaskTransitionHandler: ToggleResizeDesktopTaskTransitionHandler,
private val dragToDesktopTransitionHandler: DragToDesktopTransitionHandler,
private val desktopImmersiveController: DesktopImmersiveController,
- private val taskRepository: DesktopRepository,
+ private val userRepositories: DesktopUserRepositories,
private val recentsTransitionHandler: RecentsTransitionHandler,
private val multiInstanceHelper: MultiInstanceHelper,
@ShellMainThread private val mainExecutor: ShellExecutor,
@@ -176,6 +177,7 @@ class DesktopTasksController(
UserChangeListener {
private val desktopMode: DesktopModeImpl
+ private var taskRepository: DesktopRepository
private var visualIndicator: DesktopModeVisualIndicator? = null
private var userId: Int
private val desktopModeShellCommandHandler: DesktopModeShellCommandHandler =
@@ -228,6 +230,7 @@ class DesktopTasksController(
shellInit.addInitCallback({ onInit() }, this)
}
userId = ActivityManager.getCurrentUser()
+ taskRepository = userRepositories.getProfile(userId)
}
private fun onInit() {
@@ -795,32 +798,24 @@ class DesktopTasksController(
*/
fun toggleDesktopTaskSize(
taskInfo: RunningTaskInfo,
- resizeTrigger: ResizeTrigger,
- inputMethod: InputMethod,
- maximizeCujRecorder: (() -> Unit)? = null,
- unmaximizeCujRecorder: (() -> Unit)? = null,
+ interaction: ToggleTaskSizeInteraction
) {
val currentTaskBounds = taskInfo.configuration.windowConfiguration.bounds
desktopModeEventLogger.logTaskResizingStarted(
- resizeTrigger,
- inputMethod,
+ interaction.resizeTrigger,
+ interaction.inputMethod,
taskInfo,
currentTaskBounds.width(),
currentTaskBounds.height(),
displayController
)
-
val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return
-
- val stableBounds = Rect().apply { displayLayout.getStableBounds(this) }
val destinationBounds = Rect()
-
- val isMaximized = isTaskMaximized(taskInfo, stableBounds)
+ val isMaximized = interaction.direction == ToggleTaskSizeInteraction.Direction.RESTORE
// If the task is currently maximized, we will toggle it not to be and vice versa. This is
// helpful to eliminate the current task from logic to calculate taskbar corner rounding.
- val willMaximize = !isMaximized
+ val willMaximize = interaction.direction == ToggleTaskSizeInteraction.Direction.MAXIMIZE
if (isMaximized) {
- unmaximizeCujRecorder?.invoke()
// The desktop task is at the maximized width and/or height of the stable bounds.
// If the task's pre-maximize stable bounds were saved, toggle the task to those bounds.
// Otherwise, toggle to the default bounds.
@@ -836,7 +831,6 @@ class DesktopTasksController(
}
}
} else {
- maximizeCujRecorder?.invoke()
// Save current bounds so that task can be restored back to original bounds if necessary
// and toggle to the stable bounds.
desktopTilingDecorViewModel.removeTaskIfTiled(taskInfo.displayId, taskInfo.taskId)
@@ -857,10 +851,16 @@ class DesktopTasksController(
taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate(doesAnyTaskRequireTaskbarRounding)
val wct = WindowContainerTransaction().setBounds(taskInfo.token, destinationBounds)
+ interaction.uiEvent?.let { uiEvent ->
+ desktopModeUiEventLogger.log(taskInfo, uiEvent)
+ }
desktopModeEventLogger.logTaskResizingEnded(
- resizeTrigger, inputMethod,
- taskInfo, destinationBounds.width(),
- destinationBounds.height(), displayController
+ interaction.resizeTrigger,
+ interaction.inputMethod,
+ taskInfo,
+ destinationBounds.width(),
+ destinationBounds.height(),
+ displayController,
)
toggleResizeDesktopTaskTransitionHandler.startTransition(wct)
}
@@ -871,10 +871,7 @@ class DesktopTasksController(
currentDragBounds: Rect,
motionEvent: MotionEvent
) {
- val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return
- val stableBounds = Rect()
- displayLayout.getStableBounds(stableBounds)
- if (isTaskMaximized(taskInfo, stableBounds)) {
+ if (isTaskMaximized(taskInfo, displayController)) {
// Handle the case where we attempt to drag-to-maximize when already maximized: the task
// position won't need to change but we want to animate the surface going back to the
// maximized position.
@@ -892,8 +889,11 @@ class DesktopTasksController(
toggleDesktopTaskSize(
taskInfo,
- ResizeTrigger.DRAG_TO_TOP_RESIZE_TRIGGER,
- DesktopModeEventLogger.getInputMethodFromMotionEvent(motionEvent),
+ ToggleTaskSizeInteraction(
+ direction = ToggleTaskSizeInteraction.Direction.MAXIMIZE,
+ source = ToggleTaskSizeInteraction.Source.HEADER_DRAG_TO_TOP,
+ inputMethod = DesktopModeEventLogger.getInputMethodFromMotionEvent(motionEvent),
+ )
)
}
@@ -911,19 +911,6 @@ class DesktopTasksController(
}
}
- private fun isTaskMaximized(
- taskInfo: RunningTaskInfo,
- stableBounds: Rect
- ): Boolean {
- val currentTaskBounds = taskInfo.configuration.windowConfiguration.bounds
-
- return if (taskInfo.isResizeable) {
- isTaskBoundsEqual(currentTaskBounds, stableBounds)
- } else {
- isTaskWidthOrHeightEqual(currentTaskBounds, stableBounds)
- }
- }
-
private fun isMaximizedToStableBoundsEdges(
taskInfo: RunningTaskInfo,
stableBounds: Rect
@@ -1254,7 +1241,7 @@ class DesktopTasksController(
/* requestCode= */ 0,
intent,
PendingIntent.FLAG_IMMUTABLE,
- /* bundle= */ null,
+ /* options= */ null,
userHandle
)
wct.sendPendingIntent(pendingIntent, intent, options.toBundle())
@@ -1739,8 +1726,7 @@ class DesktopTasksController(
/** Handle task closing by removing wallpaper activity if it's the last active task */
private fun handleTaskClosing(task: RunningTaskInfo, transition: IBinder, requestType: Int): WindowContainerTransaction? {
logV("handleTaskClosing")
- if (!isDesktopModeShowing(task.displayId))
- return null
+ if (!isDesktopModeShowing(task.displayId)) return null
val wct = WindowContainerTransaction()
performDesktopExitCleanupIfNeeded(task.taskId, wct)
@@ -1757,6 +1743,7 @@ class DesktopTasksController(
)
)
}
+
taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate(
doesAnyTaskRequireTaskbarRounding(
task.displayId,
@@ -2342,7 +2329,9 @@ class DesktopTasksController(
// TODO(b/366397912): Support full multi-user mode in Windowing.
override fun onUserChanged(newUserId: Int, userContext: Context) {
+ logV("onUserChanged previousUserId=%d, newUserId=%d", userId, newUserId)
userId = newUserId
+ taskRepository = userRepositories.getProfile(userId)
desktopTilingDecorViewModel.onUserChange()
}
@@ -2365,6 +2354,7 @@ class DesktopTasksController(
val innerPrefix = "$prefix "
pw.println("${prefix}DesktopTasksController")
DesktopModeStatus.dump(pw, innerPrefix, context)
+ pw.println("${prefix}userId=$userId")
taskRepository.dump(pw, innerPrefix)
}
@@ -2393,6 +2383,7 @@ class DesktopTasksController(
displayId: Int,
transitionSource: DesktopModeTransitionSource
) {
+ logV("moveFocusedTaskToDesktop")
mainExecutor.execute {
this@DesktopTasksController.moveFocusedTaskToDesktop(displayId, transitionSource)
}
@@ -2402,12 +2393,14 @@ class DesktopTasksController(
displayId: Int,
transitionSource: DesktopModeTransitionSource
) {
+ logV("moveFocusedTaskToFullscreen")
mainExecutor.execute {
this@DesktopTasksController.enterFullscreen(displayId, transitionSource)
}
}
override fun moveFocusedTaskToStageSplit(displayId: Int, leftOrTop: Boolean) {
+ logV("moveFocusedTaskToStageSplit")
mainExecutor.execute { this@DesktopTasksController.enterSplit(displayId, leftOrTop) }
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt
index 77af627a948a..62b200a6174e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt
@@ -16,6 +16,7 @@
package com.android.wm.shell.desktopmode
+import android.app.ActivityManager
import android.content.Context
import android.os.Handler
import android.os.IBinder
@@ -31,6 +32,7 @@ import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
import com.android.wm.shell.shared.annotations.ShellMainThread
+import com.android.wm.shell.sysui.UserChangeListener;
import com.android.wm.shell.transition.Transitions
import com.android.wm.shell.transition.Transitions.TransitionObserver
@@ -43,7 +45,7 @@ import com.android.wm.shell.transition.Transitions.TransitionObserver
*/
class DesktopTasksLimiter (
transitions: Transitions,
- private val taskRepository: DesktopRepository,
+ private val desktopUserRepositories: DesktopUserRepositories,
private val shellTaskOrganizer: ShellTaskOrganizer,
private val maxTasksLimit: Int,
private val interactionJankMonitor: InteractionJankMonitor,
@@ -54,12 +56,15 @@ class DesktopTasksLimiter (
@VisibleForTesting
val leftoverMinimizedTasksRemover = LeftoverMinimizedTasksRemover()
+ private var userId: Int
+
init {
require(maxTasksLimit > 0) {
"DesktopTasksLimiter: maxTasksLimit should be greater than 0. Current value: $maxTasksLimit."
}
transitions.registerObserver(minimizeTransitionObserver)
- taskRepository.addActiveTaskListener(leftoverMinimizedTasksRemover)
+ userId = ActivityManager.getCurrentUser()
+ desktopUserRepositories.current.addActiveTaskListener(leftoverMinimizedTasksRemover)
logV("Starting limiter with a maximum of %d tasks", maxTasksLimit)
}
@@ -84,6 +89,7 @@ class DesktopTasksLimiter (
startTransaction: SurfaceControl.Transaction,
finishTransaction: SurfaceControl.Transaction
) {
+ val taskRepository = desktopUserRepositories.current
val taskToMinimize = pendingTransitionTokensAndTasks.remove(transition) ?: return
if (!taskRepository.isActiveTask(taskToMinimize.taskId)) return
if (!isTaskReadyForMinimize(info, taskToMinimize)) {
@@ -114,6 +120,7 @@ class DesktopTasksLimiter (
): Boolean {
val taskChange = info.changes.find { change ->
change.taskInfo?.taskId == taskDetails.taskId }
+ val taskRepository = desktopUserRepositories.current
if (taskChange == null) return !taskRepository.isVisibleTask(taskDetails.taskId)
return taskChange.mode == TRANSIT_TO_BACK
}
@@ -151,7 +158,8 @@ class DesktopTasksLimiter (
}
@VisibleForTesting
- inner class LeftoverMinimizedTasksRemover : DesktopRepository.ActiveTasksListener {
+ inner class LeftoverMinimizedTasksRemover
+ : DesktopRepository.ActiveTasksListener, UserChangeListener {
override fun onActiveTasksChanged(displayId: Int) {
// If back navigation is enabled, we shouldn't remove the leftover tasks
if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION.isTrue()) return
@@ -161,6 +169,7 @@ class DesktopTasksLimiter (
}
fun removeLeftoverMinimizedTasks(displayId: Int, wct: WindowContainerTransaction) {
+ val taskRepository = desktopUserRepositories.current
if (taskRepository.getExpandedTasksOrdered(displayId).isNotEmpty()) return
val remainingMinimizedTasks = taskRepository.getMinimizedTasks(displayId)
if (remainingMinimizedTasks.isEmpty()) return
@@ -173,6 +182,15 @@ class DesktopTasksLimiter (
}
}
}
+
+ override fun onUserChanged(newUserId: Int, userContext: Context) {
+ // Removes active task listener for the previous repository
+ desktopUserRepositories.getProfile(userId).removeActiveTasksListener(this);
+
+ // Sets active listener for the current repository.
+ userId = newUserId
+ desktopUserRepositories.getProfile(newUserId).addActiveTaskListener(this);
+ }
}
/**
@@ -183,6 +201,7 @@ class DesktopTasksLimiter (
*/
private fun minimizeTask(displayId: Int, taskId: Int) {
logV("Minimize taskId=%d, displayId=%d", taskId, displayId)
+ val taskRepository = desktopUserRepositories.current
taskRepository.minimizeTask(displayId, taskId)
}
@@ -196,7 +215,7 @@ class DesktopTasksLimiter (
newFrontTaskId: Int,
): Int? {
logV("addAndGetMinimizeTaskChanges, newFrontTask=%d", newFrontTaskId)
-
+ val taskRepository = desktopUserRepositories.current
val taskIdToMinimize =
getTaskIdToMinimize(
taskRepository.getExpandedTasksOrdered(displayId),
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 c39c715e685c..d6bb7f95c196 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
@@ -16,6 +16,7 @@
package com.android.wm.shell.desktopmode
+import android.app.ActivityManager
import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
import android.content.Context
import android.os.IBinder
@@ -43,7 +44,7 @@ import com.android.wm.shell.transition.Transitions
*/
class DesktopTasksTransitionObserver(
private val context: Context,
- private val desktopRepository: DesktopRepository,
+ private val desktopUserRepositories: DesktopUserRepositories,
private val transitions: Transitions,
private val shellTaskOrganizer: ShellTaskOrganizer,
private val desktopMixedTransitionHandler: DesktopMixedTransitionHandler,
@@ -51,11 +52,13 @@ class DesktopTasksTransitionObserver(
) : Transitions.TransitionObserver {
private var transitionToCloseWallpaper: IBinder? = null
+ private var currentProfileId: Int
init {
if (DesktopModeStatus.canEnterDesktopMode(context)) {
shellInit.addInitCallback(::onInit, this)
}
+ currentProfileId = ActivityManager.getCurrentUser()
}
fun onInit() {
@@ -89,6 +92,7 @@ class DesktopTasksTransitionObserver(
val taskInfo = change.taskInfo
if (taskInfo == null || taskInfo.taskId == -1) continue
+ val desktopRepository = desktopUserRepositories.getProfile(taskInfo.userId)
if (desktopRepository.isActiveTask(taskInfo.taskId) &&
taskInfo.windowingMode != WINDOWING_MODE_FREEFORM) {
desktopRepository.removeFreeformTask(taskInfo.displayId, taskInfo.taskId)
@@ -105,7 +109,7 @@ class DesktopTasksTransitionObserver(
if (taskInfo == null || taskInfo.taskId == -1) {
continue
}
-
+ val desktopRepository = desktopUserRepositories.getProfile(taskInfo.userId)
val visibleTaskCount = desktopRepository.getVisibleTaskCount(taskInfo.displayId)
if (visibleTaskCount > 0 &&
change.mode == TRANSIT_TO_BACK &&
@@ -128,12 +132,13 @@ class DesktopTasksTransitionObserver(
if (taskInfo == null || taskInfo.taskId == -1) {
continue
}
-
+ val desktopRepository = desktopUserRepositories.getProfile(taskInfo.userId)
if (desktopRepository.getVisibleTaskCount(taskInfo.displayId) == 1 &&
change.mode == TRANSIT_CLOSE &&
taskInfo.windowingMode == WINDOWING_MODE_FREEFORM &&
desktopRepository.wallpaperActivityToken != null) {
transitionToCloseWallpaper = transition
+ currentProfileId = taskInfo.userId
}
}
}
@@ -150,6 +155,7 @@ class DesktopTasksTransitionObserver(
// TODO: b/332682201 Update repository state
if (transitionToCloseWallpaper == transition) {
// TODO: b/362469671 - Handle merging the animation when desktop is also closing.
+ val desktopRepository = desktopUserRepositories.getProfile(currentProfileId)
desktopRepository.wallpaperActivityToken?.let { wallpaperActivityToken ->
transitions.startTransition(
TRANSIT_CLOSE,
@@ -167,6 +173,7 @@ class DesktopTasksTransitionObserver(
info.changes.forEach { change ->
change.taskInfo?.let { taskInfo ->
if (DesktopWallpaperActivity.isWallpaperTask(taskInfo)) {
+ val desktopRepository = desktopUserRepositories.getProfile(taskInfo.userId)
when (change.mode) {
WindowManager.TRANSIT_OPEN -> {
desktopRepository.wallpaperActivityToken = taskInfo.token
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopUserRepositories.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopUserRepositories.kt
new file mode 100644
index 000000000000..1e5a1b274729
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopUserRepositories.kt
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.desktopmode
+
+import android.app.ActivityManager
+import android.content.Context
+import android.content.pm.UserInfo
+import android.os.UserManager
+import android.util.SparseArray
+import com.android.window.flags.Flags
+import com.android.internal.protolog.ProtoLog
+import com.android.wm.shell.desktopmode.persistence.DesktopPersistentRepository
+import com.android.wm.shell.desktopmode.persistence.DesktopRepositoryInitializer
+import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
+import com.android.wm.shell.shared.annotations.ShellMainThread
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
+import com.android.wm.shell.sysui.ShellInit
+import com.android.wm.shell.sysui.UserChangeListener
+import kotlinx.coroutines.CoroutineScope
+
+/** Manages per-user DesktopRepository instances. */
+class DesktopUserRepositories(
+ context: Context,
+ shellInit: ShellInit,
+ private val persistentRepository: DesktopPersistentRepository,
+ private val repositoryInitializer: DesktopRepositoryInitializer,
+ @ShellMainThread private val mainCoroutineScope: CoroutineScope,
+ userManager: UserManager,
+) : UserChangeListener {
+ private var userId: Int
+ private var userIdToProfileIdsMap: MutableMap<Int, List<Int>> = mutableMapOf()
+
+ // TODO(b/357060209): Add caching for this logic to improve efficiency.
+ val current: DesktopRepository
+ get() = desktopRepoByUserId.getOrCreate(userId)
+
+ private val desktopRepoByUserId =
+ object : SparseArray<DesktopRepository>() {
+ /** Gets [DesktopRepository] for existing [userId] or creates a new one. */
+ fun getOrCreate(userId: Int): DesktopRepository =
+ this[userId]
+ ?: DesktopRepository(
+ persistentRepository,
+ mainCoroutineScope,
+ userId)
+ .also { this[userId] = it }
+ }
+
+ init {
+ userId = ActivityManager.getCurrentUser()
+ if (DesktopModeStatus.canEnterDesktopMode(context)) {
+ shellInit.addInitCallback(::initRepoFromPersistentStorage, this)
+ }
+ if (Flags.enableDesktopWindowingHsum()) {
+ userIdToProfileIdsMap[userId] = userManager.getProfiles(userId).map { it.id }
+ }
+ }
+
+ private fun initRepoFromPersistentStorage() {
+ repositoryInitializer.initialize(this)
+ }
+
+ /** Returns [DesktopRepository] for the parent user id. */
+ fun getProfile(profileId: Int): DesktopRepository {
+ if (Flags.enableDesktopWindowingHsum()) {
+ for ((uid, profileIds) in userIdToProfileIdsMap) {
+ if (profileId in profileIds) {
+ return desktopRepoByUserId.getOrCreate(uid)
+ }
+ }
+ }
+ return desktopRepoByUserId.getOrCreate(profileId)
+ }
+
+ override fun onUserChanged(newUserId: Int, userContext: Context) {
+ logD("onUserChanged previousUserId=%d, newUserId=%d", userId, newUserId)
+ userId = newUserId
+ }
+
+ override fun onUserProfilesChanged(profiles: MutableList<UserInfo>) {
+ logD("onUserProfilesChanged profiles=%s", profiles.toString())
+ if (Flags.enableDesktopWindowingHsum()) {
+ // TODO(b/366397912): Remove all persisted profile data when the profile changes.
+ userIdToProfileIdsMap[userId] = profiles.map { it.id }
+ }
+ }
+
+ private fun logD(msg: String, vararg arguments: Any?) {
+ ProtoLog.d(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
+ }
+
+ companion object {
+ private const val TAG = "DesktopUserRepositories"
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/ToggleTaskSizeUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/ToggleTaskSizeUtils.kt
new file mode 100644
index 000000000000..7afd8d7f6e48
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/ToggleTaskSizeUtils.kt
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.desktopmode.common
+
+import com.android.internal.jank.Cuj
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.InputMethod
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
+import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum
+import com.android.wm.shell.desktopmode.common.ToggleTaskSizeInteraction.AmbiguousSource
+import com.android.wm.shell.desktopmode.common.ToggleTaskSizeInteraction.Source
+
+/** Represents a user interaction to toggle a desktop task's size from to maximize or vice versa. */
+data class ToggleTaskSizeInteraction(
+ val direction: Direction,
+ val source: Source,
+ val inputMethod: InputMethod,
+) {
+ constructor(
+ isMaximized: Boolean,
+ source: Source,
+ inputMethod: InputMethod,
+ ) : this(
+ direction = if (isMaximized) Direction.RESTORE else Direction.MAXIMIZE,
+ source = source,
+ inputMethod = inputMethod,
+ )
+
+ val jankTag: String? =
+ when (source) {
+ Source.HEADER_BUTTON_TO_MAXIMIZE -> "caption_bar_button"
+ Source.HEADER_BUTTON_TO_RESTORE -> "caption_bar_button"
+ Source.KEYBOARD_SHORTCUT -> null
+ Source.HEADER_DRAG_TO_TOP -> null
+ Source.MAXIMIZE_MENU_TO_MAXIMIZE -> "maximize_menu"
+ Source.MAXIMIZE_MENU_TO_RESTORE -> "maximize_menu"
+ Source.DOUBLE_TAP_TO_MAXIMIZE -> "double_tap"
+ Source.DOUBLE_TAP_TO_RESTORE -> "double_tap"
+ }
+ val uiEvent: DesktopUiEventEnum? =
+ when (source) {
+ Source.HEADER_BUTTON_TO_MAXIMIZE ->
+ DesktopUiEventEnum.DESKTOP_WINDOW_MAXIMIZE_BUTTON_TAP
+ Source.HEADER_BUTTON_TO_RESTORE -> DesktopUiEventEnum.DESKTOP_WINDOW_RESTORE_BUTTON_TAP
+ Source.KEYBOARD_SHORTCUT -> null
+ Source.HEADER_DRAG_TO_TOP -> null
+ Source.MAXIMIZE_MENU_TO_MAXIMIZE -> {
+ DesktopUiEventEnum.DESKTOP_WINDOW_MAXIMIZE_BUTTON_MENU_TAP_TO_MAXIMIZE
+ }
+ Source.MAXIMIZE_MENU_TO_RESTORE -> {
+ DesktopUiEventEnum.DESKTOP_WINDOW_MAXIMIZE_BUTTON_MENU_TAP_TO_RESTORE
+ }
+ Source.DOUBLE_TAP_TO_MAXIMIZE -> {
+ DesktopUiEventEnum.DESKTOP_WINDOW_HEADER_DOUBLE_TAP_TO_MAXIMIZE
+ }
+ Source.DOUBLE_TAP_TO_RESTORE -> {
+ DesktopUiEventEnum.DESKTOP_WINDOW_HEADER_DOUBLE_TAP_TO_RESTORE
+ }
+ }
+ val resizeTrigger =
+ when (source) {
+ Source.HEADER_BUTTON_TO_MAXIMIZE -> ResizeTrigger.MAXIMIZE_BUTTON
+ Source.HEADER_BUTTON_TO_RESTORE -> ResizeTrigger.MAXIMIZE_BUTTON
+ Source.KEYBOARD_SHORTCUT -> ResizeTrigger.UNKNOWN_RESIZE_TRIGGER
+ Source.HEADER_DRAG_TO_TOP -> ResizeTrigger.DRAG_TO_TOP_RESIZE_TRIGGER
+ Source.MAXIMIZE_MENU_TO_MAXIMIZE -> ResizeTrigger.MAXIMIZE_MENU
+ Source.MAXIMIZE_MENU_TO_RESTORE -> ResizeTrigger.MAXIMIZE_MENU
+ Source.DOUBLE_TAP_TO_MAXIMIZE -> ResizeTrigger.DOUBLE_TAP_APP_HEADER
+ Source.DOUBLE_TAP_TO_RESTORE -> ResizeTrigger.DOUBLE_TAP_APP_HEADER
+ }
+ val cujTracing: Int? =
+ when (source) {
+ Source.HEADER_BUTTON_TO_MAXIMIZE -> Cuj.CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW
+ Source.HEADER_BUTTON_TO_RESTORE -> Cuj.CUJ_DESKTOP_MODE_UNMAXIMIZE_WINDOW
+ Source.KEYBOARD_SHORTCUT -> null
+ Source.HEADER_DRAG_TO_TOP -> null
+ Source.MAXIMIZE_MENU_TO_MAXIMIZE -> null
+ Source.MAXIMIZE_MENU_TO_RESTORE -> null
+ Source.DOUBLE_TAP_TO_MAXIMIZE -> null
+ Source.DOUBLE_TAP_TO_RESTORE -> null
+ }
+
+ /** The direction to which the task is being resized. */
+ enum class Direction {
+ MAXIMIZE,
+ RESTORE,
+ }
+
+ /** The user interaction source. */
+ enum class Source {
+ HEADER_BUTTON_TO_MAXIMIZE,
+ HEADER_BUTTON_TO_RESTORE,
+ KEYBOARD_SHORTCUT,
+ HEADER_DRAG_TO_TOP,
+ MAXIMIZE_MENU_TO_MAXIMIZE,
+ MAXIMIZE_MENU_TO_RESTORE,
+ DOUBLE_TAP_TO_MAXIMIZE,
+ DOUBLE_TAP_TO_RESTORE,
+ }
+
+ /**
+ * Temporary sources for interactions that should be broken into more specific sources, for
+ * example, the header button click should use [Source.HEADER_BUTTON_TO_MAXIMIZE] and
+ * [Source.HEADER_BUTTON_TO_RESTORE].
+ *
+ * TODO: b/341320112 - break these out into different [Source]s.
+ */
+ enum class AmbiguousSource {
+ HEADER_BUTTON,
+ MAXIMIZE_MENU,
+ DOUBLE_TAP,
+ }
+}
+
+/** Returns the non-ambiguous [Source] based on the maximized state of the task. */
+fun AmbiguousSource.toSource(isMaximized: Boolean): Source {
+ return when (this) {
+ AmbiguousSource.HEADER_BUTTON ->
+ if (isMaximized) {
+ Source.HEADER_BUTTON_TO_RESTORE
+ } else {
+ Source.HEADER_BUTTON_TO_MAXIMIZE
+ }
+ AmbiguousSource.MAXIMIZE_MENU ->
+ if (isMaximized) {
+ Source.MAXIMIZE_MENU_TO_RESTORE
+ } else {
+ Source.MAXIMIZE_MENU_TO_MAXIMIZE
+ }
+ AmbiguousSource.DOUBLE_TAP ->
+ if (isMaximized) {
+ Source.DOUBLE_TAP_TO_RESTORE
+ } else {
+ Source.DOUBLE_TAP_TO_MAXIMIZE
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandler.kt
index 826de08557bd..a428ce18a49e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandler.kt
@@ -29,7 +29,7 @@ import com.android.app.animation.Interpolators
import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.compatui.isTopActivityExemptFromDesktopWindowing
-import com.android.wm.shell.desktopmode.DesktopRepository
+import com.android.wm.shell.desktopmode.DesktopUserRepositories
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
import com.android.wm.shell.shared.TransitionUtil.isClosingMode
import com.android.wm.shell.shared.TransitionUtil.isClosingType
@@ -46,7 +46,7 @@ class SystemModalsTransitionHandler(
private val animExecutor: ShellExecutor,
private val shellInit: ShellInit,
private val transitions: Transitions,
- private val desktopRepository: DesktopRepository,
+ private val desktopUserRepositories: DesktopUserRepositories,
) : TransitionHandler {
private val showingSystemModalsIds = mutableSetOf<Int>()
@@ -156,7 +156,7 @@ class SystemModalsTransitionHandler(
}
private fun isDesktopModeShowing(displayId: Int): Boolean =
- desktopRepository.getVisibleTaskCount(displayId) > 0
+ desktopUserRepositories.current.getVisibleTaskCount(displayId) > 0
override fun handleRequest(
transition: IBinder,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepository.kt
index 9e646f430c98..b7de1f86601c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepository.kt
@@ -73,8 +73,8 @@ class DesktopPersistentRepository(
* Reads and returns the [DesktopRepositoryState] proto object from the DataStore for a user. If
* the DataStore is empty or there's an error reading, it returns the default value of Proto.
*/
- private suspend fun getDesktopRepositoryState(
- userId: Int = DEFAULT_USER_ID
+ suspend fun getDesktopRepositoryState(
+ userId: Int
): DesktopRepositoryState? =
try {
dataStoreFlow
@@ -85,12 +85,20 @@ class DesktopPersistentRepository(
null
}
+ suspend fun getUserDesktopRepositoryMap(): Map<Int, DesktopRepositoryState>? =
+ try {
+ dataStoreFlow.first().desktopRepoByUserMap
+ } catch (e: Exception) {
+ Log.e(TAG, "Unable to read from datastore", e)
+ null
+ }
+
/**
* Reads the [Desktop] of a desktop filtering by the [userId] and [desktopId]. Executes the
* [callback] using the [mainCoroutineScope].
*/
suspend fun readDesktop(
- userId: Int = DEFAULT_USER_ID,
+ userId: Int,
desktopId: Int = DEFAULT_DESKTOP_ID,
): Desktop? =
try {
@@ -103,7 +111,7 @@ class DesktopPersistentRepository(
/** Adds or updates a desktop stored in the datastore */
suspend fun addOrUpdateDesktop(
- userId: Int = DEFAULT_USER_ID,
+ userId: Int,
desktopId: Int = 0,
visibleTasks: ArraySet<Int> = ArraySet(),
minimizedTasks: ArraySet<Int> = ArraySet(),
@@ -111,9 +119,9 @@ class DesktopPersistentRepository(
) {
// TODO: b/367609270 - Improve the API to support multi-user
try {
- dataStore.updateData { desktopPersistentRepositories: DesktopPersistentRepositories ->
+ dataStore.updateData { persistentRepositories: DesktopPersistentRepositories ->
val currentRepository =
- desktopPersistentRepositories.getDesktopRepoByUserOrDefault(
+ persistentRepositories.getDesktopRepoByUserOrDefault(
userId, DesktopRepositoryState.getDefaultInstance())
val desktop =
getDesktop(currentRepository, desktopId)
@@ -125,7 +133,7 @@ class DesktopPersistentRepository(
)
.updateZOrder(freeformTasksInZOrder)
- desktopPersistentRepositories
+ persistentRepositories
.toBuilder()
.putDesktopRepoByUser(
userId,
@@ -135,7 +143,7 @@ class DesktopPersistentRepository(
.build())
.build()
}
- } catch (exception: IOException) {
+ } catch (exception: Exception) {
Log.e(
TAG,
"Error in updating desktop mode related data, data is " +
@@ -154,7 +162,6 @@ class DesktopPersistentRepository(
private const val TAG = "DesktopPersistenceRepo"
private const val DESKTOP_REPOSITORIES_DATASTORE_FILE = "desktop_persistent_repositories.pb"
- private const val DEFAULT_USER_ID = 1000
private const val DEFAULT_DESKTOP_ID = 0
object DesktopPersistentRepositoriesSerializer : Serializer<DesktopPersistentRepositories> {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializer.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializer.kt
index 771c3d1cb9a1..a26ebbf4c99a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializer.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializer.kt
@@ -16,9 +16,9 @@
package com.android.wm.shell.desktopmode.persistence
-import com.android.wm.shell.desktopmode.DesktopRepository
+import com.android.wm.shell.desktopmode.DesktopUserRepositories
-/** Interface for initializing the [DesktopRepository]. */
+/** Interface for initializing the [DesktopUserRepositories]. */
fun interface DesktopRepositoryInitializer {
- fun initialize(repository: DesktopRepository)
+ fun initialize(userRepositories: DesktopUserRepositories)
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt
index d8156561ff19..9539cbe0e677 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt
@@ -19,6 +19,7 @@ package com.android.wm.shell.desktopmode.persistence
import android.content.Context
import android.window.DesktopModeFlags
import com.android.wm.shell.desktopmode.DesktopRepository
+import com.android.wm.shell.desktopmode.DesktopUserRepositories
import com.android.wm.shell.shared.annotations.ShellMainThread
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
import kotlinx.coroutines.CoroutineScope
@@ -35,32 +36,52 @@ class DesktopRepositoryInitializerImpl(
private val persistentRepository: DesktopPersistentRepository,
@ShellMainThread private val mainCoroutineScope: CoroutineScope,
) : DesktopRepositoryInitializer {
- override fun initialize(repository: DesktopRepository) {
+ override fun initialize(userRepositories: DesktopUserRepositories) {
if (!DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) return
// TODO: b/365962554 - Handle the case that user moves to desktop before it's initialized
mainCoroutineScope.launch {
- val desktop = persistentRepository.readDesktop() ?: return@launch
-
- val maxTasks =
- DesktopModeStatus.getMaxTaskLimit(context).takeIf { it > 0 }
- ?: desktop.zOrderedTasksCount
-
- var visibleTasksCount = 0
- desktop.zOrderedTasksList
- // Reverse it so we initialize the repo from bottom to top.
- .reversed()
- .mapNotNull { taskId -> desktop.tasksByTaskIdMap[taskId] }
- .forEach { task ->
- if (task.desktopTaskState == DesktopTaskState.VISIBLE
- && visibleTasksCount < maxTasks
- ) {
- visibleTasksCount++
- repository.addTask(desktop.displayId, task.taskId, isVisible = false)
- } else {
- repository.addTask(desktop.displayId, task.taskId, isVisible = false)
- repository.minimizeTask(desktop.displayId, task.taskId)
+ val desktopUserPersistentRepositoryMap =
+ persistentRepository.getUserDesktopRepositoryMap() ?: return@launch
+ for (userId in desktopUserPersistentRepositoryMap.keys) {
+ val repository = userRepositories.getProfile(userId)
+ val desktopRepositoryState =
+ persistentRepository.getDesktopRepositoryState(userId) ?: continue
+ val desktopByDesktopIdMap = desktopRepositoryState.desktopMap
+ for (desktopId in desktopByDesktopIdMap.keys) {
+ val persistentDesktop =
+ persistentRepository.readDesktop(userId, desktopId) ?: continue
+ val maxTasks =
+ DesktopModeStatus.getMaxTaskLimit(context).takeIf { it > 0 }
+ ?: persistentDesktop.zOrderedTasksCount
+ var visibleTasksCount = 0
+ persistentDesktop.zOrderedTasksList
+ // Reverse it so we initialize the repo from bottom to top.
+ .reversed()
+ .mapNotNull { taskId -> persistentDesktop.tasksByTaskIdMap[taskId] }
+ .forEach { task ->
+ if (task.desktopTaskState == DesktopTaskState.VISIBLE
+ && visibleTasksCount < maxTasks) {
+ visibleTasksCount++
+ repository.addTask(
+ persistentDesktop.displayId,
+ task.taskId,
+ isVisible = false
+ )
+ } else {
+ repository.addTask(
+ persistentDesktop.displayId,
+ task.taskId,
+ isVisible = false
+ )
+ repository.minimizeTask(
+ persistentDesktop.displayId,
+ task.taskId
+ )
+ }
+ }
}
}
}
+
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
index cd20d97c7964..a17d55fdc2fe 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
@@ -30,6 +30,7 @@ import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.LaunchAdjacentController;
import com.android.wm.shell.desktopmode.DesktopRepository;
+import com.android.wm.shell.desktopmode.DesktopUserRepositories;
import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
@@ -49,7 +50,7 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
private final Context mContext;
private final ShellTaskOrganizer mShellTaskOrganizer;
- private final Optional<DesktopRepository> mDesktopRepository;
+ private final Optional<DesktopUserRepositories> mDesktopUserRepositories;
private final Optional<DesktopTasksController> mDesktopTasksController;
private final WindowDecorViewModel mWindowDecorationViewModel;
private final LaunchAdjacentController mLaunchAdjacentController;
@@ -61,7 +62,7 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
Context context,
ShellInit shellInit,
ShellTaskOrganizer shellTaskOrganizer,
- Optional<DesktopRepository> desktopRepository,
+ Optional<DesktopUserRepositories> desktopUserRepositories,
Optional<DesktopTasksController> desktopTasksController,
LaunchAdjacentController launchAdjacentController,
WindowDecorViewModel windowDecorationViewModel,
@@ -69,7 +70,7 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
mContext = context;
mShellTaskOrganizer = shellTaskOrganizer;
mWindowDecorationViewModel = windowDecorationViewModel;
- mDesktopRepository = desktopRepository;
+ mDesktopUserRepositories = desktopUserRepositories;
mDesktopTasksController = desktopTasksController;
mLaunchAdjacentController = launchAdjacentController;
mTaskChangeListener = taskChangeListener;
@@ -99,8 +100,9 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
if (!DesktopModeFlags.ENABLE_WINDOWING_TRANSITION_HANDLERS_OBSERVERS.isTrue() &&
DesktopModeStatus.canEnterDesktopMode(mContext)) {
- mDesktopRepository.ifPresent(repository -> {
- repository.addTask(taskInfo.displayId, taskInfo.taskId, taskInfo.isVisible);
+ mDesktopUserRepositories.ifPresent(userRepositories -> {
+ DesktopRepository currentRepo = userRepositories.getProfile(taskInfo.userId);
+ currentRepo.addTask(taskInfo.displayId, taskInfo.taskId, taskInfo.isVisible);
});
}
updateLaunchAdjacentController();
@@ -113,21 +115,22 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
mTasks.remove(taskInfo.taskId);
if (!DesktopModeFlags.ENABLE_WINDOWING_TRANSITION_HANDLERS_OBSERVERS.isTrue() &&
- DesktopModeStatus.canEnterDesktopMode(mContext)) {
- mDesktopRepository.ifPresent(repository -> {
- // TODO: b/370038902 - Handle Activity#finishAndRemoveTask.
- if (!DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION.isTrue()
- || repository.isClosingTask(taskInfo.taskId)) {
- // A task that's vanishing should be removed:
- // - If it's closed by the X button which means it's marked as a closing task.
- repository.removeClosingTask(taskInfo.taskId);
- repository.removeFreeformTask(taskInfo.displayId, taskInfo.taskId);
- } else {
- repository.updateTask(taskInfo.displayId, taskInfo.taskId, /* isVisible= */
- false);
- repository.minimizeTask(taskInfo.displayId, taskInfo.taskId);
- }
- });
+ DesktopModeStatus.canEnterDesktopMode(mContext)
+ && mDesktopUserRepositories.isPresent()) {
+ DesktopRepository repository =
+ mDesktopUserRepositories.get().getProfile(taskInfo.userId);
+ // TODO: b/370038902 - Handle Activity#finishAndRemoveTask.
+ if (!DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION.isTrue()
+ || repository.isClosingTask(taskInfo.taskId)) {
+ // A task that's vanishing should be removed:
+ // - If it's closed by the X button which means it's marked as a closing task.
+ repository.removeClosingTask(taskInfo.taskId);
+ repository.removeFreeformTask(taskInfo.displayId, taskInfo.taskId);
+ } else {
+ repository.updateTask(taskInfo.displayId, taskInfo.taskId, /* isVisible= */
+ false);
+ repository.minimizeTask(taskInfo.displayId, taskInfo.taskId);
+ }
}
mWindowDecorationViewModel.onTaskVanished(taskInfo);
updateLaunchAdjacentController();
@@ -148,11 +151,11 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
// does not propagate all task info changes.
mTaskChangeListener.ifPresent(listener ->
listener.onNonTransitionTaskChanging(taskInfo));
- } else {
- mDesktopRepository.ifPresent(repository -> {
- repository.updateTask(taskInfo.displayId, taskInfo.taskId,
- taskInfo.isVisible);
- });
+ } else if (mDesktopUserRepositories.isPresent()) {
+ DesktopRepository currentRepo =
+ mDesktopUserRepositories.get().getProfile(taskInfo.userId);
+ currentRepo.updateTask(taskInfo.displayId, taskInfo.taskId,
+ taskInfo.isVisible);
}
}
updateLaunchAdjacentController();
@@ -176,10 +179,11 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG,
"Freeform Task Focus Changed: #%d focused=%b",
taskInfo.taskId, taskInfo.isFocused);
- if (DesktopModeStatus.canEnterDesktopMode(mContext) && taskInfo.isFocused) {
- mDesktopRepository.ifPresent(repository -> {
- repository.addTask(taskInfo.displayId, taskInfo.taskId, taskInfo.isVisible);
- });
+ if (DesktopModeStatus.canEnterDesktopMode(mContext) && taskInfo.isFocused
+ && mDesktopUserRepositories.isPresent()) {
+ DesktopRepository repository =
+ mDesktopUserRepositories.get().getProfile(taskInfo.userId);
+ repository.addTask(taskInfo.displayId, taskInfo.taskId, taskInfo.isVisible);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
index 5276d9d6a4df..55e90e74a404 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
@@ -324,6 +324,8 @@ public class PipAnimationController {
private final @AnimationType int mAnimationType;
private final Rect mDestinationBounds = new Rect();
+ private final Point mLeashOffset = new Point();
+
private T mBaseValue;
protected T mCurrentValue;
protected T mStartValue;
@@ -338,13 +340,22 @@ public class PipAnimationController {
// Flag to avoid double-end
private boolean mHasRequestedEnd;
- private PipTransitionAnimator(TaskInfo taskInfo, SurfaceControl leash,
- @AnimationType int animationType,
- Rect destinationBounds, T baseValue, T startValue, T endValue) {
+ private PipTransitionAnimator(@NonNull TaskInfo taskInfo, @NonNull SurfaceControl leash,
+ @AnimationType int animationType, @NonNull Rect destinationBounds,
+ @NonNull T baseValue, @NonNull T startValue, @NonNull T endValue) {
+ this(taskInfo, leash, animationType, destinationBounds, new Point(), baseValue,
+ startValue, endValue);
+ }
+
+ private PipTransitionAnimator(@NonNull TaskInfo taskInfo, @NonNull SurfaceControl leash,
+ @AnimationType int animationType, @NonNull Rect destinationBounds,
+ @NonNull Point leashOffset, @NonNull T baseValue, @NonNull T startValue,
+ @NonNull T endValue) {
mTaskInfo = taskInfo;
mLeash = leash;
mAnimationType = animationType;
mDestinationBounds.set(destinationBounds);
+ mLeashOffset.set(leashOffset);
mBaseValue = baseValue;
mStartValue = startValue;
mEndValue = endValue;
@@ -496,6 +507,15 @@ public class PipAnimationController {
}
}
+ /**
+ * Returns the offset of the {@link #mLeash}.
+ */
+ @NonNull
+ Point getLeashOffset() {
+ // Use copy to prevent the leash to be modified unexpectedly.
+ return new Point(mLeashOffset);
+ }
+
void setCurrentValue(T value) {
mCurrentValue = value;
}
@@ -692,8 +712,8 @@ public class PipAnimationController {
final Rect zeroInsets = new Rect(0, 0, 0, 0);
// construct new Rect instances in case they are recycled
- return new PipTransitionAnimator<Rect>(taskInfo, leash, ANIM_TYPE_BOUNDS,
- endBounds, new Rect(baseBounds), new Rect(startBounds), new Rect(endBounds)) {
+ return new PipTransitionAnimator<Rect>(taskInfo, leash, ANIM_TYPE_BOUNDS, endBounds,
+ leashOffset, new Rect(baseBounds), new Rect(startBounds), new Rect(endBounds)) {
private final RectEvaluator mRectEvaluator = new RectEvaluator(new Rect());
private final RectEvaluator mInsetsEvaluator = new RectEvaluator(new Rect());
@@ -720,6 +740,7 @@ public class PipAnimationController {
// Use the bounds relative to the task leash in case the leash does not
// start from (0, 0).
final Rect relativeEndBounds = new Rect(end);
+ final Point leashOffset = getLeashOffset();
relativeEndBounds.offset(-leashOffset.x, -leashOffset.y);
getSurfaceTransactionHelper()
.crop(tx, leash, relativeEndBounds)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index fb4afe41e193..af187682d379 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -94,6 +94,7 @@ import com.android.wm.shell.common.pip.PipPerfHintController;
import com.android.wm.shell.common.pip.PipUiEventLogger;
import com.android.wm.shell.common.pip.PipUtils;
import com.android.wm.shell.desktopmode.DesktopRepository;
+import com.android.wm.shell.desktopmode.DesktopUserRepositories;
import com.android.wm.shell.pip.phone.PipMotionHelper;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.shared.animation.Interpolators;
@@ -152,7 +153,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;
private final Optional<SplitScreenController> mSplitScreenOptional;
@Nullable private final PipPerfHintController mPipPerfHintController;
- private final Optional<DesktopRepository> mDesktopRepositoryOptional;
+ private final Optional<DesktopUserRepositories> mDesktopUserRepositoriesOptional;
private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
private final DisplayController mDisplayController;
protected final ShellTaskOrganizer mTaskOrganizer;
@@ -398,7 +399,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
@NonNull PipParamsChangedForwarder pipParamsChangedForwarder,
Optional<SplitScreenController> splitScreenOptional,
Optional<PipPerfHintController> pipPerfHintControllerOptional,
- Optional<DesktopRepository> desktopRepositoryOptional,
+ Optional<DesktopUserRepositories> desktopUserRepositoriesOptional,
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
@NonNull DisplayController displayController,
@NonNull PipUiEventLogger pipUiEventLogger,
@@ -426,7 +427,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
new PipSurfaceTransactionHelper.VsyncSurfaceControlTransactionFactory();
mSplitScreenOptional = splitScreenOptional;
mPipPerfHintController = pipPerfHintControllerOptional.orElse(null);
- mDesktopRepositoryOptional = desktopRepositoryOptional;
+ mDesktopUserRepositoriesOptional = desktopUserRepositoriesOptional;
mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
mDisplayController = displayController;
mTaskOrganizer = shellTaskOrganizer;
@@ -764,7 +765,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
// previous freeform bounds that is saved in DesktopRepository.
// 2) If PiP was entered through other means (e.g. user swipe up), exit to initial
// freeform bounds. Note that this case has a flicker at the moment (b/379984108).
- Rect freeformBounds = mDesktopRepositoryOptional.get().removeBoundsBeforeMinimize(
+ Rect freeformBounds = getCurrentRepo().removeBoundsBeforeMinimize(
mTaskInfo.taskId);
return freeformBounds != null
? freeformBounds
@@ -779,11 +780,17 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
/** Returns whether PiP is exiting while we're in desktop mode. */
// TODO(b/377581840): Update this check to include non-minimized cases, e.g. split to PiP etc.
private boolean isPipExitingToDesktopMode() {
- return Flags.enableDesktopWindowingPip() && mDesktopRepositoryOptional.isPresent()
- && (mDesktopRepositoryOptional.get().getVisibleTaskCount(mTaskInfo.displayId) > 0
+ DesktopRepository currentRepo = getCurrentRepo();
+ return Flags.enableDesktopWindowingPip() && currentRepo != null
+ && (currentRepo.getVisibleTaskCount(mTaskInfo.displayId) > 0
|| isDisplayInFreeform());
}
+ private DesktopRepository getCurrentRepo() {
+ return mDesktopUserRepositoriesOptional.map(DesktopUserRepositories::getCurrent).orElse(
+ null);
+ }
+
private void exitLaunchIntoPipTask(WindowContainerTransaction wct) {
wct.startTask(mTaskInfo.launchIntoPipHostTaskId, null /* ActivityOptions */);
mTaskOrganizer.applyTransaction(wct);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index 72c1ef06806a..0042ec954f32 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -507,8 +507,8 @@ public class PipTransition extends PipTransitionController {
}
@Override
- public void onFinishResize(TaskInfo taskInfo, Rect destinationBounds,
- @PipAnimationController.TransitionDirection int direction,
+ public void onFinishResize(@NonNull TaskInfo taskInfo, @NonNull Rect destinationBounds,
+ @NonNull Point leashOffset, @PipAnimationController.TransitionDirection int direction,
@NonNull SurfaceControl.Transaction tx) {
final boolean enteringPip = isInPipDirection(direction);
if (enteringPip) {
@@ -531,12 +531,16 @@ public class PipTransition extends PipTransitionController {
if (mFixedRotationState != FIXED_ROTATION_TRANSITION
&& mFinishTransaction != null) {
mFinishTransaction.merge(tx);
- // Set window crop and position to destination bounds to avoid flickering.
+ // Set crop and position to destination bounds to avoid flickering.
if (hasValidLeash) {
- mFinishTransaction.setWindowCrop(leash, destinationBounds.width(),
- destinationBounds.height());
- mFinishTransaction.setPosition(leash, destinationBounds.left,
- destinationBounds.top);
+ final Rect relativeDestinationBounds = new Rect(destinationBounds);
+ relativeDestinationBounds.offset(-leashOffset.x, -leashOffset.y);
+ mFinishTransaction
+ .setCrop(leash, relativeDestinationBounds)
+ // Note that we should set the position to the start position of
+ // leash then the visible region will be at the same place even if
+ // the crop region doesn't start at (0, 0).
+ .setPosition(leash, leashOffset.x, leashOffset.y);
}
}
} else {
@@ -1267,7 +1271,8 @@ public class PipTransition extends PipTransitionController {
mPipBoundsState.setBounds(destinationBounds);
final SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
- onFinishResize(pipTaskInfo, destinationBounds, TRANSITION_DIRECTION_TO_PIP, tx);
+ onFinishResize(pipTaskInfo, destinationBounds, animator.getLeashOffset(),
+ TRANSITION_DIRECTION_TO_PIP, tx);
sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP);
if (swipePipToHomeOverlay != null) {
mPipOrganizer.fadeOutAndRemoveOverlay(swipePipToHomeOverlay,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
index a273822759f6..6129651dc271 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
@@ -31,6 +31,7 @@ import android.app.PictureInPictureUiState;
import android.app.TaskInfo;
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
+import android.graphics.Point;
import android.graphics.Rect;
import android.os.IBinder;
import android.os.RemoteException;
@@ -92,7 +93,8 @@ public abstract class PipTransitionController implements Transitions.TransitionH
mPipOrganizer.fadeOutAndRemoveOverlay(mPipOrganizer.mPipOverlay,
null /* callback */, true /* withStartDelay*/);
}
- onFinishResize(taskInfo, animator.getDestinationBounds(), direction, tx);
+ onFinishResize(taskInfo, animator.getDestinationBounds(),
+ animator.getLeashOffset(), direction, tx);
sendOnPipTransitionFinished(direction);
}
@@ -112,9 +114,9 @@ public abstract class PipTransitionController implements Transitions.TransitionH
* Called when transition is about to finish. This is usually for performing tasks such as
* applying WindowContainerTransaction to finalize the PiP bounds and send to the framework.
*/
- public void onFinishResize(TaskInfo taskInfo, Rect destinationBounds,
- @PipAnimationController.TransitionDirection int direction,
- SurfaceControl.Transaction tx) {
+ public void onFinishResize(@NonNull TaskInfo taskInfo, @NonNull Rect destinationBounds,
+ @NonNull Point leashOffset, @PipAnimationController.TransitionDirection int direction,
+ @NonNull SurfaceControl.Transaction tx) {
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
index 5438a014af00..4461a5c6a70c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
@@ -16,6 +16,7 @@
package com.android.wm.shell.pip2.phone;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP;
@@ -25,6 +26,7 @@ import android.content.Context;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.view.SurfaceControl;
+import android.window.DisplayAreaInfo;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
@@ -33,13 +35,19 @@ import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.ProtoLog;
+import com.android.window.flags.Flags;
+import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.pip.PipBoundsState;
+import com.android.wm.shell.desktopmode.DesktopUserRepositories;
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.pip2.PipSurfaceTransactionHelper;
import com.android.wm.shell.pip2.animation.PipAlphaAnimator;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
+import java.util.Objects;
+import java.util.Optional;
+
/**
* Scheduler for Shell initiated PiP transitions and animations.
*/
@@ -50,6 +58,8 @@ public class PipScheduler {
private final PipBoundsState mPipBoundsState;
private final ShellExecutor mMainExecutor;
private final PipTransitionState mPipTransitionState;
+ private final Optional<DesktopUserRepositories> mDesktopUserRepositoriesOptional;
+ private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
private PipTransitionController mPipTransitionController;
private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory
mSurfaceControlTransactionFactory;
@@ -61,11 +71,15 @@ public class PipScheduler {
public PipScheduler(Context context,
PipBoundsState pipBoundsState,
ShellExecutor mainExecutor,
- PipTransitionState pipTransitionState) {
+ PipTransitionState pipTransitionState,
+ Optional<DesktopUserRepositories> desktopUserRepositoriesOptional,
+ RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) {
mContext = context;
mPipBoundsState = pipBoundsState;
mMainExecutor = mainExecutor;
mPipTransitionState = pipTransitionState;
+ mDesktopUserRepositoriesOptional = desktopUserRepositoriesOptional;
+ mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
mSurfaceControlTransactionFactory =
new PipSurfaceTransactionHelper.VsyncSurfaceControlTransactionFactory();
@@ -87,7 +101,7 @@ public class PipScheduler {
wct.setBounds(pipTaskToken, null);
// if we are hitting a multi-activity case
// windowing mode change will reparent to original host task
- wct.setWindowingMode(pipTaskToken, WINDOWING_MODE_UNDEFINED);
+ wct.setWindowingMode(pipTaskToken, getOutPipWindowingMode());
return wct;
}
@@ -241,6 +255,47 @@ public class PipScheduler {
maybeUpdateMovementBounds();
}
+ /** Returns whether the display is in freeform windowing mode. */
+ private boolean isDisplayInFreeform() {
+ final DisplayAreaInfo tdaInfo = mRootTaskDisplayAreaOrganizer.getDisplayAreaInfo(
+ Objects.requireNonNull(mPipTransitionState.getPipTaskInfo()).displayId);
+ if (tdaInfo != null) {
+ return tdaInfo.configuration.windowConfiguration.getWindowingMode()
+ == WINDOWING_MODE_FREEFORM;
+ }
+ return false;
+ }
+
+ /** Returns whether PiP is exiting while we're in desktop mode. */
+ private boolean isPipExitingToDesktopMode() {
+ return Flags.enableDesktopWindowingPip() && mDesktopUserRepositoriesOptional.isPresent()
+ && (mDesktopUserRepositoriesOptional.get().getCurrent().getVisibleTaskCount(
+ Objects.requireNonNull(mPipTransitionState.getPipTaskInfo()).displayId) > 0
+ || isDisplayInFreeform());
+ }
+
+ /**
+ * 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.
+ */
+ private int getOutPipWindowingMode() {
+ // If we are exiting PiP while the device is in Desktop mode (the task should expand to
+ // freeform windowing mode):
+ // 1) If the display windowing mode is freeform, set windowing mode to undefined so it will
+ // resolve the windowing mode to the display's windowing mode.
+ // 2) If the display windowing mode is not freeform, set windowing mode to freeform.
+ if (isPipExitingToDesktopMode()) {
+ if (isDisplayInFreeform()) {
+ return WINDOWING_MODE_UNDEFINED;
+ } else {
+ return WINDOWING_MODE_FREEFORM;
+ }
+ }
+
+ // By default, or if the task is going to fullscreen, reset the windowing mode to undefined.
+ return WINDOWING_MODE_UNDEFINED;
+ }
+
@VisibleForTesting
void setSurfaceControlTransactionFactory(
@NonNull PipSurfaceTransactionHelper.SurfaceControlTransactionFactory factory) {
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 8f02c1b157b5..b171db2c3793 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
@@ -627,6 +627,12 @@ public class PipTransition extends PipTransitionController implements
finishTransition();
});
cacheAndStartTransitionAnimator(animator);
+
+ // Save the PiP bounds in case, we re-enter the PiP with the same component.
+ float snapFraction = mPipBoundsAlgorithm.getSnapFraction(
+ mPipBoundsState.getBounds());
+ mPipBoundsState.saveReentryState(snapFraction);
+
return true;
}
@@ -912,11 +918,6 @@ public class PipTransition extends PipTransitionController implements
"Unexpected bundle for " + mPipTransitionState);
break;
case PipTransitionState.EXITED_PIP:
- // Save the PiP bounds in case, we re-enter the PiP with the same component.
- float snapFraction = mPipBoundsAlgorithm.getSnapFraction(
- mPipBoundsState.getBounds());
- mPipBoundsState.saveReentryState(snapFraction);
-
mPipTransitionState.setPinnedTaskLeash(null);
mPipTransitionState.setPipTaskInfo(null);
break;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
index 363c95fcf010..441f96728d0c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
@@ -63,6 +63,7 @@ import com.android.wm.shell.common.SingleInstanceRemoteListener;
import com.android.wm.shell.common.TaskStackListenerCallback;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.desktopmode.DesktopRepository;
+import com.android.wm.shell.desktopmode.DesktopUserRepositories;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.shared.GroupedTaskInfo;
import com.android.wm.shell.shared.annotations.ExternalThread;
@@ -72,6 +73,7 @@ import com.android.wm.shell.shared.split.SplitBounds;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
+import com.android.wm.shell.sysui.UserChangeListener;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -89,13 +91,14 @@ import java.util.function.Consumer;
*/
public class RecentTasksController implements TaskStackListenerCallback,
RemoteCallable<RecentTasksController>, DesktopRepository.ActiveTasksListener,
- TaskStackTransitionObserver.TaskStackTransitionObserverListener {
+ TaskStackTransitionObserver.TaskStackTransitionObserverListener, UserChangeListener {
private static final String TAG = RecentTasksController.class.getSimpleName();
private final Context mContext;
private final ShellController mShellController;
private final ShellCommandHandler mShellCommandHandler;
- private final Optional<DesktopRepository> mDesktopRepository;
+ private final Optional<DesktopUserRepositories> mDesktopUserRepositories;
+
private final ShellExecutor mMainExecutor;
private final TaskStackListenerImpl mTaskStackListener;
private final RecentTasksImpl mImpl = new RecentTasksImpl();
@@ -108,6 +111,8 @@ public class RecentTasksController implements TaskStackListenerCallback,
// Mapping of split task ids, mappings are symmetrical (ie. if t1 is the taskid of a task in a
// pair, then mSplitTasks[t1] = t2, and mSplitTasks[t2] = t1)
private final SparseIntArray mSplitTasks = new SparseIntArray();
+
+ private int mUserId;
/**
* Maps taskId to {@link SplitBounds} for both taskIDs.
* Meaning there will be two taskId integers mapping to the same object.
@@ -133,7 +138,7 @@ public class RecentTasksController implements TaskStackListenerCallback,
ShellCommandHandler shellCommandHandler,
TaskStackListenerImpl taskStackListener,
ActivityTaskManager activityTaskManager,
- Optional<DesktopRepository> desktopRepository,
+ Optional<DesktopUserRepositories> desktopUserRepositories,
TaskStackTransitionObserver taskStackTransitionObserver,
@ShellMainThread ShellExecutor mainExecutor
) {
@@ -141,7 +146,7 @@ public class RecentTasksController implements TaskStackListenerCallback,
return null;
}
return new RecentTasksController(context, shellInit, shellController, shellCommandHandler,
- taskStackListener, activityTaskManager, desktopRepository,
+ taskStackListener, activityTaskManager, desktopUserRepositories,
taskStackTransitionObserver, mainExecutor);
}
@@ -151,7 +156,7 @@ public class RecentTasksController implements TaskStackListenerCallback,
ShellCommandHandler shellCommandHandler,
TaskStackListenerImpl taskStackListener,
ActivityTaskManager activityTaskManager,
- Optional<DesktopRepository> desktopRepository,
+ Optional<DesktopUserRepositories> desktopUserRepositories,
TaskStackTransitionObserver taskStackTransitionObserver,
ShellExecutor mainExecutor) {
mContext = context;
@@ -160,7 +165,7 @@ public class RecentTasksController implements TaskStackListenerCallback,
mActivityTaskManager = activityTaskManager;
mPcFeatureEnabled = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
mTaskStackListener = taskStackListener;
- mDesktopRepository = desktopRepository;
+ mDesktopUserRepositories = desktopUserRepositories;
mTaskStackTransitionObserver = taskStackTransitionObserver;
mMainExecutor = mainExecutor;
shellInit.addInitCallback(this::onInit, this);
@@ -175,12 +180,15 @@ public class RecentTasksController implements TaskStackListenerCallback,
}
@RequiresPermission(Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)
- private void onInit() {
+ void onInit() {
mShellController.addExternalInterface(KEY_EXTRA_SHELL_RECENT_TASKS,
this::createExternalInterface, this);
mShellCommandHandler.addDumpCallback(this::dump, this);
+ mUserId = ActivityManager.getCurrentUser();
+ mDesktopUserRepositories.ifPresent(
+ desktopUserRepositories ->
+ desktopUserRepositories.getCurrent().addActiveTaskListener(this));
mTaskStackListener.addListener(this);
- mDesktopRepository.ifPresent(it -> it.addActiveTaskListener(this));
mTaskStackTransitionObserver.addTaskStackTransitionObserverListener(this,
mMainExecutor);
mContext.getSystemService(KeyguardManager.class).addKeyguardLockedStateListener(
@@ -291,9 +299,9 @@ public class RecentTasksController implements TaskStackListenerCallback,
*/
@Override
public void onRecentTaskRemovedForAddTask(int taskId) {
- mDesktopRepository.ifPresent(
- repo -> repo.removeFreeformTask(INVALID_DISPLAY, taskId)
- );
+ mDesktopUserRepositories.ifPresent(
+ desktopUserRepositories -> desktopUserRepositories.getCurrent().removeFreeformTask(
+ INVALID_DISPLAY, taskId));
}
public void onTaskAdded(RunningTaskInfo taskInfo) {
@@ -512,10 +520,9 @@ public class RecentTasksController implements TaskStackListenerCallback,
// If it's not in the mapping, then it was already paired with another task
continue;
}
-
- if (DesktopModeStatus.canEnterDesktopMode(mContext)
- && mDesktopRepository.isPresent()
- && mDesktopRepository.get().isActiveTask(taskInfo.taskId)) {
+ if (DesktopModeStatus.canEnterDesktopMode(mContext) &&
+ mDesktopUserRepositories.isPresent()
+ && mDesktopUserRepositories.get().getCurrent().isActiveTask(taskInfo.taskId)) {
// Freeform tasks will be added as a separate entry
if (mostRecentFreeformTaskIndex == Integer.MAX_VALUE) {
mostRecentFreeformTaskIndex = groupedTasks.size();
@@ -531,7 +538,7 @@ public class RecentTasksController implements TaskStackListenerCallback,
taskInfo.lastNonFullscreenBounds.top);
}
freeformTasks.add(taskInfo);
- if (mDesktopRepository.get().isMinimizedTask(taskInfo.taskId)) {
+ if (mDesktopUserRepositories.get().getCurrent().isMinimizedTask(taskInfo.taskId)) {
minimizedFreeformTasks.add(taskInfo.taskId);
}
continue;
@@ -703,6 +710,21 @@ public class RecentTasksController implements TaskStackListenerCallback,
}
}
+ @Override
+ public void onUserChanged(int newUserId, @NonNull Context userContext) {
+ if (mDesktopUserRepositories.isEmpty()) return;
+
+ DesktopRepository previousUserRepository =
+ mDesktopUserRepositories.get().getProfile(mUserId);
+ mUserId = newUserId;
+ DesktopRepository currentUserRepository =
+ mDesktopUserRepositories.get().getProfile(newUserId);
+
+ // No-op if both profile ids map to the same user.
+ if (previousUserRepository.getUserId() == currentUserRepository.getUserId()) return;
+ previousUserRepository.removeActiveTasksListener(this);
+ currentUserRepository.addActiveTaskListener(this);
+ }
/**
* The interface for calls from outside the host process.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 88a95660f098..07c157b4394c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -501,6 +501,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
/**
* Deactivates main stage by removing the stage from the top level split root (usually when a
* task underneath gets removed from the stage root).
+ * This function should always be called as part of exiting split screen.
* @param stageToTop stage which we want to put on top
*/
private void deactivateSplit(WindowContainerTransaction wct, @StageType int stageToTop) {
@@ -833,7 +834,14 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
setSideStagePosition(splitPosition, wct);
options1 = options1 != null ? options1 : new Bundle();
- addActivityOptions(options1, mSideStage);
+ StageTaskListener stageForTask1;
+ if (enableFlexibleSplit()) {
+ stageForTask1 = mStageOrderOperator.getStageForLegacyPosition(splitPosition,
+ true /*checkAllStagesIfNotActive*/);
+ } else {
+ stageForTask1 = mSideStage;
+ }
+ addActivityOptions(options1, stageForTask1);
wct.sendPendingIntent(pendingIntent, fillInIntent, options1);
prepareTasksForSplitScreen(new int[] {taskId}, wct);
@@ -878,7 +886,14 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
setSideStagePosition(splitPosition, wct);
options1 = options1 != null ? options1 : new Bundle();
- addActivityOptions(options1, mSideStage);
+ StageTaskListener stageForTask1;
+ if (enableFlexibleSplit()) {
+ stageForTask1 = mStageOrderOperator.getStageForLegacyPosition(splitPosition,
+ true /*checkAllStagesIfNotActive*/);
+ } else {
+ stageForTask1 = mSideStage;
+ }
+ addActivityOptions(options1, stageForTask1);
wct.startShortcut(mContext.getPackageName(), shortcutInfo, options1);
prepareTasksForSplitScreen(new int[] {taskId}, wct);
@@ -1010,14 +1025,29 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
setRootForceTranslucent(false, wct);
options1 = options1 != null ? options1 : new Bundle();
- addActivityOptions(options1, mSideStage);
+ StageTaskListener stageForTask1;
+ if (enableFlexibleSplit()) {
+ stageForTask1 = mStageOrderOperator.getStageForLegacyPosition(splitPosition,
+ true /*checkAllStagesIfNotActive*/);
+ } else {
+ stageForTask1 = mSideStage;
+ }
+ addActivityOptions(options1, stageForTask1);
if (shortcutInfo1 != null) {
wct.startShortcut(mContext.getPackageName(), shortcutInfo1, options1);
} else {
wct.sendPendingIntent(pendingIntent1, fillInIntent1, options1);
}
+
+ StageTaskListener stageForTask2;
+ if (enableFlexibleSplit()) {
+ stageForTask2 = mStageOrderOperator.getStageForLegacyPosition(
+ reverseSplitPosition(splitPosition), true /*checkAllStagesIfNotActive*/);
+ } else {
+ stageForTask2 = mMainStage;
+ }
options2 = options2 != null ? options2 : new Bundle();
- addActivityOptions(options2, mMainStage);
+ addActivityOptions(options2, stageForTask2);
if (shortcutInfo2 != null) {
wct.startShortcut(mContext.getPackageName(), shortcutInfo2, options2);
} else {
@@ -1246,6 +1276,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// Restore focus-ability to the windows and divider
wct.setFocusable(mRootTaskInfo.token, true);
+ if (enableFlexibleSplit()) {
+ mStageOrderOperator.onDoubleTappedDivider();
+ }
setSideStagePosition(reverseSplitPosition(mSideStagePosition), wct);
mSyncQueue.queue(wct);
mSyncQueue.runInSync(st -> {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageOrderOperator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageOrderOperator.kt
index b7b3c9b62a58..3fa8df40dfef 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageOrderOperator.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageOrderOperator.kt
@@ -38,6 +38,7 @@ import com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_B
import com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_C
import com.android.wm.shell.splitscreen.SplitScreen.stageTypeToString
import com.android.wm.shell.windowdecor.WindowDecorViewModel
+import java.util.Collections
import java.util.Optional
/**
@@ -148,6 +149,24 @@ class StageOrderOperator (
}
/**
+ * This will swap the stages for the two stages on either side of the given divider.
+ * Note: This will keep [activeStages] and [allStages] in sync by swapping both of them
+ * If there are no [activeStages] then this will be a no-op.
+ *
+ * TODO(b/379984874): Take in a divider identifier to determine which array indices to swap
+ */
+ fun onDoubleTappedDivider() {
+ if (activeStages.isEmpty()) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
+ "Stages not active, ignoring swap request")
+ return
+ }
+
+ Collections.swap(activeStages, 0, 1)
+ Collections.swap(allStages, 0, 1)
+ }
+
+ /**
* Returns a legacy split position for the given stage. If no stages are active then this will
* return [SPLIT_POSITION_UNDEFINED]
*/
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
index c9f2d2e8c0e2..885f3dbed275 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
@@ -63,6 +63,7 @@ import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
import com.android.wm.shell.shared.FocusTransitionListener;
import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
+import com.android.wm.shell.shared.annotations.ShellMainThread;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.FocusTransitionObserver;
@@ -119,8 +120,8 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel, FocusT
public CaptionWindowDecorViewModel(
Context context,
Handler mainHandler,
+ @ShellMainThread ShellExecutor shellExecutor,
@ShellBackgroundThread ShellExecutor bgExecutor,
- ShellExecutor shellExecutor,
Choreographer mainChoreographer,
IWindowManager windowManager,
ShellInit shellInit,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
index 982fda0ddf36..aa954fbe5669 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
@@ -194,6 +194,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
@VisibleForTesting
static void updateRelayoutParams(
RelayoutParams relayoutParams,
+ @NonNull Context context,
ActivityManager.RunningTaskInfo taskInfo,
boolean applyStartTransactionOnDraw,
boolean shouldSetTaskVisibilityPositionAndCrop,
@@ -206,9 +207,11 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
relayoutParams.mRunningTaskInfo = taskInfo;
relayoutParams.mLayoutResId = R.layout.caption_window_decor;
relayoutParams.mCaptionHeightId = getCaptionHeightIdStatic(taskInfo.getWindowingMode());
- relayoutParams.mShadowRadiusId = hasGlobalFocus
- ? R.dimen.freeform_decor_shadow_focused_thickness
- : R.dimen.freeform_decor_shadow_unfocused_thickness;
+ relayoutParams.mShadowRadius = hasGlobalFocus
+ ? context.getResources().getDimensionPixelSize(
+ R.dimen.freeform_decor_shadow_focused_thickness)
+ : context.getResources().getDimensionPixelSize(
+ R.dimen.freeform_decor_shadow_unfocused_thickness);
relayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw;
relayoutParams.mSetTaskVisibilityPositionAndCrop = shouldSetTaskVisibilityPositionAndCrop;
relayoutParams.mIsCaptionVisible = taskInfo.isFreeform()
@@ -251,7 +254,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
final SurfaceControl oldDecorationSurface = mDecorationContainerSurface;
final WindowContainerTransaction wct = new WindowContainerTransaction();
- updateRelayoutParams(mRelayoutParams, taskInfo, applyStartTransactionOnDraw,
+ updateRelayoutParams(mRelayoutParams, mContext, taskInfo, applyStartTransactionOnDraw,
shouldSetTaskVisibilityPositionAndCrop, mIsStatusBarVisible,
mIsKeyguardVisibleAndOccluded,
mDisplayController.getInsetsState(taskInfo.displayId), hasGlobalFocus,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHeaderManageWindowsMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHeaderManageWindowsMenu.kt
index 101467df03ac..ff52a45c94e2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHeaderManageWindowsMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHeaderManageWindowsMenu.kt
@@ -32,7 +32,7 @@ import com.android.internal.annotations.VisibleForTesting
import com.android.window.flags.Flags
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.common.DisplayController
-import com.android.wm.shell.desktopmode.DesktopRepository
+import com.android.wm.shell.desktopmode.DesktopUserRepositories
import com.android.wm.shell.shared.multiinstance.ManageWindowsViewContainer
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewContainer
@@ -51,7 +51,7 @@ class DesktopHeaderManageWindowsMenu(
private val displayController: DisplayController,
private val rootTdaOrganizer: RootTaskDisplayAreaOrganizer,
context: Context,
- private val desktopRepository: DesktopRepository,
+ private val desktopUserRepositories: DesktopUserRepositories,
private val surfaceControlBuilderSupplier: Supplier<SurfaceControl.Builder>,
private val surfaceControlTransactionSupplier: Supplier<SurfaceControl.Transaction>,
snapshotList: List<Pair<Int, TaskSnapshot>>,
@@ -76,6 +76,7 @@ class DesktopHeaderManageWindowsMenu(
val flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH or
WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
+ val desktopRepository = desktopUserRepositories.getProfile(callerTaskInfo.userId)
menuViewContainer = if (Flags.enableFullyImmersiveInDesktop()
&& desktopRepository.isTaskInFullImmersiveState(callerTaskInfo.taskId)) {
// Use system view container so that forcibly shown system bars take effect in
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index 04ef7c1dc461..0c077da0a5e8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -111,13 +111,17 @@ import com.android.wm.shell.desktopmode.DesktopImmersiveController;
import com.android.wm.shell.desktopmode.DesktopModeEventLogger;
import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger;
import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum;
+import com.android.wm.shell.desktopmode.DesktopModeUtils;
import com.android.wm.shell.desktopmode.DesktopModeVisualIndicator;
import com.android.wm.shell.desktopmode.DesktopRepository;
import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition;
import com.android.wm.shell.desktopmode.DesktopTasksLimiter;
+import com.android.wm.shell.desktopmode.DesktopUserRepositories;
import com.android.wm.shell.desktopmode.DesktopWallpaperActivity;
import com.android.wm.shell.desktopmode.WindowDecorCaptionHandleRepository;
+import com.android.wm.shell.desktopmode.common.ToggleTaskSizeInteraction;
+import com.android.wm.shell.desktopmode.common.ToggleTaskSizeUtilsKt;
import com.android.wm.shell.desktopmode.education.AppHandleEducationController;
import com.android.wm.shell.desktopmode.education.AppToWebEducationController;
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
@@ -166,7 +170,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
private final ActivityTaskManager mActivityTaskManager;
private final ShellCommandHandler mShellCommandHandler;
private final ShellTaskOrganizer mTaskOrganizer;
- private final DesktopRepository mDesktopRepository;
+ private final DesktopUserRepositories mDesktopUserRepositories;
private final ShellController mShellController;
private final Context mContext;
private final @ShellMainThread Handler mMainHandler;
@@ -244,7 +248,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
ShellCommandHandler shellCommandHandler,
IWindowManager windowManager,
ShellTaskOrganizer taskOrganizer,
- DesktopRepository desktopRepository,
+ DesktopUserRepositories desktopUserRepositories,
DisplayController displayController,
ShellController shellController,
DisplayInsetsController displayInsetsController,
@@ -275,7 +279,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
shellCommandHandler,
windowManager,
taskOrganizer,
- desktopRepository,
+ desktopUserRepositories,
displayController,
shellController,
displayInsetsController,
@@ -315,7 +319,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
ShellCommandHandler shellCommandHandler,
IWindowManager windowManager,
ShellTaskOrganizer taskOrganizer,
- DesktopRepository desktopRepository,
+ DesktopUserRepositories desktopUserRepositories,
DisplayController displayController,
ShellController shellController,
DisplayInsetsController displayInsetsController,
@@ -349,7 +353,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
mBgExecutor = bgExecutor;
mActivityTaskManager = mContext.getSystemService(ActivityTaskManager.class);
mTaskOrganizer = taskOrganizer;
- mDesktopRepository = desktopRepository;
+ mDesktopUserRepositories = desktopUserRepositories;
mShellController = shellController;
mDisplayController = displayController;
mDisplayInsetsController = displayInsetsController;
@@ -580,34 +584,59 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
>= MANAGE_WINDOWS_MINIMUM_INSTANCES);
}
- private void onMaximizeOrRestore(int taskId, String source, ResizeTrigger resizeTrigger,
- MotionEvent motionEvent) {
+ private void onToggleSizeInteraction(
+ int taskId, @NonNull ToggleTaskSizeInteraction.AmbiguousSource source,
+ @Nullable MotionEvent motionEvent) {
final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId);
if (decoration == null) {
return;
}
- mDesktopTasksController.toggleDesktopTaskSize(decoration.mTaskInfo, resizeTrigger,
- DesktopModeEventLogger.getInputMethodFromMotionEvent(motionEvent), () -> {
- mInteractionJankMonitor.begin(
- decoration.mTaskSurface, mContext, mMainHandler,
- Cuj.CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW, source);
- return null;
- }, () -> {
- mInteractionJankMonitor.begin(
- decoration.mTaskSurface, mContext, mMainHandler,
- Cuj.CUJ_DESKTOP_MODE_UNMAXIMIZE_WINDOW, source);
- return null;
- });
+ final ToggleTaskSizeInteraction interaction =
+ createToggleSizeInteraction(decoration, source, motionEvent);
+ if (interaction == null) {
+ return;
+ }
+ if (interaction.getCujTracing() != null) {
+ mInteractionJankMonitor.begin(
+ decoration.mTaskSurface, mContext, mMainHandler,
+ interaction.getCujTracing(), interaction.getJankTag());
+ }
+ mDesktopTasksController.toggleDesktopTaskSize(decoration.mTaskInfo, interaction);
decoration.closeHandleMenu();
decoration.closeMaximizeMenu();
}
- private void onEnterOrExitImmersive(int taskId) {
- final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId);
+ private ToggleTaskSizeInteraction createToggleSizeInteraction(
+ @NonNull DesktopModeWindowDecoration decoration,
+ @NonNull ToggleTaskSizeInteraction.AmbiguousSource source,
+ @Nullable MotionEvent motionEvent) {
+ final RunningTaskInfo taskInfo = decoration.mTaskInfo;
+
+ final DisplayLayout displayLayout = mDisplayController.getDisplayLayout(taskInfo.displayId);
+ if (displayLayout == null) {
+ return null;
+ }
+ final Rect stableBounds = new Rect();
+ displayLayout.getStableBounds(stableBounds);
+ boolean isMaximized = DesktopModeUtils.isTaskMaximized(taskInfo, stableBounds);
+
+ return new ToggleTaskSizeInteraction(
+ isMaximized
+ ? ToggleTaskSizeInteraction.Direction.RESTORE
+ : ToggleTaskSizeInteraction.Direction.MAXIMIZE,
+ ToggleTaskSizeUtilsKt.toSource(source, isMaximized),
+ DesktopModeEventLogger.getInputMethodFromMotionEvent(motionEvent)
+ );
+ }
+
+ private void onEnterOrExitImmersive(RunningTaskInfo taskInfo) {
+ final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId);
if (decoration == null) {
return;
}
- if (mDesktopRepository.isTaskInFullImmersiveState(taskId)) {
+ final DesktopRepository desktopRepository = mDesktopUserRepositories.getProfile(
+ taskInfo.userId);
+ if (desktopRepository.isTaskInFullImmersiveState(taskInfo.taskId)) {
mDesktopModeUiEventLogger.log(decoration.mTaskInfo,
DesktopUiEventEnum.DESKTOP_WINDOW_MAXIMIZE_BUTTON_MENU_TAP_TO_RESTORE);
mDesktopImmersiveController.moveTaskToNonImmersive(
@@ -868,12 +897,12 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
&& TaskInfoKt.getRequestingImmersive(decoration.mTaskInfo)) {
// Task is requesting immersive, so it should either enter or exit immersive,
// depending on immersive state.
- onEnterOrExitImmersive(decoration.mTaskInfo.taskId);
+ onEnterOrExitImmersive(decoration.mTaskInfo);
} else {
// Full immersive is disabled or task doesn't request/support it, so just
// toggle between maximize/restore states.
- onMaximizeOrRestore(decoration.mTaskInfo.taskId, "caption_bar_button",
- ResizeTrigger.MAXIMIZE_BUTTON, mMotionEvent);
+ onToggleSizeInteraction(decoration.mTaskInfo.taskId,
+ ToggleTaskSizeInteraction.AmbiguousSource.HEADER_BUTTON, mMotionEvent);
}
} else if (id == R.id.minimize_window) {
mDesktopTasksController.minimizeTask(decoration.mTaskInfo);
@@ -1000,6 +1029,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
private void moveTaskToFront(RunningTaskInfo taskInfo) {
if (!mFocusTransitionObserver.hasGlobalFocus(taskInfo)) {
+ mDesktopModeUiEventLogger.log(taskInfo,
+ DesktopUiEventEnum.DESKTOP_WINDOW_HEADER_TAP_TO_REFOCUS);
mDesktopTasksController.moveTaskToFront(taskInfo);
}
}
@@ -1056,8 +1087,10 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
}
final boolean touchingButton = (id == R.id.close_window || id == R.id.maximize_window
|| id == R.id.open_menu_button || id == R.id.minimize_window);
+ final DesktopRepository desktopRepository = mDesktopUserRepositories.getProfile(
+ taskInfo.userId);
final boolean dragAllowed =
- !mDesktopRepository.isTaskInFullImmersiveState(taskInfo.taskId);
+ !desktopRepository.isTaskInFullImmersiveState(taskInfo.taskId);
switch (e.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
if (dragAllowed) {
@@ -1102,6 +1135,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
if (!wasDragging) {
return false;
}
+ mDesktopModeUiEventLogger.log(taskInfo,
+ DesktopUiEventEnum.DESKTOP_WINDOW_MOVE_BY_HEADER_DRAG);
if (e.findPointerIndex(mDragPointerId) == -1) {
mDragPointerId = e.getPointerId(0);
}
@@ -1165,11 +1200,13 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
&& action != MotionEvent.ACTION_CANCEL)) {
return false;
}
- if (mDesktopRepository.isTaskInFullImmersiveState(mTaskId)) {
+ final DesktopRepository desktopRepository = mDesktopUserRepositories.getCurrent();
+ if (desktopRepository.isTaskInFullImmersiveState(mTaskId)) {
// Disallow double-tap to resize when in full immersive.
return false;
}
- onMaximizeOrRestore(mTaskId, "double_tap", ResizeTrigger.DOUBLE_TAP_APP_HEADER, e);
+ onToggleSizeInteraction(mTaskId,
+ ToggleTaskSizeInteraction.AmbiguousSource.DOUBLE_TAP, e);
return true;
}
}
@@ -1577,7 +1614,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
mContext.createContextAsUser(UserHandle.of(taskInfo.userId), 0 /* flags */),
mDisplayController,
mSplitScreenController,
- mDesktopRepository,
+ mDesktopUserRepositories,
mTaskOrganizer,
taskInfo,
taskSurface,
@@ -1608,12 +1645,13 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
final DesktopModeTouchEventListener touchEventListener =
new DesktopModeTouchEventListener(taskInfo, taskPositioner);
windowDecoration.setOnMaximizeOrRestoreClickListener(() -> {
- onMaximizeOrRestore(taskInfo.taskId, "maximize_menu", ResizeTrigger.MAXIMIZE_MENU,
+ onToggleSizeInteraction(taskInfo.taskId,
+ ToggleTaskSizeInteraction.AmbiguousSource.MAXIMIZE_MENU,
touchEventListener.mMotionEvent);
return Unit.INSTANCE;
});
windowDecoration.setOnImmersiveOrRestoreClickListener(() -> {
- onEnterOrExitImmersive(taskInfo.taskId);
+ onEnterOrExitImmersive(taskInfo);
return Unit.INSTANCE;
});
windowDecoration.setOnLeftSnapClickListener(() -> {
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 96cc559a64ae..9cf90a4e7b58 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
@@ -99,7 +99,7 @@ import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.desktopmode.CaptionState;
import com.android.wm.shell.desktopmode.DesktopModeEventLogger;
-import com.android.wm.shell.desktopmode.DesktopRepository;
+import com.android.wm.shell.desktopmode.DesktopUserRepositories;
import com.android.wm.shell.desktopmode.WindowDecorCaptionHandleRepository;
import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
@@ -206,14 +206,14 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
private final Runnable mCapturedLinkExpiredRunnable = this::onCapturedLinkExpired;
private final MultiInstanceHelper mMultiInstanceHelper;
private final WindowDecorCaptionHandleRepository mWindowDecorCaptionHandleRepository;
- private final DesktopRepository mDesktopRepository;
+ private final DesktopUserRepositories mDesktopUserRepositories;
public DesktopModeWindowDecoration(
Context context,
@NonNull Context userContext,
DisplayController displayController,
SplitScreenController splitScreenController,
- DesktopRepository desktopRepository,
+ DesktopUserRepositories desktopUserRepositories,
ShellTaskOrganizer taskOrganizer,
ActivityManager.RunningTaskInfo taskInfo,
SurfaceControl taskSurface,
@@ -228,10 +228,10 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
MultiInstanceHelper multiInstanceHelper,
WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
DesktopModeEventLogger desktopModeEventLogger) {
- this (context, userContext, displayController, splitScreenController, desktopRepository,
- taskOrganizer, taskInfo, taskSurface, handler, bgExecutor, choreographer, syncQueue,
- appHeaderViewHolderFactory, rootTaskDisplayAreaOrganizer, genericLinksParser,
- assistContentRequester,
+ this (context, userContext, displayController, splitScreenController,
+ desktopUserRepositories, taskOrganizer, taskInfo, taskSurface, handler,
+ bgExecutor, choreographer, syncQueue, appHeaderViewHolderFactory,
+ rootTaskDisplayAreaOrganizer, genericLinksParser, assistContentRequester,
SurfaceControl.Builder::new, SurfaceControl.Transaction::new,
WindowContainerTransaction::new, SurfaceControl::new, new WindowManagerWrapper(
context.getSystemService(WindowManager.class)),
@@ -246,7 +246,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
@NonNull Context userContext,
DisplayController displayController,
SplitScreenController splitScreenController,
- DesktopRepository desktopRepository,
+ DesktopUserRepositories desktopUserRepositories,
ShellTaskOrganizer taskOrganizer,
ActivityManager.RunningTaskInfo taskInfo,
SurfaceControl taskSurface,
@@ -287,7 +287,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
mMultiInstanceHelper = multiInstanceHelper;
mWindowManagerWrapper = windowManagerWrapper;
mWindowDecorCaptionHandleRepository = windowDecorCaptionHandleRepository;
- mDesktopRepository = desktopRepository;
+ mDesktopUserRepositories = desktopUserRepositories;
}
/**
@@ -437,7 +437,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
public void updateDisabledResizingEdge(
DragResizeWindowGeometry.DisabledEdge disabledResizingEdge, boolean shouldDelayUpdate) {
mDisabledResizingEdge = disabledResizingEdge;
- final boolean inFullImmersive = mDesktopRepository
+ final boolean inFullImmersive = mDesktopUserRepositories.getCurrent()
.isTaskInFullImmersiveState(mTaskInfo.taskId);
if (shouldDelayUpdate) {
return;
@@ -541,7 +541,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
mOpenByDefaultDialog.relayout(taskInfo);
}
- final boolean inFullImmersive = mDesktopRepository
+ final boolean inFullImmersive = mDesktopUserRepositories.getProfile(taskInfo.userId)
.isTaskInFullImmersiveState(taskInfo.taskId);
updateRelayoutParams(mRelayoutParams, mContext, taskInfo, applyStartTransactionOnDraw,
shouldSetTaskVisibilityPositionAndCrop, mIsStatusBarVisible,
@@ -980,10 +980,15 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
relayoutParams.mInputFeatures
|= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
}
- if (DesktopModeStatus.useWindowShadow(/* isFocusedWindow= */ hasGlobalFocus)) {
- relayoutParams.mShadowRadiusId = hasGlobalFocus
- ? R.dimen.freeform_decor_shadow_focused_thickness
- : R.dimen.freeform_decor_shadow_unfocused_thickness;
+ if (isAppHeader
+ && DesktopModeStatus.useWindowShadow(/* isFocusedWindow= */ hasGlobalFocus)) {
+ relayoutParams.mShadowRadius = hasGlobalFocus
+ ? context.getResources().getDimensionPixelSize(
+ R.dimen.freeform_decor_shadow_focused_thickness)
+ : context.getResources().getDimensionPixelSize(
+ R.dimen.freeform_decor_shadow_unfocused_thickness);
+ } else {
+ relayoutParams.mShadowRadius = INVALID_SHADOW_RADIUS;
}
relayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw;
relayoutParams.mSetTaskVisibilityPositionAndCrop = shouldSetTaskVisibilityPositionAndCrop;
@@ -1297,9 +1302,11 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
mMaximizeMenu = mMaximizeMenuFactory.create(mSyncQueue, mRootTaskDisplayAreaOrganizer,
mDisplayController, mTaskInfo, mContext,
calculateMaximizeMenuPosition(menuWidth), mSurfaceControlTransactionSupplier);
+
mMaximizeMenu.show(
/* isTaskInImmersiveMode= */ Flags.enableFullyImmersiveInDesktop()
- && mDesktopRepository.isTaskInFullImmersiveState(mTaskInfo.taskId),
+ && mDesktopUserRepositories.getProfile(mTaskInfo.userId)
+ .isTaskInFullImmersiveState(mTaskInfo.taskId),
/* menuWidth= */ menuWidth,
/* showImmersiveOption= */ Flags.enableFullyImmersiveInDesktop()
&& TaskInfoKt.getRequestingImmersive(mTaskInfo),
@@ -1389,7 +1396,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
&& mMinimumInstancesFound;
final boolean shouldShowChangeAspectRatioButton = HandleMenu.Companion
.shouldShowChangeAspectRatioButton(mTaskInfo);
- final boolean inDesktopImmersive = mDesktopRepository
+ final boolean inDesktopImmersive = mDesktopUserRepositories.getProfile(mTaskInfo.userId)
.isTaskInFullImmersiveState(mTaskInfo.taskId);
final boolean isBrowserApp = isBrowserApp();
mHandleMenu = mHandleMenuFactory.create(
@@ -1469,7 +1476,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
mDisplayController,
mRootTaskDisplayAreaOrganizer,
mContext,
- mDesktopRepository,
+ mDesktopUserRepositories,
mSurfaceControlBuilderSupplier,
mSurfaceControlTransactionSupplier,
snapshotList,
@@ -1765,7 +1772,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
void setAnimatingTaskResizeOrReposition(boolean animatingTaskResizeOrReposition) {
if (mRelayoutParams.mLayoutResId == R.layout.desktop_mode_app_handle) return;
final boolean inFullImmersive =
- mDesktopRepository.isTaskInFullImmersiveState(mTaskInfo.taskId);
+ mDesktopUserRepositories.getProfile(mTaskInfo.userId)
+ .isTaskInFullImmersiveState(mTaskInfo.taskId);
asAppHeader(mWindowDecorViewHolder).bindData(new AppHeaderViewHolder.HeaderData(
mTaskInfo,
TaskInfoKt.getRequestingImmersive(mTaskInfo),
@@ -1793,8 +1801,9 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
return !animatingTaskResizeOrReposition;
}
final boolean inImmersiveAndRequesting =
- mDesktopRepository.isTaskInFullImmersiveState(mTaskInfo.taskId)
- && TaskInfoKt.getRequestingImmersive(mTaskInfo);
+ mDesktopUserRepositories.getProfile(mTaskInfo.userId)
+ .isTaskInFullImmersiveState(mTaskInfo.taskId)
+ && TaskInfoKt.getRequestingImmersive(mTaskInfo);
return !animatingTaskResizeOrReposition && !inImmersiveAndRequesting;
}
@@ -1815,7 +1824,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
@NonNull Context userContext,
DisplayController displayController,
SplitScreenController splitScreenController,
- DesktopRepository desktopRepository,
+ DesktopUserRepositories desktopUserRepositories,
ShellTaskOrganizer taskOrganizer,
ActivityManager.RunningTaskInfo taskInfo,
SurfaceControl taskSurface,
@@ -1835,7 +1844,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
userContext,
displayController,
splitScreenController,
- desktopRepository,
+ desktopUserRepositories,
taskOrganizer,
taskInfo,
taskSurface,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index 852eee5f6672..584ee39ab317 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -17,7 +17,6 @@
package com.android.wm.shell.windowdecor;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.content.res.Configuration.DENSITY_DPI_UNDEFINED;
import static android.view.WindowInsets.Type.captionBar;
import static android.view.WindowInsets.Type.mandatorySystemGestures;
@@ -110,6 +109,10 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
* Invalid corner radius that signifies that corner radius should not be set.
*/
static final int INVALID_CORNER_RADIUS = -1;
+ /**
+ * Invalid corner radius that signifies that shadow radius should not be set.
+ */
+ static final int INVALID_SHADOW_RADIUS = -1;
/**
* System-wide context. Only used to create context with overridden configurations.
@@ -439,16 +442,10 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
.setPosition(mTaskSurface, taskPosition.x, taskPosition.y);
}
- float shadowRadius;
- if (mTaskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
- // Shadow is not needed for fullscreen tasks
- shadowRadius = 0;
- } else {
- shadowRadius =
- loadDimension(mDecorWindowContext.getResources(), params.mShadowRadiusId);
+ if (params.mShadowRadius != INVALID_SHADOW_RADIUS) {
+ startT.setShadowRadius(mTaskSurface, params.mShadowRadius);
+ finishT.setShadowRadius(mTaskSurface, params.mShadowRadius);
}
- startT.setShadowRadius(mTaskSurface, shadowRadius);
- finishT.setShadowRadius(mTaskSurface, shadowRadius);
if (params.mSetTaskVisibilityPositionAndCrop) {
startT.show(mTaskSurface);
@@ -851,8 +848,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
@InsetsSource.Flags int mInsetSourceFlags;
final Region mDisplayExclusionRegion = Region.obtain();
- int mShadowRadiusId;
- int mCornerRadius;
+ int mShadowRadius = INVALID_SHADOW_RADIUS;
+ int mCornerRadius = INVALID_CORNER_RADIUS;
int mCaptionTopPadding;
boolean mIsCaptionVisible;
@@ -874,8 +871,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
mInsetSourceFlags = 0;
mDisplayExclusionRegion.setEmpty();
- mShadowRadiusId = Resources.ID_NULL;
- mCornerRadius = 0;
+ mShadowRadius = INVALID_SHADOW_RADIUS;
+ mCornerRadius = INVALID_SHADOW_RADIUS;
mCaptionTopPadding = 0;
mIsCaptionVisible = false;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/DefaultWindowDecorViewHost.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/DefaultWindowDecorViewHost.kt
new file mode 100644
index 000000000000..c470eef2578c
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/DefaultWindowDecorViewHost.kt
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.windowdecor.common.viewhost
+
+import android.content.Context
+import android.content.res.Configuration
+import android.view.Display
+import android.view.SurfaceControl
+import android.view.SurfaceControlViewHost
+import android.view.View
+import android.view.WindowManager
+import android.view.WindowlessWindowManager
+import androidx.tracing.Trace
+import com.android.internal.annotations.VisibleForTesting
+import com.android.wm.shell.shared.annotations.ShellMainThread
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+
+typealias SurfaceControlViewHostFactory =
+ (Context, Display, WindowlessWindowManager, String) -> SurfaceControlViewHost
+
+/**
+ * A default implementation of [WindowDecorViewHost] backed by a [SurfaceControlViewHost].
+ *
+ * It does not support swapping the root view added to the VRI of the [SurfaceControlViewHost], and
+ * any attempts to do will throw, which means that once a [View] is added using [updateView] or
+ * [updateViewAsync], only its properties and binding may be changed, its children views may be
+ * added, removed or changed and its [WindowManager.LayoutParams] may be changed. It also supports
+ * asynchronously updating the view hierarchy using [updateViewAsync], in which case the update work
+ * will be posted on the [ShellMainThread] with no delay.
+ */
+class DefaultWindowDecorViewHost(
+ private val context: Context,
+ @ShellMainThread private val mainScope: CoroutineScope,
+ private val display: Display,
+ private val surfaceControlViewHostFactory: SurfaceControlViewHostFactory = { c, d, wwm, s ->
+ SurfaceControlViewHost(c, d, wwm, s)
+ },
+) : WindowDecorViewHost {
+
+ private val rootSurface: SurfaceControl =
+ SurfaceControl.Builder()
+ .setName("DefaultWindowDecorViewHost surface")
+ .setContainerLayer()
+ .setCallsite("DefaultWindowDecorViewHost#init")
+ .build()
+
+ private var wwm: WindowlessWindowManager? = null
+ @VisibleForTesting var viewHost: SurfaceControlViewHost? = null
+ private var currentUpdateJob: Job? = null
+
+ override val surfaceControl: SurfaceControl
+ get() = rootSurface
+
+ override fun updateView(
+ view: View,
+ attrs: WindowManager.LayoutParams,
+ configuration: Configuration,
+ onDrawTransaction: SurfaceControl.Transaction?,
+ ) {
+ Trace.beginSection("DefaultWindowDecorViewHost#updateView")
+ clearCurrentUpdateJob()
+ updateViewHost(view, attrs, configuration, onDrawTransaction)
+ Trace.endSection()
+ }
+
+ override fun updateViewAsync(
+ view: View,
+ attrs: WindowManager.LayoutParams,
+ configuration: Configuration,
+ ) {
+ Trace.beginSection("DefaultWindowDecorViewHost#updateViewAsync")
+ clearCurrentUpdateJob()
+ currentUpdateJob =
+ mainScope.launch {
+ updateViewHost(view, attrs, configuration, onDrawTransaction = null)
+ }
+ Trace.endSection()
+ }
+
+ override fun release(t: SurfaceControl.Transaction) {
+ clearCurrentUpdateJob()
+ viewHost?.release()
+ t.remove(rootSurface)
+ }
+
+ private fun updateViewHost(
+ view: View,
+ attrs: WindowManager.LayoutParams,
+ configuration: Configuration,
+ onDrawTransaction: SurfaceControl.Transaction?,
+ ) {
+ Trace.beginSection("DefaultWindowDecorViewHost#updateViewHost")
+ if (wwm == null) {
+ wwm = WindowlessWindowManager(configuration, rootSurface, null)
+ }
+ requireWindowlessWindowManager().setConfiguration(configuration)
+ if (viewHost == null) {
+ viewHost =
+ surfaceControlViewHostFactory.invoke(
+ context,
+ display,
+ requireWindowlessWindowManager(),
+ "DefaultWindowDecorViewHost#updateViewHost",
+ )
+ }
+ onDrawTransaction?.let { requireViewHost().rootSurfaceControl.applyTransactionOnDraw(it) }
+ if (requireViewHost().view == null) {
+ Trace.beginSection("DefaultWindowDecorViewHost#updateViewHost-setView")
+ requireViewHost().setView(view, attrs)
+ Trace.endSection()
+ } else {
+ check(requireViewHost().view == view) { "Changing view is not allowed" }
+ Trace.beginSection("DefaultWindowDecorViewHost#updateViewHost-relayout")
+ requireViewHost().relayout(attrs)
+ Trace.endSection()
+ }
+ Trace.endSection()
+ }
+
+ private fun clearCurrentUpdateJob() {
+ currentUpdateJob?.cancel()
+ currentUpdateJob = null
+ }
+
+ private fun requireWindowlessWindowManager(): WindowlessWindowManager {
+ return wwm ?: error("Expected non-null windowless window manager")
+ }
+
+ private fun requireViewHost(): SurfaceControlViewHost {
+ return viewHost ?: error("Expected non-null view host")
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/DefaultWindowDecorViewHostSupplier.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/DefaultWindowDecorViewHostSupplier.kt
new file mode 100644
index 000000000000..27ffd6cd8076
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/DefaultWindowDecorViewHostSupplier.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.windowdecor.common.viewhost
+
+import android.content.Context
+import android.view.Display
+import android.view.SurfaceControl
+import com.android.wm.shell.shared.annotations.ShellMainThread
+import kotlinx.coroutines.CoroutineScope
+
+/**
+ * A supplier of [DefaultWindowDecorViewHost]s. It creates a new one every time one is requested.
+ */
+class DefaultWindowDecorViewHostSupplier(@ShellMainThread private val mainScope: CoroutineScope) :
+ WindowDecorViewHostSupplier<DefaultWindowDecorViewHost> {
+
+ override fun acquire(context: Context, display: Display): DefaultWindowDecorViewHost {
+ return DefaultWindowDecorViewHost(context, mainScope, display)
+ }
+
+ override fun release(viewHost: DefaultWindowDecorViewHost, t: SurfaceControl.Transaction) {
+ viewHost.release(t)
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/WindowDecorViewHost.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/WindowDecorViewHost.kt
new file mode 100644
index 000000000000..7c1479e9f9bd
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/WindowDecorViewHost.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.windowdecor.common.viewhost
+
+import android.content.res.Configuration
+import android.view.SurfaceControl
+import android.view.View
+import android.view.WindowManager
+import com.android.wm.shell.windowdecor.WindowDecoration
+
+/**
+ * An interface for a utility that hosts a [WindowDecoration]'s [View] hierarchy under a
+ * [SurfaceControl].
+ */
+interface WindowDecorViewHost {
+ /** The surface where the underlying [View] hierarchy is being rendered. */
+ val surfaceControl: SurfaceControl
+
+ /** Synchronously update the view hierarchy of this view host. */
+ fun updateView(
+ view: View,
+ attrs: WindowManager.LayoutParams,
+ configuration: Configuration,
+ onDrawTransaction: SurfaceControl.Transaction?,
+ )
+
+ /** Asynchronously update the view hierarchy of this view host. */
+ fun updateViewAsync(view: View, attrs: WindowManager.LayoutParams, configuration: Configuration)
+
+ /** Releases the underlying [View] hierarchy and removes the backing [SurfaceControl]. */
+ fun release(t: SurfaceControl.Transaction)
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/WindowDecorViewHostSupplier.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/WindowDecorViewHostSupplier.kt
new file mode 100644
index 000000000000..00e29ecaebe3
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/WindowDecorViewHostSupplier.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.windowdecor.common.viewhost
+
+import android.content.Context
+import android.view.Display
+import android.view.SurfaceControl
+
+/** An interface for a supplier of [WindowDecorViewHost]s. */
+interface WindowDecorViewHostSupplier<T : WindowDecorViewHost> {
+ /** Acquire a [WindowDecorViewHost]. */
+ fun acquire(context: Context, display: Display): T
+
+ /**
+ * Release a [WindowDecorViewHost] when it is no longer used.
+ *
+ * @param viewHost the [WindowDecorViewHost] to release
+ * @param t a transaction that may be used to remove any underlying backing [SurfaceControl]
+ * that are hosting this [WindowDecorViewHost]. The supplier is not expected to apply the
+ * transaction. It should be applied by the owner of this supplier.
+ */
+ fun release(viewHost: T, t: SurfaceControl.Transaction)
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt
index 0e40a5350a43..9db69d5c1bc5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt
@@ -33,6 +33,7 @@ import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.desktopmode.DesktopModeEventLogger
import com.android.wm.shell.desktopmode.DesktopRepository
import com.android.wm.shell.desktopmode.DesktopTasksController
+import com.android.wm.shell.desktopmode.DesktopUserRepositories
import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator
import com.android.wm.shell.desktopmode.ToggleResizeDesktopTaskTransitionHandler
import com.android.wm.shell.transition.Transitions
@@ -48,7 +49,7 @@ class DesktopTilingDecorViewModel(
private val shellTaskOrganizer: ShellTaskOrganizer,
private val toggleResizeDesktopTaskTransitionHandler: ToggleResizeDesktopTaskTransitionHandler,
private val returnToDragStartAnimator: ReturnToDragStartAnimator,
- private val taskRepository: DesktopRepository,
+ private val desktopUserRepositories: DesktopUserRepositories,
private val desktopModeEventLogger: DesktopModeEventLogger,
) : DisplayChangeController.OnDisplayChangingListener {
@VisibleForTesting
@@ -81,7 +82,7 @@ class DesktopTilingDecorViewModel(
shellTaskOrganizer,
toggleResizeDesktopTaskTransitionHandler,
returnToDragStartAnimator,
- taskRepository,
+ desktopUserRepositories,
desktopModeEventLogger,
)
tilingTransitionHandlerByDisplayId.put(displayId, newHandler)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
index 3b5c6ca2e58a..7ceac52dd2a1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
@@ -49,6 +49,7 @@ import com.android.wm.shell.desktopmode.DesktopModeEventLogger
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
import com.android.wm.shell.desktopmode.DesktopRepository
import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition
+import com.android.wm.shell.desktopmode.DesktopUserRepositories
import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator
import com.android.wm.shell.desktopmode.ToggleResizeDesktopTaskTransitionHandler
import com.android.wm.shell.transition.Transitions
@@ -72,7 +73,7 @@ class DesktopTilingWindowDecoration(
private val shellTaskOrganizer: ShellTaskOrganizer,
private val toggleResizeDesktopTaskTransitionHandler: ToggleResizeDesktopTaskTransitionHandler,
private val returnToDragStartAnimator: ReturnToDragStartAnimator,
- private val taskRepository: DesktopRepository,
+ private val desktopUserRepositories: DesktopUserRepositories,
private val desktopModeEventLogger: DesktopModeEventLogger,
private val transactionSupplier: Supplier<Transaction> = Supplier { Transaction() },
) :
@@ -630,6 +631,7 @@ class DesktopTilingWindowDecoration(
private fun allTiledTasksVisible(): Boolean {
val leftTiledTask = leftTaskResizingHelper ?: return false
val rightTiledTask = rightTaskResizingHelper ?: return false
+ val taskRepository = desktopUserRepositories.current
return taskRepository.isVisibleTask(leftTiledTask.taskInfo.taskId) &&
taskRepository.isVisibleTask(rightTiledTask.taskInfo.taskId)
}
diff --git a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/AndroidTestTemplate.xml
index 706c63244890..1de47df78853 100644
--- a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/AndroidTestTemplate.xml
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/AndroidTestTemplate.xml
@@ -48,6 +48,8 @@
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="test-user-token" value="%TEST_USER%"/>
<option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
+ <!-- Disable AOD -->
+ <option name="run-command" value="settings put secure doze_always_on 0"/>
<option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
<option name="run-command" value="settings put system show_touches 1"/>
<option name="run-command" value="settings put system pointer_location 1"/>
diff --git a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/AndroidTestTemplate.xml
index 7df1675f541c..34d001c858f6 100644
--- a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/AndroidTestTemplate.xml
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/AndroidTestTemplate.xml
@@ -48,6 +48,8 @@
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="test-user-token" value="%TEST_USER%"/>
<option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
+ <!-- Disable AOD -->
+ <option name="run-command" value="settings put secure doze_always_on 0"/>
<option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
<option name="run-command" value="settings put system show_touches 1"/>
<option name="run-command" value="settings put system pointer_location 1"/>
diff --git a/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/AndroidTestTemplate.xml
index 7df1675f541c..34d001c858f6 100644
--- a/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/AndroidTestTemplate.xml
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/AndroidTestTemplate.xml
@@ -48,6 +48,8 @@
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="test-user-token" value="%TEST_USER%"/>
<option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
+ <!-- Disable AOD -->
+ <option name="run-command" value="settings put secure doze_always_on 0"/>
<option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
<option name="run-command" value="settings put system show_touches 1"/>
<option name="run-command" value="settings put system pointer_location 1"/>
diff --git a/libs/WindowManager/Shell/tests/flicker/appcompat/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/flicker/appcompat/AndroidTestTemplate.xml
index d87c1795cf7b..9c1a8f17aeee 100644
--- a/libs/WindowManager/Shell/tests/flicker/appcompat/AndroidTestTemplate.xml
+++ b/libs/WindowManager/Shell/tests/flicker/appcompat/AndroidTestTemplate.xml
@@ -48,6 +48,8 @@
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="test-user-token" value="%TEST_USER%"/>
<option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
+ <!-- Disable AOD -->
+ <option name="run-command" value="settings put secure doze_always_on 0"/>
<option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
<option name="run-command" value="settings put system show_touches 1"/>
<option name="run-command" value="settings put system pointer_location 1"/>
diff --git a/libs/WindowManager/Shell/tests/flicker/bubble/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/flicker/bubble/AndroidTestTemplate.xml
index 99969e71238a..02b2cec8dbdb 100644
--- a/libs/WindowManager/Shell/tests/flicker/bubble/AndroidTestTemplate.xml
+++ b/libs/WindowManager/Shell/tests/flicker/bubble/AndroidTestTemplate.xml
@@ -48,6 +48,8 @@
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="test-user-token" value="%TEST_USER%"/>
<option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
+ <!-- Disable AOD -->
+ <option name="run-command" value="settings put secure doze_always_on 0"/>
<option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
<option name="run-command" value="settings put system show_touches 1"/>
<option name="run-command" value="settings put system pointer_location 1"/>
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/flicker/pip/AndroidTestTemplate.xml
index 19c3e4048d69..a136936c0838 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/AndroidTestTemplate.xml
+++ b/libs/WindowManager/Shell/tests/flicker/pip/AndroidTestTemplate.xml
@@ -25,7 +25,7 @@
<!-- keeps the screen on during tests -->
<option name="screen-always-on" value="on"/>
<!-- Turns off Wi-fi -->
- <option name="wifi" value="off"/>
+ <option name="wifi" value="on"/>
<!-- Turns off Bluetooth -->
<option name="bluetooth" value="off"/>
<!-- prevents the phone from restarting -->
@@ -48,6 +48,8 @@
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="test-user-token" value="%TEST_USER%"/>
<option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
+ <!-- Disable AOD -->
+ <option name="run-command" value="settings put secure doze_always_on 0"/>
<option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
<option name="run-command" value="settings put system show_touches 1"/>
<option name="run-command" value="settings put system pointer_location 1"/>
@@ -107,4 +109,11 @@
<option name="collect-on-run-ended-only" value="true"/>
<option name="clean-up" value="true"/>
</metrics_collector>
+ <!-- Enable mocking GPS location by the test app -->
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command"
+ value="appops set com.android.shell android:mock_location allow"/>
+ <option name="teardown-command"
+ value="appops set com.android.shell android:mock_location deny"/>
+ </target_preparer>
</configuration>
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/csuiteDefaultTemplate.xml b/libs/WindowManager/Shell/tests/flicker/pip/csuiteDefaultTemplate.xml
index 7505860709e9..34e4e744dae7 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/csuiteDefaultTemplate.xml
+++ b/libs/WindowManager/Shell/tests/flicker/pip/csuiteDefaultTemplate.xml
@@ -48,6 +48,8 @@
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="test-user-token" value="%TEST_USER%"/>
<option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
+ <!-- Disable AOD -->
+ <option name="run-command" value="settings put secure doze_always_on 0"/>
<option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
<option name="run-command" value="settings put system show_touches 1"/>
<option name="run-command" value="settings put system pointer_location 1"/>
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
index fd4328dee0a1..609a2849f915 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
@@ -27,6 +27,7 @@ import android.tools.flicker.legacy.LegacyFlickerTest
import android.tools.flicker.subject.exceptions.ExceptionMessageBuilder
import android.tools.flicker.subject.exceptions.IncorrectRegionException
import android.tools.flicker.subject.layers.LayerSubject
+import com.android.server.wm.flicker.helpers.PipAppHelper
import com.android.wm.shell.Flags
import com.android.wm.shell.flicker.pip.common.EnterPipTransition
import org.junit.Assume
@@ -65,6 +66,8 @@ import kotlin.math.abs
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@RequiresFlagsDisabled(Flags.FLAG_ENABLE_PIP2)
open class AutoEnterPipOnGoToHomeTest(flicker: LegacyFlickerTest) : EnterPipTransition(flicker) {
+ override val pipApp: PipAppHelper = PipAppHelper(instrumentation)
+
override val thisTransition: FlickerBuilder.() -> Unit = { transitions { tapl.goHome() } }
override val defaultEnterPip: FlickerBuilder.() -> Unit = {
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipWithSourceRectHintTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipWithSourceRectHintTest.kt
index d4ad4ef8a401..5698023240ab 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipWithSourceRectHintTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipWithSourceRectHintTest.kt
@@ -22,6 +22,7 @@ import android.tools.flicker.junit.FlickerParametersRunnerFactory
import android.tools.flicker.legacy.FlickerBuilder
import android.tools.flicker.legacy.LegacyFlickerTest
import android.tools.traces.component.ComponentNameMatcher
+import com.android.server.wm.flicker.helpers.PipAppHelper
import com.android.wm.shell.Flags
import org.junit.FixMethodOrder
import org.junit.Test
@@ -57,6 +58,8 @@ import org.junit.runners.Parameterized
@RequiresFlagsDisabled(Flags.FLAG_ENABLE_PIP2)
class AutoEnterPipWithSourceRectHintTest(flicker: LegacyFlickerTest) :
AutoEnterPipOnGoToHomeTest(flicker) {
+ override val pipApp: PipAppHelper = PipAppHelper(instrumentation)
+
override val defaultEnterPip: FlickerBuilder.() -> Unit = {
setup {
pipApp.launchViaIntent(wmHelper)
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt
index 53725fa046c6..880e4cd4e5f7 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt
@@ -21,6 +21,7 @@ import android.platform.test.annotations.RequiresFlagsDisabled
import android.tools.flicker.junit.FlickerParametersRunnerFactory
import android.tools.flicker.legacy.FlickerBuilder
import android.tools.flicker.legacy.LegacyFlickerTest
+import com.android.server.wm.flicker.helpers.PipAppHelper
import com.android.wm.shell.Flags
import com.android.wm.shell.flicker.pip.common.ClosePipTransition
import org.junit.FixMethodOrder
@@ -56,6 +57,8 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@RequiresFlagsDisabled(Flags.FLAG_ENABLE_PIP2)
class ClosePipWithDismissButtonTest(flicker: LegacyFlickerTest) : ClosePipTransition(flicker) {
+ override val pipApp: PipAppHelper = PipAppHelper(instrumentation)
+
override val thisTransition: FlickerBuilder.() -> Unit = {
transitions { pipApp.closePipWindow(wmHelper) }
}
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
index a1551b7924fe..4399a237bcbb 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
@@ -21,6 +21,7 @@ import android.platform.test.annotations.RequiresFlagsDisabled
import android.tools.flicker.junit.FlickerParametersRunnerFactory
import android.tools.flicker.legacy.FlickerBuilder
import android.tools.flicker.legacy.LegacyFlickerTest
+import com.android.server.wm.flicker.helpers.PipAppHelper
import com.android.wm.shell.Flags
import com.android.wm.shell.flicker.pip.common.EnterPipTransition
import org.junit.Assume
@@ -47,6 +48,7 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@RequiresFlagsDisabled(Flags.FLAG_ENABLE_PIP2)
class EnterPipOnUserLeaveHintTest(flicker: LegacyFlickerTest) : EnterPipTransition(flicker) {
+ override val pipApp: PipAppHelper = PipAppHelper(instrumentation)
override val thisTransition: FlickerBuilder.() -> Unit = { transitions { tapl.goHome() } }
override val defaultEnterPip: FlickerBuilder.() -> Unit = {
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
index ea5b3e5b08df..49efd1d56256 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
@@ -31,6 +31,7 @@ import android.tools.traces.component.ComponentNameMatcher
import androidx.test.filters.FlakyTest
import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.FixedOrientationAppHelper
+import com.android.server.wm.flicker.helpers.PipAppHelper
import com.android.server.wm.flicker.testapp.ActivityOptions.Pip.ACTION_ENTER_PIP
import com.android.server.wm.flicker.testapp.ActivityOptions.PortraitOnlyActivity.EXTRA_FIXED_ORIENTATION
import com.android.wm.shell.Flags
@@ -72,6 +73,7 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@RequiresFlagsDisabled(Flags.FLAG_ENABLE_PIP2)
class EnterPipToOtherOrientation(flicker: LegacyFlickerTest) : PipTransition(flicker) {
+ override val pipApp: PipAppHelper = PipAppHelper(instrumentation)
private val testApp = FixedOrientationAppHelper(instrumentation)
private val startingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_90)
private val endingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_0)
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt
index a109c4bba2b3..97cc9d29929c 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt
@@ -20,6 +20,7 @@ import android.platform.test.annotations.RequiresFlagsDisabled
import android.tools.flicker.junit.FlickerParametersRunnerFactory
import android.tools.flicker.legacy.FlickerBuilder
import android.tools.flicker.legacy.LegacyFlickerTest
+import com.android.server.wm.flicker.helpers.PipAppHelper
import com.android.wm.shell.Flags
import com.android.wm.shell.flicker.pip.common.EnterPipTransition
import org.junit.FixMethodOrder
@@ -53,6 +54,8 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@RequiresFlagsDisabled(Flags.FLAG_ENABLE_PIP2)
open class EnterPipViaAppUiButtonTest(flicker: LegacyFlickerTest) : EnterPipTransition(flicker) {
+ override val pipApp: PipAppHelper = PipAppHelper(instrumentation)
+
override val thisTransition: FlickerBuilder.() -> Unit = {
transitions { pipApp.clickEnterPipButton(wmHelper) }
}
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt
index 14ec303206ee..b5b7847e205d 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt
@@ -20,6 +20,7 @@ import android.platform.test.annotations.RequiresFlagsDisabled
import android.tools.flicker.junit.FlickerParametersRunnerFactory
import android.tools.flicker.legacy.FlickerBuilder
import android.tools.flicker.legacy.LegacyFlickerTest
+import com.android.server.wm.flicker.helpers.PipAppHelper
import com.android.wm.shell.Flags
import com.android.wm.shell.flicker.pip.common.ExitPipToAppTransition
import org.junit.FixMethodOrder
@@ -56,6 +57,8 @@ import org.junit.runners.Parameterized
@RequiresFlagsDisabled(Flags.FLAG_ENABLE_PIP2)
class ExitPipToAppViaExpandButtonTest(flicker: LegacyFlickerTest) :
ExitPipToAppTransition(flicker) {
+ override val pipApp: PipAppHelper = PipAppHelper(instrumentation)
+
override val thisTransition: FlickerBuilder.() -> Unit = {
setup {
// launch an app behind the pip one
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt
index 8a34b5e27fdb..f9a9df43a009 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt
@@ -20,6 +20,7 @@ import android.platform.test.annotations.RequiresFlagsDisabled
import android.tools.flicker.junit.FlickerParametersRunnerFactory
import android.tools.flicker.legacy.FlickerBuilder
import android.tools.flicker.legacy.LegacyFlickerTest
+import com.android.server.wm.flicker.helpers.PipAppHelper
import com.android.wm.shell.Flags
import com.android.wm.shell.flicker.pip.common.ExitPipToAppTransition
import org.junit.FixMethodOrder
@@ -54,6 +55,8 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@RequiresFlagsDisabled(Flags.FLAG_ENABLE_PIP2)
class ExitPipToAppViaIntentTest(flicker: LegacyFlickerTest) : ExitPipToAppTransition(flicker) {
+ override val pipApp: PipAppHelper = PipAppHelper(instrumentation)
+
override val thisTransition: FlickerBuilder.() -> Unit = {
setup {
// launch an app behind the pip one
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenEnterPipOnUserLeaveHintTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenEnterPipOnUserLeaveHintTest.kt
index 12e23285ea68..79e2e4e5a82c 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenEnterPipOnUserLeaveHintTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenEnterPipOnUserLeaveHintTest.kt
@@ -27,6 +27,7 @@ import android.tools.flicker.legacy.LegacyFlickerTest
import android.tools.flicker.legacy.LegacyFlickerTestFactory
import android.tools.helpers.WindowUtils
import android.tools.traces.parsers.toFlickerComponent
+import com.android.server.wm.flicker.helpers.PipAppHelper
import com.android.server.wm.flicker.helpers.SimpleAppHelper
import com.android.server.wm.flicker.testapp.ActivityOptions
import com.android.wm.shell.Flags
@@ -68,6 +69,7 @@ import org.junit.runners.Parameterized
@RequiresFlagsDisabled(Flags.FLAG_ENABLE_PIP2)
class FromSplitScreenEnterPipOnUserLeaveHintTest(flicker: LegacyFlickerTest) :
EnterPipTransition(flicker) {
+ override val pipApp: PipAppHelper = PipAppHelper(instrumentation)
private val portraitDisplayBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_0)
/** Second app used to enter split screen mode */
private val secondAppForSplitScreen =
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipAspectRatioChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipAspectRatioChangeTest.kt
index 04016a93e53d..14ae93a81c6d 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipAspectRatioChangeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipAspectRatioChangeTest.kt
@@ -23,6 +23,7 @@ import android.tools.flicker.junit.FlickerParametersRunnerFactory
import android.tools.flicker.legacy.FlickerBuilder
import android.tools.flicker.legacy.LegacyFlickerTest
import android.tools.flicker.legacy.LegacyFlickerTestFactory
+import com.android.server.wm.flicker.helpers.PipAppHelper
import com.android.wm.shell.Flags
import com.android.wm.shell.flicker.pip.common.PipTransition
import org.junit.FixMethodOrder
@@ -37,6 +38,8 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@RequiresFlagsDisabled(Flags.FLAG_ENABLE_PIP2)
class PipAspectRatioChangeTest(flicker: LegacyFlickerTest) : PipTransition(flicker) {
+ override val pipApp: PipAppHelper = PipAppHelper(instrumentation)
+
override val thisTransition: FlickerBuilder.() -> Unit = {
transitions { pipApp.changeAspectRatio(wmHelper) }
}
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipDragTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipDragTest.kt
index 6bcaabc3b680..81162c6f53f5 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipDragTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipDragTest.kt
@@ -49,7 +49,8 @@ class PipDragTest(flicker: LegacyFlickerTest) : PipTransition(flicker) {
val stringExtras = mapOf(ActivityOptions.Pip.EXTRA_ENTER_PIP to "true")
setup {
tapl.setEnableRotation(true)
- pipApp.launchViaIntentAndWaitForPip(wmHelper, stringExtras = stringExtras)
+ pipApp.launchViaIntent(wmHelper, stringExtras = stringExtras)
+ pipApp.waitForPip(wmHelper)
// determine the direction of dragging to test for
isDraggedLeft = pipApp.isCloserToRightEdge(wmHelper)
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipDragThenSnapTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipDragThenSnapTest.kt
index d82bfdd6dc2f..6118d73796a1 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipDragThenSnapTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipDragThenSnapTest.kt
@@ -59,7 +59,8 @@ class PipDragThenSnapTest(flicker: LegacyFlickerTest) : PipTransition(flicker) {
// Launch the PIP activity and wait for it to enter PiP mode
setRotation(Rotation.ROTATION_0)
RemoveAllTasksButHomeRule.removeAllTasksButHome()
- pipApp.launchViaIntentAndWaitForPip(wmHelper, stringExtras = stringExtras)
+ pipApp.launchViaIntent(wmHelper, stringExtras = stringExtras)
+ pipApp.waitForPip(wmHelper)
// get the initial region bounds and cache them
val initRegion = pipApp.getWindowRect(wmHelper)
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipPinchInTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipPinchInTest.kt
index dbc97d072f9b..61c59cc45504 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipPinchInTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipPinchInTest.kt
@@ -25,6 +25,7 @@ import android.tools.flicker.legacy.FlickerBuilder
import android.tools.flicker.legacy.LegacyFlickerTest
import android.tools.flicker.legacy.LegacyFlickerTestFactory
import android.tools.flicker.subject.exceptions.IncorrectRegionException
+import com.android.server.wm.flicker.helpers.PipAppHelper
import com.android.wm.shell.Flags
import com.android.wm.shell.flicker.pip.common.PipTransition
import org.junit.FixMethodOrder
@@ -40,6 +41,8 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@RequiresFlagsDisabled(Flags.FLAG_ENABLE_PIP2)
class PipPinchInTest(flicker: LegacyFlickerTest) : PipTransition(flicker) {
+ override val pipApp: PipAppHelper = PipAppHelper(instrumentation)
+
override val thisTransition: FlickerBuilder.() -> Unit = {
transitions { pipApp.pinchInPipWindow(wmHelper, 0.4f, 30) }
}
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt
index 65b60ce1022b..0867f654bcaf 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt
@@ -18,7 +18,6 @@ package com.android.wm.shell.flicker.pip.apps
import android.platform.test.annotations.Postsubmit
import android.tools.Rotation
-import android.tools.device.apphelpers.StandardAppHelper
import android.tools.flicker.junit.FlickerBuilderProvider
import android.tools.flicker.legacy.FlickerBuilder
import android.tools.flicker.legacy.LegacyFlickerTest
@@ -29,8 +28,6 @@ import org.junit.Test
import org.junit.runners.Parameterized
abstract class AppsEnterPipTransition(flicker: LegacyFlickerTest) : EnterPipTransition(flicker) {
- protected abstract val standardAppHelper: StandardAppHelper
-
protected abstract val permissions: Array<String>
@FlickerBuilderProvider
@@ -39,7 +36,7 @@ abstract class AppsEnterPipTransition(flicker: LegacyFlickerTest) : EnterPipTran
instrumentation.uiAutomation.adoptShellPermissionIdentity()
for (permission in permissions) {
instrumentation.uiAutomation.grantRuntimePermission(
- standardAppHelper.packageName,
+ pipApp.packageName,
permission
)
}
@@ -48,18 +45,18 @@ abstract class AppsEnterPipTransition(flicker: LegacyFlickerTest) : EnterPipTran
}
}
- /** Checks [standardAppHelper] window remains visible throughout the animation */
+ /** Checks [pipApp] window remains visible throughout the animation */
@Postsubmit
@Test
override fun pipAppWindowAlwaysVisible() {
- flicker.assertWm { this.isAppWindowVisible(standardAppHelper.packageNameMatcher) }
+ flicker.assertWm { this.isAppWindowVisible(pipApp.packageNameMatcher) }
}
- /** Checks [standardAppHelper] layer remains visible throughout the animation */
+ /** Checks [pipApp] layer remains visible throughout the animation */
@Postsubmit
@Test
override fun pipAppLayerAlwaysVisible() {
- flicker.assertLayers { this.isVisible(standardAppHelper.packageNameMatcher) }
+ flicker.assertLayers { this.isVisible(pipApp.packageNameMatcher) }
}
/** Checks the content overlay appears then disappears during the animation */
@@ -70,39 +67,39 @@ abstract class AppsEnterPipTransition(flicker: LegacyFlickerTest) : EnterPipTran
}
/**
- * Checks that [standardAppHelper] window remains inside the display bounds throughout the whole
+ * Checks that [pipApp] window remains inside the display bounds throughout the whole
* animation
*/
@Postsubmit
@Test
override fun pipWindowRemainInsideVisibleBounds() {
- flicker.assertWmVisibleRegion(standardAppHelper.packageNameMatcher) {
+ flicker.assertWmVisibleRegion(pipApp.packageNameMatcher) {
coversAtMost(displayBounds)
}
}
/**
- * Checks that the [standardAppHelper] layer remains inside the display bounds throughout the
+ * Checks that the [pipApp] layer remains inside the display bounds throughout the
* whole animation
*/
@Postsubmit
@Test
override fun pipLayerOrOverlayRemainInsideVisibleBounds() {
flicker.assertLayersVisibleRegion(
- standardAppHelper.packageNameMatcher.or(ComponentNameMatcher.PIP_CONTENT_OVERLAY)
+ pipApp.packageNameMatcher.or(ComponentNameMatcher.PIP_CONTENT_OVERLAY)
) {
coversAtMost(displayBounds)
}
}
- /** Checks that the visible region of [standardAppHelper] always reduces during the animation */
+ /** Checks that the visible region of [pipApp] always reduces during the animation */
@Postsubmit
@Test
override fun pipLayerReduces() {
flicker.assertLayers {
val pipLayerList =
this.layers {
- standardAppHelper.packageNameMatcher.layerMatchesAnyOf(it) && it.isVisible
+ pipApp.packageNameMatcher.layerMatchesAnyOf(it) && it.isVisible
}
pipLayerList.zipWithNext { previous, current ->
current.visibleRegion.notBiggerThan(previous.visibleRegion.region)
@@ -110,14 +107,14 @@ abstract class AppsEnterPipTransition(flicker: LegacyFlickerTest) : EnterPipTran
}
}
- /** Checks that [standardAppHelper] window becomes pinned */
+ /** Checks that [pipApp] window becomes pinned */
@Postsubmit
@Test
override fun pipWindowBecomesPinned() {
flicker.assertWm {
- invoke("pipWindowIsNotPinned") { it.isNotPinned(standardAppHelper.packageNameMatcher) }
+ invoke("pipWindowIsNotPinned") { it.isNotPinned(pipApp.packageNameMatcher) }
.then()
- .invoke("pipWindowIsPinned") { it.isPinned(standardAppHelper.packageNameMatcher) }
+ .invoke("pipWindowIsPinned") { it.isPinned(pipApp.packageNameMatcher) }
}
}
@@ -129,14 +126,14 @@ abstract class AppsEnterPipTransition(flicker: LegacyFlickerTest) : EnterPipTran
}
/**
- * Checks that the focus changes between the [standardAppHelper] window and the launcher when
+ * Checks that the focus changes between the [pipApp] window and the launcher when
* closing the pip window
*/
@Postsubmit
@Test
override fun focusChanges() {
flicker.assertEventLog {
- this.focusChanges(standardAppHelper.packageName, "NexusLauncherActivity")
+ this.focusChanges(pipApp.packageName, "NexusLauncherActivity")
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt
index 7b04b766a191..651c92308c04 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt
@@ -29,6 +29,8 @@ import android.tools.device.apphelpers.MapsAppHelper
import android.tools.flicker.junit.FlickerParametersRunnerFactory
import android.tools.flicker.legacy.FlickerBuilder
import android.tools.flicker.legacy.LegacyFlickerTest
+import android.tools.flicker.subject.layers.LayersTraceSubject.Companion.VISIBLE_FOR_MORE_THAN_ONE_ENTRY_IGNORE_LAYERS
+import android.tools.traces.component.ComponentRegexMatcher
import androidx.test.filters.RequiresDevice
import org.junit.Assume
import org.junit.FixMethodOrder
@@ -63,7 +65,7 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
open class MapsEnterPipTest(flicker: LegacyFlickerTest) : AppsEnterPipTransition(flicker) {
- override val standardAppHelper: MapsAppHelper = MapsAppHelper(instrumentation)
+ override val pipApp: MapsAppHelper = MapsAppHelper(instrumentation)
override val permissions: Array<String> =
arrayOf(Manifest.permission.POST_NOTIFICATIONS, Manifest.permission.ACCESS_FINE_LOCATION)
@@ -110,23 +112,23 @@ open class MapsEnterPipTest(flicker: LegacyFlickerTest) : AppsEnterPipTransition
// normal app open through the Launcher All Apps
// var mapsAddressOption = "Golden Gate Bridge"
- // standardAppHelper.open()
- // standardAppHelper.doSearch(mapsAddressOption)
- // standardAppHelper.getDirections()
- // standardAppHelper.startNavigation();
+ // pipApp.open()
+ // pipApp.doSearch(mapsAddressOption)
+ // pipApp.getDirections()
+ // pipApp.startNavigation();
- standardAppHelper.launchViaIntent(
+ pipApp.launchViaIntent(
wmHelper,
MapsAppHelper.getMapIntent(MapsAppHelper.INTENT_NAVIGATION)
)
- standardAppHelper.waitForNavigationToStart()
+ pipApp.waitForNavigationToStart()
}
}
override val defaultTeardown: FlickerBuilder.() -> Unit = {
teardown {
- standardAppHelper.exit(wmHelper)
+ pipApp.exit(wmHelper)
mainHandler.removeCallbacks(updateLocation)
// the main looper callback might have tried to provide a new location after the
// provider is no longer in test mode, causing a crash, this prevents it from happening
@@ -137,14 +139,14 @@ open class MapsEnterPipTest(flicker: LegacyFlickerTest) : AppsEnterPipTransition
override val thisTransition: FlickerBuilder.() -> Unit = { transitions { tapl.goHome() } }
- /** Checks [standardAppHelper] layer remains visible throughout the animation */
+ /** Checks [pipApp] layer remains visible throughout the animation */
@Postsubmit
@Test
override fun pipAppLayerAlwaysVisible() {
// For Maps the transition goes through the UI mode change that adds a snapshot overlay so
// we assert only start/end layers matching the app instead.
- flicker.assertLayersStart { this.isVisible(standardAppHelper.packageNameMatcher) }
- flicker.assertLayersEnd { this.isVisible(standardAppHelper.packageNameMatcher) }
+ flicker.assertLayersStart { this.isVisible(pipApp.packageNameMatcher) }
+ flicker.assertLayersEnd { this.isVisible(pipApp.packageNameMatcher) }
}
@Postsubmit
@@ -154,4 +156,15 @@ open class MapsEnterPipTest(flicker: LegacyFlickerTest) : AppsEnterPipTransition
Assume.assumeFalse(flicker.scenario.isGesturalNavigation)
super.focusChanges()
}
+
+ @Postsubmit
+ @Test
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() {
+ flicker.assertLayers {
+ this.visibleLayersShownMoreThanOneConsecutiveEntry(
+ ignoreLayers = VISIBLE_FOR_MORE_THAN_ONE_ENTRY_IGNORE_LAYERS
+ + ComponentRegexMatcher(Regex("Background for .* SurfaceView\\[com\\.google\\.android\\.apps\\.maps/com\\.google\\.android\\.maps\\.MapsActivity\\]\\#\\d+"))
+ )
+ }
+ }
}
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt
index 691194609343..be4cd780e45e 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt
@@ -61,7 +61,7 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
open class NetflixEnterPipTest(flicker: LegacyFlickerTest) : AppsEnterPipTransition(flicker) {
- override val standardAppHelper: NetflixAppHelper = NetflixAppHelper(instrumentation)
+ override val pipApp: NetflixAppHelper = NetflixAppHelper(instrumentation)
private val startingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_90)
private val endingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_0)
@@ -69,17 +69,17 @@ open class NetflixEnterPipTest(flicker: LegacyFlickerTest) : AppsEnterPipTransit
override val defaultEnterPip: FlickerBuilder.() -> Unit = {
setup {
- standardAppHelper.launchViaIntent(
+ pipApp.launchViaIntent(
wmHelper,
NetflixAppHelper.getNetflixWatchVideoIntent("81605060"),
ComponentNameMatcher(NetflixAppHelper.PACKAGE_NAME, NetflixAppHelper.WATCH_ACTIVITY)
)
- standardAppHelper.waitForVideoPlaying()
+ pipApp.waitForVideoPlaying()
}
}
override val defaultTeardown: FlickerBuilder.() -> Unit = {
- teardown { standardAppHelper.exit(wmHelper) }
+ teardown { pipApp.exit(wmHelper) }
}
override val thisTransition: FlickerBuilder.() -> Unit = {
@@ -143,7 +143,7 @@ open class NetflixEnterPipTest(flicker: LegacyFlickerTest) : AppsEnterPipTransit
// might go outside of bounds as we resize from landscape fullscreen to destination bounds,
// and once the animation is over we assert that it's fully within the display bounds, at
// which point the device also performs orientation change from landscape to portrait
- flicker.assertWmVisibleRegion(standardAppHelper.packageNameMatcher) {
+ flicker.assertWmVisibleRegion(pipApp.packageNameMatcher) {
regionsCenterPointInside(startingBounds).then().coversAtMost(endingBounds)
}
}
@@ -156,7 +156,7 @@ open class NetflixEnterPipTest(flicker: LegacyFlickerTest) : AppsEnterPipTransit
// and once the animation is over we assert that it's fully within the display bounds, at
// which point the device also performs orientation change from landscape to portrait
// since Netflix uses source rect hint, there is no PiP overlay present
- flicker.assertLayersVisibleRegion(standardAppHelper.packageNameMatcher) {
+ flicker.assertLayersVisibleRegion(pipApp.packageNameMatcher) {
regionsCenterPointInside(startingBounds).then().coversAtMost(endingBounds)
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt
index 5e54f30dae8a..3e4ff3075f73 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt
@@ -57,23 +57,23 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
open class YouTubeEnterPipTest(flicker: LegacyFlickerTest) : AppsEnterPipTransition(flicker) {
- override val standardAppHelper: YouTubeAppHelper = YouTubeAppHelper(instrumentation)
+ override val pipApp: YouTubeAppHelper = YouTubeAppHelper(instrumentation)
override val permissions: Array<String> = arrayOf(Manifest.permission.POST_NOTIFICATIONS)
override val defaultEnterPip: FlickerBuilder.() -> Unit = {
setup {
- standardAppHelper.launchViaIntent(
+ pipApp.launchViaIntent(
wmHelper,
YouTubeAppHelper.getYoutubeVideoIntent("3KtWfp0UopM"),
ComponentNameMatcher(YouTubeAppHelper.PACKAGE_NAME, "")
)
- standardAppHelper.waitForVideoPlaying()
+ pipApp.waitForVideoPlaying()
}
}
override val defaultTeardown: FlickerBuilder.() -> Unit = {
- teardown { standardAppHelper.exit(wmHelper) }
+ teardown { pipApp.exit(wmHelper) }
}
override val thisTransition: FlickerBuilder.() -> Unit = { transitions { tapl.goHome() } }
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipToOtherOrientationTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipToOtherOrientationTest.kt
index 159cba4a559e..2c6cb503465c 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipToOtherOrientationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipToOtherOrientationTest.kt
@@ -63,7 +63,7 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
open class YouTubeEnterPipToOtherOrientationTest(flicker: LegacyFlickerTest) :
YouTubeEnterPipTest(flicker) {
- override val standardAppHelper: YouTubeAppHelper = YouTubeAppHelper(instrumentation)
+ override val pipApp: YouTubeAppHelper = YouTubeAppHelper(instrumentation)
private val startingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_90)
private val endingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_0)
@@ -71,13 +71,13 @@ open class YouTubeEnterPipToOtherOrientationTest(flicker: LegacyFlickerTest) :
override val defaultEnterPip: FlickerBuilder.() -> Unit = {
setup {
- standardAppHelper.launchViaIntent(
+ pipApp.launchViaIntent(
wmHelper,
YouTubeAppHelper.getYoutubeVideoIntent("3KtWfp0UopM"),
ComponentNameMatcher(YouTubeAppHelper.PACKAGE_NAME, "")
)
- standardAppHelper.enterFullscreen()
- standardAppHelper.waitForVideoPlaying()
+ pipApp.enterFullscreen()
+ pipApp.waitForVideoPlaying()
}
}
@@ -101,7 +101,7 @@ open class YouTubeEnterPipToOtherOrientationTest(flicker: LegacyFlickerTest) :
// might go outside of bounds as we resize from landscape fullscreen to destination bounds,
// and once the animation is over we assert that it's fully within the display bounds, at
// which point the device also performs orientation change from landscape to portrait
- flicker.assertWmVisibleRegion(standardAppHelper.packageNameMatcher) {
+ flicker.assertWmVisibleRegion(pipApp.packageNameMatcher) {
regionsCenterPointInside(startingBounds).then().coversAtMost(endingBounds)
}
}
@@ -114,7 +114,7 @@ open class YouTubeEnterPipToOtherOrientationTest(flicker: LegacyFlickerTest) :
// and once the animation is over we assert that it's fully within the display bounds, at
// which point the device also performs orientation change from landscape to portrait
// since YouTube uses source rect hint, there is no PiP overlay present
- flicker.assertLayersVisibleRegion(standardAppHelper.packageNameMatcher) {
+ flicker.assertLayersVisibleRegion(pipApp.packageNameMatcher) {
regionsCenterPointInside(startingBounds).then().coversAtMost(endingBounds)
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/EnterPipTransition.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/EnterPipTransition.kt
index 6dd3a175da65..a72de0f6daf4 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/EnterPipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/EnterPipTransition.kt
@@ -71,7 +71,9 @@ abstract class EnterPipTransition(flicker: LegacyFlickerTest) : PipTransition(fl
@Presubmit
@Test
open fun pipLayerOrOverlayRemainInsideVisibleBounds() {
- flicker.assertLayersVisibleRegion(pipApp.or(ComponentNameMatcher.PIP_CONTENT_OVERLAY)) {
+ flicker.assertLayersVisibleRegion(
+ pipApp.or(ComponentNameMatcher.PIP_CONTENT_OVERLAY)
+ ) {
coversAtMost(displayBounds)
}
}
@@ -117,7 +119,9 @@ abstract class EnterPipTransition(flicker: LegacyFlickerTest) : PipTransition(fl
@Presubmit
@Test
open fun focusChanges() {
- flicker.assertEventLog { this.focusChanges(pipApp.packageName, "NexusLauncherActivity") }
+ flicker.assertEventLog {
+ this.focusChanges(pipApp.packageName, "NexusLauncherActivity")
+ }
}
companion object {
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/PipTransition.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/PipTransition.kt
index c37bf3579e93..7b6625ddc429 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/PipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/PipTransition.kt
@@ -27,6 +27,7 @@ import android.tools.flicker.legacy.LegacyFlickerTest
import android.tools.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome
import android.tools.helpers.WindowUtils
import android.tools.traces.component.ComponentNameMatcher
+import android.tools.device.apphelpers.PipApp
import com.android.server.wm.flicker.helpers.PipAppHelper
import com.android.server.wm.flicker.helpers.setRotation
import com.android.server.wm.flicker.testapp.ActivityOptions
@@ -40,7 +41,6 @@ abstract class PipTransition(flicker: LegacyFlickerTest) : BaseTest(flicker) {
@Rule
val checkFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
- protected val pipApp = PipAppHelper(instrumentation)
protected val displayBounds = WindowUtils.getDisplayBounds(flicker.scenario.startRotation)
protected val broadcastActionTrigger = BroadcastActionTrigger(instrumentation)
@@ -63,6 +63,11 @@ abstract class PipTransition(flicker: LegacyFlickerTest) : BaseTest(flicker) {
}
}
+ /**
+ * Defines the test app to run PIP flicker test.
+ */
+ protected open val pipApp: PipApp = PipAppHelper(instrumentation)
+
/** Defines the transition used to run the test */
protected open val thisTransition: FlickerBuilder.() -> Unit = {}
@@ -85,10 +90,11 @@ abstract class PipTransition(flicker: LegacyFlickerTest) : BaseTest(flicker) {
/** Defines the default method of entering PiP */
protected open val defaultEnterPip: FlickerBuilder.() -> Unit = {
setup {
- pipApp.launchViaIntentAndWaitForPip(
+ pipApp.launchViaIntent(
wmHelper,
stringExtras = mapOf(ActivityOptions.Pip.EXTRA_ENTER_PIP to "true")
)
+ pipApp.waitForPip(wmHelper)
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt
index c4954f90179c..feb3edc9dab7 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt
@@ -20,6 +20,7 @@ import android.app.Instrumentation
import android.graphics.Point
import android.os.SystemClock
import android.tools.Rotation
+import android.tools.device.apphelpers.IStandardAppHelper
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.flicker.rules.ChangeDisplayOrientationRule
import android.tools.traces.component.ComponentNameMatcher
@@ -102,8 +103,8 @@ object SplitScreenUtils {
wmHelper: WindowManagerStateHelper,
tapl: LauncherInstrumentation,
device: UiDevice,
- primaryApp: StandardAppHelper,
- secondaryApp: StandardAppHelper,
+ primaryApp: IStandardAppHelper,
+ secondaryApp: IStandardAppHelper,
rotation: Rotation
) {
primaryApp.launchViaIntent(wmHelper)
@@ -117,8 +118,8 @@ object SplitScreenUtils {
fun enterSplitViaIntent(
wmHelper: WindowManagerStateHelper,
- primaryApp: StandardAppHelper,
- secondaryApp: StandardAppHelper
+ primaryApp: IStandardAppHelper,
+ secondaryApp: IStandardAppHelper
) {
val stringExtras = mapOf(Primary.EXTRA_LAUNCH_ADJACENT to "true")
primaryApp.launchViaIntent(wmHelper, null, null, stringExtras)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/transition/TransitionStateHolderTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/transition/TransitionStateHolderTest.kt
index 7b1d27a8b823..64772d037383 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/transition/TransitionStateHolderTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/transition/TransitionStateHolderTest.kt
@@ -18,7 +18,6 @@ package com.android.wm.shell.common.transition
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
-import com.android.server.testutils.any
import com.android.wm.shell.TestShellExecutor
import com.android.wm.shell.recents.RecentsTransitionHandler
import com.android.wm.shell.recents.RecentsTransitionStateListener
@@ -35,6 +34,7 @@ import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
+import org.mockito.kotlin.any
import org.mockito.kotlin.never
/**
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
index d5287e742c2c..67573dabf2ec 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
@@ -30,6 +30,7 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.TaskInfo;
@@ -61,12 +62,16 @@ import com.android.wm.shell.common.DockStateReader;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.compatui.api.CompatUIInfo;
+import com.android.wm.shell.desktopmode.DesktopRepository;
+import com.android.wm.shell.desktopmode.DesktopUserRepositories;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.Transitions;
import dagger.Lazy;
+import java.util.Optional;
+
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
@@ -130,6 +135,10 @@ public class CompatUIControllerTest extends ShellTestCase {
private CompatUIShellCommandHandler mCompatUIShellCommandHandler;
@Mock
private AccessibilityManager mAccessibilityManager;
+ @Mock
+ private DesktopUserRepositories mDesktopUserRepositories;
+ @Mock
+ private DesktopRepository mDesktopRepository;
@Captor
ArgumentCaptor<OnInsetsChangedListener> mOnInsetsChangedListenerCaptor;
@@ -137,7 +146,6 @@ public class CompatUIControllerTest extends ShellTestCase {
@NonNull
private CompatUIStatusManager mCompatUIStatusManager;
- private boolean mInDesktopModePredicateResult;
@Before
public void setUp() {
@@ -152,6 +160,8 @@ public class CompatUIControllerTest extends ShellTestCase {
doReturn(TASK_ID).when(mMockLetterboxEduLayout).getTaskId();
doReturn(true).when(mMockLetterboxEduLayout).createLayout(anyBoolean());
doReturn(true).when(mMockLetterboxEduLayout).updateCompatInfo(any(), any(), anyBoolean());
+ doReturn(mDesktopRepository).when(mDesktopUserRepositories).getCurrent();
+ doReturn(mDesktopRepository).when(mDesktopUserRepositories).getProfile(anyInt());
doReturn(DISPLAY_ID).when(mMockRestartDialogLayout).getDisplayId();
doReturn(TASK_ID).when(mMockRestartDialogLayout).getTaskId();
@@ -164,7 +174,7 @@ public class CompatUIControllerTest extends ShellTestCase {
mMockDisplayController, mMockDisplayInsetsController, mMockImeController,
mMockSyncQueue, mMockExecutor, mMockTransitionsLazy, mDockStateReader,
mCompatUIConfiguration, mCompatUIShellCommandHandler, mAccessibilityManager,
- mCompatUIStatusManager, i -> mInDesktopModePredicateResult) {
+ mCompatUIStatusManager, Optional.of(mDesktopUserRepositories)) {
@Override
CompatUIWindowManager createCompatUiWindowManager(Context context, TaskInfo taskInfo,
ShellTaskOrganizer.TaskListener taskListener) {
@@ -707,13 +717,17 @@ public class CompatUIControllerTest extends ShellTestCase {
@RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
@EnableFlags(Flags.FLAG_SKIP_COMPAT_UI_EDUCATION_IN_DESKTOP_MODE)
public void testUpdateActiveTaskInfo_removeAllComponentWhenInDesktopModeFlagEnabled() {
- mInDesktopModePredicateResult = false;
TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
+ when(mDesktopUserRepositories.getCurrent().getVisibleTaskCount(DISPLAY_ID)).thenReturn(0);
+
mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
+
verify(mController, never()).removeLayouts(taskInfo.taskId);
- mInDesktopModePredicateResult = true;
+ when(mDesktopUserRepositories.getCurrent().getVisibleTaskCount(DISPLAY_ID)).thenReturn(2);
+
mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
+
verify(mController).removeLayouts(taskInfo.taskId);
}
@@ -721,13 +735,17 @@ public class CompatUIControllerTest extends ShellTestCase {
@RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
@DisableFlags(Flags.FLAG_SKIP_COMPAT_UI_EDUCATION_IN_DESKTOP_MODE)
public void testUpdateActiveTaskInfo_removeAllComponentWhenInDesktopModeFlagDisabled() {
- mInDesktopModePredicateResult = false;
+ when(mDesktopUserRepositories.getCurrent().getVisibleTaskCount(DISPLAY_ID)).thenReturn(0);
TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
+
mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
+
verify(mController, never()).removeLayouts(taskInfo.taskId);
- mInDesktopModePredicateResult = true;
+ when(mDesktopUserRepositories.getCurrent().getVisibleTaskCount(DISPLAY_ID)).thenReturn(2);
+
mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
+
verify(mController, never()).removeLayouts(taskInfo.taskId);
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxTransitionObserverTest.kt
index 9c6afcb8be63..07bfefe0b275 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxTransitionObserverTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxTransitionObserverTest.kt
@@ -25,9 +25,12 @@ import android.testing.AndroidTestingRunner
import android.view.SurfaceControl
import android.view.WindowManager.TRANSIT_CLOSE
import androidx.test.filters.SmallTest
+import com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn
import com.android.window.flags.Flags
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.common.ShellExecutor
+import com.android.wm.shell.common.transition.TransitionStateHolder
+import com.android.wm.shell.recents.RecentsTransitionHandler
import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.transition.Transitions
import com.android.wm.shell.util.TransitionObserverInputBuilder
@@ -37,6 +40,7 @@ import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.never
@@ -154,21 +158,38 @@ class LetterboxTransitionObserverTest : ShellTestCase() {
}
@Test
- fun `When closing change letterbox surface destroy is triggered`() {
+ fun `When closing change with no recents running letterbox surfaces are destroyed`() {
runTestScenario { r ->
executeTransitionObserverTest(observerFactory = r.observerFactory) {
r.invokeShellInit()
inputBuilder {
buildTransitionInfo()
+ r.configureRecentsState(running = false)
r.createClosingChange(inputBuilder = this)
}
validateOutput {
r.destroyEventDetected(expected = true)
- r.creationEventDetected(expected = false)
- r.visibilityEventDetected(expected = false, visible = false)
- r.updateSurfaceBoundsEventDetected(expected = false)
+ }
+ }
+ }
+ }
+
+ @Test
+ fun `When closing change and recents are running letterbox surfaces are not destroyed`() {
+ runTestScenario { r ->
+ executeTransitionObserverTest(observerFactory = r.observerFactory) {
+ r.invokeShellInit()
+
+ inputBuilder {
+ buildTransitionInfo()
+ r.createClosingChange(inputBuilder = this)
+ r.configureRecentsState(running = true)
+ }
+
+ validateOutput {
+ r.destroyEventDetected(expected = false)
}
}
}
@@ -197,6 +218,7 @@ class LetterboxTransitionObserverTest : ShellTestCase() {
private val transitions: Transitions
private val letterboxController: LetterboxController
private val letterboxObserver: LetterboxTransitionObserver
+ private val transitionStateHolder: TransitionStateHolder
val observerFactory: () -> LetterboxTransitionObserver
@@ -205,8 +227,16 @@ class LetterboxTransitionObserverTest : ShellTestCase() {
shellInit = ShellInit(executor)
transitions = mock<Transitions>()
letterboxController = mock<LetterboxController>()
+ transitionStateHolder =
+ TransitionStateHolder(shellInit, mock<RecentsTransitionHandler>())
+ spyOn(transitionStateHolder)
letterboxObserver =
- LetterboxTransitionObserver(shellInit, transitions, letterboxController)
+ LetterboxTransitionObserver(
+ shellInit,
+ transitions,
+ letterboxController,
+ transitionStateHolder
+ )
observerFactory = { letterboxObserver }
}
@@ -218,6 +248,10 @@ class LetterboxTransitionObserverTest : ShellTestCase() {
verify(transitions, expected.asMode()).registerObserver(observer())
}
+ fun configureRecentsState(running: Boolean) {
+ doReturn(running).`when`(transitionStateHolder).isRecentsTransitionRunning()
+ }
+
fun creationEventDetected(
expected: Boolean,
displayId: Int = DISPLAY_ID,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt
index 2ea0379e3bf7..41a594a3347a 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt
@@ -23,6 +23,7 @@ import android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
import android.content.pm.ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
import android.graphics.Rect
import android.os.Binder
+import android.os.UserManager
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
import android.testing.AndroidTestingRunner
@@ -96,11 +97,12 @@ class DesktopActivityOrientationChangeHandlerTest : ShellTestCase() {
@Mock lateinit var taskStackListener: TaskStackListenerImpl
@Mock lateinit var persistentRepository: DesktopPersistentRepository
@Mock lateinit var repositoryInitializer: DesktopRepositoryInitializer
+ @Mock lateinit var userManager: UserManager
private lateinit var mockitoSession: StaticMockitoSession
private lateinit var handler: DesktopActivityOrientationChangeHandler
private lateinit var shellInit: ShellInit
- private lateinit var taskRepository: DesktopRepository
+ private lateinit var userRepositories: DesktopUserRepositories
private lateinit var testScope: CoroutineScope
// Mock running tasks are registered here so we can get the list from mock shell task organizer.
private val runningTasks = mutableListOf<RunningTaskInfo>()
@@ -117,13 +119,14 @@ class DesktopActivityOrientationChangeHandlerTest : ShellTestCase() {
testScope = CoroutineScope(Dispatchers.Unconfined + SupervisorJob())
shellInit = spy(ShellInit(testExecutor))
- taskRepository =
- DesktopRepository(
+ userRepositories =
+ DesktopUserRepositories(
context,
shellInit,
persistentRepository,
repositoryInitializer,
- testScope
+ testScope,
+ userManager
)
whenever(shellTaskOrganizer.getRunningTasks(anyInt())).thenAnswer { runningTasks }
whenever(transitions.startTransition(anyInt(), any(), isNull())).thenAnswer { Binder() }
@@ -132,7 +135,7 @@ class DesktopActivityOrientationChangeHandlerTest : ShellTestCase() {
)
handler = DesktopActivityOrientationChangeHandler(context, shellInit, shellTaskOrganizer,
- taskStackListener, resizeTransitionHandler, taskRepository)
+ taskStackListener, resizeTransitionHandler, userRepositories)
shellInit.init()
}
@@ -156,7 +159,7 @@ class DesktopActivityOrientationChangeHandlerTest : ShellTestCase() {
clearInvocations(shellInit)
handler = DesktopActivityOrientationChangeHandler(context, shellInit, shellTaskOrganizer,
- taskStackListener, resizeTransitionHandler, taskRepository)
+ taskStackListener, resizeTransitionHandler, userRepositories)
verify(shellInit, never()).addInitCallback(any(),
any<DesktopActivityOrientationChangeHandler>())
@@ -180,7 +183,7 @@ class DesktopActivityOrientationChangeHandlerTest : ShellTestCase() {
activityInfo.screenOrientation = SCREEN_ORIENTATION_PORTRAIT
task.topActivityInfo = activityInfo
whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
- taskRepository.addTask(DEFAULT_DISPLAY, task.taskId, isVisible = true)
+ userRepositories.current.addTask(DEFAULT_DISPLAY, task.taskId, isVisible = true)
runningTasks.add(task)
taskStackListener.onActivityRequestedOrientationChanged(task.taskId,
@@ -203,7 +206,7 @@ class DesktopActivityOrientationChangeHandlerTest : ShellTestCase() {
@Test
fun handleActivityOrientationChange_notInDesktopMode_doNothing() {
val task = setUpFreeformTask(isResizeable = false)
- taskRepository.updateTask(task.displayId, task.taskId, isVisible = false)
+ userRepositories.current.updateTask(task.displayId, task.taskId, isVisible = false)
taskStackListener.onActivityRequestedOrientationChanged(task.taskId,
SCREEN_ORIENTATION_LANDSCAPE)
@@ -268,7 +271,7 @@ class DesktopActivityOrientationChangeHandlerTest : ShellTestCase() {
task.topActivityInfo = activityInfo
task.isResizeable = isResizeable
whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
- taskRepository.addTask(displayId, task.taskId, isVisible = true)
+ userRepositories.current.addTask(displayId, task.taskId, isVisible = true)
runningTasks.add(task)
return task
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt
index b57c55c4c45a..db4c7465ae48 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt
@@ -76,18 +76,19 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
@JvmField @Rule val animatorTestRule = AnimatorTestRule(this)
@Mock private lateinit var mockTransitions: Transitions
- private lateinit var desktopRepository: DesktopRepository
+ private lateinit var userRepositories: DesktopUserRepositories
@Mock private lateinit var mockDisplayController: DisplayController
@Mock private lateinit var mockShellTaskOrganizer: ShellTaskOrganizer
@Mock private lateinit var mockDisplayLayout: DisplayLayout
private val transactionSupplier = { StubTransaction() }
private lateinit var controller: DesktopImmersiveController
+ private lateinit var desktopRepository: DesktopRepository
@Before
fun setUp() {
- desktopRepository = DesktopRepository(
- context, ShellInit(TestShellExecutor()), mock(), mock(), mock()
+ userRepositories = DesktopUserRepositories(
+ context, ShellInit(TestShellExecutor()), mock(), mock(), mock(), mock()
)
whenever(mockDisplayController.getDisplayLayout(DEFAULT_DISPLAY))
.thenReturn(mockDisplayLayout)
@@ -97,12 +98,13 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
controller = DesktopImmersiveController(
shellInit = mock(),
transitions = mockTransitions,
- desktopRepository = desktopRepository,
+ desktopUserRepositories = userRepositories,
displayController = mockDisplayController,
shellTaskOrganizer = mockShellTaskOrganizer,
shellCommandHandler = mock(),
transactionSupplier = transactionSupplier,
)
+ desktopRepository = userRepositories.current
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandlerTest.kt
index 62717a32d99f..2d5544527436 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandlerTest.kt
@@ -60,6 +60,7 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
+import org.mockito.Mockito
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.kotlin.any
@@ -84,7 +85,7 @@ class DesktopMixedTransitionHandlerTest : ShellTestCase() {
@Mock
lateinit var transitions: Transitions
@Mock
- lateinit var desktopRepository: DesktopRepository
+ lateinit var userRepositories: DesktopUserRepositories
@Mock
lateinit var freeformTaskTransitionHandler: FreeformTaskTransitionHandler
@Mock
@@ -103,16 +104,21 @@ class DesktopMixedTransitionHandlerTest : ShellTestCase() {
lateinit var shellInit: ShellInit
@Mock
lateinit var rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer
+ @Mock
+ private lateinit var desktopRepository: DesktopRepository
private lateinit var mixedHandler: DesktopMixedTransitionHandler
+
@Before
fun setUp() {
+ whenever(userRepositories.current).thenReturn(desktopRepository)
+ whenever(userRepositories.getProfile(Mockito.anyInt())).thenReturn(desktopRepository)
mixedHandler =
DesktopMixedTransitionHandler(
context,
transitions,
- desktopRepository,
+ userRepositories,
freeformTaskTransitionHandler,
closeDesktopTaskTransitionHandler,
desktopImmersiveController,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt
index d4682c1325f2..dc7fb5f36952 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt
@@ -53,10 +53,9 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
import com.android.dx.mockito.inline.extended.StaticMockitoSession
import com.android.window.flags.Flags.FLAG_ENABLE_TASK_RESIZING_KEYBOARD_SHORTCUTS
+import com.android.wm.shell.TestShellExecutor
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.DisplayLayout
-import com.android.wm.shell.common.ShellExecutor
-import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.windowdecor.DesktopModeWindowDecorViewModel
@@ -91,7 +90,7 @@ class DesktopModeKeyGestureHandlerTest : ShellTestCase() {
private val rootTaskDisplayAreaOrganizer = mock<RootTaskDisplayAreaOrganizer>()
private val shellTaskOrganizer = mock<ShellTaskOrganizer>()
private val focusTransitionObserver = mock<FocusTransitionObserver>()
- private val testExecutor = mock<ShellExecutor>()
+ private val testExecutor = TestShellExecutor()
private val inputManager = mock<InputManager>()
private val displayController = mock<DisplayController>()
private val displayLayout = mock<DisplayLayout>()
@@ -137,8 +136,13 @@ class DesktopModeKeyGestureHandlerTest : ShellTestCase() {
desktopModeKeyGestureHandler = DesktopModeKeyGestureHandler(
context,
- Optional.of(desktopModeWindowDecorViewModel), Optional.of(desktopTasksController),
- inputManager, shellTaskOrganizer, focusTransitionObserver, testExecutor
+ Optional.of(desktopModeWindowDecorViewModel),
+ Optional.of(desktopTasksController),
+ inputManager,
+ shellTaskOrganizer,
+ focusTransitionObserver,
+ testExecutor,
+ displayController
)
}
@@ -148,6 +152,7 @@ class DesktopModeKeyGestureHandlerTest : ShellTestCase() {
runningTasks.clear()
testScope.cancel()
+ testExecutor.flushAll()
}
@Test
@@ -201,12 +206,7 @@ class DesktopModeKeyGestureHandlerTest : ShellTestCase() {
val result = keyGestureEventHandler.handleKeyGestureEvent(event, null)
assertThat(result).isTrue()
- verify(desktopModeWindowDecorViewModel).onSnapResize(
- task.taskId,
- true,
- DesktopModeEventLogger.Companion.InputMethod.KEYBOARD,
- /* fromMenu= */ false
- )
+ assertThat(testExecutor.callbacks.size).isEqualTo(1)
}
@Test
@@ -228,12 +228,7 @@ class DesktopModeKeyGestureHandlerTest : ShellTestCase() {
val result = keyGestureEventHandler.handleKeyGestureEvent(event, null)
assertThat(result).isTrue()
- verify(desktopModeWindowDecorViewModel).onSnapResize(
- task.taskId,
- false,
- DesktopModeEventLogger.Companion.InputMethod.KEYBOARD,
- /* fromMenu= */ false
- )
+ assertThat(testExecutor.callbacks.size).isEqualTo(1)
}
@Test
@@ -255,11 +250,7 @@ class DesktopModeKeyGestureHandlerTest : ShellTestCase() {
val result = keyGestureEventHandler.handleKeyGestureEvent(event, null)
assertThat(result).isTrue()
- verify(desktopTasksController).toggleDesktopTaskSize(
- task,
- ResizeTrigger.MAXIMIZE_MENU,
- DesktopModeEventLogger.Companion.InputMethod.KEYBOARD,
- )
+ assertThat(testExecutor.callbacks.size).isEqualTo(1)
}
@Test
@@ -281,6 +272,7 @@ class DesktopModeKeyGestureHandlerTest : ShellTestCase() {
val result = keyGestureEventHandler.handleKeyGestureEvent(event, null)
assertThat(result).isTrue()
+ assertThat(testExecutor.callbacks.size).isEqualTo(1)
}
private fun setUpFreeformTask(
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 7f790d574a7e..9059d7d5342c 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
@@ -30,7 +30,6 @@ import com.android.wm.shell.TestShellExecutor
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.desktopmode.persistence.Desktop
import com.android.wm.shell.desktopmode.persistence.DesktopPersistentRepository
-import com.android.wm.shell.desktopmode.persistence.DesktopRepositoryInitializer
import com.android.wm.shell.sysui.ShellInit
import com.google.common.truth.Truth.assertThat
import junit.framework.Assert.fail
@@ -70,7 +69,6 @@ class DesktopRepositoryTest : ShellTestCase() {
@Mock private lateinit var testExecutor: ShellExecutor
@Mock private lateinit var persistentRepository: DesktopPersistentRepository
- @Mock lateinit var repositoryInitializer: DesktopRepositoryInitializer
@Before
fun setUp() {
@@ -80,11 +78,9 @@ class DesktopRepositoryTest : ShellTestCase() {
repo =
DesktopRepository(
- context,
- shellInit,
persistentRepository,
- repositoryInitializer,
- datastoreScope
+ datastoreScope,
+ DEFAULT_USER_ID
)
whenever(runBlocking { persistentRepository.readDesktop(any(), any()) }).thenReturn(
Desktop.getDefaultInstance()
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListenerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListenerTest.kt
index 8e323acc4e66..b4daa6637f83 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListenerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListenerTest.kt
@@ -22,6 +22,7 @@ import android.platform.test.flag.junit.SetFlagsRule
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION
+import com.android.wm.shell.desktopmode.DesktopUserRepositories
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFullscreenTask
@@ -29,6 +30,7 @@ import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
import org.mockito.kotlin.mock
import org.mockito.kotlin.never
import org.mockito.kotlin.verify
@@ -47,131 +49,163 @@ class DesktopTaskChangeListenerTest : ShellTestCase() {
private lateinit var desktopTaskChangeListener: DesktopTaskChangeListener
+ private val desktopUserRepositories = mock<DesktopUserRepositories>()
private val desktopRepository = mock<DesktopRepository>()
@Before
fun setUp() {
- desktopTaskChangeListener = DesktopTaskChangeListener(desktopRepository)
+ desktopTaskChangeListener = DesktopTaskChangeListener(desktopUserRepositories)
+
+ whenever(desktopUserRepositories.current).thenReturn(desktopRepository)
+ whenever(desktopUserRepositories.getProfile(anyInt())).thenReturn(desktopRepository)
}
@Test
fun onTaskOpening_fullscreenTask_notActiveDesktopTask_noop() {
val task = createFullscreenTask().apply { isVisible = true }
- whenever(desktopRepository.isActiveTask(task.taskId)).thenReturn(false)
+ whenever(desktopUserRepositories.current.isActiveTask(task.taskId))
+ .thenReturn(false)
desktopTaskChangeListener.onTaskOpening(task)
- verify(desktopRepository, never()).addTask(task.displayId, task.taskId, task.isVisible)
- verify(desktopRepository, never()).removeFreeformTask(task.displayId, task.taskId)
+ verify(desktopUserRepositories.current, never())
+ .addTask(task.displayId, task.taskId, task.isVisible)
+ verify(desktopUserRepositories.current, never())
+ .removeFreeformTask(task.displayId, task.taskId)
}
@Test
fun onTaskOpening_freeformTask_activeDesktopTask_removesTaskFromRepo() {
val task = createFullscreenTask().apply { isVisible = true }
- whenever(desktopRepository.isActiveTask(task.taskId)).thenReturn(true)
+ whenever(desktopUserRepositories.current.isActiveTask(task.taskId))
+ .thenReturn(true)
desktopTaskChangeListener.onTaskOpening(task)
- verify(desktopRepository).removeFreeformTask(task.displayId, task.taskId)
+ verify(desktopUserRepositories.current).removeFreeformTask(task.displayId, task.taskId)
}
@Test
fun onTaskOpening_freeformTask_visibleDesktopTask_addsTaskToRepository() {
val task = createFreeformTask().apply { isVisible = true }
- whenever(desktopRepository.isActiveTask(task.taskId)).thenReturn(false)
+ whenever(desktopUserRepositories.current.isActiveTask(task.taskId))
+ .thenReturn(false)
desktopTaskChangeListener.onTaskOpening(task)
- verify(desktopRepository).addTask(task.displayId, task.taskId, task.isVisible)
+ verify(desktopUserRepositories.current)
+ .addTask(task.displayId, task.taskId, task.isVisible)
}
@Test
fun onTaskOpening_freeformTask_nonVisibleDesktopTask_addsTaskToRepository() {
val task = createFreeformTask().apply { isVisible = false }
- whenever(desktopRepository.isActiveTask(task.taskId)).thenReturn(true)
+ whenever(desktopUserRepositories.current.isActiveTask(task.taskId))
+ .thenReturn(true)
desktopTaskChangeListener.onTaskOpening(task)
- verify(desktopRepository).addTask(task.displayId, task.taskId, task.isVisible)
+ verify(desktopUserRepositories.current)
+ .addTask(task.displayId, task.taskId, task.isVisible)
}
@Test
fun onTaskChanging_freeformTaskOutsideDesktop_removesTaskFromRepo() {
val task = createFullscreenTask().apply { isVisible = true }
- whenever(desktopRepository.isActiveTask(task.taskId)).thenReturn(true)
+ whenever(desktopUserRepositories.current.isActiveTask(task.taskId))
+ .thenReturn(true)
desktopTaskChangeListener.onTaskChanging(task)
- verify(desktopRepository).removeFreeformTask(task.displayId, task.taskId)
+ verify(desktopUserRepositories.current)
+ .removeFreeformTask(task.displayId, task.taskId)
}
@Test
fun onTaskChanging_visibleTaskInDesktop_updatesTaskVisibility() {
val task = createFreeformTask().apply { isVisible = true }
- whenever(desktopRepository.isActiveTask(task.taskId)).thenReturn(true)
+ whenever(desktopUserRepositories.current.isActiveTask(task.taskId))
+ .thenReturn(true)
desktopTaskChangeListener.onTaskChanging(task)
- verify(desktopRepository).updateTask(task.displayId, task.taskId, task.isVisible)
+ verify(desktopUserRepositories.current)
+ .updateTask(task.displayId, task.taskId, task.isVisible)
}
@Test
fun onTaskChanging_nonVisibleTask_updatesTaskVisibility() {
val task = createFreeformTask().apply { isVisible = false }
- whenever(desktopRepository.isActiveTask(task.taskId)).thenReturn(true)
+ whenever(desktopUserRepositories.current.isActiveTask(task.taskId))
+ .thenReturn(true)
desktopTaskChangeListener.onTaskChanging(task)
- verify(desktopRepository).updateTask(task.displayId, task.taskId, task.isVisible)
+ verify(desktopUserRepositories.current)
+ .updateTask(task.displayId, task.taskId, task.isVisible)
}
@Test
fun onTaskMovingToFront_freeformTaskOutsideDesktop_removesTaskFromRepo() {
val task = createFullscreenTask().apply { isVisible = true }
- whenever(desktopRepository.isActiveTask(task.taskId)).thenReturn(true)
+ whenever(desktopUserRepositories.current.isActiveTask(task.taskId))
+ .thenReturn(true)
desktopTaskChangeListener.onTaskMovingToFront(task)
- verify(desktopRepository).removeFreeformTask(task.displayId, task.taskId)
+ verify(desktopUserRepositories.current)
+ .removeFreeformTask(task.displayId, task.taskId)
}
@Test
@EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION)
fun onTaskClosing_backNavEnabled_nonClosingTask_minimizesTaskInRepo() {
val task = createFreeformTask().apply { isVisible = true }
- whenever(desktopRepository.isActiveTask(task.taskId)).thenReturn(true)
- whenever(desktopRepository.isClosingTask(task.taskId)).thenReturn(false)
+ whenever(desktopUserRepositories.current.isActiveTask(task.taskId))
+ .thenReturn(true)
+ whenever(desktopUserRepositories.current.isClosingTask(task.taskId))
+ .thenReturn(false)
desktopTaskChangeListener.onTaskClosing(task)
- verify(desktopRepository).updateTask(task.displayId, task.taskId, isVisible = false)
- verify(desktopRepository).minimizeTask(task.displayId, task.taskId)
+ verify(desktopUserRepositories.current)
+ .updateTask(task.displayId, task.taskId, isVisible = false)
+ verify(desktopUserRepositories.current)
+ .minimizeTask(task.displayId, task.taskId)
}
@Test
@DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION)
fun onTaskClosing_backNavDisabled_closingTask_removesTaskInRepo() {
val task = createFreeformTask().apply { isVisible = true }
- whenever(desktopRepository.isActiveTask(task.taskId)).thenReturn(true)
- whenever(desktopRepository.isClosingTask(task.taskId)).thenReturn(true)
+ whenever(desktopUserRepositories.current.isActiveTask(task.taskId))
+ .thenReturn(true)
+ whenever(desktopUserRepositories.current.isClosingTask(task.taskId))
+ .thenReturn(true)
desktopTaskChangeListener.onTaskClosing(task)
- verify(desktopRepository, never()).minimizeTask(task.displayId, task.taskId)
- verify(desktopRepository).removeClosingTask(task.taskId)
- verify(desktopRepository).removeFreeformTask(task.displayId, task.taskId)
+ verify(desktopUserRepositories.current, never())
+ .minimizeTask(task.displayId, task.taskId)
+ verify(desktopUserRepositories.current)
+ .removeClosingTask(task.taskId)
+ verify(desktopUserRepositories.current)
+ .removeFreeformTask(task.displayId, task.taskId)
}
@Test
@EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION)
fun onTaskClosing_backNavEnabled_closingTask_removesTaskFromRepo() {
val task = createFreeformTask().apply { isVisible = true }
- whenever(desktopRepository.isActiveTask(task.taskId)).thenReturn(true)
- whenever(desktopRepository.isClosingTask(task.taskId)).thenReturn(true)
+ whenever(desktopUserRepositories.current.isActiveTask(task.taskId))
+ .thenReturn(true)
+ whenever(desktopUserRepositories.current.isClosingTask(task.taskId))
+ .thenReturn(true)
desktopTaskChangeListener.onTaskClosing(task)
- verify(desktopRepository).removeClosingTask(task.taskId)
- verify(desktopRepository).removeFreeformTask(task.displayId, task.taskId)
+ verify(desktopUserRepositories.current).removeClosingTask(task.taskId)
+ verify(desktopUserRepositories.current)
+ .removeFreeformTask(task.displayId, task.taskId)
}
}
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 5c0027220ec9..c10434aa6d6f 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
@@ -44,6 +44,7 @@ import android.os.Binder
import android.os.Bundle
import android.os.Handler
import android.os.IBinder
+import android.os.UserManager
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
@@ -93,6 +94,7 @@ import com.android.wm.shell.common.DisplayLayout
import com.android.wm.shell.common.MultiInstanceHelper
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.common.SyncTransactionQueue
+import com.android.wm.shell.desktopmode.common.ToggleTaskSizeInteraction
import com.android.wm.shell.desktopmode.DesktopImmersiveController.ExitResult
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.InputMethod
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
@@ -233,9 +235,11 @@ class DesktopTasksControllerTest : ShellTestCase() {
@Mock private lateinit var resources: Resources
@Mock
lateinit var desktopModeEnterExitTransitionListener: DesktopModeEntryExitTransitionListener
+ @Mock private lateinit var userManager: UserManager
private lateinit var controller: DesktopTasksController
private lateinit var shellInit: ShellInit
private lateinit var taskRepository: DesktopRepository
+ private lateinit var userRepositories: DesktopUserRepositories
private lateinit var desktopTasksLimiter: DesktopTasksLimiter
private lateinit var recentsTransitionStateListener: RecentsTransitionStateListener
private lateinit var testScope: CoroutineScope
@@ -267,12 +271,18 @@ class DesktopTasksControllerTest : ShellTestCase() {
testScope = CoroutineScope(Dispatchers.Unconfined + SupervisorJob())
shellInit = spy(ShellInit(testExecutor))
- taskRepository =
- DesktopRepository(context, shellInit, persistentRepository, repositoryInitializer, testScope)
+ userRepositories =
+ DesktopUserRepositories(
+ context,
+ shellInit,
+ persistentRepository,
+ repositoryInitializer,
+ testScope,
+ userManager)
desktopTasksLimiter =
DesktopTasksLimiter(
transitions,
- taskRepository,
+ userRepositories,
shellTaskOrganizer,
MAX_TASK_LIMIT,
mockInteractionJankMonitor,
@@ -315,6 +325,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
controller.taskbarDesktopTaskListener = taskbarDesktopTaskListener
assumeTrue(ENABLE_SHELL_TRANSITIONS)
+
+ taskRepository = userRepositories.current
}
private fun createController(): DesktopTasksController {
@@ -338,7 +350,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
toggleResizeDesktopTaskTransitionHandler,
dragToDesktopTransitionHandler,
mMockDesktopImmersiveController,
- taskRepository,
+ userRepositories,
recentsTransitionHandler,
multiInstanceHelper,
shellExecutor,
@@ -377,7 +389,14 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task1 = setUpFreeformTask()
val argumentCaptor = ArgumentCaptor.forClass(Boolean::class.java)
- controller.toggleDesktopTaskSize(task1, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
+ controller.toggleDesktopTaskSize(
+ task1,
+ ToggleTaskSizeInteraction(
+ ToggleTaskSizeInteraction.Direction.MAXIMIZE,
+ ToggleTaskSizeInteraction.Source.HEADER_BUTTON_TO_MAXIMIZE,
+ InputMethod.TOUCH
+ )
+ )
verify(taskbarDesktopTaskListener).onTaskbarCornerRoundingUpdate(argumentCaptor.capture())
verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
@@ -399,21 +418,29 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
- fun doesAnyTaskRequireTaskbarRounding_toggleResizeOfFullScreenTask_returnFalse() {
+ fun doesAnyTaskRequireTaskbarRounding_toggleResizeOfMaximizedTask_returnFalse() {
val stableBounds = Rect().apply { displayLayout.getStableBounds(this) }
val task1 = setUpFreeformTask(bounds = stableBounds, active = true)
val argumentCaptor = ArgumentCaptor.forClass(Boolean::class.java)
- controller.toggleDesktopTaskSize(task1, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
+ controller.toggleDesktopTaskSize(
+ task1,
+ ToggleTaskSizeInteraction(
+ ToggleTaskSizeInteraction.Direction.RESTORE,
+ ToggleTaskSizeInteraction.Source.HEADER_BUTTON_TO_RESTORE,
+ InputMethod.TOUCH
+ )
+ )
verify(taskbarDesktopTaskListener).onTaskbarCornerRoundingUpdate(argumentCaptor.capture())
verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
- ResizeTrigger.MAXIMIZE_BUTTON,
- InputMethod.TOUCH,
- task1,
- 0,
- 0,
- displayController
+ eq(ResizeTrigger.MAXIMIZE_BUTTON),
+ eq(InputMethod.TOUCH),
+ eq(task1),
+ anyOrNull(),
+ anyOrNull(),
+ eq(displayController),
+ anyOrNull()
)
assertThat(argumentCaptor.value).isFalse()
}
@@ -3359,7 +3386,14 @@ class DesktopTasksControllerTest : ShellTestCase() {
val bounds = Rect(0, 0, 100, 100)
val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds)
- controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
+ controller.toggleDesktopTaskSize(
+ task,
+ ToggleTaskSizeInteraction(
+ ToggleTaskSizeInteraction.Direction.MAXIMIZE,
+ ToggleTaskSizeInteraction.Source.HEADER_BUTTON_TO_MAXIMIZE,
+ InputMethod.TOUCH
+ )
+ )
// Assert bounds set to stable bounds
val wct = getLatestToggleResizeDesktopTaskWct()
@@ -3584,7 +3618,14 @@ class DesktopTasksControllerTest : ShellTestCase() {
// Bounds should be 1000 x 500, vertically centered in the 1000 x 1000 stable bounds
val expectedBounds = Rect(STABLE_BOUNDS.left, 250, STABLE_BOUNDS.right, 750)
- controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
+ controller.toggleDesktopTaskSize(
+ task,
+ ToggleTaskSizeInteraction(
+ ToggleTaskSizeInteraction.Direction.MAXIMIZE,
+ ToggleTaskSizeInteraction.Source.HEADER_BUTTON_TO_MAXIMIZE,
+ InputMethod.TOUCH
+ )
+ )
// Assert bounds set to stable bounds
val wct = getLatestToggleResizeDesktopTaskWct()
@@ -3604,7 +3645,15 @@ class DesktopTasksControllerTest : ShellTestCase() {
val bounds = Rect(0, 0, 100, 100)
val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds)
- controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
+ controller.toggleDesktopTaskSize(
+ task,
+ ToggleTaskSizeInteraction(
+ ToggleTaskSizeInteraction.Direction.MAXIMIZE,
+ ToggleTaskSizeInteraction.Source.HEADER_BUTTON_TO_MAXIMIZE,
+ InputMethod.TOUCH
+ )
+ )
+
assertThat(taskRepository.removeBoundsBeforeMaximize(task.taskId)).isEqualTo(bounds)
verify(desktopModeEventLogger, never()).logTaskResizingEnded(
any(), any(), any(), any(),
@@ -3618,11 +3667,25 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task = setUpFreeformTask(DEFAULT_DISPLAY, boundsBeforeMaximize)
// Maximize
- controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
+ controller.toggleDesktopTaskSize(
+ task,
+ ToggleTaskSizeInteraction(
+ ToggleTaskSizeInteraction.Direction.MAXIMIZE,
+ ToggleTaskSizeInteraction.Source.HEADER_BUTTON_TO_MAXIMIZE,
+ InputMethod.TOUCH
+ )
+ )
task.configuration.windowConfiguration.bounds.set(STABLE_BOUNDS)
// Restore
- controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
+ controller.toggleDesktopTaskSize(
+ task,
+ ToggleTaskSizeInteraction(
+ ToggleTaskSizeInteraction.Direction.RESTORE,
+ ToggleTaskSizeInteraction.Source.HEADER_BUTTON_TO_RESTORE,
+ InputMethod.TOUCH
+ )
+ )
// Assert bounds set to last bounds before maximize
val wct = getLatestToggleResizeDesktopTaskWct()
@@ -3645,12 +3708,26 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
// Maximize
- controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
+ controller.toggleDesktopTaskSize(
+ task,
+ ToggleTaskSizeInteraction(
+ ToggleTaskSizeInteraction.Direction.MAXIMIZE,
+ ToggleTaskSizeInteraction.Source.HEADER_BUTTON_TO_MAXIMIZE,
+ InputMethod.TOUCH
+ )
+ )
task.configuration.windowConfiguration.bounds.set(STABLE_BOUNDS.left,
boundsBeforeMaximize.top, STABLE_BOUNDS.right, boundsBeforeMaximize.bottom)
// Restore
- controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
+ controller.toggleDesktopTaskSize(
+ task,
+ ToggleTaskSizeInteraction(
+ ToggleTaskSizeInteraction.Direction.RESTORE,
+ ToggleTaskSizeInteraction.Source.HEADER_BUTTON_TO_RESTORE,
+ InputMethod.TOUCH
+ )
+ )
// Assert bounds set to last bounds before maximize
val wct = getLatestToggleResizeDesktopTaskWct()
@@ -3673,12 +3750,26 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
// Maximize
- controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
+ controller.toggleDesktopTaskSize(
+ task,
+ ToggleTaskSizeInteraction(
+ ToggleTaskSizeInteraction.Direction.MAXIMIZE,
+ ToggleTaskSizeInteraction.Source.HEADER_BUTTON_TO_MAXIMIZE,
+ InputMethod.TOUCH
+ )
+ )
task.configuration.windowConfiguration.bounds.set(boundsBeforeMaximize.left,
STABLE_BOUNDS.top, boundsBeforeMaximize.right, STABLE_BOUNDS.bottom)
// Restore
- controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
+ controller.toggleDesktopTaskSize(
+ task,
+ ToggleTaskSizeInteraction(
+ ToggleTaskSizeInteraction.Direction.RESTORE,
+ ToggleTaskSizeInteraction.Source.HEADER_BUTTON_TO_RESTORE,
+ InputMethod.TOUCH
+ )
+ )
// Assert bounds set to last bounds before maximize
val wct = getLatestToggleResizeDesktopTaskWct()
@@ -3699,11 +3790,25 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task = setUpFreeformTask(DEFAULT_DISPLAY, boundsBeforeMaximize)
// Maximize
- controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
+ controller.toggleDesktopTaskSize(
+ task,
+ ToggleTaskSizeInteraction(
+ ToggleTaskSizeInteraction.Direction.MAXIMIZE,
+ ToggleTaskSizeInteraction.Source.HEADER_BUTTON_TO_MAXIMIZE,
+ InputMethod.TOUCH
+ )
+ )
task.configuration.windowConfiguration.bounds.set(STABLE_BOUNDS)
// Restore
- controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
+ controller.toggleDesktopTaskSize(
+ task,
+ ToggleTaskSizeInteraction(
+ ToggleTaskSizeInteraction.Direction.RESTORE,
+ ToggleTaskSizeInteraction.Source.HEADER_BUTTON_TO_RESTORE,
+ InputMethod.TOUCH
+ )
+ )
// Assert last bounds before maximize removed after use
assertThat(taskRepository.removeBoundsBeforeMaximize(task.taskId)).isNull()
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
index 797b12505ef2..0712d58166bb 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
@@ -20,6 +20,7 @@ import android.app.ActivityManager.RunningTaskInfo
import android.graphics.Rect
import android.os.Binder
import android.os.Handler
+import android.os.UserManager
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
@@ -73,7 +74,6 @@ import org.mockito.kotlin.eq
import org.mockito.kotlin.verify
import org.mockito.quality.Strictness
-
/**
* Test class for {@link DesktopTasksLimiter}
*
@@ -95,9 +95,11 @@ class DesktopTasksLimiterTest : ShellTestCase() {
@Mock lateinit var testExecutor: ShellExecutor
@Mock lateinit var persistentRepository: DesktopPersistentRepository
@Mock lateinit var repositoryInitializer: DesktopRepositoryInitializer
+ @Mock lateinit var userManager: UserManager
private lateinit var mockitoSession: StaticMockitoSession
private lateinit var desktopTasksLimiter: DesktopTasksLimiter
+ private lateinit var userRepositories: DesktopUserRepositories
private lateinit var desktopTaskRepo: DesktopRepository
private lateinit var shellInit: ShellInit
private lateinit var testScope: CoroutineScope
@@ -111,16 +113,18 @@ class DesktopTasksLimiterTest : ShellTestCase() {
Dispatchers.setMain(StandardTestDispatcher())
testScope = CoroutineScope(Dispatchers.Unconfined + SupervisorJob())
- desktopTaskRepo =
- DesktopRepository(
+ userRepositories =
+ DesktopUserRepositories(
context,
shellInit,
persistentRepository,
repositoryInitializer,
- testScope
+ testScope,
+ userManager
)
+ desktopTaskRepo = userRepositories.current
desktopTasksLimiter =
- DesktopTasksLimiter(transitions, desktopTaskRepo, shellTaskOrganizer, MAX_TASK_LIMIT,
+ DesktopTasksLimiter(transitions, userRepositories, shellTaskOrganizer, MAX_TASK_LIMIT,
interactionJankMonitor, mContext, handler)
}
@@ -133,7 +137,7 @@ class DesktopTasksLimiterTest : ShellTestCase() {
@Test
fun createDesktopTasksLimiter_withZeroLimit_shouldThrow() {
assertFailsWith<IllegalArgumentException> {
- DesktopTasksLimiter(transitions, desktopTaskRepo, shellTaskOrganizer, 0,
+ DesktopTasksLimiter(transitions, userRepositories, shellTaskOrganizer, 0,
interactionJankMonitor, mContext, handler)
}
}
@@ -141,7 +145,7 @@ class DesktopTasksLimiterTest : ShellTestCase() {
@Test
fun createDesktopTasksLimiter_withNegativeLimit_shouldThrow() {
assertFailsWith<IllegalArgumentException> {
- DesktopTasksLimiter(transitions, desktopTaskRepo, shellTaskOrganizer, -5,
+ DesktopTasksLimiter(transitions, userRepositories, shellTaskOrganizer, -5,
interactionJankMonitor, mContext, handler)
}
}
@@ -411,7 +415,7 @@ class DesktopTasksLimiterTest : ShellTestCase() {
@Test
fun getTaskToMinimize_tasksAboveLimit_otherLimit_returnsBackTask() {
desktopTasksLimiter =
- DesktopTasksLimiter(transitions, desktopTaskRepo, shellTaskOrganizer, MAX_TASK_LIMIT2,
+ DesktopTasksLimiter(transitions, userRepositories, shellTaskOrganizer, MAX_TASK_LIMIT2,
interactionJankMonitor, mContext, handler)
val tasks = (1..MAX_TASK_LIMIT2 + 1).map { setUpFreeformTask() }
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 7f1c1db3207a..238483da537c 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
@@ -50,6 +50,7 @@ import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.eq
import org.mockito.ArgumentMatchers.isA
import org.mockito.Mockito
@@ -75,6 +76,7 @@ class DesktopTasksTransitionObserverTest {
private val transitions = mock<Transitions>()
private val context = mock<Context>()
private val shellTaskOrganizer = mock<ShellTaskOrganizer>()
+ private val userRepositories = mock<DesktopUserRepositories>()
private val taskRepository = mock<DesktopRepository>()
private val mixedHandler = mock<DesktopMixedTransitionHandler>()
@@ -86,9 +88,12 @@ class DesktopTasksTransitionObserverTest {
whenever(DesktopModeStatus.canEnterDesktopMode(any())).thenReturn(true)
shellInit = spy(ShellInit(testExecutor))
+ whenever(userRepositories.current).thenReturn(taskRepository)
+ whenever(userRepositories.getProfile(anyInt())).thenReturn(taskRepository)
+
transitionObserver =
DesktopTasksTransitionObserver(
- context, taskRepository, transitions, shellTaskOrganizer, mixedHandler, shellInit
+ context, userRepositories, transitions, shellTaskOrganizer, mixedHandler, shellInit
)
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandlerTest.kt
index 226e974d2875..b9d7bbf567b7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandlerTest.kt
@@ -25,10 +25,11 @@ import android.view.WindowManager.TRANSIT_OPEN
import androidx.test.filters.SmallTest
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.common.ShellExecutor
-import com.android.wm.shell.desktopmode.DesktopRepository
import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFullscreenTask
import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFullscreenTaskBuilder
import com.android.wm.shell.desktopmode.DesktopTestHelpers.createSystemModalTask
+import com.android.wm.shell.desktopmode.DesktopRepository
+import com.android.wm.shell.desktopmode.DesktopUserRepositories
import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.transition.TransitionInfoBuilder
import com.android.wm.shell.transition.Transitions
@@ -49,6 +50,7 @@ class SystemModalsTransitionHandlerTest : ShellTestCase() {
private val animExecutor = mock<ShellExecutor>()
private val shellInit = mock<ShellInit>()
private val transitions = mock<Transitions>()
+ private val desktopUserRepositories = mock<DesktopUserRepositories>()
private val desktopRepository = mock<DesktopRepository>()
private val startT = mock<SurfaceControl.Transaction>()
private val finishT = mock<SurfaceControl.Transaction>()
@@ -58,6 +60,7 @@ class SystemModalsTransitionHandlerTest : ShellTestCase() {
@Before
fun setUp() {
// Simulate having one Desktop task so that we see Desktop Mode as active
+ whenever(desktopUserRepositories.current).thenReturn(desktopRepository)
whenever(desktopRepository.getVisibleTaskCount(anyInt())).thenReturn(1)
transitionHandler = createTransitionHandler()
}
@@ -69,7 +72,7 @@ class SystemModalsTransitionHandlerTest : ShellTestCase() {
animExecutor,
shellInit,
transitions,
- desktopRepository,
+ desktopUserRepositories,
)
@Test
@@ -79,7 +82,7 @@ class SystemModalsTransitionHandlerTest : ShellTestCase() {
@Test
fun startAnimation_desktopNotActive_doesNotAnimate() {
- whenever(desktopRepository.getVisibleTaskCount(anyInt())).thenReturn(1)
+ whenever(desktopUserRepositories.current.getVisibleTaskCount(anyInt())).thenReturn(1)
val info =
TransitionInfoBuilder(TRANSIT_OPEN)
.addChange(TRANSIT_OPEN, createSystemModalTask())
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepositoryTest.kt
index 8495580f42a5..4f7e80cf8330 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepositoryTest.kt
@@ -112,7 +112,8 @@ class DesktopPersistentRepositoryTest : ShellTestCase() {
datastoreRepository.addOrUpdateDesktop(
visibleTasks = visibleTasks,
minimizedTasks = minimizedTasks,
- freeformTasksInZOrder = freeformTasksInZOrder)
+ freeformTasksInZOrder = freeformTasksInZOrder,
+ userId = DEFAULT_USER_ID)
val actualDesktop = datastoreRepository.readDesktop(DEFAULT_USER_ID, DEFAULT_DESKTOP_ID)
assertThat(actualDesktop?.tasksByTaskIdMap).hasSize(2)
@@ -135,7 +136,8 @@ class DesktopPersistentRepositoryTest : ShellTestCase() {
datastoreRepository.addOrUpdateDesktop(
visibleTasks = visibleTasks,
minimizedTasks = minimizedTasks,
- freeformTasksInZOrder = freeformTasksInZOrder)
+ freeformTasksInZOrder = freeformTasksInZOrder,
+ userId = DEFAULT_USER_ID)
val actualDesktop = datastoreRepository.readDesktop(DEFAULT_USER_ID, DEFAULT_DESKTOP_ID)
assertThat(actualDesktop?.tasksByTaskIdMap?.get(task.taskId)?.desktopTaskState)
@@ -158,7 +160,8 @@ class DesktopPersistentRepositoryTest : ShellTestCase() {
datastoreRepository.addOrUpdateDesktop(
visibleTasks = visibleTasks,
minimizedTasks = minimizedTasks,
- freeformTasksInZOrder = freeformTasksInZOrder)
+ freeformTasksInZOrder = freeformTasksInZOrder,
+ userId = DEFAULT_USER_ID)
val actualDesktop = datastoreRepository.readDesktop(DEFAULT_USER_ID, DEFAULT_DESKTOP_ID)
assertThat(actualDesktop?.tasksByTaskIdMap).isEmpty()
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerTest.kt
index 975342902814..1c88a290d677 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerTest.kt
@@ -16,14 +16,17 @@
package com.android.wm.shell.desktopmode.persistence
+import android.os.UserManager
import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.SetFlagsRule
import android.testing.AndroidTestingRunner
import android.view.Display.DEFAULT_DISPLAY
import androidx.test.filters.SmallTest
+import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_HSUM
import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PERSISTENCE
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.common.ShellExecutor
-import com.android.wm.shell.desktopmode.DesktopRepository
+import com.android.wm.shell.desktopmode.DesktopUserRepositories
import com.android.wm.shell.sysui.ShellInit
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineScope
@@ -36,26 +39,30 @@ import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.setMain
import org.junit.After
import org.junit.Before
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mockito.inOrder
import org.mockito.Mockito.spy
-import org.mockito.kotlin.any
import org.mockito.kotlin.mock
-import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
+
@SmallTest
@RunWith(AndroidTestingRunner::class)
@ExperimentalCoroutinesApi
class DesktopRepositoryInitializerTest : ShellTestCase() {
+ @JvmField
+ @Rule
+ val setFlagsRule = SetFlagsRule()
+
private lateinit var repositoryInitializer: DesktopRepositoryInitializer
private lateinit var shellInit: ShellInit
private lateinit var datastoreScope: CoroutineScope
- private lateinit var desktopRepository: DesktopRepository
+ private lateinit var desktopUserRepositories: DesktopUserRepositories
private val persistentRepository = mock<DesktopPersistentRepository>()
+ private val userManager = mock<UserManager>()
private val testExecutor = mock<ShellExecutor>()
@Before
@@ -65,55 +72,193 @@ class DesktopRepositoryInitializerTest : ShellTestCase() {
datastoreScope = CoroutineScope(Dispatchers.Unconfined + SupervisorJob())
repositoryInitializer =
DesktopRepositoryInitializerImpl(context, persistentRepository, datastoreScope)
- desktopRepository =
- DesktopRepository(
- context, shellInit, persistentRepository, repositoryInitializer, datastoreScope)
+ desktopUserRepositories =
+ DesktopUserRepositories(
+ context, shellInit, persistentRepository, repositoryInitializer, datastoreScope,
+ userManager
+ )
}
@Test
+ @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PERSISTENCE, FLAG_ENABLE_DESKTOP_WINDOWING_HSUM)
+ fun initWithPersistence_multipleUsers_addedCorrectly() =
+ runTest(StandardTestDispatcher()) {
+ whenever(persistentRepository.getUserDesktopRepositoryMap()).thenReturn(
+ mapOf(
+ USER_ID_1 to desktopRepositoryState1,
+ USER_ID_2 to desktopRepositoryState2
+ )
+ )
+ whenever(persistentRepository.getDesktopRepositoryState(USER_ID_1))
+ .thenReturn(desktopRepositoryState1)
+ whenever(persistentRepository.getDesktopRepositoryState(USER_ID_2))
+ .thenReturn(desktopRepositoryState2)
+ whenever(persistentRepository.readDesktop(USER_ID_1, DESKTOP_ID_1))
+ .thenReturn(desktop1)
+ whenever(persistentRepository.readDesktop(USER_ID_1, DESKTOP_ID_2))
+ .thenReturn(desktop2)
+ whenever(persistentRepository.readDesktop(USER_ID_2, DESKTOP_ID_3))
+ .thenReturn(desktop3)
+
+ repositoryInitializer.initialize(desktopUserRepositories)
+
+ // Desktop Repository currently returns all tasks across desktops for a specific user
+ // since the repository currently doesn't handle desktops. This test logic should be updated
+ // once the repository handles multiple desktops.
+ assertThat(
+ desktopUserRepositories.getProfile(USER_ID_1)
+ .getActiveTasks(DEFAULT_DISPLAY)
+ )
+ .containsExactly(1, 3, 4, 5)
+ .inOrder()
+ assertThat(
+ desktopUserRepositories.getProfile(USER_ID_1)
+ .getExpandedTasksOrdered(DEFAULT_DISPLAY)
+ )
+ .containsExactly(5, 1)
+ .inOrder()
+ assertThat(
+ desktopUserRepositories.getProfile(USER_ID_1)
+ .getMinimizedTasks(DEFAULT_DISPLAY)
+ )
+ .containsExactly(3, 4)
+ .inOrder()
+
+ assertThat(
+ desktopUserRepositories.getProfile(USER_ID_2)
+ .getActiveTasks(DEFAULT_DISPLAY)
+ )
+ .containsExactly(7, 8)
+ .inOrder()
+ assertThat(
+ desktopUserRepositories.getProfile(USER_ID_2)
+ .getExpandedTasksOrdered(DEFAULT_DISPLAY)
+ )
+ .contains(7)
+ assertThat(
+ desktopUserRepositories.getProfile(USER_ID_2)
+ .getMinimizedTasks(DEFAULT_DISPLAY)
+ ).containsExactly(8)
+ }
+
+ @Test
@EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PERSISTENCE)
- fun initWithPersistence_multipleTasks_addedCorrectly() =
+ fun initWithPersistence_singleUser_addedCorrectly() =
runTest(StandardTestDispatcher()) {
- val freeformTasksInZOrder = listOf(1, 2, 3)
- whenever(persistentRepository.readDesktop(any(), any()))
- .thenReturn(
- Desktop.newBuilder()
- .setDesktopId(1)
- .addAllZOrderedTasks(freeformTasksInZOrder)
- .putTasksByTaskId(
- 1,
- DesktopTask.newBuilder()
- .setTaskId(1)
- .setDesktopTaskState(DesktopTaskState.VISIBLE)
- .build())
- .putTasksByTaskId(
- 2,
- DesktopTask.newBuilder()
- .setTaskId(2)
- .setDesktopTaskState(DesktopTaskState.VISIBLE)
- .build())
- .putTasksByTaskId(
- 3,
- DesktopTask.newBuilder()
- .setTaskId(3)
- .setDesktopTaskState(DesktopTaskState.MINIMIZED)
- .build())
- .build())
-
- repositoryInitializer.initialize(desktopRepository)
-
- verify(persistentRepository).readDesktop(any(), any())
- assertThat(desktopRepository.getActiveTasks(DEFAULT_DISPLAY))
- .containsExactly(1, 2, 3)
+ whenever(persistentRepository.getUserDesktopRepositoryMap()).thenReturn(
+ mapOf(
+ USER_ID_1 to desktopRepositoryState1,
+ )
+ )
+ whenever(persistentRepository.getDesktopRepositoryState(USER_ID_1))
+ .thenReturn(desktopRepositoryState1)
+ whenever(persistentRepository.readDesktop(USER_ID_1, DESKTOP_ID_1))
+ .thenReturn(desktop1)
+ whenever(persistentRepository.readDesktop(USER_ID_1, DESKTOP_ID_2))
+ .thenReturn(desktop2)
+
+ repositoryInitializer.initialize(desktopUserRepositories)
+
+ // Desktop Repository currently returns all tasks across desktops for a specific user
+ // since the repository currently doesn't handle desktops. This test logic should be updated
+ // once the repository handles multiple desktops.
+ assertThat(
+ desktopUserRepositories.getProfile(USER_ID_1)
+ .getActiveTasks(DEFAULT_DISPLAY)
+ )
+ .containsExactly(1, 3, 4, 5)
+ .inOrder()
+ assertThat(
+ desktopUserRepositories.getProfile(USER_ID_1)
+ .getExpandedTasksOrdered(DEFAULT_DISPLAY)
+ )
+ .containsExactly(5, 1)
.inOrder()
- assertThat(desktopRepository.getExpandedTasksOrdered(DEFAULT_DISPLAY))
- .containsExactly(1, 2)
+ assertThat(
+ desktopUserRepositories.getProfile(USER_ID_1)
+ .getMinimizedTasks(DEFAULT_DISPLAY)
+ )
+ .containsExactly(3, 4)
.inOrder()
- assertThat(desktopRepository.getMinimizedTasks(DEFAULT_DISPLAY)).containsExactly(3)
}
@After
fun tearDown() {
datastoreScope.cancel()
}
+
+ private companion object {
+ const val USER_ID_1 = 5
+ const val USER_ID_2 = 6
+ const val DESKTOP_ID_1 = 2
+ const val DESKTOP_ID_2 = 3
+ const val DESKTOP_ID_3 = 4
+
+ val freeformTasksInZOrder1 = listOf(1, 3)
+ val desktop1: Desktop = Desktop.newBuilder()
+ .setDesktopId(DESKTOP_ID_1)
+ .addAllZOrderedTasks(freeformTasksInZOrder1)
+ .putTasksByTaskId(
+ 1,
+ DesktopTask.newBuilder()
+ .setTaskId(1)
+ .setDesktopTaskState(DesktopTaskState.VISIBLE)
+ .build()
+ )
+ .putTasksByTaskId(
+ 3,
+ DesktopTask.newBuilder()
+ .setTaskId(3)
+ .setDesktopTaskState(DesktopTaskState.MINIMIZED)
+ .build()
+ )
+ .build()
+
+ val freeformTasksInZOrder2 = listOf(4, 5)
+ val desktop2: Desktop = Desktop.newBuilder()
+ .setDesktopId(DESKTOP_ID_2)
+ .addAllZOrderedTasks(freeformTasksInZOrder2)
+ .putTasksByTaskId(
+ 4,
+ DesktopTask.newBuilder()
+ .setTaskId(4)
+ .setDesktopTaskState(DesktopTaskState.MINIMIZED)
+ .build()
+ )
+ .putTasksByTaskId(
+ 5,
+ DesktopTask.newBuilder()
+ .setTaskId(5)
+ .setDesktopTaskState(DesktopTaskState.VISIBLE)
+ .build()
+ )
+ .build()
+
+ val freeformTasksInZOrder3 = listOf(7, 8)
+ val desktop3: Desktop = Desktop.newBuilder()
+ .setDesktopId(DESKTOP_ID_3)
+ .addAllZOrderedTasks(freeformTasksInZOrder3)
+ .putTasksByTaskId(
+ 7,
+ DesktopTask.newBuilder()
+ .setTaskId(7)
+ .setDesktopTaskState(DesktopTaskState.VISIBLE)
+ .build()
+ )
+ .putTasksByTaskId(
+ 8,
+ DesktopTask.newBuilder()
+ .setTaskId(8)
+ .setDesktopTaskState(DesktopTaskState.MINIMIZED)
+ .build()
+ )
+ .build()
+ val desktopRepositoryState1: DesktopRepositoryState = DesktopRepositoryState.newBuilder()
+ .putDesktop(DESKTOP_ID_1, desktop1)
+ .putDesktop(DESKTOP_ID_2, desktop2)
+ .build()
+ val desktopRepositoryState2: DesktopRepositoryState = DesktopRepositoryState.newBuilder()
+ .putDesktop(DESKTOP_ID_3, desktop3)
+ .build()
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java
index b504a88e71fc..794ba48e2581 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java
@@ -27,6 +27,7 @@ import static com.android.window.flags.Flags.FLAG_ENABLE_WINDOWING_TRANSITION_HA
import static com.android.window.flags.Flags.FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -46,6 +47,7 @@ import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestRunningTaskInfoBuilder;
import com.android.wm.shell.common.LaunchAdjacentController;
import com.android.wm.shell.desktopmode.DesktopRepository;
+import com.android.wm.shell.desktopmode.DesktopUserRepositories;
import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.sysui.ShellInit;
@@ -81,6 +83,8 @@ public final class FreeformTaskListenerTests extends ShellTestCase {
@Mock
private SurfaceControl mMockSurfaceControl;
@Mock
+ private DesktopUserRepositories mDesktopUserRepositories;
+ @Mock
private DesktopRepository mDesktopRepository;
@Mock
private DesktopTasksController mDesktopTasksController;
@@ -101,13 +105,14 @@ public final class FreeformTaskListenerTests extends ShellTestCase {
.mockStatic(DesktopModeStatus.class)
.startMocking();
doReturn(true).when(() -> DesktopModeStatus.canEnterDesktopMode(any()));
-
+ when(mDesktopUserRepositories.getCurrent()).thenReturn(mDesktopRepository);
+ when(mDesktopUserRepositories.getProfile(anyInt())).thenReturn(mDesktopRepository);
mFreeformTaskListener =
new FreeformTaskListener(
mContext,
mShellInit,
mTaskOrganizer,
- Optional.of(mDesktopRepository),
+ Optional.of(mDesktopUserRepositories),
Optional.of(mDesktopTasksController),
mLaunchAdjacentController,
mWindowDecorViewModel,
@@ -123,7 +128,8 @@ public final class FreeformTaskListenerTests extends ShellTestCase {
mFreeformTaskListener.onTaskAppeared(task, mMockSurfaceControl);
- verify(mDesktopRepository).addTask(task.displayId, task.taskId, task.isVisible = true);
+ verify(mDesktopUserRepositories.getCurrent())
+ .addTask(task.displayId, task.taskId, task.isVisible = true);
}
@Test
@@ -135,7 +141,8 @@ public final class FreeformTaskListenerTests extends ShellTestCase {
mFreeformTaskListener.onTaskAppeared(task, mMockSurfaceControl);
- verify(mDesktopRepository).addTask(task.displayId, task.taskId, task.isVisible);
+ verify(mDesktopUserRepositories.getCurrent())
+ .addTask(task.displayId, task.taskId, task.isVisible);
}
@Test
@@ -147,7 +154,8 @@ public final class FreeformTaskListenerTests extends ShellTestCase {
mFreeformTaskListener.onTaskAppeared(task, mMockSurfaceControl);
- verify(mDesktopRepository, never()).addTask(task.displayId, task.taskId, task.isVisible);
+ verify(mDesktopUserRepositories.getCurrent(), never())
+ .addTask(task.displayId, task.taskId, task.isVisible);
}
@Test
@@ -158,7 +166,8 @@ public final class FreeformTaskListenerTests extends ShellTestCase {
mFreeformTaskListener.onFocusTaskChanged(task);
- verify(mDesktopRepository).addTask(task.displayId, task.taskId, task.isVisible);
+ verify(mDesktopUserRepositories.getCurrent())
+ .addTask(task.displayId, task.taskId, task.isVisible);
}
@Test
@@ -171,7 +180,7 @@ public final class FreeformTaskListenerTests extends ShellTestCase {
mFreeformTaskListener.onFocusTaskChanged(fullscreenTask);
- verify(mDesktopRepository, never())
+ verify(mDesktopUserRepositories.getCurrent(), never())
.addTask(fullscreenTask.displayId, fullscreenTask.taskId, fullscreenTask.isVisible);
}
@@ -214,7 +223,7 @@ public final class FreeformTaskListenerTests extends ShellTestCase {
task.displayId = INVALID_DISPLAY;
mFreeformTaskListener.onTaskVanished(task);
- verify(mDesktopRepository).minimizeTask(task.displayId, task.taskId);
+ verify(mDesktopUserRepositories.getCurrent()).minimizeTask(task.displayId, task.taskId);
}
@Test
@@ -227,14 +236,17 @@ public final class FreeformTaskListenerTests extends ShellTestCase {
mFreeformTaskListener.onTaskAppeared(task, mMockSurfaceControl);
- when(mDesktopRepository.isClosingTask(task.taskId)).thenReturn(true);
+ when(mDesktopUserRepositories.getCurrent()
+ .isClosingTask(task.taskId)).thenReturn(true);
task.isVisible = false;
task.displayId = INVALID_DISPLAY;
mFreeformTaskListener.onTaskVanished(task);
- verify(mDesktopRepository, never()).minimizeTask(task.displayId, task.taskId);
- verify(mDesktopRepository).removeClosingTask(task.taskId);
- verify(mDesktopRepository).removeFreeformTask(task.displayId, task.taskId);
+ verify(mDesktopUserRepositories.getCurrent(), never())
+ .minimizeTask(task.displayId, task.taskId);
+ verify(mDesktopUserRepositories.getCurrent()).removeClosingTask(task.taskId);
+ verify(mDesktopUserRepositories.getCurrent())
+ .removeFreeformTask(task.displayId, task.taskId);
}
@Test
@@ -246,9 +258,12 @@ public final class FreeformTaskListenerTests extends ShellTestCase {
mFreeformTaskListener.onTaskVanished(task);
- verify(mDesktopRepository, never()).minimizeTask(task.displayId, task.taskId);
- verify(mDesktopRepository, never()).removeClosingTask(task.taskId);
- verify(mDesktopRepository, never()).removeFreeformTask(task.displayId, task.taskId);
+ verify(mDesktopUserRepositories.getCurrent(), never())
+ .minimizeTask(task.displayId, task.taskId);
+ verify(mDesktopUserRepositories.getCurrent(), never())
+ .removeClosingTask(task.taskId);
+ verify(mDesktopUserRepositories.getCurrent(), never())
+ .removeFreeformTask(task.displayId, task.taskId);
}
@Test
@@ -274,7 +289,8 @@ public final class FreeformTaskListenerTests extends ShellTestCase {
mFreeformTaskListener.onTaskInfoChanged(task);
verify(mTaskChangeListener, never()).onTaskChanging(any());
- verify(mDesktopRepository).updateTask(task.displayId, task.taskId, task.isVisible);
+ verify(mDesktopUserRepositories.getCurrent())
+ .updateTask(task.displayId, task.taskId, task.isVisible);
}
@Test
@@ -289,7 +305,7 @@ public final class FreeformTaskListenerTests extends ShellTestCase {
mFreeformTaskListener.onTaskInfoChanged(task);
verify(mTaskChangeListener).onNonTransitionTaskChanging(any());
- verify(mDesktopRepository, never())
+ verify(mDesktopUserRepositories.getCurrent(), never())
.updateTask(task.displayId, task.taskId, task.isVisible);
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
index 289fd2d838fd..2eb2c3b8e2f7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
@@ -65,7 +65,7 @@ import com.android.wm.shell.common.pip.PipKeepClearAlgorithmInterface;
import com.android.wm.shell.common.pip.PipSnapAlgorithm;
import com.android.wm.shell.common.pip.PipUiEventLogger;
import com.android.wm.shell.common.pip.SizeSpecSource;
-import com.android.wm.shell.desktopmode.DesktopRepository;
+import com.android.wm.shell.desktopmode.DesktopUserRepositories;
import com.android.wm.shell.pip.phone.PhonePipMenuController;
import com.android.wm.shell.splitscreen.SplitScreenController;
@@ -103,7 +103,7 @@ public class PipTaskOrganizerTest extends ShellTestCase {
@Mock private PipSurfaceTransactionHelper mMockPipSurfaceTransactionHelper;
@Mock private PipUiEventLogger mMockPipUiEventLogger;
@Mock private Optional<SplitScreenController> mMockOptionalSplitScreen;
- @Mock private Optional<DesktopRepository> mMockOptionalDesktopRepository;
+ @Mock private Optional<DesktopUserRepositories> mMockOptionalDesktopUserRepositories;
@Mock private RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
@Mock private ShellTaskOrganizer mMockShellTaskOrganizer;
@Mock private PipParamsChangedForwarder mMockPipParamsChangedForwarder;
@@ -136,7 +136,7 @@ public class PipTaskOrganizerTest extends ShellTestCase {
mMockPipSurfaceTransactionHelper, mMockPipTransitionController,
mMockPipParamsChangedForwarder, mMockOptionalSplitScreen,
Optional.empty() /* pipPerfHintControllerOptional */,
- mMockOptionalDesktopRepository, mRootTaskDisplayAreaOrganizer,
+ mMockOptionalDesktopUserRepositories, mRootTaskDisplayAreaOrganizer,
mMockDisplayController, mMockPipUiEventLogger, mMockShellTaskOrganizer,
mMainExecutor);
mMainExecutor.flushAll();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java
index cab625216236..3fe8c109807a 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java
@@ -42,8 +42,10 @@ import android.window.WindowContainerTransaction;
import androidx.test.filters.SmallTest;
+import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.pip.PipBoundsState;
+import com.android.wm.shell.desktopmode.DesktopUserRepositories;
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.pip2.PipSurfaceTransactionHelper;
import com.android.wm.shell.pip2.animation.PipAlphaAnimator;
@@ -56,6 +58,8 @@ import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.Optional;
+
/**
* Unit test against {@link PipScheduler}
*/
@@ -79,6 +83,8 @@ public class PipSchedulerTest {
@Mock private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory mMockFactory;
@Mock private SurfaceControl.Transaction mMockTransaction;
@Mock private PipAlphaAnimator mMockAlphaAnimator;
+ @Mock private Optional<DesktopUserRepositories> mMockOptionalDesktopUserRepositories;
+ @Mock private RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
@Captor private ArgumentCaptor<Runnable> mRunnableArgumentCaptor;
@Captor private ArgumentCaptor<WindowContainerTransaction> mWctArgumentCaptor;
@@ -96,7 +102,8 @@ public class PipSchedulerTest {
.thenReturn(mMockTransaction);
mPipScheduler = new PipScheduler(mMockContext, mMockPipBoundsState, mMockMainExecutor,
- mMockPipTransitionState);
+ mMockPipTransitionState, mMockOptionalDesktopUserRepositories,
+ mRootTaskDisplayAreaOrganizer);
mPipScheduler.setPipTransitionController(mMockPipTransitionController);
mPipScheduler.setSurfaceControlTransactionFactory(mMockFactory);
mPipScheduler.setPipAlphaAnimatorSupplier((context, leash, tx, direction) ->
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
index 68c8aab8849d..95f371f7000a 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
@@ -26,6 +26,8 @@ import static com.android.launcher3.Flags.FLAG_ENABLE_REFACTOR_TASK_THUMBNAIL;
import static com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PERSISTENCE;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_50_50;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -57,6 +59,7 @@ import android.content.pm.PackageManager;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
+import android.os.UserManager;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
@@ -74,6 +77,7 @@ import com.android.wm.shell.TestShellExecutor;
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.desktopmode.DesktopRepository;
+import com.android.wm.shell.desktopmode.DesktopUserRepositories;
import com.android.wm.shell.desktopmode.DesktopWallpaperActivity;
import com.android.wm.shell.shared.GroupedTaskInfo;
import com.android.wm.shell.shared.ShellSharedConstants;
@@ -113,8 +117,6 @@ public class RecentTasksControllerTest extends ShellTestCase {
@Mock
private ShellCommandHandler mShellCommandHandler;
@Mock
- private DesktopRepository mDesktopRepository;
- @Mock
private ActivityTaskManager mActivityTaskManager;
@Mock
private DisplayInsetsController mDisplayInsetsController;
@@ -122,6 +124,10 @@ public class RecentTasksControllerTest extends ShellTestCase {
private IRecentTasksListener mRecentTasksListener;
@Mock
private TaskStackTransitionObserver mTaskStackTransitionObserver;
+ @Mock
+ private DesktopUserRepositories mDesktopUserRepositories;
+ @Mock
+ private DesktopRepository mDesktopRepository;
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@@ -142,6 +148,8 @@ public class RecentTasksControllerTest extends ShellTestCase {
.when(() -> DesktopModeStatus.canEnterDesktopMode(any()));
mMainExecutor = new TestShellExecutor();
+ when(mDesktopUserRepositories.getCurrent()).thenReturn(mDesktopRepository);
+ when(mDesktopUserRepositories.getProfile(anyInt())).thenReturn(mDesktopRepository);
when(mContext.getPackageManager()).thenReturn(mock(PackageManager.class));
when(mContext.getSystemService(KeyguardManager.class))
.thenReturn(mock(KeyguardManager.class));
@@ -150,7 +158,7 @@ public class RecentTasksControllerTest extends ShellTestCase {
mDisplayInsetsController, mMainExecutor));
mRecentTasksControllerReal = new RecentTasksController(mContext, mShellInit,
mShellController, mShellCommandHandler, mTaskStackListener, mActivityTaskManager,
- Optional.of(mDesktopRepository), mTaskStackTransitionObserver,
+ Optional.of(mDesktopUserRepositories), mTaskStackTransitionObserver,
mMainExecutor);
mRecentTasksController = spy(mRecentTasksControllerReal);
mShellTaskOrganizer = new ShellTaskOrganizer(mShellInit, mShellCommandHandler,
@@ -182,6 +190,12 @@ public class RecentTasksControllerTest extends ShellTestCase {
}
@Test
+ public void instantiateController_initializesRepository() {
+ verify(mDesktopUserRepositories, times(1)).getCurrent();
+ verify(mDesktopRepository, times(1)).addActiveTaskListener(any());
+ }
+
+ @Test
public void testInvalidateExternalInterface_unregistersListener() {
// Note: We have to use the real instance of the controller here since that is the instance
// that is passed to ShellController internally, and the instance that the listener will be
@@ -323,8 +337,8 @@ public class RecentTasksControllerTest extends ShellTestCase {
RecentTaskInfo t4 = makeTaskInfo(4);
setRawList(t1, t2, t3, t4);
- when(mDesktopRepository.isActiveTask(1)).thenReturn(true);
- when(mDesktopRepository.isActiveTask(3)).thenReturn(true);
+ when(mDesktopUserRepositories.getCurrent().isActiveTask(1)).thenReturn(true);
+ when(mDesktopUserRepositories.getCurrent().isActiveTask(3)).thenReturn(true);
ArrayList<GroupedTaskInfo> recentTasks =
mRecentTasksController.getRecentTasks(MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
@@ -362,8 +376,8 @@ public class RecentTasksControllerTest extends ShellTestCase {
new SplitBounds(new Rect(), new Rect(), 1, 2, SNAP_TO_2_50_50);
mRecentTasksController.addSplitPair(t1.taskId, t2.taskId, pair1Bounds);
- when(mDesktopRepository.isActiveTask(3)).thenReturn(true);
- when(mDesktopRepository.isActiveTask(5)).thenReturn(true);
+ when(mDesktopUserRepositories.getCurrent().isActiveTask(3)).thenReturn(true);
+ when(mDesktopUserRepositories.getCurrent().isActiveTask(5)).thenReturn(true);
ArrayList<GroupedTaskInfo> recentTasks =
mRecentTasksController.getRecentTasks(MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
@@ -402,8 +416,8 @@ public class RecentTasksControllerTest extends ShellTestCase {
RecentTaskInfo t4 = makeTaskInfo(4);
setRawList(t1, t2, t3, t4);
- when(mDesktopRepository.isActiveTask(1)).thenReturn(true);
- when(mDesktopRepository.isActiveTask(3)).thenReturn(true);
+ when(mDesktopUserRepositories.getCurrent().isActiveTask(1)).thenReturn(true);
+ when(mDesktopUserRepositories.getCurrent().isActiveTask(3)).thenReturn(true);
ArrayList<GroupedTaskInfo> recentTasks =
mRecentTasksController.getRecentTasks(MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
@@ -431,7 +445,9 @@ public class RecentTasksControllerTest extends ShellTestCase {
setRawList(t1, t2, t3, t4, t5);
when(mDesktopRepository.isActiveTask(1)).thenReturn(true);
+ when(mDesktopRepository.isActiveTask(2)).thenReturn(false);
when(mDesktopRepository.isActiveTask(3)).thenReturn(true);
+ when(mDesktopRepository.isActiveTask(4)).thenReturn(false);
when(mDesktopRepository.isActiveTask(5)).thenReturn(true);
when(mDesktopRepository.isMinimizedTask(3)).thenReturn(true);
@@ -470,8 +486,8 @@ public class RecentTasksControllerTest extends ShellTestCase {
t2.lastNonFullscreenBounds = new Rect(150, 250, 350, 450);
setRawList(t1, t2);
- when(mDesktopRepository.isActiveTask(1)).thenReturn(true);
- when(mDesktopRepository.isActiveTask(2)).thenReturn(true);
+ when(mDesktopUserRepositories.getCurrent().isActiveTask(1)).thenReturn(true);
+ when(mDesktopUserRepositories.getCurrent().isActiveTask(2)).thenReturn(true);
ArrayList<GroupedTaskInfo> recentTasks =
mRecentTasksController.getRecentTasks(MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java
index f0f5fe159069..894d238b7e15 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java
@@ -65,6 +65,7 @@ import com.android.wm.shell.TestShellExecutor;
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.desktopmode.DesktopRepository;
+import com.android.wm.shell.desktopmode.DesktopUserRepositories;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
@@ -100,7 +101,7 @@ public class RecentsTransitionHandlerTest extends ShellTestCase {
@Mock
private ShellCommandHandler mShellCommandHandler;
@Mock
- private DesktopRepository mDesktopRepository;
+ private DesktopUserRepositories mDesktopUserRepositories;
@Mock
private ActivityTaskManager mActivityTaskManager;
@Mock
@@ -112,6 +113,8 @@ public class RecentsTransitionHandlerTest extends ShellTestCase {
@Mock
private Transitions mTransitions;
+ @Mock private DesktopRepository mDesktopRepository;
+
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@@ -131,6 +134,7 @@ public class RecentsTransitionHandlerTest extends ShellTestCase {
ExtendedMockito.doReturn(true)
.when(() -> DesktopModeStatus.canEnterDesktopMode(any()));
+ when(mDesktopUserRepositories.getCurrent()).thenReturn(mDesktopRepository);
mMainExecutor = new TestShellExecutor();
when(mContext.getPackageManager()).thenReturn(mock(PackageManager.class));
when(mContext.getSystemService(KeyguardManager.class))
@@ -140,7 +144,7 @@ public class RecentsTransitionHandlerTest extends ShellTestCase {
mDisplayInsetsController, mMainExecutor));
mRecentTasksControllerReal = new RecentTasksController(mContext, mShellInit,
mShellController, mShellCommandHandler, mTaskStackListener, mActivityTaskManager,
- Optional.of(mDesktopRepository), mTaskStackTransitionObserver,
+ Optional.of(mDesktopUserRepositories), mTaskStackTransitionObserver,
mMainExecutor);
mRecentTasksController = spy(mRecentTasksControllerReal);
mShellTaskOrganizer = new ShellTaskOrganizer(mShellInit, mShellCommandHandler,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/util/TransitionObserverTestUtils.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/util/TransitionObserverTestUtils.kt
index 0e15668a05a7..a328b5b2bb6b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/util/TransitionObserverTestUtils.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/util/TransitionObserverTestUtils.kt
@@ -77,6 +77,30 @@ class TransitionObserverTestContext : TransitionObserverTestStep {
validateObj.validate()
}
+ fun validateOnMerged(
+ validate:
+ TransitionObserverOnTransitionMergedValidation.() -> Unit
+ ) {
+ val validateObj = TransitionObserverOnTransitionMergedValidation()
+ transitionObserver.onTransitionMerged(
+ validateObj.playing,
+ validateObj.merged
+ )
+ validateObj.validate()
+ }
+
+ fun validateOnFinished(
+ validate:
+ TransitionObserverOnTransitionFinishedValidation.() -> Unit
+ ) {
+ val validateObj = TransitionObserverOnTransitionFinishedValidation()
+ transitionObserver.onTransitionFinished(
+ transitionReadyInput.transition,
+ validateObj.aborted
+ )
+ validateObj.validate()
+ }
+
fun invokeObservable() {
transitionObserver.onTransitionReady(
transitionReadyInput.transition,
@@ -162,6 +186,28 @@ class TransitionObserverInputBuilder : TransitionObserverTestStep {
class TransitionObserverResultValidation : TransitionObserverTestStep
/**
+ * Phase responsible for the execution of validation methods after the
+ * [TransitionObservable#onTransitionMerged] has been executed.
+ */
+class TransitionObserverOnTransitionMergedValidation : TransitionObserverTestStep {
+ val merged = mock<IBinder>()
+ val playing = mock<IBinder>()
+
+ init {
+ spyOn(merged)
+ spyOn(playing)
+ }
+}
+
+/**
+ * Phase responsible for the execution of validation methods after the
+ * [TransitionObservable#onTransitionFinished] has been executed.
+ */
+class TransitionObserverOnTransitionFinishedValidation : TransitionObserverTestStep {
+ var aborted: Boolean = false
+}
+
+/**
* Allows to run a test about a specific [TransitionObserver] passing the specific
* implementation and input value as parameters for the [TransitionObserver#onTransitionReady]
* method.
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/CaptionWindowDecorationTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/CaptionWindowDecorationTests.kt
index 59141ca39487..b856a28e54db 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/CaptionWindowDecorationTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/CaptionWindowDecorationTests.kt
@@ -48,6 +48,7 @@ class CaptionWindowDecorationTests : ShellTestCase() {
CaptionWindowDecoration.updateRelayoutParams(
relayoutParams,
+ mContext,
taskInfo,
true,
false,
@@ -71,6 +72,7 @@ class CaptionWindowDecorationTests : ShellTestCase() {
CaptionWindowDecoration.updateRelayoutParams(
relayoutParams,
+ mContext,
taskInfo,
true,
false,
@@ -90,6 +92,7 @@ class CaptionWindowDecorationTests : ShellTestCase() {
val relayoutParams = WindowDecoration.RelayoutParams()
CaptionWindowDecoration.updateRelayoutParams(
relayoutParams,
+ mContext,
taskInfo,
true,
false,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopHeaderManageWindowsMenuTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopHeaderManageWindowsMenuTest.kt
index 1215c52209a5..44035588887f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopHeaderManageWindowsMenuTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopHeaderManageWindowsMenuTest.kt
@@ -29,12 +29,13 @@ import com.android.wm.shell.MockToken
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.TestRunningTaskInfoBuilder
import com.android.wm.shell.TestShellExecutor
-import com.android.wm.shell.desktopmode.DesktopRepository
+import com.android.wm.shell.desktopmode.DesktopUserRepositories
import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -55,17 +56,18 @@ class DesktopHeaderManageWindowsMenuTest : ShellTestCase() {
@Rule
val setFlagsRule: SetFlagsRule = SetFlagsRule()
- private lateinit var desktopRepository: DesktopRepository
+ private lateinit var userRepositories: DesktopUserRepositories
private lateinit var menu: DesktopHeaderManageWindowsMenu
@Before
fun setUp() {
- desktopRepository = DesktopRepository(
+ userRepositories = DesktopUserRepositories(
context = context,
shellInit = ShellInit(TestShellExecutor()),
persistentRepository = mock(),
repositoryInitializer = mock(),
- mainCoroutineScope = mock()
+ mainCoroutineScope = mock(),
+ userManager = mock(),
)
}
@@ -75,15 +77,15 @@ class DesktopHeaderManageWindowsMenuTest : ShellTestCase() {
}
@Test
+ @Ignore("Test is failing internally")
@EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
fun testShow_forImmersiveTask_usesSystemViewContainer() {
val task = createFreeformTask()
- desktopRepository.setTaskInFullImmersiveState(
+ userRepositories.getProfile(DEFAULT_USER_ID).setTaskInFullImmersiveState(
displayId = task.displayId,
taskId = task.taskId,
immersive = true
)
-
menu = createMenu(task)
assertThat(menu.menuViewContainer).isInstanceOf(AdditionalSystemViewContainer::class.java)
@@ -96,7 +98,7 @@ class DesktopHeaderManageWindowsMenuTest : ShellTestCase() {
displayController = mock(),
rootTdaOrganizer = mock(),
context = context,
- desktopRepository = desktopRepository,
+ desktopUserRepositories = userRepositories,
surfaceControlBuilderSupplier = { SurfaceControl.Builder() },
surfaceControlTransactionSupplier = { SurfaceControl.Transaction() },
snapshotList = emptyList(),
@@ -109,4 +111,8 @@ class DesktopHeaderManageWindowsMenuTest : ShellTestCase() {
.setActivityType(ACTIVITY_TYPE_STANDARD)
.setWindowingMode(WINDOWING_MODE_FREEFORM)
.build()
+
+ private companion object {
+ const val DEFAULT_USER_ID = 10
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
index 153be07bd204..a4e3af47edaa 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
@@ -59,6 +59,7 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
import com.android.window.flags.Flags
import com.android.wm.shell.R
+import com.android.wm.shell.desktopmode.common.ToggleTaskSizeInteraction
import com.android.wm.shell.desktopmode.DesktopImmersiveController
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.InputMethod
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
@@ -398,11 +399,12 @@ class DesktopModeWindowDecorViewModelTests : DesktopModeWindowDecorViewModelTest
maxOrRestoreListenerCaptor.value.invoke()
verify(mockDesktopTasksController).toggleDesktopTaskSize(
- eq(decor.mTaskInfo),
- eq(ResizeTrigger.MAXIMIZE_MENU),
- eq(InputMethod.UNKNOWN_INPUT_METHOD),
- any(),
- any()
+ decor.mTaskInfo,
+ ToggleTaskSizeInteraction(
+ ToggleTaskSizeInteraction.Direction.MAXIMIZE,
+ ToggleTaskSizeInteraction.Source.MAXIMIZE_MENU_TO_MAXIMIZE,
+ InputMethod.UNKNOWN_INPUT_METHOD
+ )
)
}
@@ -1061,11 +1063,12 @@ class DesktopModeWindowDecorViewModelTests : DesktopModeWindowDecorViewModelTest
verify(mockDesktopTasksController)
.toggleDesktopTaskSize(
- eq(decor.mTaskInfo),
- eq(ResizeTrigger.MAXIMIZE_BUTTON),
- eq(InputMethod.UNKNOWN_INPUT_METHOD),
- any(),
- any(),
+ decor.mTaskInfo,
+ ToggleTaskSizeInteraction(
+ ToggleTaskSizeInteraction.Direction.MAXIMIZE,
+ ToggleTaskSizeInteraction.Source.HEADER_BUTTON_TO_MAXIMIZE,
+ InputMethod.UNKNOWN_INPUT_METHOD
+ )
)
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
index 080f496593cf..afd46078074c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
@@ -60,6 +60,7 @@ import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger
import com.android.wm.shell.desktopmode.DesktopRepository
import com.android.wm.shell.desktopmode.DesktopTasksController
import com.android.wm.shell.desktopmode.DesktopTasksLimiter
+import com.android.wm.shell.desktopmode.DesktopUserRepositories
import com.android.wm.shell.desktopmode.WindowDecorCaptionHandleRepository
import com.android.wm.shell.desktopmode.education.AppHandleEducationController
import com.android.wm.shell.desktopmode.education.AppToWebEducationController
@@ -108,7 +109,7 @@ open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() {
protected val mockTaskOrganizer = mock<ShellTaskOrganizer>()
protected val mockDisplayController = mock<DisplayController>()
protected val mockSplitScreenController = mock<SplitScreenController>()
- protected val mockDesktopRepository = mock<DesktopRepository>()
+ protected val mockDesktopUserRepositories = mock<DesktopUserRepositories>()
protected val mockDisplayLayout = mock<DisplayLayout>()
protected val displayInsetsController = mock<DisplayInsetsController>()
protected val mockSyncQueue = mock<SyncTransactionQueue>()
@@ -142,6 +143,7 @@ open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() {
protected val mockAppToWebEducationController = mock<AppToWebEducationController>()
protected val mockFocusTransitionObserver = mock<FocusTransitionObserver>()
protected val mockCaptionHandleRepository = mock<WindowDecorCaptionHandleRepository>()
+ protected val mockDesktopRepository: DesktopRepository = mock<DesktopRepository>()
protected val motionEvent = mock<MotionEvent>()
val displayController = mock<DisplayController>()
val displayLayout = mock<DisplayLayout>()
@@ -168,6 +170,9 @@ open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() {
windowDecorByTaskIdSpy.clear()
spyContext.addMockSystemService(InputManager::class.java, mockInputManager)
desktopModeEventLogger = mock<DesktopModeEventLogger>()
+ whenever(mockDesktopUserRepositories.current).thenReturn(mockDesktopRepository)
+ whenever(mockDesktopUserRepositories.getProfile(anyInt()))
+ .thenReturn(mockDesktopRepository)
desktopModeWindowDecorViewModel = DesktopModeWindowDecorViewModel(
spyContext,
testShellExecutor,
@@ -178,7 +183,7 @@ open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() {
mockShellCommandHandler,
mockWindowManager,
mockTaskOrganizer,
- mockDesktopRepository,
+ mockDesktopUserRepositories,
mockDisplayController,
mockShellController,
displayInsetsController,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
index e390fbbd751f..a389bea03141 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
@@ -61,7 +61,6 @@ import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
-import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.PointF;
import android.graphics.Rect;
@@ -110,6 +109,7 @@ import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.desktopmode.CaptionState;
import com.android.wm.shell.desktopmode.DesktopModeEventLogger;
import com.android.wm.shell.desktopmode.DesktopRepository;
+import com.android.wm.shell.desktopmode.DesktopUserRepositories;
import com.android.wm.shell.desktopmode.WindowDecorCaptionHandleRepository;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.splitscreen.SplitScreenController;
@@ -166,7 +166,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
@Mock
private ShellTaskOrganizer mMockShellTaskOrganizer;
@Mock
- private DesktopRepository mMockDesktopRepository;
+ private DesktopUserRepositories mMockDesktopUserRepositories;
@Mock
private Choreographer mMockChoreographer;
@Mock
@@ -215,6 +215,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
private WindowDecorCaptionHandleRepository mMockCaptionHandleRepository;
@Mock
private DesktopModeEventLogger mDesktopModeEventLogger;
+ @Mock
+ private DesktopRepository mDesktopRepository;
@Captor
private ArgumentCaptor<Function1<Boolean, Unit>> mOnMaxMenuHoverChangeListener;
@Captor
@@ -271,6 +273,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
when(mMockMultiInstanceHelper.supportsMultiInstanceSplit(any())).thenReturn(false);
when(mMockAppHeaderViewHolderFactory.create(any(), any(), any(), any(), any(), any(), any(),
any())).thenReturn(mMockAppHeaderViewHolder);
+ when(mMockDesktopUserRepositories.getCurrent()).thenReturn(mDesktopRepository);
+ when(mMockDesktopUserRepositories.getProfile(anyInt())).thenReturn(mDesktopRepository);
}
@After
@@ -295,8 +299,48 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
}
@Test
- public void updateRelayoutParams_noSysPropFlagsSet_windowShadowsAreEnabled() {
+ public void updateRelayoutParams_noSysPropFlagsSet_windowShadowsAreSetForFreeform() {
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+ taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+ RelayoutParams relayoutParams = new RelayoutParams();
+
+ DesktopModeWindowDecoration.updateRelayoutParams(
+ relayoutParams, mContext, taskInfo, /* applyStartTransactionOnDraw= */ true,
+ /* shouldSetTaskPositionAndCrop */ false,
+ /* isStatusBarVisible */ true,
+ /* isKeyguardVisibleAndOccluded */ false,
+ /* inFullImmersiveMode */ false,
+ new InsetsState(),
+ /* hasGlobalFocus= */ true,
+ mExclusionRegion);
+
+ assertThat(relayoutParams.mShadowRadius)
+ .isNotEqualTo(WindowDecoration.INVALID_SHADOW_RADIUS);
+ }
+
+ @Test
+ public void updateRelayoutParams_noSysPropFlagsSet_windowShadowsAreNotSetForFullscreen() {
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+ taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ RelayoutParams relayoutParams = new RelayoutParams();
+
+ DesktopModeWindowDecoration.updateRelayoutParams(
+ relayoutParams, mContext, taskInfo, /* applyStartTransactionOnDraw= */ true,
+ /* shouldSetTaskPositionAndCrop */ false,
+ /* isStatusBarVisible */ true,
+ /* isKeyguardVisibleAndOccluded */ false,
+ /* inFullImmersiveMode */ false,
+ new InsetsState(),
+ /* hasGlobalFocus= */ true,
+ mExclusionRegion);
+
+ assertThat(relayoutParams.mShadowRadius).isEqualTo(WindowDecoration.INVALID_SHADOW_RADIUS);
+ }
+
+ @Test
+ public void updateRelayoutParams_noSysPropFlagsSet_windowShadowsAreNotSetForSplit() {
final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+ taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
RelayoutParams relayoutParams = new RelayoutParams();
DesktopModeWindowDecoration.updateRelayoutParams(
@@ -309,7 +353,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
/* hasGlobalFocus= */ true,
mExclusionRegion);
- assertThat(relayoutParams.mShadowRadiusId).isNotEqualTo(Resources.ID_NULL);
+ assertThat(relayoutParams.mShadowRadius).isEqualTo(WindowDecoration.INVALID_SHADOW_RADIUS);
}
@Test
@@ -359,6 +403,29 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
}
@Test
+ public void updateRelayoutParams_noSysPropFlagsSet_roundedCornersNotSetForSplit() {
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+ taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+ fillRoundedCornersResources(/* fillValue= */ 30);
+ RelayoutParams relayoutParams = new RelayoutParams();
+
+ DesktopModeWindowDecoration.updateRelayoutParams(
+ relayoutParams,
+ mTestableContext,
+ taskInfo,
+ /* applyStartTransactionOnDraw= */ true,
+ /* shouldSetTaskPositionAndCrop */ false,
+ /* isStatusBarVisible */ true,
+ /* isKeyguardVisibleAndOccluded */ false,
+ /* inFullImmersiveMode */ false,
+ new InsetsState(),
+ /* hasGlobalFocus= */ true,
+ mExclusionRegion);
+
+ assertThat(relayoutParams.mCornerRadius).isEqualTo(INVALID_CORNER_RADIUS);
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_ENABLE_APP_HEADER_WITH_TASK_DENSITY)
public void updateRelayoutParams_appHeader_usesTaskDensity() {
final int systemDensity = mTestableContext.getOrCreateTestableResources().getResources()
@@ -1407,8 +1474,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
final DesktopModeWindowDecoration decoration = createWindowDecoration(taskInfo,
true /* relayout */);
- when(mMockDesktopRepository.isTaskInFullImmersiveState(taskInfo.taskId))
- .thenReturn(true);
+ when(mMockDesktopUserRepositories.getCurrent()
+ .isTaskInFullImmersiveState(taskInfo.taskId)).thenReturn(true);
createHandleMenu(decoration);
@@ -1643,8 +1710,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
boolean relayout) {
final DesktopModeWindowDecoration windowDecor = new DesktopModeWindowDecoration(mContext,
mContext, mMockDisplayController, mMockSplitScreenController,
- mMockDesktopRepository, mMockShellTaskOrganizer, taskInfo, mMockSurfaceControl,
- mMockHandler, mBgExecutor, mMockChoreographer, mMockSyncQueue,
+ mMockDesktopUserRepositories, mMockShellTaskOrganizer, taskInfo,
+ mMockSurfaceControl, mMockHandler, mBgExecutor, mMockChoreographer, mMockSyncQueue,
mMockAppHeaderViewHolderFactory, mMockRootTaskDisplayAreaOrganizer,
mMockGenericLinksParser, mMockAssistContentRequester, SurfaceControl.Builder::new,
mMockTransactionSupplier, WindowContainerTransaction::new, SurfaceControl::new,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
index 534803db5fe0..04b2be0b1a25 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
@@ -114,6 +114,7 @@ public class WindowDecorationTests extends ShellTestCase {
private static final Rect TASK_BOUNDS = new Rect(100, 300, 400, 400);
private static final Point TASK_POSITION_IN_PARENT = new Point(40, 60);
private static final int CORNER_RADIUS = 20;
+ private static final int SHADOW_RADIUS = 10;
private static final int STATUS_BAR_INSET_SOURCE_ID = 0;
@Rule
@@ -162,7 +163,7 @@ public class WindowDecorationTests extends ShellTestCase {
mRelayoutParams.mLayoutResId = 0;
mRelayoutParams.mCaptionHeightId = R.dimen.test_freeform_decor_caption_height;
mCaptionMenuWidthId = R.dimen.test_freeform_decor_caption_menu_width;
- mRelayoutParams.mShadowRadiusId = R.dimen.test_window_decor_shadow_radius;
+ mRelayoutParams.mShadowRadius = SHADOW_RADIUS;
mRelayoutParams.mCornerRadius = CORNER_RADIUS;
when(mMockDisplayController.getDisplay(Display.DEFAULT_DISPLAY))
@@ -280,7 +281,7 @@ public class WindowDecorationTests extends ShellTestCase {
verify(mMockSurfaceControlStartT).setCornerRadius(mMockTaskSurface, CORNER_RADIUS);
verify(mMockSurfaceControlFinishT).setCornerRadius(mMockTaskSurface, CORNER_RADIUS);
- verify(mMockSurfaceControlStartT).setShadowRadius(mMockTaskSurface, 10);
+ verify(mMockSurfaceControlStartT).setShadowRadius(mMockTaskSurface, SHADOW_RADIUS);
assertEquals(300, mRelayoutResult.mWidth);
assertEquals(100, mRelayoutResult.mHeight);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/viewhost/DefaultWindowDecorViewHostTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/viewhost/DefaultWindowDecorViewHostTest.kt
new file mode 100644
index 000000000000..2f223ded5ce1
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/viewhost/DefaultWindowDecorViewHostTest.kt
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.windowdecor.common.viewhost
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.SurfaceControl
+import android.view.SurfaceControlViewHost
+import android.view.View
+import android.view.WindowManager
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.ShellTestCase
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.advanceUntilIdle
+import kotlinx.coroutines.test.runTest
+import org.junit.Assert.assertThrows
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.verify
+
+/**
+ * Tests for [DefaultWindowDecorViewHost].
+ *
+ * Build/Install/Run: atest WMShellUnitTests:DefaultWindowDecorViewHostTest
+ */
+@SmallTest
+@TestableLooper.RunWithLooper
+@RunWith(AndroidTestingRunner::class)
+class DefaultWindowDecorViewHostTest : ShellTestCase() {
+
+ @Test
+ fun updateView_layoutInViewHost() = runTest {
+ val windowDecorViewHost = createDefaultViewHost()
+ val view = View(context)
+
+ windowDecorViewHost.updateView(
+ view = view,
+ attrs = WindowManager.LayoutParams(100, 100),
+ configuration = context.resources.configuration,
+ onDrawTransaction = null,
+ )
+
+ assertThat(windowDecorViewHost.viewHost).isNotNull()
+ assertThat(windowDecorViewHost.viewHost!!.view).isEqualTo(view)
+ }
+
+ @Test
+ fun updateView_alreadyLaidOut_relayouts() = runTest {
+ val windowDecorViewHost = createDefaultViewHost()
+ val view = View(context)
+ windowDecorViewHost.updateView(
+ view = view,
+ attrs = WindowManager.LayoutParams(100, 100),
+ configuration = context.resources.configuration,
+ onDrawTransaction = null,
+ )
+
+ val otherParams = WindowManager.LayoutParams(200, 200)
+ windowDecorViewHost.updateView(
+ view = view,
+ attrs = otherParams,
+ configuration = context.resources.configuration,
+ onDrawTransaction = null,
+ )
+
+ assertThat(windowDecorViewHost.viewHost!!.view).isEqualTo(view)
+ assertThat(windowDecorViewHost.viewHost!!.view!!.layoutParams.width)
+ .isEqualTo(otherParams.width)
+ }
+
+ @Test
+ fun updateView_replacingView_throws() = runTest {
+ val windowDecorViewHost = createDefaultViewHost()
+ val view = View(context)
+ windowDecorViewHost.updateView(
+ view = view,
+ attrs = WindowManager.LayoutParams(100, 100),
+ configuration = context.resources.configuration,
+ onDrawTransaction = null,
+ )
+
+ val otherView = View(context)
+ assertThrows(Exception::class.java) {
+ windowDecorViewHost.updateView(
+ view = otherView,
+ attrs = WindowManager.LayoutParams(100, 100),
+ configuration = context.resources.configuration,
+ onDrawTransaction = null,
+ )
+ }
+ }
+
+ @OptIn(ExperimentalCoroutinesApi::class)
+ @Test
+ fun updateView_clearsPendingAsyncJob() = runTest {
+ val windowDecorViewHost = createDefaultViewHost()
+ val asyncView = View(context)
+ val syncView = View(context)
+ val asyncAttrs = WindowManager.LayoutParams(100, 100)
+ val syncAttrs = WindowManager.LayoutParams(200, 200)
+
+ windowDecorViewHost.updateViewAsync(
+ view = asyncView,
+ attrs = asyncAttrs,
+ configuration = context.resources.configuration,
+ )
+
+ // No view host yet, since the coroutine hasn't run.
+ assertThat(windowDecorViewHost.viewHost).isNull()
+
+ windowDecorViewHost.updateView(
+ view = syncView,
+ attrs = syncAttrs,
+ configuration = context.resources.configuration,
+ onDrawTransaction = null,
+ )
+
+ // Would run coroutine if it hadn't been cancelled.
+ advanceUntilIdle()
+
+ assertThat(windowDecorViewHost.viewHost).isNotNull()
+ assertThat(windowDecorViewHost.viewHost!!.view).isNotNull()
+ // View host view/attrs should match the ones from the sync call, plus, since the
+ // sync/async were made with different views, if the job hadn't been cancelled there
+ // would've been an exception thrown as replacing views isn't allowed.
+ assertThat(windowDecorViewHost.viewHost!!.view).isEqualTo(syncView)
+ assertThat(windowDecorViewHost.viewHost!!.view!!.layoutParams.width)
+ .isEqualTo(syncAttrs.width)
+ }
+
+ @OptIn(ExperimentalCoroutinesApi::class)
+ @Test
+ fun updateViewAsync() = runTest {
+ val windowDecorViewHost = createDefaultViewHost()
+ val view = View(context)
+ val attrs = WindowManager.LayoutParams(100, 100)
+
+ windowDecorViewHost.updateViewAsync(
+ view = view,
+ attrs = attrs,
+ configuration = context.resources.configuration,
+ )
+
+ assertThat(windowDecorViewHost.viewHost).isNull()
+
+ advanceUntilIdle()
+
+ assertThat(windowDecorViewHost.viewHost).isNotNull()
+ }
+
+ @OptIn(ExperimentalCoroutinesApi::class)
+ @Test
+ fun updateViewAsync_clearsPendingAsyncJob() = runTest {
+ val windowDecorViewHost = createDefaultViewHost()
+
+ val view = View(context)
+ windowDecorViewHost.updateViewAsync(
+ view = view,
+ attrs = WindowManager.LayoutParams(100, 100),
+ configuration = context.resources.configuration,
+ )
+ val otherView = View(context)
+ windowDecorViewHost.updateViewAsync(
+ view = otherView,
+ attrs = WindowManager.LayoutParams(100, 100),
+ configuration = context.resources.configuration,
+ )
+
+ advanceUntilIdle()
+
+ assertThat(windowDecorViewHost.viewHost).isNotNull()
+ assertThat(windowDecorViewHost.viewHost!!.view).isNotNull()
+ assertThat(windowDecorViewHost.viewHost!!.view).isEqualTo(otherView)
+ }
+
+ @Test
+ fun release() = runTest {
+ val windowDecorViewHost = createDefaultViewHost()
+
+ val view = View(context)
+ windowDecorViewHost.updateView(
+ view = view,
+ attrs = WindowManager.LayoutParams(100, 100),
+ configuration = context.resources.configuration,
+ onDrawTransaction = null,
+ )
+
+ val t = mock(SurfaceControl.Transaction::class.java)
+ windowDecorViewHost.release(t)
+
+ verify(windowDecorViewHost.viewHost!!).release()
+ verify(t).remove(windowDecorViewHost.surfaceControl)
+ }
+
+ private fun CoroutineScope.createDefaultViewHost() =
+ DefaultWindowDecorViewHost(
+ context = context,
+ mainScope = this,
+ display = context.display,
+ surfaceControlViewHostFactory = { c, d, wwm, s ->
+ spy(SurfaceControlViewHost(c, d, wwm, s))
+ },
+ )
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
index d29002199f9d..193c2c25d26d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
@@ -25,7 +25,7 @@ import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.desktopmode.DesktopModeEventLogger
-import com.android.wm.shell.desktopmode.DesktopRepository
+import com.android.wm.shell.desktopmode.DesktopUserRepositories
import com.android.wm.shell.desktopmode.DesktopTasksController
import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator
@@ -52,7 +52,7 @@ class DesktopTilingDecorViewModelTest : ShellTestCase() {
private val syncQueueMock: SyncTransactionQueue = mock()
private val transitionsMock: Transitions = mock()
private val shellTaskOrganizerMock: ShellTaskOrganizer = mock()
- private val desktopRepository: DesktopRepository = mock()
+ private val userRepositories: DesktopUserRepositories = mock()
private val desktopModeEventLogger: DesktopModeEventLogger = mock()
private val toggleResizeDesktopTaskTransitionHandlerMock:
ToggleResizeDesktopTaskTransitionHandler =
@@ -75,7 +75,7 @@ class DesktopTilingDecorViewModelTest : ShellTestCase() {
shellTaskOrganizerMock,
toggleResizeDesktopTaskTransitionHandlerMock,
returnToDragStartAnimatorMock,
- desktopRepository,
+ userRepositories,
desktopModeEventLogger,
)
whenever(contextMock.createContextAsUser(any(), any())).thenReturn(contextMock)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
index 3b39f1e4a25a..95e2151be96c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
@@ -39,6 +39,7 @@ import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeT
import com.android.wm.shell.desktopmode.DesktopRepository
import com.android.wm.shell.desktopmode.DesktopTasksController
import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
+import com.android.wm.shell.desktopmode.DesktopUserRepositories
import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator
import com.android.wm.shell.desktopmode.ToggleResizeDesktopTaskTransitionHandler
import com.android.wm.shell.transition.Transitions
@@ -93,10 +94,11 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
private val transition: IBinder = mock()
private val info: TransitionInfo = mock()
private val finishCallback: Transitions.TransitionFinishCallback = mock()
- private val desktopRepository: DesktopRepository = mock()
+ private val userRepositories: DesktopUserRepositories = mock()
private val desktopModeEventLogger: DesktopModeEventLogger = mock()
private val desktopTilingDividerWindowManager: DesktopTilingDividerWindowManager = mock()
private val motionEvent: MotionEvent = mock()
+ private val desktopRepository: DesktopRepository = mock()
private lateinit var tilingDecoration: DesktopTilingWindowDecoration
private val split_divider_width = 10
@@ -116,10 +118,11 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
shellTaskOrganizer,
toggleResizeDesktopTaskTransitionHandler,
returnToDragStartAnimator,
- desktopRepository,
+ userRepositories,
desktopModeEventLogger,
)
whenever(context.createContextAsUser(any(), any())).thenReturn(context)
+ whenever(userRepositories.current).thenReturn(desktopRepository)
}
@Test
@@ -275,8 +278,8 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
}
whenever(context.resources).thenReturn(resources)
whenever(resources.getDimensionPixelSize(any())).thenReturn(split_divider_width)
- whenever(desktopRepository.isVisibleTask(eq(task1.taskId))).thenReturn(true)
- whenever(desktopRepository.isVisibleTask(eq(task2.taskId))).thenReturn(true)
+ whenever(userRepositories.current.isVisibleTask(eq(task1.taskId))).thenReturn(true)
+ whenever(userRepositories.current.isVisibleTask(eq(task2.taskId))).thenReturn(true)
tilingDecoration.onAppTiled(
task1,
@@ -308,7 +311,7 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
whenever(context.resources).thenReturn(resources)
whenever(resources.getDimensionPixelSize(any())).thenReturn(split_divider_width)
whenever(desktopWindowDecoration.getLeash()).thenReturn(surfaceControlMock)
- whenever(desktopRepository.isVisibleTask(any())).thenReturn(true)
+ whenever(userRepositories.current.isVisibleTask(any())).thenReturn(true)
tilingDecoration.onAppTiled(
task1,
desktopWindowDecoration,
@@ -341,7 +344,7 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
whenever(context.resources).thenReturn(resources)
whenever(resources.getDimensionPixelSize(any())).thenReturn(split_divider_width)
whenever(desktopWindowDecoration.getLeash()).thenReturn(surfaceControlMock)
- whenever(desktopRepository.isVisibleTask(any())).thenReturn(true)
+ whenever(userRepositories.current.isVisibleTask(any())).thenReturn(true)
tilingDecoration.onAppTiled(
task1,
desktopWindowDecoration,
@@ -614,7 +617,7 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
private fun createVisibleTask() =
createFreeformTask().also {
- whenever(desktopRepository.isVisibleTask(eq(it.taskId))).thenReturn(true)
+ whenever(userRepositories.current.isVisibleTask(eq(it.taskId))).thenReturn(true)
}
companion object {
diff --git a/media/java/android/media/MediaCas.java b/media/java/android/media/MediaCas.java
index 1ecba31ce07f..3efb5f961dc8 100644
--- a/media/java/android/media/MediaCas.java
+++ b/media/java/android/media/MediaCas.java
@@ -1010,17 +1010,17 @@ public final class MediaCas implements AutoCloseable {
* scenario, when both resource holder and resource challenger have same processId and same
* priority.
*
- * @param resourceHolderRetain Set to {@code true} to allow the resource holder to retain
- * ownership, or false to allow the resource challenger to acquire the resource.
- * If not explicitly set, resourceHolderRetain is set to {@code false}.
+ *@param enabled Set to {@code true} to allow the resource holder to retain ownership,
+ * or false to allow the resource challenger to acquire the resource.
+ * If not explicitly set, enabled is set to {@code false}.
* @hide
*/
@FlaggedApi(FLAG_SET_RESOURCE_HOLDER_RETAIN)
@SystemApi
@RequiresPermission(android.Manifest.permission.TUNER_RESOURCE_ACCESS)
- public void setResourceHolderRetain(boolean resourceHolderRetain) {
+ public void setResourceOwnershipRetention(boolean enabled) {
if (mTunerResourceManager != null) {
- mTunerResourceManager.setResourceHolderRetain(mClientId, resourceHolderRetain);
+ mTunerResourceManager.setResourceOwnershipRetention(mClientId, enabled);
}
}
diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java
index 09022782e6c3..d433ec876af9 100644
--- a/media/java/android/media/MediaRoute2Info.java
+++ b/media/java/android/media/MediaRoute2Info.java
@@ -21,6 +21,7 @@ import static android.media.audio.Flags.FLAG_ENABLE_MULTICHANNEL_GROUP_DEVICE;
import static com.android.media.flags.Flags.FLAG_ENABLE_AUDIO_POLICIES_DEVICE_AND_BLUETOOTH_CONTROLLER;
import static com.android.media.flags.Flags.FLAG_ENABLE_BUILT_IN_SPEAKER_ROUTE_SUITABILITY_STATUSES;
+import static com.android.media.flags.Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2;
import static com.android.media.flags.Flags.FLAG_ENABLE_NEW_MEDIA_ROUTE_2_INFO_TYPES;
import static com.android.media.flags.Flags.FLAG_ENABLE_NEW_WIRED_MEDIA_ROUTE_2_INFO_TYPES;
@@ -421,6 +422,51 @@ public final class MediaRoute2Info implements Parcelable {
*/
public static final int TYPE_GROUP = 2000;
+ /** @hide */
+ @IntDef(
+ prefix = {"ROUTING_TYPE_"},
+ value = {
+ FLAG_ROUTING_TYPE_SYSTEM_AUDIO,
+ FLAG_ROUTING_TYPE_SYSTEM_VIDEO,
+ FLAG_ROUTING_TYPE_REMOTE
+ },
+ flag = true)
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface RoutingType {}
+
+ /**
+ * Indicates that a route supports routing of the system audio.
+ *
+ * <p>Providers that support this type of routing require the {@link
+ * android.Manifest.permission#MODIFY_AUDIO_ROUTING} permission.
+ */
+ @FlaggedApi(FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
+ public static final int FLAG_ROUTING_TYPE_SYSTEM_AUDIO = 1;
+
+ /**
+ * Indicates that a route supports routing of the system video.
+ *
+ * @hide
+ */
+ // TODO: b/380431086 - Enable this API once we add support for system video routing.
+ @FlaggedApi(FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
+ public static final int FLAG_ROUTING_TYPE_SYSTEM_VIDEO = 1 << 1;
+
+ /**
+ * Indicates that a route supports routing playback to remote routes through control commands.
+ *
+ * <p>This type of routing does not affect affect this system's audio or video, but instead
+ * relies on the device that corresponds to this route to fetch and play the media. It also
+ * requires the media app to take care of initializing and controlling playback.
+ */
+ @FlaggedApi(FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
+ public static final int FLAG_ROUTING_TYPE_REMOTE = 1 << 2;
+
+ private static final int FLAG_ROUTING_TYPE_ALL =
+ FLAG_ROUTING_TYPE_SYSTEM_AUDIO
+ | FLAG_ROUTING_TYPE_SYSTEM_VIDEO
+ | FLAG_ROUTING_TYPE_REMOTE;
+
/**
* Route feature: Live audio.
* <p>
@@ -553,6 +599,7 @@ public final class MediaRoute2Info implements Parcelable {
private final List<String> mFeatures;
@Type
private final int mType;
+ @RoutingType private final int mRoutingTypeFlags;
private final boolean mIsSystem;
private final Uri mIconUri;
private final CharSequence mDescription;
@@ -576,6 +623,7 @@ public final class MediaRoute2Info implements Parcelable {
mName = builder.mName;
mFeatures = builder.mFeatures;
mType = builder.mType;
+ mRoutingTypeFlags = builder.mRoutingTypeFlags;
mIsSystem = builder.mIsSystem;
mIconUri = builder.mIconUri;
mDescription = builder.mDescription;
@@ -600,6 +648,7 @@ public final class MediaRoute2Info implements Parcelable {
mName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
mFeatures = in.createStringArrayList();
mType = in.readInt();
+ mRoutingTypeFlags = validateRoutingTypeFlags(in.readInt());
mIsSystem = in.readBoolean();
mIconUri = in.readParcelable(null, android.net.Uri.class);
mDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
@@ -660,6 +709,13 @@ public final class MediaRoute2Info implements Parcelable {
return mType;
}
+ /** Returns the flags that indicate the routing types supported by this route. */
+ @RoutingType
+ @FlaggedApi(FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
+ public int getSupportedRoutingTypes() {
+ return mRoutingTypeFlags;
+ }
+
/**
* Returns whether the route is a system route or not.
* <p>
@@ -904,6 +960,7 @@ public final class MediaRoute2Info implements Parcelable {
pw.println(indent + "mName=" + mName);
pw.println(indent + "mFeatures=" + mFeatures);
pw.println(indent + "mType=" + getDeviceTypeString(mType));
+ pw.println(indent + "mRoutingTypeFlags=" + getRoutingTypeFlagsString(mRoutingTypeFlags));
pw.println(indent + "mIsSystem=" + mIsSystem);
pw.println(indent + "mIconUri=" + mIconUri);
pw.println(indent + "mDescription=" + mDescription);
@@ -941,6 +998,7 @@ public final class MediaRoute2Info implements Parcelable {
&& Objects.equals(mName, other.mName)
&& Objects.equals(mFeatures, other.mFeatures)
&& (mType == other.mType)
+ && (mRoutingTypeFlags == other.mRoutingTypeFlags)
&& (mIsSystem == other.mIsSystem)
&& Objects.equals(mIconUri, other.mIconUri)
&& Objects.equals(mDescription, other.mDescription)
@@ -966,6 +1024,7 @@ public final class MediaRoute2Info implements Parcelable {
mName,
mFeatures,
mType,
+ mRoutingTypeFlags,
mIsSystem,
mIconUri,
mDescription,
@@ -994,6 +1053,8 @@ public final class MediaRoute2Info implements Parcelable {
.append(getName())
.append(", type=")
.append(getDeviceTypeString(getType()))
+ .append(", routingTypes=")
+ .append(getRoutingTypeFlagsString(getSupportedRoutingTypes()))
.append(", isSystem=")
.append(isSystemRoute())
.append(", features=")
@@ -1035,6 +1096,7 @@ public final class MediaRoute2Info implements Parcelable {
TextUtils.writeToParcel(mName, dest, flags);
dest.writeStringList(mFeatures);
dest.writeInt(mType);
+ dest.writeInt(mRoutingTypeFlags);
dest.writeBoolean(mIsSystem);
dest.writeParcelable(mIconUri, flags);
TextUtils.writeToParcel(mDescription, dest, flags);
@@ -1143,6 +1205,34 @@ public final class MediaRoute2Info implements Parcelable {
}
}
+ /** Returns a human-readable representation of the given {@code routingTypeFlags}. */
+ private static String getRoutingTypeFlagsString(@RoutingType int routingTypeFlags) {
+ List<String> typeStrings = new ArrayList<>();
+ if ((routingTypeFlags & FLAG_ROUTING_TYPE_SYSTEM_AUDIO) != 0) {
+ typeStrings.add("SYSTEM_AUDIO");
+ }
+ if ((routingTypeFlags & FLAG_ROUTING_TYPE_SYSTEM_VIDEO) != 0) {
+ typeStrings.add("SYSTEM_VIDEO");
+ }
+ if ((routingTypeFlags & FLAG_ROUTING_TYPE_REMOTE) != 0) {
+ typeStrings.add("REMOTE");
+ }
+ return String.join(/* delimiter= */ "|", typeStrings);
+ }
+
+ /**
+ * Throws an {@link IllegalArgumentException} if the provided {@code routingTypeFlags} are not
+ * valid. Otherwise, returns the provided value.
+ */
+ private static int validateRoutingTypeFlags(@RoutingType int routingTypeFlags) {
+ if (routingTypeFlags == 0 || (routingTypeFlags & ~FLAG_ROUTING_TYPE_ALL) != 0) {
+ throw new IllegalArgumentException(
+ "Invalid routing type flags: " + Integer.toHexString(routingTypeFlags));
+ } else {
+ return routingTypeFlags;
+ }
+ }
+
/**
* Builder for {@link MediaRoute2Info media route info}.
*/
@@ -1153,6 +1243,7 @@ public final class MediaRoute2Info implements Parcelable {
@Type
private int mType = TYPE_UNKNOWN;
+ @RoutingType private int mRoutingTypeFlags = FLAG_ROUTING_TYPE_REMOTE;
private boolean mIsSystem;
private Uri mIconUri;
private CharSequence mDescription;
@@ -1224,6 +1315,7 @@ public final class MediaRoute2Info implements Parcelable {
mName = routeInfo.mName;
mFeatures = new ArrayList<>(routeInfo.mFeatures);
mType = routeInfo.mType;
+ mRoutingTypeFlags = routeInfo.mRoutingTypeFlags;
mIsSystem = routeInfo.mIsSystem;
mIconUri = routeInfo.mIconUri;
mDescription = routeInfo.mDescription;
@@ -1301,6 +1393,18 @@ public final class MediaRoute2Info implements Parcelable {
}
/**
+ * Sets the routing types that this route supports.
+ *
+ * @see MediaRoute2Info#getSupportedRoutingTypes()
+ */
+ @NonNull
+ @FlaggedApi(FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
+ public Builder setSupportedRoutingTypes(@RoutingType int routingTypeFlags) {
+ mRoutingTypeFlags = validateRoutingTypeFlags(routingTypeFlags);
+ return this;
+ }
+
+ /**
* Sets whether the route is a system route or not.
* @hide
*/
diff --git a/media/java/android/media/quality/IMediaQualityManager.aidl b/media/java/android/media/quality/IMediaQualityManager.aidl
index b7e75b7e6649..dc3fbf60c0b3 100644
--- a/media/java/android/media/quality/IMediaQualityManager.aidl
+++ b/media/java/android/media/quality/IMediaQualityManager.aidl
@@ -30,42 +30,42 @@ import android.media.quality.SoundProfile;
* @hide
*/
interface IMediaQualityManager {
- PictureProfile createPictureProfile(in PictureProfile pp);
- void updatePictureProfile(in String id, in PictureProfile pp);
- void removePictureProfile(in String id);
- PictureProfile getPictureProfile(in int type, in String name);
- List<PictureProfile> getPictureProfilesByPackage(in String packageName);
- List<PictureProfile> getAvailablePictureProfiles();
- List<String> getPictureProfilePackageNames();
- List<String> getPictureProfileAllowList();
- void setPictureProfileAllowList(in List<String> packages);
- PictureProfileHandle getPictureProfileHandle(in String id);
+ PictureProfile createPictureProfile(in PictureProfile pp, int userId);
+ void updatePictureProfile(in String id, in PictureProfile pp, int userId);
+ void removePictureProfile(in String id, int userId);
+ PictureProfile getPictureProfile(in int type, in String name, int userId);
+ List<PictureProfile> getPictureProfilesByPackage(in String packageName, int userId);
+ List<PictureProfile> getAvailablePictureProfiles(int userId);
+ List<String> getPictureProfilePackageNames(int userId);
+ List<String> getPictureProfileAllowList(int userId);
+ void setPictureProfileAllowList(in List<String> packages, int userId);
+ PictureProfileHandle getPictureProfileHandle(in String id, int userId);
- SoundProfile createSoundProfile(in SoundProfile pp);
- void updateSoundProfile(in String id, in SoundProfile pp);
- void removeSoundProfile(in String id);
- SoundProfile getSoundProfile(in int type, in String name);
- List<SoundProfile> getSoundProfilesByPackage(in String packageName);
- List<SoundProfile> getAvailableSoundProfiles();
- List<String> getSoundProfilePackageNames();
- List<String> getSoundProfileAllowList();
- void setSoundProfileAllowList(in List<String> packages);
+ SoundProfile createSoundProfile(in SoundProfile pp, int userId);
+ void updateSoundProfile(in String id, in SoundProfile pp, int userId);
+ void removeSoundProfile(in String id, int userId);
+ SoundProfile getSoundProfile(in int type, in String name, int userId);
+ List<SoundProfile> getSoundProfilesByPackage(in String packageName, int userId);
+ List<SoundProfile> getAvailableSoundProfiles(int userId);
+ List<String> getSoundProfilePackageNames(int userId);
+ List<String> getSoundProfileAllowList(int userId);
+ void setSoundProfileAllowList(in List<String> packages, int userId);
void registerPictureProfileCallback(in IPictureProfileCallback cb);
void registerSoundProfileCallback(in ISoundProfileCallback cb);
void registerAmbientBacklightCallback(in IAmbientBacklightCallback cb);
- List<ParamCapability> getParamCapabilities(in List<String> names);
+ List<ParamCapability> getParamCapabilities(in List<String> names, int userId);
- boolean isSupported();
- void setAutoPictureQualityEnabled(in boolean enabled);
- boolean isAutoPictureQualityEnabled();
- void setSuperResolutionEnabled(in boolean enabled);
- boolean isSuperResolutionEnabled();
- void setAutoSoundQualityEnabled(in boolean enabled);
- boolean isAutoSoundQualityEnabled();
+ boolean isSupported(int userId);
+ void setAutoPictureQualityEnabled(in boolean enabled, int userId);
+ boolean isAutoPictureQualityEnabled(int userId);
+ void setSuperResolutionEnabled(in boolean enabled, int userId);
+ boolean isSuperResolutionEnabled(int userId);
+ void setAutoSoundQualityEnabled(in boolean enabled, int userId);
+ boolean isAutoSoundQualityEnabled(int userId);
- void setAmbientBacklightSettings(in AmbientBacklightSettings settings);
- void setAmbientBacklightEnabled(in boolean enabled);
- boolean isAmbientBacklightEnabled();
+ void setAmbientBacklightSettings(in AmbientBacklightSettings settings, int userId);
+ void setAmbientBacklightEnabled(in boolean enabled, int userId);
+ boolean isAmbientBacklightEnabled(int userId);
}
diff --git a/media/java/android/media/quality/MediaQualityContract.java b/media/java/android/media/quality/MediaQualityContract.java
index 3fac74b2a37d..7b0bd04f3559 100644
--- a/media/java/android/media/quality/MediaQualityContract.java
+++ b/media/java/android/media/quality/MediaQualityContract.java
@@ -74,6 +74,130 @@ public class MediaQualityContract {
*/
public static final String PARAMETER_SATURATION = "saturation";
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_COLOR = "color";
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_HUE = "hue";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_BACKLIGHT = "backlight";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_COLOR_TUNER_BRIGHTNESS = "color_tuner_brightness";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_COLOR_TUNER_SATURATION = "color_tuner_saturation";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_COLOR_TUNER_HUE = "color_tuner_hue";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_COLOR_TUNER_REDO_FFSET = "color_tuner_red_offset";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_COLOR_TUNER_GREEN_OFFSET = "color_tuner_green_offset";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_COLOR_TUNER_BLUE_OFFSET = "color_tuner_blue_offset";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_COLOR_TUNER_RED_GAIN = "color_tuner_red_gain";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_COLOR_TUNER_GREEN_GAIN = "color_tuner_green_gain";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_COLOR_TUNER_BLUE_GAIN = "color_tuner_blue_gain";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_AI_PQ = "ai_pq";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_AI_SUPER_RESOLUTION = "ai_super_resolution";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_NOISE_REDUCTION = "noise_reduction";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_MPEG_NOISE_REDUCTION = "mpeg_noise_reduction";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_FLESH_TONE = "flesh_tone";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_DECONTOUR = "decontour";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_DYNAMIC_LUMA_CONTROL = "dynamic_luma_control";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_FILM_MODE = "film_mode";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_BLACK_STRETCH = "black_stretch";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_BLUE_STRETCH = "blue_stretch";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_COLOR_TUNE = "color_tune";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_COLOR_TEMPERATURE = "color_temperature";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_GLOBAL_DIMMING = "global_dimming";
+
private PictureQuality() {
}
}
@@ -105,6 +229,129 @@ public class MediaQualityContract {
*/
public static final String PARAMETER_TREBLE = "treble";
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_SOUND_MODE = "sound_mode";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_SURROUND_SOUND = "surround_sound";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_EQUALIZER_DETAIL = "equalizer_detail";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_SPEAKERS = "speakers";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_SPEAKERS_DELAY = "speakers_delay";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_EARC = "earc";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_AUTO_VOLUME_CONTROL = "auto_volume_control";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_DOWN_MIX_MODE = "down_mix_mode";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_DTS_DRC = "dts_drc";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_DOLBY_AUDIO_PROCESSING = "dolby_audio_processing";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_DOLBY_AUDIO_PROCESSING_SOUND_MODE =
+ "dolby_audio_processing_sound_mode";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_DOLBY_AUDIO_PROCESSING_VOLUME_LEVELER =
+ "dolby_audio_processing_volume_leveler";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_DOLBY_AUDIO_PROCESSING_SURROUND_VIRTUALIZER =
+ "dolby_audio_processing_surround_virtualizer";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_DOLBY_AUDIO_PROCESSING_DOLBY_ATMOS =
+ "dolby_audio_processing_dolby_atmos";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_DIALOGUE_ENHANCER = "dialogue_enhancer";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_DTS_VIRTUAL_X = "dts_virtual_x";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_DTS_VIRTUAL_X_TBHDX = "dts_virtual_x_tbhdx";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_DTS_VIRTUAL_X_LIMITER = "dts_virtual_x_limiter";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_DTS_VIRTUAL_X_TRU_SURROUND_X =
+ "dts_virtual_x_tru_surround_x";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_DTS_VIRTUAL_X_TRU_VOLUME_HD =
+ "dts_virtual_x_tru_volume_hd";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_DTS_VIRTUAL_X_DIALOG_CLARITY =
+ "dts_virtual_x_dialog_clarity";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_DTS_VIRTUAL_X_DEFINITION = "dts_virtual_x_definition";
+
+ /**
+ * @hide
+ */
+ public static final String PARAMETER_DTS_VIRTUAL_X_HEIGHT = "dts_virtual_x_height";
+
+
private SoundQuality() {
}
}
diff --git a/media/java/android/media/quality/MediaQualityManager.java b/media/java/android/media/quality/MediaQualityManager.java
index 50055971d66d..d4de99aadb14 100644
--- a/media/java/android/media/quality/MediaQualityManager.java
+++ b/media/java/android/media/quality/MediaQualityManager.java
@@ -47,6 +47,7 @@ public final class MediaQualityManager {
private final IMediaQualityManager mService;
private final Context mContext;
+ private final int mUserId;
private final Object mLock = new Object();
// @GuardedBy("mLock")
private final List<PictureProfileCallbackRecord> mPpCallbackRecords = new ArrayList<>();
@@ -61,6 +62,7 @@ public final class MediaQualityManager {
*/
public MediaQualityManager(Context context, IMediaQualityManager service) {
mContext = context;
+ mUserId = context.getUserId();
mService = service;
IPictureProfileCallback ppCallback = new IPictureProfileCallback.Stub() {
@Override
@@ -219,7 +221,7 @@ public final class MediaQualityManager {
public PictureProfile getPictureProfile(
@PictureProfile.ProfileType int type, @NonNull String name) {
try {
- return mService.getPictureProfile(type, name);
+ return mService.getPictureProfile(type, name, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -236,7 +238,7 @@ public final class MediaQualityManager {
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
public List<PictureProfile> getPictureProfilesByPackage(@NonNull String packageName) {
try {
- return mService.getPictureProfilesByPackage(packageName);
+ return mService.getPictureProfilesByPackage(packageName, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -248,7 +250,7 @@ public final class MediaQualityManager {
@NonNull
public List<PictureProfile> getAvailablePictureProfiles() {
try {
- return mService.getAvailablePictureProfiles();
+ return mService.getAvailablePictureProfiles(mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -265,7 +267,7 @@ public final class MediaQualityManager {
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
public List<String> getPictureProfilePackageNames() {
try {
- return mService.getPictureProfilePackageNames();
+ return mService.getPictureProfilePackageNames(mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -277,7 +279,7 @@ public final class MediaQualityManager {
*/
public PictureProfileHandle getPictureProfileHandle(String id) {
try {
- return mService.getPictureProfileHandle(id);
+ return mService.getPictureProfileHandle(id, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -291,7 +293,7 @@ public final class MediaQualityManager {
*/
public void createPictureProfile(@NonNull PictureProfile pp) {
try {
- mService.createPictureProfile(pp);
+ mService.createPictureProfile(pp, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -303,7 +305,7 @@ public final class MediaQualityManager {
*/
public void updatePictureProfile(@NonNull String profileId, @NonNull PictureProfile pp) {
try {
- mService.updatePictureProfile(profileId, pp);
+ mService.updatePictureProfile(profileId, pp, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -315,7 +317,7 @@ public final class MediaQualityManager {
*/
public void removePictureProfile(@NonNull String profileId) {
try {
- mService.removePictureProfile(profileId);
+ mService.removePictureProfile(profileId, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -362,7 +364,7 @@ public final class MediaQualityManager {
public SoundProfile getSoundProfile(
@SoundProfile.ProfileType int type, @NonNull String name) {
try {
- return mService.getSoundProfile(type, name);
+ return mService.getSoundProfile(type, name, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -379,7 +381,7 @@ public final class MediaQualityManager {
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
public List<SoundProfile> getSoundProfilesByPackage(@NonNull String packageName) {
try {
- return mService.getSoundProfilesByPackage(packageName);
+ return mService.getSoundProfilesByPackage(packageName, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -391,7 +393,7 @@ public final class MediaQualityManager {
@NonNull
public List<SoundProfile> getAvailableSoundProfiles() {
try {
- return mService.getAvailableSoundProfiles();
+ return mService.getAvailableSoundProfiles(mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -409,7 +411,7 @@ public final class MediaQualityManager {
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
public List<String> getSoundProfilePackageNames() {
try {
- return mService.getSoundProfilePackageNames();
+ return mService.getSoundProfilePackageNames(mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -424,7 +426,7 @@ public final class MediaQualityManager {
*/
public void createSoundProfile(@NonNull SoundProfile sp) {
try {
- mService.createSoundProfile(sp);
+ mService.createSoundProfile(sp, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -436,7 +438,7 @@ public final class MediaQualityManager {
*/
public void updateSoundProfile(@NonNull String profileId, @NonNull SoundProfile sp) {
try {
- mService.updateSoundProfile(profileId, sp);
+ mService.updateSoundProfile(profileId, sp, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -448,7 +450,7 @@ public final class MediaQualityManager {
*/
public void removeSoundProfile(@NonNull String profileId) {
try {
- mService.removeSoundProfile(profileId);
+ mService.removeSoundProfile(profileId, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -460,7 +462,7 @@ public final class MediaQualityManager {
@NonNull
public List<ParamCapability> getParamCapabilities(@NonNull List<String> names) {
try {
- return mService.getParamCapabilities(names);
+ return mService.getParamCapabilities(names, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -478,7 +480,7 @@ public final class MediaQualityManager {
@NonNull
public List<String> getPictureProfileAllowList() {
try {
- return mService.getPictureProfileAllowList();
+ return mService.getPictureProfileAllowList(mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -492,7 +494,7 @@ public final class MediaQualityManager {
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
public void setPictureProfileAllowList(@NonNull List<String> packageNames) {
try {
- mService.setPictureProfileAllowList(packageNames);
+ mService.setPictureProfileAllowList(packageNames, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -510,7 +512,7 @@ public final class MediaQualityManager {
@NonNull
public List<String> getSoundProfileAllowList() {
try {
- return mService.getSoundProfileAllowList();
+ return mService.getSoundProfileAllowList(mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -524,7 +526,7 @@ public final class MediaQualityManager {
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
public void setSoundProfileAllowList(@NonNull List<String> packageNames) {
try {
- mService.setSoundProfileAllowList(packageNames);
+ mService.setSoundProfileAllowList(packageNames, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -536,7 +538,7 @@ public final class MediaQualityManager {
*/
public boolean isSupported() {
try {
- return mService.isSupported();
+ return mService.isSupported(mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -554,7 +556,7 @@ public final class MediaQualityManager {
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
public void setAutoPictureQualityEnabled(boolean enabled) {
try {
- mService.setAutoPictureQualityEnabled(enabled);
+ mService.setAutoPictureQualityEnabled(enabled, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -565,7 +567,7 @@ public final class MediaQualityManager {
*/
public boolean isAutoPictureQualityEnabled() {
try {
- return mService.isAutoPictureQualityEnabled();
+ return mService.isAutoPictureQualityEnabled(mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -582,7 +584,7 @@ public final class MediaQualityManager {
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
public void setSuperResolutionEnabled(boolean enabled) {
try {
- mService.setSuperResolutionEnabled(enabled);
+ mService.setSuperResolutionEnabled(enabled, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -593,7 +595,7 @@ public final class MediaQualityManager {
*/
public boolean isSuperResolutionEnabled() {
try {
- return mService.isSuperResolutionEnabled();
+ return mService.isSuperResolutionEnabled(mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -611,7 +613,7 @@ public final class MediaQualityManager {
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
public void setAutoSoundQualityEnabled(boolean enabled) {
try {
- mService.setAutoSoundQualityEnabled(enabled);
+ mService.setAutoSoundQualityEnabled(enabled, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -622,7 +624,7 @@ public final class MediaQualityManager {
*/
public boolean isAutoSoundQualityEnabled() {
try {
- return mService.isAutoSoundQualityEnabled();
+ return mService.isAutoSoundQualityEnabled(mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -668,7 +670,7 @@ public final class MediaQualityManager {
@NonNull AmbientBacklightSettings settings) {
Preconditions.checkNotNull(settings);
try {
- mService.setAmbientBacklightSettings(settings);
+ mService.setAmbientBacklightSettings(settings, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -679,7 +681,7 @@ public final class MediaQualityManager {
*/
public boolean isAmbientBacklightEnabled() {
try {
- return mService.isAmbientBacklightEnabled();
+ return mService.isAmbientBacklightEnabled(mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -692,7 +694,7 @@ public final class MediaQualityManager {
*/
public void setAmbientBacklightEnabled(boolean enabled) {
try {
- mService.setAmbientBacklightEnabled(enabled);
+ mService.setAmbientBacklightEnabled(enabled, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/media/java/android/media/tv/flags/media_tv.aconfig b/media/java/android/media/tv/flags/media_tv.aconfig
index 4b832aee49c5..3451dfc559ee 100644
--- a/media/java/android/media/tv/flags/media_tv.aconfig
+++ b/media/java/android/media/tv/flags/media_tv.aconfig
@@ -93,7 +93,7 @@ flag {
name: "set_resource_holder_retain"
is_exported: true
namespace: "media_tv"
- description: "Feature flag to add setResourceHolderRetain api to MediaCas and Tuner JAVA."
+ description: "Feature flag to add setResourceOwnershipRetention api to MediaCas and Tuner JAVA."
bug: "372973197"
}
@@ -112,3 +112,11 @@ flag {
description : "Feature flag to enable APIs for applying picture profiles"
bug: "337330263"
}
+
+flag {
+ name: "hdmi_control_collect_physical_address"
+ is_exported: true
+ namespace: "media_tv"
+ description: "Collect physical address from HDMI-CEC messages in metrics"
+ bug: "376001043"
+}
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index b1adb77f9543..7f7a23969411 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -757,14 +757,14 @@ public class Tuner implements AutoCloseable {
* scenario, when both resource holder and resource challenger have same processId and same
* priority.
*
- * @param resourceHolderRetain Set to true to allow the resource holder to retain ownership, or
- * false to allow the resource challenger to acquire the resource. If not explicitly set,
- * resourceHolderRetain is set to false.
+ * @param enabled Set to {@code true} to allow the resource holder to retain ownership,
+ * or false to allow the resource challenger to acquire the resource.
+ * If not explicitly set, enabled is set to {@code false}.
*/
@FlaggedApi(FLAG_SET_RESOURCE_HOLDER_RETAIN)
@RequiresPermission(android.Manifest.permission.TUNER_RESOURCE_ACCESS)
- public void setResourceHolderRetain(boolean resourceHolderRetain) {
- mTunerResourceManager.setResourceHolderRetain(mClientId, resourceHolderRetain);
+ public void setResourceOwnershipRetention(boolean enabled) {
+ mTunerResourceManager.setResourceOwnershipRetention(mClientId, enabled);
}
/**
diff --git a/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java b/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java
index be65ad98c35b..2ed642eecb81 100644
--- a/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java
+++ b/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java
@@ -21,6 +21,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresFeature;
+import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemService;
import android.annotation.TestApi;
@@ -227,15 +228,16 @@ public class TunerResourceManager {
* scenario, when both resource holder and resource challenger have same processId and same
* priority.
*
- * @param clientId The client id used to set ownership of resource to owner in case of resource
+ * @param clientId The client id used to set ownership of resource in case of resource
* challenger situation.
- * @param resourceHolderRetain Set to true to allow the resource holder to retain ownership, or
- * false to allow the resource challenger to acquire the resource. If not explicitly set,
- * resourceHolderRetain is set to false.
+ * @param enabled Set to {@code true} to allow the resource holder to retain ownership,
+ * or false to allow the resource challenger to acquire the resource.
+ * If not explicitly set, enabled is set to {@code false}.
*/
- public void setResourceHolderRetain(int clientId, boolean resourceHolderRetain) {
+ @RequiresPermission(android.Manifest.permission.TUNER_RESOURCE_ACCESS)
+ public void setResourceOwnershipRetention(int clientId, boolean enabled) {
try {
- mService.setResourceHolderRetain(clientId, resourceHolderRetain);
+ mService.setResourceOwnershipRetention(clientId, enabled);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/media/java/android/media/tv/tunerresourcemanager/aidl/android/media/tv/tunerresourcemanager/ITunerResourceManager.aidl b/media/java/android/media/tv/tunerresourcemanager/aidl/android/media/tv/tunerresourcemanager/ITunerResourceManager.aidl
index c57be1b09b66..50f9fe556cee 100644
--- a/media/java/android/media/tv/tunerresourcemanager/aidl/android/media/tv/tunerresourcemanager/ITunerResourceManager.aidl
+++ b/media/java/android/media/tv/tunerresourcemanager/aidl/android/media/tv/tunerresourcemanager/ITunerResourceManager.aidl
@@ -156,12 +156,13 @@ interface ITunerResourceManager {
* scenario, when both Resource Holder and Resource Challenger have same processId and same
* priority.
*
- * @param clientId The resourceHolderRetain of the client is updated using client ID.
- * @param resourceHolderRetain set to true to allow the Resource Holder to retain ownership, or
- * false to allow the Resource Challenger to acquire the resource. If not explicitly set,
- * resourceHolderRetain is set to false.
+ * @param clientId The client id used to set ownership of resource in case of resource
+ * challenger situation.
+ * @param enabled Set to {@code true} to allow the Resource Holder to retain ownership,
+ * or false to allow the Resource Challenger to acquire the resource.
+ * If not explicitly set, enabled is set to {@code false}.
*/
- void setResourceHolderRetain(int clientId, boolean resourceHolderRetain);
+ void setResourceOwnershipRetention(int clientId, boolean enabled);
/*
* This API is used by the Tuner framework to request a frontend from the TunerHAL.
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
index 88c1c434cc0d..ec336d5efee6 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
@@ -27,6 +27,7 @@ import android.hardware.ICameraService;
import android.hardware.ICameraServiceListener;
import android.hardware.camera2.ICameraDeviceCallbacks;
import android.hardware.camera2.ICameraDeviceUser;
+import android.hardware.camera2.CameraMetadataInfo;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.impl.CaptureResultExtras;
import android.hardware.camera2.impl.PhysicalCaptureResultInfo;
@@ -217,7 +218,7 @@ public class CameraBinderTest extends AndroidTestCase {
* android.hardware.camera2.CaptureResultExtras)
*/
@Override
- public void onResultReceived(CameraMetadataNative result, CaptureResultExtras resultExtras,
+ public void onResultReceived(CameraMetadataInfo result, CaptureResultExtras resultExtras,
PhysicalCaptureResultInfo physicalResults[]) throws RemoteException {
// TODO Auto-generated method stub
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
index 3758c515c1a5..7d1e5f821c05 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
@@ -33,6 +33,7 @@ import android.graphics.SurfaceTexture;
import android.hardware.ICameraService;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraMetadataInfo;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.ICameraDeviceCallbacks;
import android.hardware.camera2.ICameraDeviceUser;
@@ -141,7 +142,7 @@ public class CameraDeviceBinderTest extends AndroidTestCase {
* android.hardware.camera2.impl.CameraMetadataNative,
* android.hardware.camera2.CaptureResultExtras)
*/
- public void onResultReceived(CameraMetadataNative result, CaptureResultExtras resultExtras,
+ public void onResultReceived(CameraMetadataInfo result, CaptureResultExtras resultExtras,
PhysicalCaptureResultInfo physicalResults[]) throws RemoteException {
// TODO Auto-generated method stub
@@ -186,10 +187,14 @@ public class CameraDeviceBinderTest extends AndroidTestCase {
}
}
- class IsMetadataNotEmpty implements ArgumentMatcher<CameraMetadataNative> {
+ class IsMetadataNotEmpty implements ArgumentMatcher<CameraMetadataInfo> {
@Override
- public boolean matches(CameraMetadataNative obj) {
- return !obj.isEmpty();
+ public boolean matches(CameraMetadataInfo obj) {
+ if (obj.getTag() == CameraMetadataInfo.metadata) {
+ return !(obj.getMetadata().isEmpty());
+ } else {
+ return (obj.getFmqSize() != 0);
+ }
}
}
diff --git a/packages/PackageInstaller/res/values-it/strings.xml b/packages/PackageInstaller/res/values-it/strings.xml
index 1561e790ff2e..ec6d3fcc185d 100644
--- a/packages/PackageInstaller/res/values-it/strings.xml
+++ b/packages/PackageInstaller/res/values-it/strings.xml
@@ -43,7 +43,7 @@
<string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"L\'amministratore non consente l\'installazione di app ottenute da origini sconosciute"</string>
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Questo utente non può installare app sconosciute"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"L\'utente non dispone dell\'autorizzazione a installare app"</string>
- <string name="ok" msgid="7871959885003339302">"OK"</string>
+ <string name="ok" msgid="7871959885003339302">"Ok"</string>
<string name="archive" msgid="4447791830199354721">"Archivia"</string>
<string name="update_anyway" msgid="8792432341346261969">"Aggiorna comunque"</string>
<string name="manage_applications" msgid="5400164782453975580">"Gestisci app"</string>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-af/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-af/strings.xml
index 38cae307f5dc..7209cc2e86af 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-af/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-af/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Kies \'n prent"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Neem \'n foto"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Kies ’n profielprent"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Verstekgebruikerikoon"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Klaar"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-am/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-am/strings.xml
index 917a2fdc6a61..713e0d951a39 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-am/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-am/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"ምስል ይምረጡ"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"ፎቶ ያንሱ"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"የመገለጫ ሥዕል ይምረጡ"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"ነባሪ የተጠቃሚ አዶ"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"ተከናውኗል"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ar/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ar/strings.xml
index 8e5231ba1e77..1b5dbc0248cc 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-ar/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-ar/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"اختيار صورة"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"التقاط صورة"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"اختيار صورة للملف الشخصي"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"رمز المستخدم التلقائي"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"تم"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-as/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-as/strings.xml
index c77b573b26c6..628132809831 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-as/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-as/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"এখন প্ৰতিচ্ছবি বাছনি কৰক"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"এখন ফট’ তোলক"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"এখন প্ৰ’ফাইল চিত্ৰ বাছনি কৰক"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"ডিফ’ল্ট ব্যৱহাৰকাৰীৰ চিহ্ন"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"কৰা হ’ল"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-az/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-az/strings.xml
index 6871473a82a3..d47ffceae5d8 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-az/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-az/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Şəkil seçin"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Foto çəkin"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Profil şəkli seçin"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Defolt istifadəçi ikonası"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Hazırdır"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-b+sr+Latn/strings.xml
index 42fb478f5ca0..886bd5d946dd 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-b+sr+Latn/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Odaberite sliku"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Slikajte"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Odaberite sliku profila"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Podrazumevana ikona korisnika"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Gotovo"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-be/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-be/strings.xml
index c2ef4db67c5d..38a1340d17d5 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-be/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-be/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Выбраць відарыс"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Зрабіць фота"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Выберыце відарыс профілю"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Стандартны карыстальніцкі значок"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Гатова"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-bg/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-bg/strings.xml
index eeca7d8d5c9e..90e78b5051c2 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-bg/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-bg/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Избиране на изображение"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Правене на снимка"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Изберете снимка на потребителския профил"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Икона за основния потребител"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Готово"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-bn/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-bn/strings.xml
index 6d4d29f47ac6..c56c9dae178c 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-bn/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-bn/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"একটি ছবি বেছে নিন"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"ফটো তুলুন"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"কোনও একটি প্রোফাইল ছবি বেছে নিন"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"ডিফল্ট ব্যবহারকারীর আইকন"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"হয়ে গেছে"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-bs/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-bs/strings.xml
index def1b4525c40..1dd707dd5f13 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-bs/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-bs/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Odaberite sliku"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Snimite fotografiju"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Odaberite sliku profila"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Zadana ikona korisnika"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Gotovo"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ca/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ca/strings.xml
index 1b613cafa4df..d8d3171a7b94 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-ca/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-ca/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Tria una imatge"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Fes una foto"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Tria una foto de perfil"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Icona d\'usuari predeterminat"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Fet"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-cs/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-cs/strings.xml
index ffe2f47df489..6ee5b3e56f66 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-cs/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-cs/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Zvolit obrázek"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Vyfotit"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Vyberte profilový obrázek"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Výchozí uživatelská ikona"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Hotovo"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-da/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-da/strings.xml
index ab01eef4ab6e..0583399e3ef7 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-da/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-da/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Vælg et billede"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Tag et billede"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Vælg et profilbillede"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Ikon for standardbruger"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Udfør"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-de/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-de/strings.xml
index 4d6c651adabd..345b4faff396 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-de/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-de/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Bild auswählen"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Foto aufnehmen"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Profilbild auswählen"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Standardmäßiges Nutzersymbol"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Fertig"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-el/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-el/strings.xml
index 9e6813fff4d0..7cecd45dc11f 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-el/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-el/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Επιλέξτε μια εικόνα"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Λήψη φωτογραφίας"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Επιλογή φωτογραφ­ίας προφίλ"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Προεπιλεγμένο εικονίδιο χρήστη"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Τέλος"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-en-rAU/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-en-rAU/strings.xml
index d0aae7917ffd..f9905d0eb796 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-en-rAU/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Choose an image"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Take a photo"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Choose a profile picture"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Default user icon"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Done"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-en-rGB/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-en-rGB/strings.xml
index d0aae7917ffd..f9905d0eb796 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-en-rGB/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Choose an image"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Take a photo"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Choose a profile picture"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Default user icon"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Done"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-en-rIN/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-en-rIN/strings.xml
index d0aae7917ffd..f9905d0eb796 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-en-rIN/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Choose an image"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Take a photo"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Choose a profile picture"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Default user icon"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Done"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-es-rUS/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-es-rUS/strings.xml
index 296dcc8603e6..8e9d407bd994 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-es-rUS/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Elegir una imagen"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Tomar una foto"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Elige una foto de perfil"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Ícono de usuario predeterminado"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Listo"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-es/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-es/strings.xml
index 5d4a8d280796..a7da134da528 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-es/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-es/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Seleccionar una imagen"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Hacer una foto"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Elige una imagen de perfil"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Icono de usuario predeterminado"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Hecho"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-et/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-et/strings.xml
index ecd3a83ea2b2..ecf140da20be 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-et/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-et/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Vali pilt"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Pildista"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Profiilipildi valimine"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Vaikekasutajaikoon"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Valmis"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-eu/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-eu/strings.xml
index e29bc114b5ec..c55d559738a2 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-eu/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-eu/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Aukeratu irudi bat"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Atera argazki bat"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Aukeratu profileko argazki bat"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Erabiltzaile lehenetsiaren ikonoa"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Eginda"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-fa/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-fa/strings.xml
index 25efac4ba93d..7db55cfa5fc7 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-fa/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-fa/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"انتخاب تصویر"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"عکس گرفتن"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"انتخاب عکس نمایه"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"نماد کاربر پیش‌فرض"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"تمام"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-fi/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-fi/strings.xml
index 4d805ed242cb..7a0cca10c5b4 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-fi/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-fi/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Valitse kuva"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Ota kuva"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Valitse profiilikuva"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Oletuskäyttäjäkuvake"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Valmis"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-fr-rCA/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-fr-rCA/strings.xml
index fb32c5b118fb..e43947111fa9 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-fr-rCA/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Sélectionner une image"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Prendre une photo"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Choisir une photo de profil"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Icône d\'utilisateur par défaut"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Terminé"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-fr/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-fr/strings.xml
index 79620e96bcac..2ffeb4365e36 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-fr/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-fr/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Choisir une image"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Prendre une photo"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Choisir une photo de profil"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Icône de l\'utilisateur par défaut"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"OK"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-gl/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-gl/strings.xml
index bbfa18bf0080..5e46474eb195 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-gl/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-gl/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Escoller unha imaxe"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Tirar unha foto"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Escoller unha imaxe do perfil"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Icona do usuario predeterminado"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Feito"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-gu/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-gu/strings.xml
index 247afe13d0fb..96e67530cf90 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-gu/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-gu/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"છબી પસંદ કરો"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"ફોટો લો"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"પ્રોફાઇલ ફોટો પસંદ કરો"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"ડિફૉલ્ટ વપરાશકર્તાનું આઇકન"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"થઈ ગયું"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-hi/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-hi/strings.xml
index 3c515769630e..0878ff22f20e 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-hi/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-hi/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"इमेज चुनें"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"फ़ोटो खींचें"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"प्रोफ़ाइल फ़ोटो चुनें"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"उपयोगकर्ता के लिए डिफ़ॉल्ट आइकॉन"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"हो गया"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-hr/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-hr/strings.xml
index e9a56bdc839e..b599ddf42977 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-hr/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-hr/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Odaberite sliku"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Snimi fotografiju"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Odaberite profilnu sliku"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Ikona zadanog korisnika"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Gotovo"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-hu/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-hu/strings.xml
index f3d53cd57d53..55f4a6098f96 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-hu/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-hu/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Kép kiválasztása"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Fotó készítése"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Profilkép választása"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Alapértelmezett felhasználó ikonja"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Kész"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-in/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-in/strings.xml
index bfa0d935c6e7..9b5cbf3717de 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-in/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-in/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Pilih gambar"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Ambil foto"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Pilih foto profil"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Ikon pengguna default"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Selesai"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-is/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-is/strings.xml
index d49652480db5..4007c385c8a4 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-is/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-is/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Velja mynd"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Taka mynd"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Veldu prófílmynd"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Tákn sjálfgefins notanda"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Lokið"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-it/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-it/strings.xml
index 3ba0a01cbed2..caeb93b79204 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-it/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-it/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Scegli un\'immagine"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Scatta una foto"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Scegli un\'immagine del profilo"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Icona dell\'utente predefinito"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Fine"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-iw/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-iw/strings.xml
index 903989d999e0..03ca68eec0be 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-iw/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-iw/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"לבחירת תמונה"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"צילום תמונה"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"בחירה של תמונת הפרופיל"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"סמל המשתמש שמוגדר כברירת מחדל"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"סיום"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ka/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ka/strings.xml
index 817180bb6493..ae61afcba50d 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-ka/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-ka/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"სურათის არჩევა"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"ფოტოს გადაღება"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"პროფილის სურათის არჩევა"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"მომხმარებლის ნაგულისხმევი ხატულა"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"მზადაა"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-kk/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-kk/strings.xml
index ec01801bace9..f1e8950cd1e7 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-kk/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-kk/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Кескін таңдау"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Суретке түсіру"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Профиль суретін таңдау"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Әдепкі пайдаланушы белгішесі"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Дайын"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-km/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-km/strings.xml
index 7a311224646e..a86491e3bb7d 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-km/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-km/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"ជ្រើសរើស​រូបភាព"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"ថតរូប"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"ជ្រើសរើសរូបភាពកម្រងព័ត៌មាន"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"រូបអ្នកប្រើប្រាស់លំនាំដើម"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"រួចរាល់"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ko/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ko/strings.xml
index 45bfb532e6e1..682ebfd827ac 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-ko/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-ko/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"이미지 선택"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"사진 찍기"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"프로필 사진 선택"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"기본 사용자 아이콘"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"완료"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ky/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ky/strings.xml
index b3d39de49bda..3d8e7bff7396 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-ky/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-ky/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Сүрөт тандоо"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Сүрөткө тартуу"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Профилдин сүрөтүн тандоо"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Демейки колдонуучунун сүрөтчөсү"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Бүттү"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-lo/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-lo/strings.xml
index 3ba6709d04a4..64bd871481d5 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-lo/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-lo/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"ເລືອກຮູບ"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"ຖ່າຍຮູບ"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"ເລືອກຮູບໂປຣໄຟລ໌"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"ໄອຄອນຜູ້ໃຊ້ເລີ່ມຕົ້ນ"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"ແລ້ວໆ"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-lt/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-lt/strings.xml
index b0c0c39495f5..4bc183b5cd4c 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-lt/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-lt/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Pasirinkti vaizdą"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Fotografuoti"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Profilio nuotraukos pasirinkimas"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Numatytojo naudotojo piktograma"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Atlikta"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-lv/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-lv/strings.xml
index e664c80b5e7c..72e6ec438389 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-lv/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-lv/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Izvēlēties attēlu"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Uzņemt fotoattēlu"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Profila attēla izvēle"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Noklusējuma lietotāja ikona"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Gatavs"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-mk/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-mk/strings.xml
index bb0e2476bdc2..4b6939ec7775 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-mk/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-mk/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Изберете слика"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Фотографирај"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Изберете профилна слика"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Икона за стандарден корисник"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Готово"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ml/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ml/strings.xml
index 674b4f5d8fb5..aec39b13074c 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-ml/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-ml/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"ഒരു ചിത്രം തിരഞ്ഞെടുക്കുക"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"ഒരു ഫോട്ടോ എടുക്കുക"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"പ്രൊഫൈൽ ചിത്രം തിരഞ്ഞെടുക്കുക"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"ഡിഫോൾട്ട് ഉപയോക്തൃ ഐക്കൺ"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"പൂർത്തിയായി"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-mn/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-mn/strings.xml
index 61553b54d745..4d13e871aa64 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-mn/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-mn/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Зураг сонгох"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Зураг авах"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Профайл зураг сонгох"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Өгөгдмөл хэрэглэгчийн дүрс тэмдэг"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Болсон"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ms/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ms/strings.xml
index 25996969e61e..45f1b36e9332 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-ms/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-ms/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Pilih imej"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Ambil foto"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Pilih gambar profil"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Ikon pengguna lalai"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Selesai"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-my/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-my/strings.xml
index f9f697b3c200..697308460b15 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-my/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-my/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"ပုံရွေးရန်"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"ဓာတ်ပုံရိုက်ရန်"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"ပရိုဖိုင်ပုံ ရွေးပါ"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"မူရင်းအသုံးပြုသူ သင်္ကေတ"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"ပြီးပြီ"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-nb/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-nb/strings.xml
index c1b7631fa8b2..8a5500665a57 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-nb/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-nb/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Velg et bilde"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Ta et bilde"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Velg et profilbilde"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Standard brukerikon"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Ferdig"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ne/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ne/strings.xml
index a8c02b97cac8..8373058d7fd5 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-ne/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-ne/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"कुनै फोटो छनौट गर्नुहोस्"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"फोटो खिच्नुहोस्"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"प्रोफाइल फोटो छान्नुहोस्"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"प्रयोगकर्ताको डिफल्ट आइकन"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"सम्पन्न भयो"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-nl/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-nl/strings.xml
index 47352bc12100..cb3bd51cb9d4 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-nl/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-nl/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Een afbeelding kiezen"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Een foto maken"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Kies een profielfoto"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Standaard gebruikersicoon"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Klaar"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-or/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-or/strings.xml
index 132b97a6f46c..dd54ac304a24 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-or/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-or/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"ଗୋଟିଏ ଛବି ବାଛନ୍ତୁ"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"ଗୋଟିଏ ଫଟୋ ଉଠାନ୍ତୁ"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"ଏକ ପ୍ରୋଫାଇଲ ଛବି ବାଛନ୍ତୁ"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"ଡିଫଲ୍ଟ ୟୁଜର ଆଇକନ"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"ହୋଇଗଲା"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-pl/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-pl/strings.xml
index 7db79047047b..35787c91d141 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-pl/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-pl/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Wybierz obraz"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Zrób zdjęcie"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Wybierz zdjęcie profilowe"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Ikona domyślnego użytkownika"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Gotowe"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-pt-rBR/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-pt-rBR/strings.xml
index ae3e6e508c8b..ba1ce2ad34e1 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-pt-rBR/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Escolher uma imagem"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Tirar uma foto"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Escolha uma foto de perfil"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Ícone de usuário padrão"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Concluir"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-pt/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-pt/strings.xml
index ae3e6e508c8b..ba1ce2ad34e1 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-pt/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-pt/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Escolher uma imagem"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Tirar uma foto"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Escolha uma foto de perfil"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Ícone de usuário padrão"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Concluir"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ro/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ro/strings.xml
index ce662d41a113..51bcd5794cb9 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-ro/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-ro/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Alege o imagine"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Fă o fotografie"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Alege o fotografie de profil"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Pictograma prestabilită a utilizatorului"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Gata"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ru/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ru/strings.xml
index 47f8a839beb4..59fb913841e8 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-ru/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-ru/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Выбрать фото"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Сделать снимок"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Выберите фото профиля"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Значок пользователя по умолчанию"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Готово"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-si/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-si/strings.xml
index aaba44266bb1..db7e0b8e4b65 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-si/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-si/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"රූපයක් තෝරන්න"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"ඡායාරූපයක් ගන්න"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"පැතිකඩ පින්තූරයක් තේරීම"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"පෙරනිමි පරිශීලක නිරූපකය"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"නිමයි"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-sk/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-sk/strings.xml
index 3f801a36843d..36e94f3c5ed6 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-sk/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-sk/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Vybrať obrázok"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Odfotiť"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Vyberte profilovú fotku"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Predvolená ikona používateľa"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Hotovo"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-sq/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-sq/strings.xml
index 0b8a58d0d5d5..0093380052db 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-sq/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-sq/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Zgjidh një imazh"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Bëj një fotografi"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Zgjidh një fotografi profili"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Ikona e parazgjedhur e përdoruesit"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"U krye"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-sr/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-sr/strings.xml
index 1014df4f3b95..971d8c567cdc 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-sr/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-sr/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Одаберите слику"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Сликајте"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Одаберите слику профила"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Подразумевана икона корисника"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Готово"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-sv/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-sv/strings.xml
index 82034092288a..9196e2ac2adc 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-sv/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-sv/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Välj en bild"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Ta ett foto"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Välj en profilbild"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Ikon för standardanvändare"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Klar"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-sw/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-sw/strings.xml
index b0e8c44d5e8a..a0bc5548f6fe 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-sw/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-sw/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Chagua picha"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Piga picha"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Chagua picha ya wasifu"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Aikoni chaguomsingi ya mtumiaji"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Nimemaliza"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-th/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-th/strings.xml
index 31e753e04cc1..b8b4324878af 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-th/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-th/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"เลือกรูปภาพ"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"ถ่ายรูป"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"เลือกรูปโปรไฟล์"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"ไอคอนผู้ใช้เริ่มต้น"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"เสร็จสิ้น"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-tr/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-tr/strings.xml
index 26d96c22c7f2..3e10257d6b24 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-tr/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-tr/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Resim seç"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Fotoğraf çek"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Profil fotoğrafı seçin"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Varsayılan kullanıcı simgesi"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Bitti"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-uk/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-uk/strings.xml
index 1fbe5fb1076a..ee4a2fc22960 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-uk/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-uk/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Вибрати зображення"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Зробити фото"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Виберіть зображення профілю"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Значок користувача за умовчанням"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Готово"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-vi/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-vi/strings.xml
index 036c0065ebd7..c6b4ef5ef050 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-vi/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-vi/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Chọn hình ảnh"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Chụp ảnh"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Chọn một ảnh hồ sơ"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Biểu tượng người dùng mặc định"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Xong"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-zh-rCN/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-zh-rCN/strings.xml
index 58488b35b0a6..684449f446e1 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-zh-rCN/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"选择图片"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"拍照"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"选择个人资料照片"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"默认用户图标"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"完成"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-zh-rHK/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-zh-rHK/strings.xml
index e5f375205844..e0d405272dc8 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-zh-rHK/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"選擇圖片"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"拍攝相片"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"選擇個人檔案相片"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"預設使用者圖示"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"完成"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-zh-rTW/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-zh-rTW/strings.xml
index 4a58180ba15f..d82ad7e43417 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-zh-rTW/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"選擇圖片"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"拍照"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"選擇個人資料相片"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"預設使用者圖示"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"完成"</string>
</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-zu/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-zu/strings.xml
index ad15f890cd05..8678332d8b54 100644
--- a/packages/SettingsLib/AvatarPicker/res/values-zu/strings.xml
+++ b/packages/SettingsLib/AvatarPicker/res/values-zu/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_image_choose_photo" msgid="5630717762469961028">"Khetha isithombe"</string>
<string name="user_image_take_photo" msgid="3147097821937166738">"Thatha isithombe"</string>
- <!-- no translation found for avatar_picker_title (7478146965334560463) -->
- <skip />
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Khetha isithombe sephrofayela"</string>
<string name="default_user_icon_description" msgid="6018582161341388812">"Isithonjana somsebenzisi sokuzenzakalelayo"</string>
- <!-- no translation found for done (3587741621903511576) -->
- <skip />
+ <string name="done" msgid="3587741621903511576">"Kwenziwe"</string>
</resources>
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 bc62e565599c..83858d9c9c54 100644
--- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
@@ -141,7 +141,7 @@ public class MainSwitchPreference extends TwoStatePreference
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- buttonView.post(() -> super.setChecked(isChecked));
+ super.setChecked(isChecked);
}
/**
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-hi/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-hi/strings.xml
index b5534b9c9246..6de84388bbe4 100644
--- a/packages/SettingsLib/RestrictedLockUtils/res/values-hi/strings.xml
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-hi/strings.xml
@@ -18,5 +18,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="enabled_by_admin" msgid="6630472777476410137">"एडमिन की ओर से चालू किया गया"</string>
- <string name="disabled_by_admin" msgid="4023569940620832713">"एडमिन ने यह सुविधा बंद की है"</string>
+ <string name="disabled_by_admin" msgid="4023569940620832713">"एडमिन ने यह सुविधा बंद की हुई है"</string>
</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-hu/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-hu/strings.xml
index 2ab8142d7610..ecfa2c794e28 100644
--- a/packages/SettingsLib/RestrictedLockUtils/res/values-hu/strings.xml
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-hu/strings.xml
@@ -18,5 +18,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="enabled_by_admin" msgid="6630472777476410137">"A rendszergazda bekapcsolta"</string>
- <string name="disabled_by_admin" msgid="4023569940620832713">"A rendszergazda kikapcsolta"</string>
+ <string name="disabled_by_admin" msgid="4023569940620832713">"A rendszergazda letiltotta"</string>
</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-af/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-af/strings.xml
new file mode 100644
index 000000000000..eb48b4ec2515
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-af/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Vou uit"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Vou in"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-am/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-am/strings.xml
new file mode 100644
index 000000000000..442819244b25
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-am/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"ዘርጋ"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"ሰብስብ"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-ar/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-ar/strings.xml
new file mode 100644
index 000000000000..e6d4c7b6cd19
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-ar/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"توسيع"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"تصغير"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-as/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-as/strings.xml
new file mode 100644
index 000000000000..2b5a5c98b98c
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-as/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"বিস্তাৰ কৰক"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"সংকোচন কৰক"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-az/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-az/strings.xml
new file mode 100644
index 000000000000..c7adee3095f2
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-az/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Genişləndirin"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Yığcamlaşdırın"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 000000000000..8b245a63cd91
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Proširi"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Skupi"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-be/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-be/strings.xml
new file mode 100644
index 000000000000..b468f819397a
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-be/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Разгарнуць"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Згарнуць"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-bg/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-bg/strings.xml
new file mode 100644
index 000000000000..b177fa76a7d9
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-bg/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Разгъване"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Свиване"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-bn/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-bn/strings.xml
new file mode 100644
index 000000000000..67bb59fab828
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-bn/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"বড় করুন"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"আড়াল করুন"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-bs/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-bs/strings.xml
new file mode 100644
index 000000000000..31afc8b07002
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-bs/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Proširi"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Suzi"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-ca/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-ca/strings.xml
new file mode 100644
index 000000000000..0f999c9a20e2
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-ca/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Desplega"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Replega"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-cs/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-cs/strings.xml
new file mode 100644
index 000000000000..144dba82e50b
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-cs/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Rozbalit"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Sbalit"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-da/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-da/strings.xml
new file mode 100644
index 000000000000..85497f143ef9
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-da/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Udvid"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Skjul"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-de/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-de/strings.xml
new file mode 100644
index 000000000000..9e47741a0945
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-de/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Maximieren"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Minimieren"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-el/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-el/strings.xml
new file mode 100644
index 000000000000..0b325b5ac4cd
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-el/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Ανάπτυξη"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Σύμπτυξη"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-en-rAU/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-en-rAU/strings.xml
new file mode 100644
index 000000000000..2539aa040a60
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-en-rAU/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Expand"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Collapse"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-en-rGB/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-en-rGB/strings.xml
new file mode 100644
index 000000000000..2539aa040a60
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-en-rGB/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Expand"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Collapse"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-en-rIN/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-en-rIN/strings.xml
new file mode 100644
index 000000000000..2539aa040a60
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-en-rIN/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Expand"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Collapse"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-es-rUS/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-es-rUS/strings.xml
new file mode 100644
index 000000000000..c976a2ed7757
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-es-rUS/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Expandir"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Contraer"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-es/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-es/strings.xml
new file mode 100644
index 000000000000..72ba9d11ecf1
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-es/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Mostrar"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Ocultar"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-et/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-et/strings.xml
new file mode 100644
index 000000000000..856360669354
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-et/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Laienda"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Ahenda"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-eu/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-eu/strings.xml
new file mode 100644
index 000000000000..d8c2c35aed31
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-eu/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Zabaldu"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Tolestu"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-fa/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-fa/strings.xml
new file mode 100644
index 000000000000..24087411b5b9
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-fa/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"ازهم بازکردن"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"جمع کردن"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-fi/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-fi/strings.xml
new file mode 100644
index 000000000000..0d226bf8bbe6
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-fi/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Laajenna"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Tiivistä"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-fr-rCA/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-fr-rCA/strings.xml
new file mode 100644
index 000000000000..fecfaa275e5e
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-fr-rCA/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Développer"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Réduire"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-fr/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-fr/strings.xml
new file mode 100644
index 000000000000..fecfaa275e5e
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-fr/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Développer"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Réduire"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-gl/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-gl/strings.xml
new file mode 100644
index 000000000000..7999aa1b4658
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-gl/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Despregar"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Contraer"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-gu/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-gu/strings.xml
new file mode 100644
index 000000000000..1457d34d3691
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-gu/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"મોટું કરો"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"નાનું કરો"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-hi/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-hi/strings.xml
new file mode 100644
index 000000000000..856379aaea84
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-hi/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"बड़ा करें"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"छोटा करें"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-hr/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-hr/strings.xml
new file mode 100644
index 000000000000..2d637f4a94c0
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-hr/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Proširi"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Sažmi"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-hu/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-hu/strings.xml
new file mode 100644
index 000000000000..42731635f35c
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-hu/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Kibontás"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Összecsukás"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-in/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-in/strings.xml
new file mode 100644
index 000000000000..97c1d602b94a
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-in/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Luaskan"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Ciutkan"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-is/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-is/strings.xml
new file mode 100644
index 000000000000..cc4d05bc869c
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-is/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Stækka"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Minnka"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-it/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-it/strings.xml
new file mode 100644
index 000000000000..8edcf2450b22
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-it/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Espandi"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Comprimi"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-iw/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-iw/strings.xml
new file mode 100644
index 000000000000..784bd8e34789
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-iw/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"הרחבה"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"כיווץ"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-ka/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-ka/strings.xml
new file mode 100644
index 000000000000..ec8f1ddaad7d
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-ka/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"გაფართოება"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"ჩაკეცვა"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-kk/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-kk/strings.xml
new file mode 100644
index 000000000000..329ccbbcddde
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-kk/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Жаю"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Жию"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-km/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-km/strings.xml
new file mode 100644
index 000000000000..5ca0269e8eb8
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-km/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"ពង្រីក"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"បង្រួម"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-ko/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-ko/strings.xml
new file mode 100644
index 000000000000..05d4921064cc
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-ko/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"펼치기"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"접기"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-ky/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-ky/strings.xml
new file mode 100644
index 000000000000..4f5b8dc3643d
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-ky/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Жайып көрсөтүү"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Жыйыштыруу"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-lo/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-lo/strings.xml
new file mode 100644
index 000000000000..d6ec47939596
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-lo/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"ຂະຫຍາຍ"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"ຫຍໍ້ລົງ"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-lt/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-lt/strings.xml
new file mode 100644
index 000000000000..54076c4fd3c2
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-lt/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Išskleisti"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Sutraukti"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-lv/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-lv/strings.xml
new file mode 100644
index 000000000000..2f87b0eb7abe
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-lv/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Izvērst"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Sakļaut"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-mk/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-mk/strings.xml
new file mode 100644
index 000000000000..b4f8fb901e26
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-mk/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Прошири"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Собери"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-ml/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-ml/strings.xml
new file mode 100644
index 000000000000..c68141e31d96
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-ml/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"വികസിപ്പിക്കുക"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"ചുരുക്കുക"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-mn/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-mn/strings.xml
new file mode 100644
index 000000000000..86b333d115d0
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-mn/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Дэлгэх"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Хураах"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-ms/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-ms/strings.xml
new file mode 100644
index 000000000000..1ffa5a083575
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-ms/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Kembangkan"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Kuncupkan"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-my/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-my/strings.xml
new file mode 100644
index 000000000000..6f79acc6e8ad
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-my/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"ပိုပြပါ"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"လျှော့ပြပါ"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-nb/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-nb/strings.xml
new file mode 100644
index 000000000000..359c9abe316e
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-nb/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Vis"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Skjul"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-ne/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-ne/strings.xml
new file mode 100644
index 000000000000..374fd31129c9
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-ne/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"एक्स्पान्ड गर्नुहोस्"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"कोल्याप्स गर्नुहोस्"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-nl/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-nl/strings.xml
new file mode 100644
index 000000000000..76a4f9996340
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-nl/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Uitvouwen"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Samenvouwen"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-or/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-or/strings.xml
new file mode 100644
index 000000000000..1e1e87025986
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-or/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"ବିସ୍ତାର କରନ୍ତୁ"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"ସଙ୍କୁଚିତ କରନ୍ତୁ"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-pl/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-pl/strings.xml
new file mode 100644
index 000000000000..da273b3bd137
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-pl/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Rozwiń"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Zwiń"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-pt-rBR/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-pt-rBR/strings.xml
new file mode 100644
index 000000000000..4e3d0e624d16
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-pt-rBR/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Abrir"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Fechar"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-pt/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-pt/strings.xml
new file mode 100644
index 000000000000..4e3d0e624d16
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-pt/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Abrir"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Fechar"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-ro/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-ro/strings.xml
new file mode 100644
index 000000000000..ec208843efa4
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-ro/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Extinde"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Restrânge"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-ru/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-ru/strings.xml
new file mode 100644
index 000000000000..ba6ab9687d41
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-ru/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Развернуть"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Свернуть"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-si/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-si/strings.xml
new file mode 100644
index 000000000000..9adb6466c9a4
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-si/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"දිග හරින්න"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"හකුළන්න"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-sk/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-sk/strings.xml
new file mode 100644
index 000000000000..574ee839a089
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-sk/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Rozbaliť"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Zbaliť"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-sq/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-sq/strings.xml
new file mode 100644
index 000000000000..e02ecbfada36
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-sq/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Zgjero"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Palos"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-sr/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-sr/strings.xml
new file mode 100644
index 000000000000..35f6aa3a635a
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-sr/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Прошири"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Скупи"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-sv/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-sv/strings.xml
new file mode 100644
index 000000000000..241683984626
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-sv/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Utöka"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Komprimera"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-sw/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-sw/strings.xml
new file mode 100644
index 000000000000..9a6075842a22
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-sw/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Panua"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Kunja"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-th/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-th/strings.xml
new file mode 100644
index 000000000000..d6dce9c076c9
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-th/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"ขยาย"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"ยุบ"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-tr/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-tr/strings.xml
new file mode 100644
index 000000000000..8c7dbcfd987a
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-tr/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Genişlet"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Daralt"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-uk/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-uk/strings.xml
new file mode 100644
index 000000000000..6da0ca81450e
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-uk/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Розгорнути"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Згорнути"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-vi/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-vi/strings.xml
new file mode 100644
index 000000000000..46f3351b7964
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-vi/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Mở rộng"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Thu gọn"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-zh-rCN/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-zh-rCN/strings.xml
new file mode 100644
index 000000000000..ea5f29b2413b
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-zh-rCN/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"展开"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"收起"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-zh-rHK/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-zh-rHK/strings.xml
new file mode 100644
index 000000000000..36203139566c
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-zh-rHK/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"展開"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"收合"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-zh-rTW/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-zh-rTW/strings.xml
new file mode 100644
index 000000000000..36203139566c
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-zh-rTW/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"展開"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"收合"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-zu/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-zu/strings.xml
new file mode 100644
index 000000000000..725d8bc27b2f
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-zu/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Nweba"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Goqa"</string>
+</resources>
diff --git a/packages/SettingsLib/Spa/build.gradle.kts b/packages/SettingsLib/Spa/build.gradle.kts
index 73d0beccd0ba..02e190417853 100644
--- a/packages/SettingsLib/Spa/build.gradle.kts
+++ b/packages/SettingsLib/Spa/build.gradle.kts
@@ -29,7 +29,7 @@ val androidTop: String = File(rootDir, "../../../../..").canonicalPath
allprojects {
extra["androidTop"] = androidTop
- extra["jetpackComposeVersion"] = "1.7.3"
+ extra["jetpackComposeVersion"] = "1.8.0-alpha06"
}
subprojects {
diff --git a/packages/SettingsLib/Spa/gradle/libs.versions.toml b/packages/SettingsLib/Spa/gradle/libs.versions.toml
index 272dc2d1958f..74811d3ae7a6 100644
--- a/packages/SettingsLib/Spa/gradle/libs.versions.toml
+++ b/packages/SettingsLib/Spa/gradle/libs.versions.toml
@@ -15,7 +15,7 @@
#
[versions]
-agp = "8.6.1"
+agp = "8.7.2"
compose-compiler = "1.5.11"
dexmaker-mockito = "2.28.3"
jvm = "17"
diff --git a/packages/SettingsLib/Spa/gradle/wrapper/gradle-8.10.2-bin.zip b/packages/SettingsLib/Spa/gradle/wrapper/gradle-8.11.1-bin.zip
index 45f0424639f2..f8c4ecb9df7a 100644
--- a/packages/SettingsLib/Spa/gradle/wrapper/gradle-8.10.2-bin.zip
+++ b/packages/SettingsLib/Spa/gradle/wrapper/gradle-8.11.1-bin.zip
Binary files differ
diff --git a/packages/SettingsLib/Spa/gradle/wrapper/gradle-wrapper.properties b/packages/SettingsLib/Spa/gradle/wrapper/gradle-wrapper.properties
index 1c25e97452eb..ca510ebb7271 100644
--- a/packages/SettingsLib/Spa/gradle/wrapper/gradle-wrapper.properties
+++ b/packages/SettingsLib/Spa/gradle/wrapper/gradle-wrapper.properties
@@ -16,6 +16,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=gradle-8.10.2-bin.zip
+distributionUrl=gradle-8.11.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/packages/SettingsLib/Spa/spa/build.gradle.kts b/packages/SettingsLib/Spa/spa/build.gradle.kts
index 914f06c1fef7..1f32ad6622a2 100644
--- a/packages/SettingsLib/Spa/spa/build.gradle.kts
+++ b/packages/SettingsLib/Spa/spa/build.gradle.kts
@@ -54,14 +54,14 @@ android {
dependencies {
api(project(":SettingsLibColor"))
api("androidx.appcompat:appcompat:1.7.0")
- api("androidx.compose.material3:material3:1.4.0-alpha01")
- api("androidx.compose.material:material-icons-extended:$jetpackComposeVersion")
+ api("androidx.compose.material3:material3:1.4.0-alpha04")
+ api("androidx.compose.material:material-icons-extended")
api("androidx.compose.runtime:runtime-livedata:$jetpackComposeVersion")
api("androidx.compose.ui:ui-tooling-preview:$jetpackComposeVersion")
api("androidx.graphics:graphics-shapes-android:1.0.1")
api("androidx.lifecycle:lifecycle-livedata-ktx")
api("androidx.lifecycle:lifecycle-runtime-compose")
- api("androidx.navigation:navigation-compose:2.8.1")
+ api("androidx.navigation:navigation-compose:2.9.0-alpha03")
api("com.github.PhilJay:MPAndroidChart:v3.1.0-alpha")
api("com.google.android.material:material:1.12.0")
debugApi("androidx.compose.ui:ui-tooling:$jetpackComposeVersion")
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 322598574f26..656c32d98377 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Hierdie foon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Hierdie tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Hierdie rekenaar (intern)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Dokluidspreker"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Eksterne toestel"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Gekoppel deur ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Gekoppel deur eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"TV-verstek"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI-uitset"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Interne luidsprekers"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Kan nie koppel nie. Skakel toestel af en weer aan"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Bedrade oudiotoestel"</string>
<string name="help_label" msgid="3528360748637781274">"Hulp en terugvoer"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 34f37b47fae6..3757d9064500 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"ይህ ስልክ"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ይህ ጡባዊ"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"ይህ ኮምፒውተር (ውስጣዊ)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"የመትከያ ድምፅ ማውጫ"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"የውጭ መሣሪያ"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI ኢኤአርሲ"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"በኤአርሲ በኩል ተገናኝቷል"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"በኢኤአርሲ በኩል ተገናኝቷል"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"የቲቪ ነባሪ"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"የHDMI ውጤት"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"ውስጣዊ ድምፅ ማውጫዎች"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"መገናኘት ላይ ችግር። መሳሪያውን ያጥፉት እና እንደገና ያብሩት"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ባለገመድ የኦዲዮ መሣሪያ"</string>
<string name="help_label" msgid="3528360748637781274">"እገዛ እና ግብረመልስ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 2ea1486ace31..838b9742c1c7 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"هذا الهاتف"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"هذا الجهاز اللوحي"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"هذا الكمبيوتر (داخلي)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"مكبّر صوت بقاعدة إرساء"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"جهاز خارجي"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"‏متّصل من خلال ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"‏متّصل من خلال eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"الجهاز التلقائي لإخراج صوت التلفزيون"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"‏إخراج الصوت من خلال HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"مكبّرات الصوت الداخلية"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"حدثت مشكلة أثناء الاتصال. يُرجى إيقاف الجهاز ثم إعادة تشغيله."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"جهاز سماعي سلكي"</string>
<string name="help_label" msgid="3528360748637781274">"المساعدة والملاحظات"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 432d443a5045..d00e7eeef8de 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"এই ফ’নটো"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"এই টেবলেটটো"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"এই কম্পিউটাৰ (অভ্যন্তৰীণ)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"ড’ক স্পীকাৰ"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"বাহ্যিক ডিভাইচ"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARCৰ জৰিয়তে সংযুক্ত"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARCৰ জৰিয়তে সংযুক্ত"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"টিভি ডিফ’ল্ট"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI আউটপুট"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"অভ্যন্তৰীণ স্পীকাৰ"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"সংযোগ হোৱাত সমস্যা হৈছে। ডিভাইচটো অফ কৰি পুনৰ অন কৰক"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"তাঁৰযুক্ত অডিঅ’ ডিভাইচ"</string>
<string name="help_label" msgid="3528360748637781274">"সহায় আৰু মতামত"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 330532ec48b0..3607a97dd41f 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Bu telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Bu planşet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Bu kompüter (daxili)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Dok dinamiki"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Xarici cihaz"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Chrome-da Tətbiqin İşləmə Müddəti vasitəsilə qoşulub"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC vasitəsilə qoşulub"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"TV defoltu"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI çıxışı"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Daxili dinamiklər"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Qoşulmaqla bağlı problem. Cihazı deaktiv edin, sonra yenidən aktiv edin"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Simli audio cihaz"</string>
<string name="help_label" msgid="3528360748637781274">"Yardım və rəy"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 4dfd25302708..94f4bd036b20 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ovaj telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ovaj tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Ovaj računar (interno)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Zvučnik bazne stanice"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Spoljni uređaj"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Povezano preko ARC-a"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Povezano preko eARC-a"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Podrazumevana vrednost za TV"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI izlaz"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Unutrašnji zvučnici"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem pri povezivanju. Isključite uređaj, pa ga ponovo uključite"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Žičani audio uređaj"</string>
<string name="help_label" msgid="3528360748637781274">"Pomoć i povratne informacije"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index de25460e4cbc..1903a3025935 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Гэты тэлефон"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Гэты планшэт"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Гэты камп’ютар (унутраны)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Дынамік док-станцыі"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Знешняя прылада"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Падключана праз ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Падключана праз eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Стандартны аўдыявыхад тэлевізара"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Выхад HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Унутраныя дынамікі"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Праблема з падключэннем. Выключыце і зноў уключыце прыладу"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Правадная аўдыяпрылада"</string>
<string name="help_label" msgid="3528360748637781274">"Даведка і водгукі"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 47ce37cfc900..da1561a20387 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Този телефон"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Този таблет"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Този компютър (вграден)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Високоговорител докинг станция"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Външно устройство"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Свързано посредством ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Свързано посредством eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Стандартното за телевизора"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI изход"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Вградени високоговорители"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"При свързването възникна проблем. Изключете устройството и го включете отново"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Аудиоустройство с кабел"</string>
<string name="help_label" msgid="3528360748637781274">"Помощ и отзиви"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 3b77cfdae6b5..90e7e6051fb1 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"এই ফোন"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"এই ট্যাবলেট"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"এই কম্পিউটার (ইন্টার্নাল)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"ডক স্পিকার"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"এক্সটার্নাল ডিভাইস"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC-এর মাধ্যমে কানেক্ট করা হয়েছে"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC-এর মাধ্যমে কানেক্ট করা হয়েছে"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"টিভির ডিফল্ট সেটিং"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI আউটপুট"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"ইন্টার্নাল স্পিকার"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"কানেক্ট করতে সমস্যা হচ্ছে। ডিভাইস বন্ধ করে আবার চালু করুন"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ওয়্যার অডিও ডিভাইস"</string>
<string name="help_label" msgid="3528360748637781274">"সহায়তা ও মতামত"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 65eb6817f631..2ac15c494af8 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ovaj telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ovaj tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Ovaj računar (interno)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Zvučnik priključne stanice"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Vanjski uređaj"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Povezano je putem ARC-a"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Povezano je putem eARC-a"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Zadano za TV"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI izlaz"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Interni zvučnici"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Došlo je do problema prilikom povezivanja. Isključite, pa ponovo uključite uređaj"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Žičani audio uređaj"</string>
<string name="help_label" msgid="3528360748637781274">"Pomoć i povratne informacije"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index a7c3fafd48ef..dcc614ff2b16 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Aquest telèfon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Aquesta tauleta"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Aquest ordinador (intern)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Base d\'altaveu"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositiu extern"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Connectat mitjançant ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Connectat mitjançant eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Televisor predeterminat"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Sortida HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Altaveus interns"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Hi ha hagut un problema amb la connexió. Apaga el dispositiu i torna\'l a encendre."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositiu d\'àudio amb cable"</string>
<string name="help_label" msgid="3528360748637781274">"Ajuda i suggeriments"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 832d320cd805..3d45732e4755 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Tento telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Tento tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Tento počítač (interní)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Reproduktor doku"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Externí zařízení"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Připojeno přes ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Připojeno přes eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Výchozí nastavení televize"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Výstup HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Interní reproduktory"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problém s připojením. Vypněte zařízení a znovu jej zapněte"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Kabelové audiozařízení"</string>
<string name="help_label" msgid="3528360748637781274">"Nápověda a zpětná vazba"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 708d5df4c6b3..7ed51e4f6d46 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Denne telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Denne tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Denne computer (intern)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Dockhøjttaler"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Ekstern enhed"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Forbundet via ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Forbundet via eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Standardindstillinger for fjernsyn"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI-udgang"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Interne højttalere"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Der kunne ikke oprettes forbindelse. Sluk og tænd enheden"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Lydenhed med ledning"</string>
<string name="help_label" msgid="3528360748637781274">"Hjælp og feedback"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 069201a63174..ee6234448483 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Dieses Smartphone"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Dieses Tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Dieser Computer (intern)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Dock-Lautsprecher"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Externes Gerät"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Per ARC verbunden"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Per eARC verbunden"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Standardeinstellung: Fernseher"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI-Ausgang"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Interne Lautsprecher"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Verbindung kann nicht hergestellt werden. Schalte das Gerät aus und wieder ein."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Netzbetriebenes Audiogerät"</string>
<string name="help_label" msgid="3528360748637781274">"Hilfe und Feedback"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 8577a9a8acdf..ec3949c46666 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Αυτό το τηλέφωνο"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Αυτό το tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Αυτός ο υπολογιστής (εσωτερ.)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Ηχείο βάσης σύνδεσης"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Εξωτερική συσκευή"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Συνδέθηκε μέσω ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Συνδέθηκε μέσω eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Προεπιλογή τηλεόρασης"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Έξοδος HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Εσωτερικά ηχεία"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Πρόβλημα κατά τη σύνδεση. Απενεργοποιήστε τη συσκευή και ενεργοποιήστε την ξανά"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Ενσύρματη συσκευή ήχου"</string>
<string name="help_label" msgid="3528360748637781274">"Βοήθεια και σχόλια"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index f9d2f082b06c..bb1efc47307d 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"This phone"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"This tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"This computer (internal)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Dock speaker"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"External device"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Connected via ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Connected via eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"TV default"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI output"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Internal speakers"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem connecting. Turn device off and back on"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired audio device"</string>
<string name="help_label" msgid="3528360748637781274">"Help and feedback"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 2cf98ef44c26..6d1cce60c73b 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"This phone"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"This tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"This computer (internal)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Dock speaker"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"External Device"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Connected via ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Connected via eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"TV default"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI output"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Internal speakers"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem connecting. Turn device off &amp; back on"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired audio device"</string>
<string name="help_label" msgid="3528360748637781274">"Help and feedback"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index f9d2f082b06c..bb1efc47307d 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"This phone"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"This tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"This computer (internal)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Dock speaker"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"External device"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Connected via ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Connected via eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"TV default"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI output"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Internal speakers"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem connecting. Turn device off and back on"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired audio device"</string>
<string name="help_label" msgid="3528360748637781274">"Help and feedback"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index f9d2f082b06c..bb1efc47307d 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"This phone"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"This tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"This computer (internal)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Dock speaker"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"External device"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Connected via ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Connected via eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"TV default"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI output"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Internal speakers"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem connecting. Turn device off and back on"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired audio device"</string>
<string name="help_label" msgid="3528360748637781274">"Help and feedback"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index a4834d887140..f5fd36895525 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Este teléfono"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Esta tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Esta computadora (interna)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Bocina de la estación de carga"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Se estableció conexión con un cable ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Se estableció conexión con un cable eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Configuración predeterminada de la TV"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Salida de HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Bocinas internas"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Error al establecer la conexión. Apaga el dispositivo y vuelve a encenderlo."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de audio con cable"</string>
<string name="help_label" msgid="3528360748637781274">"Ayuda y comentarios"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 1792fd13a5f5..b78d9fde9d8d 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Este teléfono"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Esta tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Este ordenador (interno)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Altavoz de la base"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Conectado mediante ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Conectado mediante eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Predeterminada de la televisión"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Salida HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Altavoces internos"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"No se ha podido conectar; reinicia el dispositivo"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de audio con cable"</string>
<string name="help_label" msgid="3528360748637781274">"Ayuda y comentarios"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 5411d0bd30b5..078e038ba489 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"See telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"See tahvelarvuti"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"See arvuti (sisemine)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Doki kõlar"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Väline seade"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Ühendatud ARC-i kaudu"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Ühendatud eARC-i kaudu"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Teleri vaikeväljund"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI-väljund"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Sisemised kõlarid"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Probleem ühendamisel. Lülitage seade välja ja uuesti sisse"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Juhtmega heliseade"</string>
<string name="help_label" msgid="3528360748637781274">"Abi ja tagasiside"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 090d99d3b771..cc60fd5775df 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Telefono hau"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Tableta hau"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Ordenagailu hau (barnekoa)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Oinarri bozgorailuduna"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Kanpoko gailua"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC bidez konektatuta"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC bidez konektatuta"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Telebistaren audio-erreproduzigailu lehenetsia"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI irteera"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Barneko bozgorailuak"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Arazo bat izan da konektatzean. Itzali gailua eta pitz ezazu berriro."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Audio-gailu kableduna"</string>
<string name="help_label" msgid="3528360748637781274">"Laguntza eta iritziak"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index c350175b788d..61b0b0f7825d 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"این تلفن"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"این رایانه لوحی"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"این رایانه (داخلی)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"بلندگوی پایه اتصال"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"دستگاه خارجی"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"‏متصل ازطریق ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"‏متصل ازطریق eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"پیش‌فرض تلویزیون"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"‏خروجی HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"بلندگوهای داخلی"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"مشکل در اتصال. دستگاه را خاموش و دوباره روشن کنید"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"دستگاه صوتی سیمی"</string>
<string name="help_label" msgid="3528360748637781274">"راهنما و بازخورد"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 18a84b5f4ead..683c3c7d59d3 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Tämä puhelin"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Tämä tabletti"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Tämä tietokone (sisäinen)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Telinekaiutin"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Ulkoinen laite"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Yhdistetty ARC:n kautta"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Yhdistetty eARC:n kautta"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"TV:n oletusasetus"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI-toisto"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Sisäiset kaiuttimet"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Yhteysvirhe. Sammuta laite ja käynnistä se uudelleen."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Langallinen äänilaite"</string>
<string name="help_label" msgid="3528360748637781274">"Ohjeet ja palaute"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 066244a06620..29eaee3f30cd 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ce téléphone"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Cette tablette"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Cet ordinateur (interne)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Haut-parleur du socle"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Appareil externe"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Connecté par ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Connecté par eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Sortie audio par défaut de la télévision"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Sortie HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Haut-parleurs internes"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problème de connexion. Éteignez et rallumez l\'appareil"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Appareil audio à câble"</string>
<string name="help_label" msgid="3528360748637781274">"Aide et commentaires"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 84c2f15b12e2..04a212c4797a 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ce téléphone"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Cette tablette"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Cet ordinateur (interne)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Haut-parleur station d\'accueil"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Appareil externe"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Connecté via ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Connecté via eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Sortie par défaut de la TV"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Sortie HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Haut-parleurs internes"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problème de connexion. Éteignez l\'appareil, puis rallumez-le"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Appareil audio filaire"</string>
<string name="help_label" msgid="3528360748637781274">"Aide et commentaires"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index d15b6e22e135..d5be2ce8789a 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Este teléfono"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Esta tableta"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Este ordenador (interno)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Altofalante da base"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Conectado mediante ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Conectado mediante eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Opción predeterminada da televisión"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Saída HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Altofalantes internos"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Produciuse un problema coa conexión. Apaga e acende o dispositivo."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de audio con cable"</string>
<string name="help_label" msgid="3528360748637781274">"Axuda e comentarios"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 5fd187f06c3c..54094cbf444a 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"આ ફોન"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"આ ટૅબ્લેટ"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"આ કમ્પ્યૂટર (આંતરિક)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"ડૉક સ્પીકર"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"બહારનું ડિવાઇસ"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC મારફતે કનેક્ટેડ"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC મારફતે કનેક્ટેડ"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"ડિવાઇસનું ડિફૉલ્ટ ઑડિયો આઉટપુટ, ટીવી"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI આઉટપુટ"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"આંતરિક સ્પીકર"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"કનેક્ટ કરવામાં સમસ્યા આવી રહી છે. ડિવાઇસને બંધ કરીને ફરી ચાલુ કરો"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"વાયરવાળો ઑડિયો ડિવાઇસ"</string>
<string name="help_label" msgid="3528360748637781274">"સહાય અને પ્રતિસાદ"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index fa0716e4ad22..1654b05a34a6 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"यह फ़ोन"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"यह टैबलेट"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"यह कंप्यूटर (इंटरनल)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"डॉक स्पीकर"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"बाहरी डिवाइस"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"एचडीएमआई eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC से कनेक्ट किए गए डिवाइस"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC से कनेक्ट किए गए डिवाइस"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"टीवी की डिफ़ॉल्ट सेटिंग"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"एचडीएमआई आउटपुट"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"इंटरनल स्पीकर"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"कनेक्ट करने में समस्या हो रही है. डिवाइस को बंद करके चालू करें"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"वायर वाला ऑडियो डिवाइस"</string>
<string name="help_label" msgid="3528360748637781274">"सहायता और सुझाव"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 8ad5c9d559d7..f7552b23e2e7 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ovaj telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ovaj tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Ovo računalo (interno)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Zvučnik priključne stanice"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Vanjski uređaj"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Povezano putem ARC-a"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Povezano putem eARC-a"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Zadano za TV"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI izlaz"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Unutarnji zvučnici"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem s povezivanjem. Isključite i ponovo uključite uređaj"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Žičani audiouređaj"</string>
<string name="help_label" msgid="3528360748637781274">"Pomoć i povratne informacije"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 18c6ea307651..2e5d6b522b10 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ez a telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ez a táblagép"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Ez a számítógép (belső)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Dokkhangszóró"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Külső eszköz"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Csatlakoztatva ARC-n keresztül"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Csatlakoztatva eARC-n keresztül"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Tévé alapértelmezett eszköze"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI-kimenet"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Belső hangszórók"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Sikertelen csatlakozás. Kapcsolja ki az eszközt, majd kapcsolja be újra."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Vezetékes audioeszköz"</string>
<string name="help_label" msgid="3528360748637781274">"Súgó és visszajelzés"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 593479a4c011..cc8891997d67 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Այս հեռախոսը"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Այս պլանշետը"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Այս համակարգիչը (ներքին)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Դոկ-կայանով բարձրախոս"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Արտաքին սարք"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Միացված է ARC-ի միջոցով"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Միացված է eARC-ի միջոցով"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Հեռուստացույցի կանխադրված կարգավորումներ"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI ելք"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Ներքին բարձրախոսներ"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Կապի խնդիր կա: Սարքն անջատեք և նորից միացրեք:"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Լարով աուդիո սարք"</string>
<string name="help_label" msgid="3528360748637781274">"Օգնություն և հետադարձ կապ"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 6522e22734b9..0f01dea73bdb 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ponsel ini"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Tablet ini"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Komputer ini (internal)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Speaker dok"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Perangkat Eksternal"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Terhubung melalui ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Terhubung melalui eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"TV sebagai default"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Output HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Speaker internal"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ada masalah saat menghubungkan. Nonaktifkan perangkat &amp; aktifkan kembali"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Perangkat audio berkabel"</string>
<string name="help_label" msgid="3528360748637781274">"Bantuan &amp; masukan"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 4a10fb3e94d3..c163cc25108e 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Þessi sími"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Þessi spjaldtölva"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Þessi tölva (innbyggður)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Hátalaradokka"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Ytra tæki"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Tengt með ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Tengt með eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Sjálfgefið í sjónvarpi"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI-úttak"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Innri hátalarar"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Vandamál í tengingu. Slökktu og kveiktu á tækinu"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Snúrutengt hljómtæki"</string>
<string name="help_label" msgid="3528360748637781274">"Hjálp og ábendingar"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 21f78ddbdb72..c7eb70c92769 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Questo smartphone"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Questo tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Questo computer (interno)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Base con altoparlante"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo esterno"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"eARC HDMI"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Connessione tramite ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Connessione tramite eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"TV predefinita"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Uscita HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Altoparlanti interni"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problema di connessione. Spegni e riaccendi il dispositivo"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo audio cablato"</string>
<string name="help_label" msgid="3528360748637781274">"Guida e feedback"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 3b28bd2745e3..c884362a2ef1 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"הטלפון הזה"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"הטאבלט הזה"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"המחשב הזה (פנימי)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"רמקול של אביזר העגינה"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"מכשיר חיצוני"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"‏חיבור דרך ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"‏חיבור דרך eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"ברירת המחדל של הטלוויזיה"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"‏פלט HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"רמקולים פנימיים"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"יש בעיה בחיבור. עליך לכבות את המכשיר ולהפעיל אותו מחדש"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"התקן אודיו חוטי"</string>
<string name="help_label" msgid="3528360748637781274">"עזרה ומשוב"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index a826810508e5..bd781be2b73d 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"このデバイス"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"このタブレット"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"このパソコン(内蔵)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"ホルダー スピーカー"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"外部デバイス"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC 経由で接続済み"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC 経由で接続済み"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"テレビのデフォルト"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI 出力"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"内蔵スピーカー"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"接続エラーです。デバイスを OFF にしてから ON に戻してください"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"有線オーディオ デバイス"</string>
<string name="help_label" msgid="3528360748637781274">"ヘルプとフィードバック"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index f321371a744e..89ef86e84217 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"ეს ტელეფონი"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ამ ტაბლეტზე"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"ეს კომპიუტერი (შიდა)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"სამაგრის დინამიკი"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"გარე მოწყობილობა"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"დაკავშირებულია ARC-ის მეშვეობით"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"დაკავშირებულია eARC-ის მეშვეობით"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"ტელევიზორის ნაგულისხმევი"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"გამომავალი HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"შიდა დინამიკები"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"დაკავშირებისას წარმოიქმნა პრობლემა. გამორთეთ და კვლავ ჩართეთ მოწყობილობა"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"სადენიანი აუდიო მოწყობილობა"</string>
<string name="help_label" msgid="3528360748637781274">"დახმარება და გამოხმაურება"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 85b86d4ef392..fe4f1cdd0c71 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Осы телефон"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Осы планшет"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Осы компьютер (ішкі)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Динамигі бар қондыру станциясы"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Сыртқы құрылғы"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC арқылы жалғанған."</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC арқылы жалғанған."</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Теледидардың әдепкі шығысы"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI шығыс интерфейсі"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Ішкі динамиктер"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Байланыс орнату қатесі шығуып жатыр. Құрылғыны өшіріп, қайта қосыңыз."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Сымды аудио құрылғысы"</string>
<string name="help_label" msgid="3528360748637781274">"Анықтама және пікір"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 12d35cf78685..36421c9495d7 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"ទូរសព្ទនេះ"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ថេប្លេតនេះ"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"កុំព្យូទ័រនេះ (ខាងក្នុង)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"ឧបាល័រជើងទម្រ"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"ឧបករណ៍ខាងក្រៅ"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"បានភ្ជាប់តាមរយៈ ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"បានភ្ជាប់តាមរយៈ eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"លំនាំដើម​ទូរទស្សន៍"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"ធាតុចេញ HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"ឧបករណ៍បំពងសំឡេងខាងក្នុង"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"មាន​បញ្ហា​ក្នុងការ​ភ្ជាប់។ បិទ រួច​បើក​ឧបករណ៍​វិញ"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ឧបករណ៍​សំឡេងប្រើខ្សែ"</string>
<string name="help_label" msgid="3528360748637781274">"ជំនួយ និងមតិកែលម្អ"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index d95846fba071..78f0a37b6201 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"ಈ ಫೋನ್"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ಈ ಟ್ಯಾಬ್ಲೆಟ್"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"ಈ ಕಂಪ್ಯೂಟರ್ (ಆಂತರಿಕ)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"ಡಾಕ್ ಸ್ಪೀಕರ್"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"ಬಾಹ್ಯ ಸಾಧನ"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC ಮೂಲಕ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC ಮೂಲಕ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"ಟಿವಿ ಡೀಫಾಲ್ಟ್"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI ಔಟ್‌‌ಪುಟ್"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"ಆಂತರಿಕ ಸ್ಪೀಕರ್‌ಗಳು"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"ಕನೆಕ್ಟ್ ಮಾಡುವಾಗ ಸಮಸ್ಯೆ ಎದುರಾಗಿದೆ ಸಾಧನವನ್ನು ಆಫ್ ಮಾಡಿ ಹಾಗೂ ನಂತರ ಪುನಃ ಆನ್ ಮಾಡಿ"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ವೈರ್ ಹೊಂದಿರುವ ಆಡಿಯೋ ಸಾಧನ"</string>
<string name="help_label" msgid="3528360748637781274">"ಸಹಾಯ ಮತ್ತು ಪ್ರತಿಕ್ರಿಯೆ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index f82a6a6ec442..9ce92221e928 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"이 휴대전화"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"이 태블릿"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"이 컴퓨터(내부)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"도크 스피커"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"외부 기기"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC를 통해 연결됨"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC를 통해 연결됨"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"TV 기본값"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI 출력"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"내부 스피커"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"연결 중에 문제가 발생했습니다. 기기를 껐다가 다시 켜 보세요."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"유선 오디오 기기"</string>
<string name="help_label" msgid="3528360748637781274">"고객센터"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index ff63c1922940..86eb12d9677c 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ушул телефон"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ушул планшет"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Бул компьютер (ички)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Док бекеттин динамиги"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Тышкы түзмөк"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC аркылуу туташты"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC аркылуу туташты"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Cыналгыдагы демейки түзмөк"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI аудио түзмөгү"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Ички динамиктер"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Туташууда маселе келип чыкты. Түзмөктү өчүрүп, кайра күйгүзүп көрүңүз"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Зымдуу аудио түзмөк"</string>
<string name="help_label" msgid="3528360748637781274">"Жардам/Пикир билдирүү"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 36d2ccf041db..2d800c587230 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"ໂທລະສັບນີ້"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ແທັບເລັດນີ້"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"ຄອມພິວເຕີນີ້ (ພາຍໃນ)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"ແທ່ນວາງລຳໂພງ"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"ອຸປະກອນພາຍນອກ"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ເຊື່ອມຕໍ່ຜ່ານ ARC ແລ້ວ"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"ເຊື່ອມຕໍ່ຜ່ານ eARC ແລ້ວ"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"ຄ່າເລີ່ມຕົ້ນສຳລັບໂທລະທັດ"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"ເອົ້າພຸດ HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"ລຳໂພງຂອງເຄື່ອງ"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"ເກີດບັນຫາໃນການເຊື່ອມຕໍ່. ປິດອຸປະກອນແລ້ວເປີດກັບຄືນມາໃໝ່"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ອຸປະກອນສຽງແບບມີສາຍ"</string>
<string name="help_label" msgid="3528360748637781274">"ຊ່ວຍເຫຼືອ ແລະ ຕິຊົມ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 5b20db3cd464..08bf30368cd5 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Šis telefonas"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Šis planšetinis kompiuteris"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Šis kompiuteris (vidinis)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Doko garsiakalbis"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Išorinis įrenginys"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI „eARC“"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Prisijungta per ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Prisijungta per „eARC“"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"TV numatytoji išvestis"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI išvestis"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Vidiniai garsiakalbiai"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Prisijungiant kilo problema. Išjunkite įrenginį ir vėl jį įjunkite"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Laidinis garso įrenginys"</string>
<string name="help_label" msgid="3528360748637781274">"Pagalba ir atsiliepimai"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 620318a08f18..e0ba42408894 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Šis tālrunis"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Šis planšetdators"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Šī datora iekšējais skaļrunis"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Doka skaļrunis"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Ārēja ierīce"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Savienojums izveidots, izmantojot ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Savienojums izveidots, izmantojot eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Noklusējuma iestatījums televizorā"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI izvade"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Iekšējie skaļruņi"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Radās problēma ar savienojuma izveidi. Izslēdziet un atkal ieslēdziet ierīci."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Vadu audioierīce"</string>
<string name="help_label" msgid="3528360748637781274">"Palīdzība un atsauksmes"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 0331ece3c4dc..86312aa9cd24 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -359,7 +359,7 @@
<string name="enable_terminal_summary" msgid="2481074834856064500">"Овозможи апликација на терминал што овозможува локален пристап кон школка."</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Програмерска околина на Linux"</string>
<string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Експериментално) Вклучете го Linux-терминалот на Android"</string>
- <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ако оневозможите, податоците за Linux-терминалот ќе се избришат"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ако го оневозможите, податоците за Linux-терминалот ќе се избришат"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Проверка со HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Постави однесување на проверка на HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Отстранување грешки"</string>
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Овој телефон"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Овој таблет"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Овој компјуер (внатрешен)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Док со звучник"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Надворешен уред"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Поврзано преку ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Поврзано преку eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Стандарден излез на телевизор"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Излез за HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Внатрешни звучници"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Проблем со поврзување. Исклучете го уредот и повторно вклучете го"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Жичен аудиоуред"</string>
<string name="help_label" msgid="3528360748637781274">"Помош и повратни информации"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index aaebe4cd6abf..04596d2436bf 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"ഈ ഫോൺ"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ഈ ടാബ്‌ലെറ്റ്"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"ഈ കമ്പ്യൂട്ടർ (ഇന്റേണൽ)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"ഡോക്ക് സ്‌പീക്കർ"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"ബാഹ്യ ഉപകരണം"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC വഴി കണക്റ്റ് ചെയ്തിരിക്കുന്നു"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC വഴി കണക്റ്റ് ചെയ്തിരിക്കുന്നു"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"ടിവി ഡിഫോൾട്ട്"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI ഔട്ട്പുട്ട്"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"ആന്തരിക സ്‌പീക്കറുകൾ"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"കണക്‌റ്റ് ചെയ്യുന്നതിൽ പ്രശ്‌നമുണ്ടായി. ഉപകരണം ഓഫാക്കി വീണ്ടും ഓണാക്കുക"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"വയർ മുഖേന ബന്ധിപ്പിച്ച ഓഡിയോ ഉപകരണം"</string>
<string name="help_label" msgid="3528360748637781274">"സഹായവും ഫീഡ്‌ബാക്കും"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index fb2b7291bb88..a4d5a8f4c2e7 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Энэ утас"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Энэ таблет"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Энэ компьютер (дотоод)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Суурилуулагчийн чанга яригч"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Гадаад төхөөрөмж"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC-р холбогдсон"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC-р холбогдсон"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"ТВ-ийн өгөгдмөл"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI гаралт"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Дотоод чанга яригч"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Холбогдоход асуудал гарлаа. Төхөөрөмжийг унтраагаад дахин асаана уу"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Утастай аудио төхөөрөмж"</string>
<string name="help_label" msgid="3528360748637781274">"Тусламж, санал хүсэлт"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 023a2e47e8f3..0ac6b84f7779 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"हा फोन"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"हा टॅबलेट"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"हा काँप्युटर (अंतर्गत)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"डॉक स्पीकर"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"बाह्य डिव्हाइस"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC द्वारे कनेक्ट केलेली"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC द्वारे कनेक्ट केलेली"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"टीव्ही डीफॉल्ट"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI आउटपुट"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"अंतर्गत स्पीकर"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"कनेक्‍ट करण्‍यात समस्‍या आली. डिव्हाइस बंद करा आणि नंतर सुरू करा"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"वायर असलेले ऑडिओ डिव्हाइस"</string>
<string name="help_label" msgid="3528360748637781274">"मदत आणि फीडबॅक"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 4212eb49f2cf..888eca2fde67 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Telefon ini"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Tablet ini"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Komputer ini (dalaman)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Pembesar suara dok"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Peranti Luar"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Disambungkan melalui ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Disambungkan melalui eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Tetapan lalai TV"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Output HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Pembesar suara dalaman"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Masalah penyambungan. Matikan &amp; hidupkan kembali peranti"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Peranti audio berwayar"</string>
<string name="help_label" msgid="3528360748637781274">"Bantuan &amp; maklum balas"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index df13e6c5f33e..0ce738150a2b 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"ဤဖုန်း"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ဤတက်ဘလက်"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"ဤကွန်ပျူတာ (စက်တွင်း)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"အထိုင် စပီကာ"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"ပြင်ပစက်"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC မှတစ်ဆင့် ချိတ်ဆက်ထားသည်"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC မှတစ်ဆင့် ချိတ်ဆက်ထားသည်"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"TV မူရင်း"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI အထွက်"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"စက်ရှိ စပီကာများ"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"ချိတ်ဆက်ရာတွင် ပြဿနာရှိပါသည်။ စက်ကိုပိတ်ပြီး ပြန်ဖွင့်ပါ"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ကြိုးတပ် အသံစက်ပစ္စည်း"</string>
<string name="help_label" msgid="3528360748637781274">"အကူအညီနှင့် အကြံပြုချက်"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 812666350505..72bce76dac6e 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Denne telefonen"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Dette nettbrettet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Denne datamaskinen (intern)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Dokkhøyttaler"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Ekstern enhet"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Tilkoblet via ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Tilkoblet via eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"TV-ens standardinnstilling"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI-utgang"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Interne høyttalere"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Tilkoblingsproblemer. Slå enheten av og på igjen"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Lydenhet med kabel"</string>
<string name="help_label" msgid="3528360748637781274">"Hjelp og tilbakemelding"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index a233622362b8..cab816fc3066 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"यो फोन"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"यो ट्याब्लेट"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"यो कम्प्युटर (आन्तरिक)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"डक स्पिकर"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"बाह्य डिभाइस"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC मार्फत कनेक्ट गरिएका"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC मार्फत कनेक्ट गरिएका"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"टिभीको डिफल्ट अडियो आउटपुट"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI आउटपुट"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"आन्तरिक स्पिकरहरू"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"जोड्ने क्रममा समस्या भयो। यन्त्रलाई निष्क्रिय पारेर फेरि अन गर्नुहोस्"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"तारयुक्त अडियो यन्त्र"</string>
<string name="help_label" msgid="3528360748637781274">"मद्दत र प्रतिक्रिया"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 551097d9e442..22b320db21ae 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Deze telefoon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Deze tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Deze computer (intern)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Dockspeaker"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Extern apparaat"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Verbonden via ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Verbonden via eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Tv-standaard"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI-uitvoer"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Interne speakers"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Probleem bij verbinding maken. Zet het apparaat uit en weer aan."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Bedraad audioapparaat"</string>
<string name="help_label" msgid="3528360748637781274">"Hulp en feedback"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 790acffe2b80..b8a73f7dc22b 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"ଏହି ଫୋନ"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ଏହି ଟାବଲେଟ"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"ଏହି କମ୍ପ୍ୟୁଟର (ଇଣ୍ଟର୍ନଲ)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"ଡକ ସ୍ପିକର"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"ଏକ୍ସଟର୍ନଲ ଡିଭାଇସ"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC ମାଧ୍ୟମରେ କନେକ୍ଟ କରାଯାଇଛି"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC ମାଧ୍ୟମରେ କନେକ୍ଟ କରାଯାଇଛି"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"ଟିଭିର ଡିଫଲ୍ଟ ଅଡିଓ ଆଉଟପୁଟ"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI ଆଉଟପୁଟ"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"ଇଣ୍ଟର୍ନଲ ସ୍ପିକର"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"ସଂଯୋଗ କରିବାରେ ସମସ୍ୟା ହେଉଛି। ଡିଭାଇସ୍ ବନ୍ଦ କରି ପୁଣି ଚାଲୁ କରନ୍ତୁ"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ତାରଯୁକ୍ତ ଅଡିଓ ଡିଭାଇସ୍"</string>
<string name="help_label" msgid="3528360748637781274">"ସାହାଯ୍ୟ ଓ ମତାମତ"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index c20e0d88ee3f..77eb146d5d52 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"ਇਹ ਫ਼ੋਨ"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ਇਹ ਟੈਬਲੈੱਟ"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"ਇਸ ਕੰਪਿਊਟਰ \'ਤੇ (ਅੰਦਰੂਨੀ)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"ਡੌਕ ਸਪੀਕਰ"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"ਬਾਹਰੀ ਡੀਵਾਈਸ"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC ਰਾਹੀਂ ਕਨੈਕਟ ਕੀਤੇ ਗਏ ਡੀਵਾਈਸ"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC ਰਾਹੀਂ ਕਨੈਕਟ ਕੀਤੇ ਗਏ ਡੀਵਾਈਸ"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"ਟੀਵੀ ਦਾ ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਆਊਟਪੁੱਟ"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI ਆਊਟਪੁੱਟ"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"ਅੰਦਰੂਨੀ ਸਪੀਕਰ"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"ਕਨੈਕਟ ਕਰਨ ਵਿੱਚ ਸਮੱਸਿਆ ਆਈ। ਡੀਵਾਈਸ ਨੂੰ ਬੰਦ ਕਰਕੇ ਵਾਪਸ ਚਾਲੂ ਕਰੋ"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ਤਾਰ ਵਾਲਾ ਆਡੀਓ ਡੀਵਾਈਸ"</string>
<string name="help_label" msgid="3528360748637781274">"ਮਦਦ ਅਤੇ ਵਿਚਾਰ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index f6ab8a7c19a4..e5cca9c375f8 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ten telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ten tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Ten komputer (wewnętrzny)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Głośnik ze stacją dokującą"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Urządzenie zewnętrzne"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Połączono przez ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Połączono przez eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Ustawienie domyślne telewizora"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Wyjście HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Głośniki wewnętrzne"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem z połączeniem. Wyłącz i ponownie włącz urządzenie"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Przewodowe urządzenie audio"</string>
<string name="help_label" msgid="3528360748637781274">"Pomoc i opinie"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index dedc65c1369f..a879f17bcb18 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Este telefone"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Este tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Este computador (interno)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Alto-falante da base"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Conectado via ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Conectado via eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Padrão da TV"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Saída HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Alto-falantes internos"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ocorreu um problema na conexão. Desligue o dispositivo e ligue-o novamente"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de áudio com fio"</string>
<string name="help_label" msgid="3528360748637781274">"Ajuda e feedback"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index f1ac88bdda40..3ae270ec0041 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Este telemóvel"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Este tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Este computador (interno)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Altifalante estação carregamento"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Ligado através de ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Ligado através de eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Predefinição da TV"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Saída HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Altifalantes internos"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problema ao ligar. Desligue e volte a ligar o dispositivo."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de áudio com fios"</string>
<string name="help_label" msgid="3528360748637781274">"Ajuda e feedback"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index dedc65c1369f..a879f17bcb18 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Este telefone"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Este tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Este computador (interno)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Alto-falante da base"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Conectado via ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Conectado via eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Padrão da TV"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Saída HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Alto-falantes internos"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ocorreu um problema na conexão. Desligue o dispositivo e ligue-o novamente"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de áudio com fio"</string>
<string name="help_label" msgid="3528360748637781274">"Ajuda e feedback"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index cafb7881a32a..1fe3651bb497 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Acest telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Această tabletă"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Acest computer (intern)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Difuzorul dispozitivului de andocare"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispozitiv extern"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Conectat prin ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Conectat prin eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Prestabilit pentru televizor"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Ieșire HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Difuzoare interne"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problemă la conectare. Oprește și repornește dispozitivul."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispozitiv audio cu fir"</string>
<string name="help_label" msgid="3528360748637781274">"Ajutor și feedback"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 951f3a0dd146..f8389ba3b6c5 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Этот смартфон"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Этот планшет"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Встроенное"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Колонка с док-станцией"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Внешнее устройство"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Подключено через ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Подключено через eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Стандартный выход на телевизоре"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Выход HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Внутренние динамики"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ошибка подключения. Выключите и снова включите устройство."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Проводное аудиоустройство"</string>
<string name="help_label" msgid="3528360748637781274">"Справка/отзыв"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 8427064b99ef..07ce339c86a6 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"මෙම දුරකථනය"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"මෙම ටැබ්ලටය"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"මෙම පරිගණකය (අභ්‍යන්තර)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"ඩොක් ස්පීකරය"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"බාහිර උපාංගය"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC හරහා සම්බන්ධ කර ඇත"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC හරහා සම්බන්ධ කර ඇත"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"රූපවාහිනී පෙරනිමිය"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI ප්‍රතිදානය"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"අභ්‍යන්තර ස්පීකර්"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"සම්බන්ධ කිරීමේ ගැටලුවකි උපාංගය ක්‍රියාවිරහිත කර &amp; ආපසු ක්‍රියාත්මක කරන්න"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"රැහැන්ගත කළ ඕඩියෝ උපාංගය"</string>
<string name="help_label" msgid="3528360748637781274">"උදවු &amp; ප්‍රතිපෝෂණ"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index aca07e5a32c3..2a244970377a 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Tento telefón"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Tento tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Tento počítač (interný)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Reproduktor doku"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Externé zariadenie"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Pripojené prostredníctvom rozhrania ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Pripojené prostredníctvom rozhrania eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Predvolené nastavenie televízora"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Výstup HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Interné reproduktory"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Pri pripájaní sa vyskytol problém. Zariadenie vypnite a znova zapnite."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Audio zariadenie s káblom"</string>
<string name="help_label" msgid="3528360748637781274">"Pomocník a spätná väzba"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 00d93a65d2f1..81f30634d1b1 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ta telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ta tablični računalnik"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Ta računalnik (notranji)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Zvočnik nosilca"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Zunanja naprava"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Povezano prek zvočnega kanala ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Povezano prek zvočnega kanala eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Privzeti izhod televizorja"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Izhod HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Notranji zvočniki"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Težava pri povezovanju. Napravo izklopite in znova vklopite."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Žična zvočna naprava"</string>
<string name="help_label" msgid="3528360748637781274">"Pomoč in povratne informacije"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index c907e22c7784..504d821a95d9 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ky telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ky tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Ky kompjuter (i brendshëm)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Altoparlanti i stacionit"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Pajisja e jashtme"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Lidhur përmes ARC-së"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Lidhur përmes eARC-së"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Parazgjedhja e televizorit"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Dalja HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Altoparlantët e brendshëm"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem me lidhjen. Fike dhe ndize përsëri pajisjen"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Pajisja audio me tel"</string>
<string name="help_label" msgid="3528360748637781274">"Ndihma dhe komentet"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 65000e468fea..b2dc5fe09e31 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Овај телефон"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Овај таблет"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Овај рачунар (интерно)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Звучник базне станице"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Спољни уређај"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Повезано преко ARC-а"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Повезано преко eARC-а"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Подразумевана вредност за ТВ"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI излаз"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Унутрашњи звучници"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Проблем при повезивању. Искључите уређај, па га поново укључите"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Жичани аудио уређај"</string>
<string name="help_label" msgid="3528360748637781274">"Помоћ и повратне информације"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 12c17290bf15..aaa90e0737f0 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Den här telefonen"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Den här surfplattan"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Den här datorn (intern)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Dockningsstationens högtalare"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Extern enhet"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Ansluten via ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Ansluten via eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Standardutgång för tv:n"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI-utgång"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Interna högtalare"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Det gick inte att ansluta. Stäng av enheten och slå på den igen"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Ljudenhet med kabelanslutning"</string>
<string name="help_label" msgid="3528360748637781274">"Hjälp och feedback"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 1bf5677668ca..99d2949ea9d0 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Simu hii"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Kishikwambi hiki"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Kompyuta hii (spika ya ndani)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Spika ya kituo"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Kifaa cha Nje"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Imeunganishwa kupitia ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Imeunganishwa kupitia eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Mipangilio Chaguomsingi ya TV"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Kutoa sauti kupitia HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Spika za ndani"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Kuna tatizo la kuunganisha kwenye Intaneti. Zima kisha uwashe kifaa"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Kifaa cha sauti kinachotumia waya"</string>
<string name="help_label" msgid="3528360748637781274">"Usaidizi na maoni"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 8ee8fa22c61f..fa2819c286cf 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"இந்த மொபைல்"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"இந்த டேப்லெட்"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"இந்தக் கம்ப்யூட்டர் (அகம்)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"டாக் ஸ்பீக்கர்"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"வெளிப்புறச் சாதனம்"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC மூலம் இணைக்கப்பட்டுள்ளவை"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC மூலம் இணைக்கப்பட்டுள்ளவை"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"டிவி இயல்புநிலை"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI அவுட்புட்"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"உட்புற ஸ்பீக்கர்கள்"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"இணைப்பதில் சிக்கல். சாதனத்தை ஆஃப் செய்து மீண்டும் ஆன் செய்யவும்"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"வயருடன்கூடிய ஆடியோ சாதனம்"</string>
<string name="help_label" msgid="3528360748637781274">"உதவியும் கருத்தும்"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 46350d5bf30c..84fb65bfb561 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"ఈ ఫోన్"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ఈ టాబ్లెట్"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"ఈ కంప్యూటర్ (ఇంటర్నల్)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"డాక్ స్పీకర్"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"ఎక్స్‌టర్నల్ పరికరం"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC ద్వారా కనెక్ట్ చేయబడింది"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC ద్వారా కనెక్ట్ చేయబడింది"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"టీవీ ఆటోమేటిక్ సెట్టింగ్"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI అవుట్‌పుట్"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"అంతర్గత స్పీకర్‌లు"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"కనెక్ట్ చేయడంలో సమస్య ఉంది. పరికరాన్ని ఆఫ్ చేసి, ఆపై తిరిగి ఆన్ చేయండి"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"వైర్ గల ఆడియో పరికరం"</string>
<string name="help_label" msgid="3528360748637781274">"సహాయం &amp; ఫీడ్‌బ్యాక్"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 460782af8457..22a2a5bbdec4 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -304,7 +304,7 @@
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"เลือกเวอร์ชันของบลูทูธ AVRCP"</string>
<string name="bluetooth_select_map_version_string" msgid="526308145174175327">"เวอร์ชันของบลูทูธ MAP"</string>
<string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"เลือกเวอร์ชันของบลูทูธ MAP"</string>
- <string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"ตัวแปลงสัญญาณเสียงบลูทูธ"</string>
+ <string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"ตัวแปลงรหัสเสียงบลูทูธ"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"ทริกเกอร์การเลือกตัวแปลงรหัส\nเสียงบลูทูธ"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"อัตราตัวอย่างเสียงบลูทูธ"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="5876305103137067798">"ทริกเกอร์การเลือกตัวแปลงรหัส\nเสียงบลูทูธ: อัตราตัวอย่าง"</string>
@@ -313,7 +313,7 @@
<string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4898693684282596143">"ทริกเกอร์การเลือกตัวแปลงรหัส\nเสียงบลูทูธ: บิตต่อตัวอย่าง"</string>
<string name="bluetooth_select_a2dp_codec_channel_mode" msgid="364277285688014427">"โหมดช่องสัญญาณเสียงบลูทูธ"</string>
<string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="2076949781460359589">"ทริกเกอร์การเลือกตัวแปลงรหัส\nเสียงบลูทูธ: โหมดช่องสัญญาณ"</string>
- <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3233402355917446304">"ตัวแปลงสัญญาณเสียงบลูทูธที่ใช้ LDAC: คุณภาพการเล่น"</string>
+ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3233402355917446304">"ตัวแปลงรหัสเสียงบลูทูธที่ใช้ LDAC: คุณภาพการเล่น"</string>
<string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"ทริกเกอร์การเลือกตัวแปลงรหัส LDAC\nเสียงบลูทูธ: คุณภาพการเล่น"</string>
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"สตรีมมิง: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="select_private_dns_configuration_title" msgid="7887550926056143018">"DNS ส่วนตัว"</string>
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"โทรศัพท์เครื่องนี้"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"แท็บเล็ตเครื่องนี้"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"คอมพิวเตอร์เครื่องนี้ (ภายใน)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"แท่นชาร์จที่มีลำโพง"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"อุปกรณ์ภายนอก"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"เชื่อมต่อผ่าน ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"เชื่อมต่อผ่าน eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"ค่าเริ่มต้นของทีวี"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"เอาต์พุต HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"ลำโพงของเครื่อง"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"เกิดปัญหาในการเชื่อมต่อ ปิดอุปกรณ์แล้วเปิดใหม่อีกครั้ง"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"อุปกรณ์เสียงแบบมีสาย"</string>
<string name="help_label" msgid="3528360748637781274">"ความช่วยเหลือและความคิดเห็น"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 986b7771d9f5..2d094e3f142c 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ang teleponong ito"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ang tablet na ito"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Sa computer na ito (internal)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Speaker ng dock"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"External na Device"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Nakakonekta sa pamamagitan ng ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Nakakonekta sa pamamagitan ng eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Default ng TV"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI output"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Mga internal speaker"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Nagkaproblema sa pagkonekta. I-off at pagkatapos ay i-on ang device"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired na audio device"</string>
<string name="help_label" msgid="3528360748637781274">"Tulong at feedback"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index df47dacc7d7b..5f15fc2d001d 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Bu telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Bu tablet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Bu bilgisayar (dahili)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Yuva hoparlörü"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Harici Cihaz"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC ile bağlandı"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC ile bağlandı"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"TV varsayılanı"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI çıkışı"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Dahili hoparlörler"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Bağlanırken sorun oluştu. Cihazı kapatıp tekrar açın"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Kablolu ses cihazı"</string>
<string name="help_label" msgid="3528360748637781274">"Yardım ve geri bildirim"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 3ba99a2f443e..0385ca0e90c2 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Цей телефон"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Цей планшет"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Цей комп’ютер (внутрішній)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Динамік док-станції"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Зовнішній пристрій"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Підключено через ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Підключено через eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Стандартний вихід телевізора"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Вихід HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Внутрішні динаміки"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Не вдається підключитися. Перезавантажте пристрій."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Дротовий аудіопристрій"</string>
<string name="help_label" msgid="3528360748637781274">"Довідка й відгуки"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index e5e29faae8f5..85472d67ea49 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"یہ فون"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"یہ ٹیبلیٹ"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"یہ کمپیوٹر (داخلی)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"ڈاک اسپیکر"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"بیرونی آلہ"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"‏ARC کے ذریعے منسلک ہے"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"‏eARC کے ذریعے منسلک ہے"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"‏TV ڈیفالٹ"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"‏HDMI آؤٹ پٹ"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"اندرونی اسپیکرز"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"منسلک کرنے میں مسئلہ پیش آ گیا۔ آلہ کو آف اور بیک آن کریں"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"وائرڈ آڈیو آلہ"</string>
<string name="help_label" msgid="3528360748637781274">"مدد اور تاثرات"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 2417d5556bee..d55608277de5 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Shu telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Shu planshet"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Bu kompyuter (ichki)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Dok-stansiyali karnay"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Tashqi qurilma"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC orqali ulangan"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC orqali ulangan"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Televizorda birlamchi"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI chiqishi"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Ichki karnaylar"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ulanishda muammo yuz berdi. Qurilmani oʻchiring va yoqing"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Simli audio qurilma"</string>
<string name="help_label" msgid="3528360748637781274">"Yordam/fikr-mulohaza"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 0239a3f2c39d..d70019c0d7f7 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Điện thoại này"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Máy tính bảng này"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Máy tính này (nội bộ)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Loa có gắn đế"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Thiết bị bên ngoài"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Đã kết nối qua ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Đã kết nối qua eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"Chế độ mặc định của TV"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Đầu ra HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Các loa trong"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Sự cố kết nối. Hãy tắt thiết bị rồi bật lại"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Thiết bị âm thanh có dây"</string>
<string name="help_label" msgid="3528360748637781274">"Trợ giúp và phản hồi"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 22bfda4fe6fc..1c679331c16a 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -359,7 +359,7 @@
<string name="enable_terminal_summary" msgid="2481074834856064500">"启用终端应用,以便在本地访问 Shell"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux 开发环境"</string>
<string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(实验性)在 Android 上运行 Linux 终端"</string>
- <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"如果您停用它,Linux 终端数据会被清除"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"停用后,Linux 终端数据会被清除"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP 检查"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"设置 HDCP 检查行为"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"调试"</string>
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"这部手机"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"这部平板电脑"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"此计算机(内部)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"基座音箱"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"外部设备"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"已通过 ARC 连接"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"已通过 eARC 连接"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"电视默认设置"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI 输出"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"内置扬声器"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"连接时遇到问题。请关闭并重新开启设备"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"有线音频设备"</string>
<string name="help_label" msgid="3528360748637781274">"帮助和反馈"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 594273a327ce..2a8c1ee5658a 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"此手機"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"此平板電腦"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"此電腦 (內置)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"插座喇叭"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"外部裝置"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"已透過 ARC 連接"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"已透過 eARC 連接"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"電視預設的音訊輸出"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI 輸出"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"內置喇叭"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"無法連接,請關閉裝置然後重新開機"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"有線音響裝置"</string>
<string name="help_label" msgid="3528360748637781274">"說明與意見反映"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 483dbf30b31c..beb30df2d8b6 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"這支手機"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"這台平板電腦"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"這部電腦 (內部)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"座架喇叭"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"外部裝置"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"透過 ARC 連線"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"透過 eARC 連線"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"電視預設的音訊輸出裝置"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI 輸出裝置"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"內建揚聲器"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"無法連線,請關閉裝置後再重新開啟"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"有線音訊裝置"</string>
<string name="help_label" msgid="3528360748637781274">"說明與意見回饋"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 2bb3f225565e..1031bb7ac322 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -586,7 +586,7 @@
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Le foni"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Le thebhulethi"</string>
<string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Le khompyutha (ngaphakathi)"</string>
- <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
+ <!-- no translation found for media_transfer_this_device_name_tv (8508713779441163887) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Isipikha sentuba"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Idivayisi Yangaphandle"</string>
@@ -607,9 +607,10 @@
<string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"I-HDMI eARC"</string>
<string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Ixhunywe nge-ARC"</string>
<string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Ixhunywe nge-eARC"</string>
- <string name="tv_media_transfer_default" msgid="5403053145185843843">"I-TV ezenzakalelayo"</string>
- <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"umphumela we-HDMI"</string>
- <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Izipikha zangaphakathi"</string>
+ <!-- no translation found for tv_media_transfer_internal_speakers (4662765121700213785) -->
+ <skip />
+ <!-- no translation found for tv_media_transfer_hdmi_title (6715658310934507444) -->
+ <skip />
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Inkinga yokuxhumeka. Vala idivayisi futhi uphinde uyivule"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Idivayisi yomsindo enentambo"</string>
<string name="help_label" msgid="3528360748637781274">"Usizo nempendulo"</string>
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
index 8e7180c4dc8d..935ea2549d49 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
@@ -119,7 +119,8 @@ public class SystemSettings {
Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR,
Settings.System.NOTIFICATION_COOLDOWN_ENABLED,
Settings.System.NOTIFICATION_COOLDOWN_ALL,
- Settings.System.NOTIFICATION_COOLDOWN_VIBRATE_UNLOCKED
+ Settings.System.NOTIFICATION_COOLDOWN_VIBRATE_UNLOCKED,
+ Settings.System.PREFERRED_REGION
));
if (Flags.backUpSmoothDisplayAndForcePeakRefreshRate()) {
settings.add(Settings.System.PEAK_REFRESH_RATE);
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
index cfc7743f0a8d..9938139293fd 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
@@ -265,5 +265,6 @@ public class SystemSettingsValidators {
VALIDATORS.put(System.NOTIFICATION_COOLDOWN_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(System.NOTIFICATION_COOLDOWN_ALL, BOOLEAN_VALIDATOR);
VALIDATORS.put(System.NOTIFICATION_COOLDOWN_VIBRATE_UNLOCKED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.PREFERRED_REGION, ANY_STRING_VALIDATOR);
}
}
diff --git a/packages/StatementService/src/com/android/statementservice/StatementServiceApplication.kt b/packages/StatementService/src/com/android/statementservice/StatementServiceApplication.kt
index 021a5143c09a..6af8004c4015 100644
--- a/packages/StatementService/src/com/android/statementservice/StatementServiceApplication.kt
+++ b/packages/StatementService/src/com/android/statementservice/StatementServiceApplication.kt
@@ -30,6 +30,7 @@ class StatementServiceApplication : Application() {
// WorkManager can only schedule when the user data directories are unencrypted (after
// the user has entered their lock password.
DomainVerificationUtils.schedulePeriodicCheckUnlocked(WorkManager.getInstance(this))
+ DomainVerificationUtils.schedulePeriodicUpdateUnlocked(WorkManager.getInstance(this))
}
}
}
diff --git a/packages/StatementService/src/com/android/statementservice/domain/DomainVerificationUtils.kt b/packages/StatementService/src/com/android/statementservice/domain/DomainVerificationUtils.kt
index 694424822b30..157a800d0e09 100644
--- a/packages/StatementService/src/com/android/statementservice/domain/DomainVerificationUtils.kt
+++ b/packages/StatementService/src/com/android/statementservice/domain/DomainVerificationUtils.kt
@@ -22,6 +22,7 @@ import androidx.work.NetworkType
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import com.android.statementservice.domain.worker.RetryRequestWorker
+import com.android.statementservice.domain.worker.UpdateVerifiedDomainsWorker
import java.time.Duration
object DomainVerificationUtils {
@@ -30,6 +31,10 @@ object DomainVerificationUtils {
private const val PERIODIC_SHORT_HOURS = 24L
private const val PERIODIC_LONG_ID = "retry_long"
private const val PERIODIC_LONG_HOURS = 72L
+ private const val PERIODIC_UPDATE_ID = "update"
+ private const val PERIODIC_UPDATE_HOURS = 720L
+
+ private const val UPDATE_WORKER_ENABLED = false
/**
* In a majority of cases, the initial requests will be enough to verify domains, since they
@@ -74,4 +79,38 @@ object DomainVerificationUtils {
}
}
}
+
+ /**
+ * Schedule a periodic worker to check for any updates to assetlink.json files for domains that
+ * have already been verified.
+ *
+ * Due to the potential for this worker to generate enough traffic across all android devices
+ * to overwhelm websites, this method is hardcoded to be disabled by default. It is highly
+ * recommended to not enable this worker and instead implement a custom worker that pulls
+ * updates from a caching service instead of directly from websites.
+ */
+ fun schedulePeriodicUpdateUnlocked(workManager: WorkManager) {
+ if (UPDATE_WORKER_ENABLED) {
+ workManager.apply {
+ PeriodicWorkRequestBuilder<UpdateVerifiedDomainsWorker>(
+ Duration.ofDays(
+ PERIODIC_UPDATE_HOURS
+ )
+ )
+ .setConstraints(
+ Constraints.Builder()
+ .setRequiredNetworkType(NetworkType.CONNECTED)
+ .setRequiresDeviceIdle(true)
+ .build()
+ )
+ .build()
+ .let {
+ enqueueUniquePeriodicWork(
+ PERIODIC_UPDATE_ID,
+ ExistingPeriodicWorkPolicy.KEEP, it
+ )
+ }
+ }
+ }
+ }
}
diff --git a/packages/StatementService/src/com/android/statementservice/domain/DomainVerifier.kt b/packages/StatementService/src/com/android/statementservice/domain/DomainVerifier.kt
index 6914347544de..c7f6c184fd22 100644
--- a/packages/StatementService/src/com/android/statementservice/domain/DomainVerifier.kt
+++ b/packages/StatementService/src/com/android/statementservice/domain/DomainVerifier.kt
@@ -64,7 +64,8 @@ class DomainVerifier private constructor(
private val targetAssetCache = AssetLruCache()
- fun collectHosts(packageNames: Iterable<String>): Iterable<Triple<UUID, String, String>> {
+ fun collectHosts(packageNames: Iterable<String>, statusFilter: (Int) -> Boolean):
+ Iterable<Triple<UUID, String, Iterable<String>>> {
return packageNames.mapNotNull { packageName ->
val (domainSetId, _, hostToStateMap) = try {
manager.getDomainVerificationInfo(packageName)
@@ -74,14 +75,13 @@ class DomainVerifier private constructor(
} ?: return@mapNotNull null
val hostsToRetry = hostToStateMap
- .filterValues(VerifyStatus::shouldRetry)
+ .filterValues(statusFilter)
.takeIf { it.isNotEmpty() }
?.map { it.key }
?: return@mapNotNull null
- hostsToRetry.map { Triple(domainSetId, packageName, it) }
+ Triple(domainSetId, packageName, hostsToRetry)
}
- .flatten()
}
suspend fun verifyHost(
diff --git a/packages/StatementService/src/com/android/statementservice/domain/VerifyStatus.kt b/packages/StatementService/src/com/android/statementservice/domain/VerifyStatus.kt
index 2193ec542238..c771da3ab563 100644
--- a/packages/StatementService/src/com/android/statementservice/domain/VerifyStatus.kt
+++ b/packages/StatementService/src/com/android/statementservice/domain/VerifyStatus.kt
@@ -49,7 +49,7 @@ enum class VerifyStatus(val value: Int) {
return false
}
- val status = values().find { it.value == state } ?: return true
+ val status = entries.find { it.value == state } ?: return true
return when (status) {
SUCCESS,
FAILURE_LEGACY_UNSUPPORTED_WILDCARD,
@@ -62,5 +62,20 @@ enum class VerifyStatus(val value: Int) {
FAILURE_REDIRECT -> true
}
}
+
+ fun canUpdate(state: Int): Boolean {
+ if (state == DomainVerificationInfo.STATE_UNMODIFIABLE) {
+ return false
+ }
+
+ val status = entries.find { it.value == state }
+ return when (status) {
+ SUCCESS,
+ FAILURE_LEGACY_UNSUPPORTED_WILDCARD,
+ FAILURE_REJECTED_BY_SERVER,
+ UNKNOWN -> true
+ else -> false
+ }
+ }
}
}
diff --git a/packages/StatementService/src/com/android/statementservice/domain/worker/PeriodicUpdateWorker.kt b/packages/StatementService/src/com/android/statementservice/domain/worker/PeriodicUpdateWorker.kt
new file mode 100644
index 000000000000..7ec6e6c28e9b
--- /dev/null
+++ b/packages/StatementService/src/com/android/statementservice/domain/worker/PeriodicUpdateWorker.kt
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.statementservice.domain.worker
+
+import android.content.Context
+import android.content.UriRelativeFilterGroup
+import android.content.pm.verify.domain.DomainVerificationManager
+import androidx.work.ListenableWorker
+import androidx.work.WorkerParameters
+import com.android.statementservice.domain.VerifyStatus
+import com.android.statementservice.utils.AndroidUtils
+import com.android.statementservice.utils.StatementUtils
+import kotlinx.coroutines.async
+import kotlinx.coroutines.awaitAll
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.isActive
+
+abstract class PeriodicUpdateWorker(
+ appContext: Context,
+ params: WorkerParameters
+) : BaseRequestWorker(appContext, params) {
+
+ data class VerifyResult(
+ val host: String,
+ val status: VerifyStatus,
+ val groups: List<UriRelativeFilterGroup>
+ )
+
+ protected suspend fun updateDomainVerificationStatus(verifyStatusFilter: (Int) -> Boolean):
+ ListenableWorker.Result {
+ return coroutineScope {
+ if (!AndroidUtils.isReceiverV2Enabled(appContext)) {
+ return@coroutineScope Result.success()
+ }
+
+ val packageNames = verificationManager.queryValidVerificationPackageNames()
+
+ verifier.collectHosts(packageNames, verifyStatusFilter)
+ .map { (domainSetId, packageName, hosts) ->
+ hosts.map { host ->
+ async {
+ if (isActive && !isStopped) {
+ val (_, status, statement) = verifier.verifyHost(
+ host,
+ packageName,
+ params.network
+ )
+ val groups = statement?.dynamicAppLinkComponents.orEmpty().map {
+ StatementUtils.createUriRelativeFilterGroup(it)
+ }
+ VerifyResult(host, status, groups)
+ } else {
+ // If the job gets cancelled, stop the remaining hosts, but continue the
+ // job to commit the results for hosts that were already requested.
+ null
+ }
+ }
+ }.awaitAll().filterNotNull().groupBy { it.status }
+ .forEach { (status, results) ->
+ val error = verificationManager.setDomainVerificationStatus(
+ domainSetId,
+ results.map { it.host }.toSet(),
+ status.value
+ )
+ if (error == DomainVerificationManager.STATUS_OK
+ && status == VerifyStatus.SUCCESS
+ ) {
+ updateUriRelativeFilterGroups(
+ packageName,
+ results.associateBy({ it.host }, { it.groups })
+ )
+ }
+ }
+ }
+
+ // Succeed regardless of results since this retry is best effort and not required
+ Result.success()
+ }
+ }
+} \ No newline at end of file
diff --git a/packages/StatementService/src/com/android/statementservice/domain/worker/RetryRequestWorker.kt b/packages/StatementService/src/com/android/statementservice/domain/worker/RetryRequestWorker.kt
index f83601a7807b..e8b4df9b0943 100644
--- a/packages/StatementService/src/com/android/statementservice/domain/worker/RetryRequestWorker.kt
+++ b/packages/StatementService/src/com/android/statementservice/domain/worker/RetryRequestWorker.kt
@@ -17,18 +17,9 @@
package com.android.statementservice.domain.worker
import android.content.Context
-import android.content.UriRelativeFilterGroup
-import android.content.pm.verify.domain.DomainVerificationManager
import androidx.work.NetworkType
import androidx.work.WorkerParameters
import com.android.statementservice.domain.VerifyStatus
-import com.android.statementservice.utils.AndroidUtils
-import com.android.statementservice.utils.StatementUtils
-import kotlinx.coroutines.async
-import kotlinx.coroutines.awaitAll
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.isActive
-import java.util.UUID
/**
* Scheduled every 24 hours with [NetworkType.CONNECTED] and every 72 hours without any constraints
@@ -37,63 +28,7 @@ import java.util.UUID
class RetryRequestWorker(
appContext: Context,
params: WorkerParameters
-) : BaseRequestWorker(appContext, params) {
+) : PeriodicUpdateWorker(appContext, params) {
- data class VerifyResult(
- val domainSetId: UUID,
- val host: String,
- val status: VerifyStatus,
- val packageName: String,
- val groups: List<UriRelativeFilterGroup>
- )
-
- override suspend fun doWork() = coroutineScope {
- if (!AndroidUtils.isReceiverV2Enabled(appContext)) {
- return@coroutineScope Result.success()
- }
-
- val packageNames = verificationManager.queryValidVerificationPackageNames()
-
- verifier.collectHosts(packageNames)
- .map { (domainSetId, packageName, host) ->
- async {
- if (isActive && !isStopped) {
- val (_, status, statement) = verifier.verifyHost(host, packageName, params.network)
- val groups = statement?.dynamicAppLinkComponents.orEmpty().map {
- StatementUtils.createUriRelativeFilterGroup(it)
- }
- VerifyResult(domainSetId, host, status, packageName, groups)
- } else {
- // If the job gets cancelled, stop the remaining hosts, but continue the
- // job to commit the results for hosts that were already requested.
- null
- }
- }
- }
- .awaitAll()
- .filterNotNull() // TODO(b/159952358): Fast fail packages which can't be retrieved.
- .groupBy { it.packageName }
- .forEach { (packageName, resultsByName) ->
- val groupUpdates = mutableMapOf<String, List<UriRelativeFilterGroup>>()
- resultsByName.groupBy { it.domainSetId }
- .forEach { (domainSetId, resultsById) ->
- resultsById.groupBy { it.status }
- .forEach { (status, verifyResults) ->
- val error = verificationManager.setDomainVerificationStatus(
- domainSetId,
- verifyResults.map(VerifyResult::host).toSet(),
- status.value
- )
- if (error == DomainVerificationManager.STATUS_OK
- && status == VerifyStatus.SUCCESS) {
- verifyResults.forEach { groupUpdates[it.host] = it.groups }
- }
- }
- }
- updateUriRelativeFilterGroups(packageName, groupUpdates)
- }
-
- // Succeed regardless of results since this retry is best effort and not required
- Result.success()
- }
+ override suspend fun doWork() = updateDomainVerificationStatus(VerifyStatus::shouldRetry)
}
diff --git a/packages/StatementService/src/com/android/statementservice/domain/worker/UpdateVerifiedDomainsWorker.kt b/packages/StatementService/src/com/android/statementservice/domain/worker/UpdateVerifiedDomainsWorker.kt
new file mode 100644
index 000000000000..c6f40c832860
--- /dev/null
+++ b/packages/StatementService/src/com/android/statementservice/domain/worker/UpdateVerifiedDomainsWorker.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.statementservice.domain.worker
+
+import android.content.Context
+import androidx.work.WorkerParameters
+import com.android.statementservice.domain.VerifyStatus
+
+class UpdateVerifiedDomainsWorker(
+ appContext: Context,
+ params: WorkerParameters
+) : PeriodicUpdateWorker(appContext, params) {
+
+ override suspend fun doWork() = updateDomainVerificationStatus(VerifyStatus::canUpdate)
+} \ No newline at end of file
diff --git a/packages/SystemUI/TEST_MAPPING b/packages/SystemUI/TEST_MAPPING
index e47704ebdf86..cc01071c91a4 100644
--- a/packages/SystemUI/TEST_MAPPING
+++ b/packages/SystemUI/TEST_MAPPING
@@ -55,14 +55,6 @@
"exclude-filter": "android.platform.tests.HomeTest#testAssistantWidget"
}
]
- },
- {
- "name": "AndroidAutomotiveNotificationsTests",
- "options" : [
- {
- "include-filter": "android.platform.tests.NotificationTest"
- }
- ]
}
],
diff --git a/packages/SystemUI/aconfig/biometrics_framework.aconfig b/packages/SystemUI/aconfig/biometrics_framework.aconfig
index 10d7352da7dc..e3f5378175d2 100644
--- a/packages/SystemUI/aconfig/biometrics_framework.aconfig
+++ b/packages/SystemUI/aconfig/biometrics_framework.aconfig
@@ -12,3 +12,10 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "cont_auth_plugin"
+ namespace: "biometrics_framework"
+ description: "Plugin and related API hooks for contextual auth plugins"
+ bug: "373600589"
+}
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 20b83e10e821..0d654d9c8f67 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -1201,6 +1201,16 @@ flag {
}
flag {
+ name: "communal_hub_use_thread_pool_for_widgets"
+ namespace: "systemui"
+ description: "Use a dedicated thread pool executor for loading widgets on glanceable hub"
+ bug: "369412569"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "communal_standalone_support"
namespace: "systemui"
description: "Support communal features without a dock"
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
index f1cbba7272b0..38f09988e7a7 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
@@ -702,6 +702,8 @@ constructor(
object : Controller by controller {
override val isLaunching: Boolean = false
}
+ // Cross-task close transitions should not use this animation, so we only register it for
+ // when the opening window is Launcher.
val returnFilter =
TransitionFilter().apply {
mRequirements =
@@ -710,7 +712,11 @@ constructor(
mActivityType = WindowConfiguration.ACTIVITY_TYPE_STANDARD
mModes = intArrayOf(TRANSIT_CLOSE, TRANSIT_TO_BACK)
mTopActivity = component
- }
+ },
+ TransitionFilter.Requirement().apply {
+ mActivityType = WindowConfiguration.ACTIVITY_TYPE_HOME
+ mModes = intArrayOf(TRANSIT_OPEN, TRANSIT_TO_FRONT)
+ },
)
}
val returnRemoteTransition =
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
index ae92d259d62b..85f549d43a11 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
@@ -21,6 +21,7 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.DisposableEffect
import androidx.compose.ui.Modifier
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.SceneScope
@@ -71,9 +72,7 @@ constructor(
}
@Composable
- override fun SceneScope.Content(
- modifier: Modifier,
- ) =
+ override fun SceneScope.Content(modifier: Modifier) =
BouncerScene(
viewModel = rememberViewModel("BouncerScene") { contentViewModelFactory.create() },
dialogFactory = dialogFactory,
@@ -89,6 +88,8 @@ private fun SceneScope.BouncerScene(
) {
val backgroundColor = MaterialTheme.colorScheme.surface
+ DisposableEffect(Unit) { onDispose { viewModel.onUiDestroyed() } }
+
Box(modifier) {
Canvas(Modifier.element(Bouncer.Elements.Background).fillMaxSize()) {
drawRect(color = backgroundColor)
@@ -101,7 +102,7 @@ private fun SceneScope.BouncerScene(
dialogFactory,
Modifier.element(Bouncer.Elements.Content)
.sysuiResTag(Bouncer.TestTags.Root)
- .fillMaxSize()
+ .fillMaxSize(),
)
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResponsiveLazyHorizontalGrid.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResponsiveLazyHorizontalGrid.kt
new file mode 100644
index 000000000000..e3310780afd7
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResponsiveLazyHorizontalGrid.kt
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.communal.ui.compose
+
+import android.content.res.Configuration
+import androidx.compose.foundation.OverscrollEffect
+import androidx.compose.foundation.gestures.FlingBehavior
+import androidx.compose.foundation.gestures.ScrollableDefaults
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.BoxWithConstraints
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.calculateEndPadding
+import androidx.compose.foundation.layout.calculateStartPadding
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.lazy.grid.GridCells
+import androidx.compose.foundation.lazy.grid.LazyGridScope
+import androidx.compose.foundation.lazy.grid.LazyGridState
+import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid
+import androidx.compose.foundation.lazy.grid.rememberLazyGridState
+import androidx.compose.foundation.rememberOverscrollEffect
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalConfiguration
+import androidx.compose.ui.platform.LocalLayoutDirection
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.DpSize
+import androidx.compose.ui.unit.IntSize
+import androidx.compose.ui.unit.coerceAtMost
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.times
+
+/**
+ * Renders a responsive [LazyHorizontalGrid] with dynamic columns and rows. Each cell will maintain
+ * the specified aspect ratio, but is otherwise resizeable in order to best fill the available
+ * space.
+ */
+@Composable
+fun ResponsiveLazyHorizontalGrid(
+ cellAspectRatio: Float,
+ modifier: Modifier = Modifier,
+ state: LazyGridState = rememberLazyGridState(),
+ minContentPadding: PaddingValues = PaddingValues(0.dp),
+ minHorizontalArrangement: Dp = 0.dp,
+ minVerticalArrangement: Dp = 0.dp,
+ flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
+ userScrollEnabled: Boolean = true,
+ overscrollEffect: OverscrollEffect? = rememberOverscrollEffect(),
+ content: LazyGridScope.(sizeInfo: SizeInfo) -> Unit,
+) {
+ check(cellAspectRatio > 0f) { "Aspect ratio must be greater than 0, but was $cellAspectRatio" }
+ check(minHorizontalArrangement.value >= 0f && minVerticalArrangement.value >= 0f) {
+ "Horizontal and vertical arrangements must be non-negative, but were " +
+ "$minHorizontalArrangement and $minVerticalArrangement, respectively."
+ }
+ BoxWithConstraints(modifier) {
+ val gridSize = rememberGridSize(maxWidth = maxWidth, maxHeight = maxHeight)
+ val layoutDirection = LocalLayoutDirection.current
+
+ val minStartPadding = minContentPadding.calculateStartPadding(layoutDirection)
+ val minEndPadding = minContentPadding.calculateEndPadding(layoutDirection)
+ val minTopPadding = minContentPadding.calculateTopPadding()
+ val minBottomPadding = minContentPadding.calculateBottomPadding()
+ val minHorizontalPadding = minStartPadding + minEndPadding
+ val minVerticalPadding = minTopPadding + minBottomPadding
+
+ // Determine the maximum allowed cell width and height based on the available width and
+ // height, and the desired number of columns and rows.
+ val maxCellWidth =
+ calculateCellSize(
+ availableSpace = maxWidth,
+ padding = minHorizontalPadding,
+ numCells = gridSize.width,
+ cellSpacing = minHorizontalArrangement,
+ )
+ val maxCellHeight =
+ calculateCellSize(
+ availableSpace = maxHeight,
+ padding = minVerticalPadding,
+ numCells = gridSize.height,
+ cellSpacing = minVerticalArrangement,
+ )
+
+ // Constrain the max size to the desired aspect ratio.
+ val finalSize =
+ calculateClosestSize(
+ maxWidth = maxCellWidth,
+ maxHeight = maxCellHeight,
+ aspectRatio = cellAspectRatio,
+ )
+
+ // Determine how much space in each dimension we've used up, and how much we have left as
+ // extra space. Distribute the extra space evenly along the content padding.
+ val usedWidth =
+ calculateUsedSpace(
+ cellSize = finalSize.width,
+ numCells = gridSize.width,
+ padding = minHorizontalPadding,
+ cellSpacing = minHorizontalArrangement,
+ )
+ .coerceAtMost(maxWidth)
+ val usedHeight =
+ calculateUsedSpace(
+ cellSize = finalSize.height,
+ numCells = gridSize.height,
+ padding = minVerticalPadding,
+ cellSpacing = minVerticalArrangement,
+ )
+ .coerceAtMost(maxHeight)
+ val extraWidth = maxWidth - usedWidth
+ val extraHeight = maxHeight - usedHeight
+
+ val finalContentPadding =
+ PaddingValues(
+ start = minStartPadding + extraWidth / 2,
+ end = minEndPadding + extraWidth / 2,
+ top = minTopPadding + extraHeight / 2,
+ bottom = minBottomPadding + extraHeight / 2,
+ )
+
+ LazyHorizontalGrid(
+ rows = GridCells.Fixed(gridSize.height),
+ modifier = Modifier.fillMaxSize(),
+ state = state,
+ contentPadding = finalContentPadding,
+ horizontalArrangement = Arrangement.spacedBy(minHorizontalArrangement),
+ verticalArrangement = Arrangement.spacedBy(minVerticalArrangement),
+ flingBehavior = flingBehavior,
+ userScrollEnabled = userScrollEnabled,
+ overscrollEffect = overscrollEffect,
+ ) {
+ content(
+ SizeInfo(
+ cellSize = finalSize,
+ contentPadding = finalContentPadding,
+ horizontalArrangement = minHorizontalArrangement,
+ verticalArrangement = minVerticalArrangement,
+ maxHeight = maxHeight,
+ )
+ )
+ }
+ }
+}
+
+private fun calculateCellSize(availableSpace: Dp, padding: Dp, numCells: Int, cellSpacing: Dp): Dp =
+ (availableSpace - padding - cellSpacing * (numCells - 1)) / numCells
+
+private fun calculateUsedSpace(cellSize: Dp, numCells: Int, padding: Dp, cellSpacing: Dp): Dp =
+ cellSize * numCells + padding + (numCells - 1) * cellSpacing
+
+private fun calculateClosestSize(maxWidth: Dp, maxHeight: Dp, aspectRatio: Float): DpSize {
+ return if (maxWidth / maxHeight > aspectRatio) {
+ // Target is too wide, shrink width
+ DpSize(maxHeight * aspectRatio, maxHeight)
+ } else {
+ // Target is too tall, shrink height
+ DpSize(maxWidth, maxWidth / aspectRatio)
+ }
+}
+
+/**
+ * Provides size info of the responsive grid, since the size is dynamic.
+ *
+ * @property cellSize The size of each cell in the grid.
+ * @property contentPadding The final content padding of the grid.
+ * @property horizontalArrangement The space between columns in the grid.
+ * @property verticalArrangement The space between rows in the grid.
+ * @property availableHeight The maximum height an item in the grid may occupy.
+ */
+data class SizeInfo(
+ val cellSize: DpSize,
+ val contentPadding: PaddingValues,
+ val horizontalArrangement: Dp,
+ val verticalArrangement: Dp,
+ private val maxHeight: Dp,
+) {
+ val availableHeight: Dp
+ get() =
+ maxHeight -
+ contentPadding.calculateBottomPadding() -
+ contentPadding.calculateTopPadding()
+}
+
+@Composable
+private fun rememberGridSize(maxWidth: Dp, maxHeight: Dp): IntSize {
+ val configuration = LocalConfiguration.current
+ val orientation = configuration.orientation
+
+ return remember(orientation, maxWidth, maxHeight) {
+ if (orientation == Configuration.ORIENTATION_PORTRAIT) {
+ IntSize(
+ width = calculateNumCellsWidth(maxWidth),
+ height = calculateNumCellsHeight(maxHeight),
+ )
+ } else {
+ // In landscape we invert the rows/columns to ensure we match the same area as portrait.
+ // This keeps the number of elements in the grid consistent when changing orientation.
+ IntSize(
+ width = calculateNumCellsHeight(maxWidth),
+ height = calculateNumCellsWidth(maxHeight),
+ )
+ }
+ }
+}
+
+private fun calculateNumCellsWidth(width: Dp) =
+ // See https://developer.android.com/develop/ui/views/layout/use-window-size-classes
+ when {
+ width >= 840.dp -> 3
+ width >= 600.dp -> 2
+ else -> 1
+ }
+
+private fun calculateNumCellsHeight(height: Dp) =
+ // See https://developer.android.com/develop/ui/views/layout/use-window-size-classes
+ when {
+ height >= 900.dp -> 3
+ height >= 480.dp -> 2
+ else -> 1
+ }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
index a266e7eb44a1..c3dc84d0a12c 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
@@ -39,6 +39,7 @@ import com.android.compose.animation.scene.MutableSceneTransitionLayoutState
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.SceneTransitions
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.compose.animation.scene.observableTransitionState
@@ -78,6 +79,7 @@ fun SceneContainer(
sceneByKey: Map<SceneKey, Scene>,
overlayByKey: Map<OverlayKey, Overlay>,
initialSceneKey: SceneKey,
+ sceneTransitions: SceneTransitions,
dataSourceDelegator: SceneDataSourceDelegator,
qsSceneAdapter: Provider<QSSceneAdapter>,
modifier: Modifier = Modifier,
@@ -87,7 +89,7 @@ fun SceneContainer(
MutableSceneTransitionLayoutState(
initialScene = initialSceneKey,
canChangeScene = { toScene -> viewModel.canChangeScene(toScene) },
- transitions = SceneContainerTransitions,
+ transitions = sceneTransitions,
)
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
index eb2a01632095..e819bfd18578 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
@@ -53,10 +53,10 @@ import com.android.compose.animation.scene.content.state.TransitionState
import com.android.compose.animation.scene.transformation.CustomPropertyTransformation
import com.android.compose.animation.scene.transformation.InterpolatedPropertyTransformation
import com.android.compose.animation.scene.transformation.PropertyTransformation
-import com.android.compose.animation.scene.transformation.SharedElementTransformation
import com.android.compose.animation.scene.transformation.TransformationWithRange
import com.android.compose.modifiers.thenIf
import com.android.compose.ui.graphics.drawInContainer
+import com.android.compose.ui.util.IntIndexedMap
import com.android.compose.ui.util.lerp
import kotlin.math.roundToInt
import kotlinx.coroutines.launch
@@ -70,6 +70,14 @@ internal class Element(val key: ElementKey) {
val stateByContent = SnapshotStateMap<ContentKey, State>()
/**
+ * A sorted map of nesting depth (key) to content key (value). For shared elements it is used to
+ * determine which content this element should be rendered by. The nesting depth refers to the
+ * number of STLs nested within each other, starting at 0 for the parent STL and increasing by
+ * one for each nested [NestedSceneTransitionLayout].
+ */
+ val renderAuthority = IntIndexedMap<ContentKey>()
+
+ /**
* The last transition that was used when computing the state (size, position and alpha) of this
* element in any content, or `null` if it was last laid out when idle.
*/
@@ -232,9 +240,8 @@ internal class ElementNode(
private val element: Element
get() = _element!!
- private var _stateInContent: Element.State? = null
private val stateInContent: Element.State
- get() = _stateInContent!!
+ get() = element.stateByContent.getValue(content.key)
override val traverseKey: Any = ElementTraverseKey
@@ -248,9 +255,13 @@ internal class ElementNode(
val element =
layoutImpl.elements[key] ?: Element(key).also { layoutImpl.elements[key] = it }
_element = element
- _stateInContent =
- element.stateByContent[content.key]
- ?: Element.State(content.key).also { element.stateByContent[content.key] = it }
+ addToRenderAuthority(element)
+ if (!element.stateByContent.contains(content.key)) {
+ val elementState = Element.State(content.key)
+ element.stateByContent[content.key] = elementState
+
+ layoutImpl.ancestorContentKeys.forEach { element.stateByContent[it] = elementState }
+ }
}
private fun addNodeToContentState() {
@@ -272,8 +283,20 @@ internal class ElementNode(
removeNodeFromContentState()
maybePruneMaps(layoutImpl, element, stateInContent)
+ removeFromRenderAuthority()
_element = null
- _stateInContent = null
+ }
+
+ private fun addToRenderAuthority(element: Element) {
+ val nestingDepth = layoutImpl.ancestorContentKeys.size
+ element.renderAuthority[nestingDepth] = content.key
+ }
+
+ private fun removeFromRenderAuthority() {
+ val nestingDepth = layoutImpl.ancestorContentKeys.size
+ if (element.renderAuthority[nestingDepth] == content.key) {
+ element.renderAuthority.remove(nestingDepth)
+ }
}
private fun removeNodeFromContentState() {
@@ -346,15 +369,17 @@ internal class ElementNode(
val elementState = elementState(layoutImpl, element, currentTransitionStates)
if (elementState == null) {
// If the element is not part of any transition, place it normally in its idle scene.
+ // This is the case if for example a transition between two overlays is ongoing where
+ // sharedElement isn't part of either but the element is still rendered as part of
+ // the underlying scene that is currently not being transitioned.
val currentState = currentTransitionStates.last()
- val placeInThisContent =
+ val shouldPlaceInThisContent =
elementContentWhenIdle(
layoutImpl,
currentState,
isInContent = { it in element.stateByContent },
) == content.key
-
- return if (placeInThisContent) {
+ return if (shouldPlaceInThisContent) {
placeNormally(measurable, constraints)
} else {
doNotPlace(measurable, constraints)
@@ -536,7 +561,9 @@ internal class ElementNode(
stateInContent.clearLastPlacementValues()
traverseDescendants(ElementTraverseKey) { node ->
- (node as ElementNode)._stateInContent?.clearLastPlacementValues()
+ if ((node as ElementNode)._element != null) {
+ node.stateInContent.clearLastPlacementValues()
+ }
TraversableNode.Companion.TraverseDescendantsAction.ContinueTraversal
}
}
@@ -569,22 +596,30 @@ internal class ElementNode(
element: Element,
stateInContent: Element.State,
) {
- // If element is not composed in this content anymore, remove the content values. This
- // works because [onAttach] is called before [onDetach], so if an element is moved from
- // the UI tree we will first add the new code location then remove the old one.
- if (
- stateInContent.nodes.isEmpty() &&
- element.stateByContent[stateInContent.content] == stateInContent
- ) {
- element.stateByContent.remove(stateInContent.content)
-
- // If the element is not composed in any content, remove it from the elements map.
+ fun pruneForContent(contentKey: ContentKey) {
+ // If element is not composed in this content anymore, remove the content values.
+ // This works because [onAttach] is called before [onDetach], so if an element is
+ // moved from the UI tree we will first add the new code location then remove the
+ // old one.
if (
- element.stateByContent.isEmpty() && layoutImpl.elements[element.key] == element
+ stateInContent.nodes.isEmpty() &&
+ element.stateByContent[contentKey] == stateInContent
) {
- layoutImpl.elements.remove(element.key)
+ element.stateByContent.remove(contentKey)
+
+ // If the element is not composed in any content, remove it from the elements
+ // map.
+ if (
+ element.stateByContent.isEmpty() &&
+ layoutImpl.elements[element.key] == element
+ ) {
+ layoutImpl.elements.remove(element.key)
+ }
}
}
+
+ pruneForContent(stateInContent.content)
+ layoutImpl.ancestorContentKeys.forEach { content -> pruneForContent(content) }
}
}
}
@@ -890,12 +925,13 @@ private fun shouldPlaceElement(
val transition =
when (elementState) {
is TransitionState.Idle -> {
- return content ==
- elementContentWhenIdle(
- layoutImpl,
- elementState,
- isInContent = { it in element.stateByContent },
- )
+ return element.shouldBeRenderedBy(content) &&
+ content ==
+ elementContentWhenIdle(
+ layoutImpl,
+ elementState,
+ isInContent = { it in element.stateByContent },
+ )
}
is TransitionState.Transition -> elementState
}
@@ -925,76 +961,7 @@ private fun shouldPlaceElement(
return true
}
- return shouldPlaceOrComposeSharedElement(
- layoutImpl,
- content,
- element.key,
- transition,
- isInContent = { it in element.stateByContent },
- )
-}
-
-internal inline fun shouldPlaceOrComposeSharedElement(
- layoutImpl: SceneTransitionLayoutImpl,
- content: ContentKey,
- element: ElementKey,
- transition: TransitionState.Transition,
- isInContent: (ContentKey) -> Boolean,
-): Boolean {
- val overscrollContent = transition.currentOverscrollSpec?.content
- if (overscrollContent != null) {
- return when (transition) {
- // If we are overscrolling between scenes, only place/compose the element in the
- // overscrolling scene.
- is TransitionState.Transition.ChangeScene -> content == overscrollContent
-
- // If we are overscrolling an overlay, place/compose the element if [content] is the
- // overscrolling content or if [content] is the current scene and the overscrolling
- // overlay does not contain the element.
- is TransitionState.Transition.ReplaceOverlay,
- is TransitionState.Transition.ShowOrHideOverlay ->
- content == overscrollContent ||
- (content == transition.currentScene && !isInContent(overscrollContent))
- }
- }
-
- val scenePicker = element.contentPicker
- val pickedScene =
- scenePicker.contentDuringTransition(
- element = element,
- transition = transition,
- fromContentZIndex = layoutImpl.content(transition.fromContent).zIndex,
- toContentZIndex = layoutImpl.content(transition.toContent).zIndex,
- )
-
- return pickedScene == content
-}
-
-private fun isSharedElementEnabled(
- element: ElementKey,
- transition: TransitionState.Transition,
-): Boolean {
- return sharedElementTransformation(element, transition)?.transformation?.enabled ?: true
-}
-
-internal fun sharedElementTransformation(
- element: ElementKey,
- transition: TransitionState.Transition,
-): TransformationWithRange<SharedElementTransformation>? {
- val transformationSpec = transition.transformationSpec
- val sharedInFromContent =
- transformationSpec.transformations(element, transition.fromContent).shared
- val sharedInToContent = transformationSpec.transformations(element, transition.toContent).shared
-
- // The sharedElement() transformation must either be null or be the same in both contents.
- if (sharedInFromContent != sharedInToContent) {
- error(
- "Different sharedElement() transformations matched $element " +
- "(from=$sharedInFromContent to=$sharedInToContent)"
- )
- }
-
- return sharedInFromContent
+ return shouldPlaceSharedElement(layoutImpl, content, element.key, transition)
}
/**
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt
index 509a16c5a704..17510c732e65 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt
@@ -196,18 +196,54 @@ private fun shouldComposeMovableElement(
is TransitionState.Transition -> {
// During transitions, always compose movable elements in the scene picked by their
// content picker.
- val contents = element.contentPicker.contents
- shouldPlaceOrComposeSharedElement(
+ shouldComposeMoveableElement(
layoutImpl,
content,
element,
elementState,
- isInContent = { contents.contains(it) },
+ element.contentPicker.contents,
)
}
}
}
+private fun shouldComposeMoveableElement(
+ layoutImpl: SceneTransitionLayoutImpl,
+ content: ContentKey,
+ elementKey: ElementKey,
+ transition: TransitionState.Transition,
+ containingContents: Set<ContentKey>,
+): Boolean {
+ val overscrollContent = transition.currentOverscrollSpec?.content
+ if (overscrollContent != null) {
+ return when (transition) {
+ // If we are overscrolling between scenes, only place/compose the element in the
+ // overscrolling scene.
+ is TransitionState.Transition.ChangeScene -> content == overscrollContent
+
+ // If we are overscrolling an overlay, place/compose the element if [content] is the
+ // overscrolling content or if [content] is the current scene and the overscrolling
+ // overlay does not contain the element.
+ is TransitionState.Transition.ReplaceOverlay,
+ is TransitionState.Transition.ShowOrHideOverlay ->
+ content == overscrollContent ||
+ (content == transition.currentScene &&
+ !containingContents.contains(overscrollContent))
+ }
+ }
+
+ val scenePicker = elementKey.contentPicker
+ val pickedScene =
+ scenePicker.contentDuringTransition(
+ element = elementKey,
+ transition = transition,
+ fromContentZIndex = layoutImpl.content(transition.fromContent).zIndex,
+ toContentZIndex = layoutImpl.content(transition.toContent).zIndex,
+ )
+
+ return pickedScene == content
+}
+
private fun movableElementState(
element: MovableElementKey,
transitionStates: List<TransitionState>,
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 d3ddb5003469..a91a5058a436 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
@@ -28,6 +28,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.pointer.PointerType
+import androidx.compose.ui.layout.LookaheadScope
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.Density
@@ -68,7 +69,7 @@ fun SceneTransitionLayout(
swipeDetector,
transitionInterceptionThreshold,
onLayoutImpl = null,
- builder,
+ builder = builder,
)
}
@@ -261,6 +262,18 @@ interface BaseContentScope : ElementStateScope {
* lists keep a constant size during transitions even if its elements are growing/shrinking.
*/
fun Modifier.noResizeDuringTransitions(): Modifier
+
+ /**
+ * A [NestedSceneTransitionLayout] will share its elements with its ancestor STLs therefore
+ * enabling sharedElement transitions between them.
+ */
+ // TODO(b/380070506): Add more parameters when default params are supported in Kotlin 2.0.21
+ @Composable
+ fun NestedSceneTransitionLayout(
+ state: SceneTransitionLayoutState,
+ modifier: Modifier,
+ builder: SceneTransitionLayoutScope.() -> Unit,
+ )
}
typealias SceneScope = ContentScope
@@ -677,6 +690,9 @@ internal fun SceneTransitionLayoutForTesting(
swipeDetector: SwipeDetector = DefaultSwipeDetector,
transitionInterceptionThreshold: Float = 0f,
onLayoutImpl: ((SceneTransitionLayoutImpl) -> Unit)? = null,
+ sharedElementMap: MutableMap<ElementKey, Element> = remember { mutableMapOf() },
+ ancestorContentKeys: List<ContentKey> = emptyList(),
+ lookaheadScope: LookaheadScope? = null,
builder: SceneTransitionLayoutScope.() -> Unit,
) {
val density = LocalDensity.current
@@ -691,6 +707,9 @@ internal fun SceneTransitionLayoutForTesting(
transitionInterceptionThreshold = transitionInterceptionThreshold,
builder = builder,
animationScope = animationScope,
+ elements = sharedElementMap,
+ ancestorContentKeys = ancestorContentKeys,
+ lookaheadScope = lookaheadScope,
)
.also { onLayoutImpl?.invoke(it) }
}
@@ -706,6 +725,24 @@ internal fun SceneTransitionLayoutForTesting(
" that was used when creating it, which is not supported"
)
}
+ if (layoutImpl.elements != sharedElementMap) {
+ error(
+ "This SceneTransitionLayout was bound to a different elements map that was used " +
+ "when creating it, which is not supported"
+ )
+ }
+ if (layoutImpl.ancestorContentKeys != ancestorContentKeys) {
+ error(
+ "This SceneTransitionLayout was bound to a different ancestorContents that was " +
+ "used when creating it, which is not supported"
+ )
+ }
+ if (lookaheadScope != null && layoutImpl.lookaheadScope != lookaheadScope) {
+ error(
+ "This SceneTransitionLayout was bound to a different lookaheadScope that was " +
+ "used when creating it, which is not supported"
+ )
+ }
layoutImpl.density = density
layoutImpl.layoutDirection = layoutDirection
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 b916b0b45e41..bdc1461f06c9 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
@@ -70,7 +70,39 @@ internal class SceneTransitionLayoutImpl(
* animations.
*/
internal val animationScope: CoroutineScope,
+
+ /**
+ * The map of [Element]s.
+ *
+ * Important: [Element]s from this map should never be accessed during composition because the
+ * Elements are added when the associated Modifier.element() node is attached to the Modifier
+ * tree, i.e. after composition.
+ */
+ internal val elements: MutableMap<ElementKey, Element> = mutableMapOf(),
+
+ /**
+ * When this STL is a [NestedSceneTransitionLayout], this is a list of [ContentKey]s of where
+ * this STL is composed in within its ancestors.
+ *
+ * The root STL holds an emptyList. With each nesting level the parent is supposed to add
+ * exactly one scene to the list, therefore the size of this list is equal to the nesting depth
+ * of this STL.
+ *
+ * This is used to know in which content of the ancestors a sharedElement appears in.
+ */
+ internal val ancestorContentKeys: List<ContentKey> = emptyList(),
+ lookaheadScope: LookaheadScope? = null,
) {
+
+ /**
+ * The [LookaheadScope] of this layout, that can be used to compute offsets relative to the
+ * layout. For [NestedSceneTransitionLayout]s this scope is the scope of the root STL, such that
+ * offset computations can be shared among all children.
+ */
+ private var _lookaheadScope: LookaheadScope? = lookaheadScope
+ internal val lookaheadScope: LookaheadScope
+ get() = _lookaheadScope!!
+
/**
* The map of [Scene]s.
*
@@ -89,15 +121,6 @@ internal class SceneTransitionLayoutImpl(
get() = _overlays ?: SnapshotStateMap<OverlayKey, Overlay>().also { _overlays = it }
/**
- * The map of [Element]s.
- *
- * Important: [Element]s from this map should never be accessed during composition because the
- * Elements are added when the associated Modifier.element() node is attached to the Modifier
- * tree, i.e. after composition.
- */
- internal val elements = mutableMapOf<ElementKey, Element>()
-
- /**
* The map of contents of movable elements.
*
* Note that given that this map is mutated directly during a composition, it has to be a
@@ -138,13 +161,6 @@ internal class SceneTransitionLayoutImpl(
_userActionDistanceScope = it
}
- /**
- * The [LookaheadScope] of this layout, that can be used to compute offsets relative to the
- * layout.
- */
- internal lateinit var lookaheadScope: LookaheadScope
- private set
-
internal var lastSize: IntSize = IntSize.Zero
init {
@@ -347,7 +363,12 @@ internal class SceneTransitionLayoutImpl(
.then(LayoutElement(layoutImpl = this))
) {
LookaheadScope {
- lookaheadScope = this
+ if (_lookaheadScope == null) {
+ // We can't init this in a SideEffect as other NestedSTLs are already calling
+ // this during composition. However, when composition is canceled
+ // SceneTransitionLayoutImpl is discarded as well. So it's fine to do this here.
+ _lookaheadScope = this
+ }
BackHandler()
Scenes()
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SharedElement.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SharedElement.kt
new file mode 100644
index 000000000000..599a152a23bd
--- /dev/null
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SharedElement.kt
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compose.animation.scene
+
+import com.android.compose.animation.scene.content.state.TransitionState
+import com.android.compose.animation.scene.transformation.SharedElementTransformation
+import com.android.compose.animation.scene.transformation.TransformationWithRange
+
+/**
+ * Whether this element should be rendered by the given [content]. This method returns true only for
+ * exactly one content at any given time.
+ */
+internal fun Element.shouldBeRenderedBy(content: ContentKey): Boolean {
+ // The current strategy is that always the content with the lowest nestingDepth has authority.
+ // This content is supposed to render the shared element because this is also the level at which
+ // the transition is running. If the [renderAuthority.size] is 1 it means that that this element
+ // is currently composed only in one nesting level, which means that the render authority
+ // is determined by "classic" shared element code.
+ return renderAuthority.size == 1 || renderAuthority.first() == content
+}
+
+/**
+ * Whether this element is currently composed in multiple [SceneTransitionLayout]s.
+ *
+ * Note: Shared elements across [NestedSceneTransitionLayout]s side-by-side are not supported.
+ */
+internal fun Element.isPresentInMultipleStls(): Boolean {
+ return renderAuthority.size > 1
+}
+
+internal fun shouldPlaceSharedElement(
+ layoutImpl: SceneTransitionLayoutImpl,
+ content: ContentKey,
+ elementKey: ElementKey,
+ transition: TransitionState.Transition,
+): Boolean {
+ val element = layoutImpl.elements.getValue(elementKey)
+ if (element.isPresentInMultipleStls()) {
+ // If the element is present in multiple STLs we require the highest STL to render it and
+ // we don't want contentPicker to potentially return false for the highest STL.
+ return element.shouldBeRenderedBy(content)
+ }
+
+ val overscrollContent = transition.currentOverscrollSpec?.content
+ if (overscrollContent != null) {
+ return when (transition) {
+ // If we are overscrolling between scenes, only place/compose the element in the
+ // overscrolling scene.
+ is TransitionState.Transition.ChangeScene -> content == overscrollContent
+
+ // If we are overscrolling an overlay, place/compose the element if [content] is the
+ // overscrolling content or if [content] is the current scene and the overscrolling
+ // overlay does not contain the element.
+ is TransitionState.Transition.ReplaceOverlay,
+ is TransitionState.Transition.ShowOrHideOverlay ->
+ content == overscrollContent ||
+ (content == transition.currentScene &&
+ overscrollContent !in element.stateByContent)
+ }
+ }
+
+ val scenePicker = elementKey.contentPicker
+ val pickedScene =
+ scenePicker.contentDuringTransition(
+ element = elementKey,
+ transition = transition,
+ fromContentZIndex = layoutImpl.content(transition.fromContent).zIndex,
+ toContentZIndex = layoutImpl.content(transition.toContent).zIndex,
+ )
+
+ return pickedScene == content
+}
+
+internal fun isSharedElementEnabled(
+ element: ElementKey,
+ transition: TransitionState.Transition,
+): Boolean {
+ return sharedElementTransformation(element, transition)?.transformation?.enabled ?: true
+}
+
+internal fun sharedElementTransformation(
+ element: ElementKey,
+ transition: TransitionState.Transition,
+): TransformationWithRange<SharedElementTransformation>? {
+ val transformationSpec = transition.transformationSpec
+ val sharedInFromContent =
+ transformationSpec.transformations(element, transition.fromContent).shared
+ val sharedInToContent = transformationSpec.transformations(element, transition.toContent).shared
+
+ // The sharedElement() transformation must either be null or be the same in both contents.
+ if (sharedInFromContent != sharedInToContent) {
+ error(
+ "Different sharedElement() transformations matched $element " +
+ "(from=$sharedInFromContent to=$sharedInToContent)"
+ )
+ }
+
+ return sharedInFromContent
+}
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 255a16c6de6b..8c4cd8c93b87 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
@@ -23,6 +23,7 @@ import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.approachLayout
@@ -41,7 +42,9 @@ import com.android.compose.animation.scene.MovableElement
import com.android.compose.animation.scene.MovableElementContentScope
import com.android.compose.animation.scene.MovableElementKey
import com.android.compose.animation.scene.NestedScrollBehavior
+import com.android.compose.animation.scene.SceneTransitionLayoutForTesting
import com.android.compose.animation.scene.SceneTransitionLayoutImpl
+import com.android.compose.animation.scene.SceneTransitionLayoutScope
import com.android.compose.animation.scene.SceneTransitionLayoutState
import com.android.compose.animation.scene.SharedValueType
import com.android.compose.animation.scene.UserAction
@@ -175,4 +178,24 @@ internal class ContentScopeImpl(
override fun Modifier.noResizeDuringTransitions(): Modifier {
return noResizeDuringTransitions(layoutState = layoutImpl.state)
}
+
+ @Composable
+ override fun NestedSceneTransitionLayout(
+ state: SceneTransitionLayoutState,
+ modifier: Modifier,
+ builder: SceneTransitionLayoutScope.() -> Unit,
+ ) {
+ SceneTransitionLayoutForTesting(
+ state,
+ modifier,
+ onLayoutImpl = null,
+ builder = builder,
+ sharedElementMap = layoutImpl.elements,
+ ancestorContentKeys =
+ remember(layoutImpl.ancestorContentKeys, contentKey) {
+ layoutImpl.ancestorContentKeys + contentKey
+ },
+ lookaheadScope = layoutImpl.lookaheadScope,
+ )
+ }
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/ui/util/IntIndexedMap.kt b/packages/SystemUI/compose/scene/src/com/android/compose/ui/util/IntIndexedMap.kt
new file mode 100644
index 000000000000..1b5341b8048a
--- /dev/null
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/ui/util/IntIndexedMap.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compose.ui.util
+
+/**
+ * This is a custom implementation that resembles a SortedMap<Int, T> but is based on a simple
+ * ArrayList to avoid the allocation overhead and boxing.
+ *
+ * It can only hold positive keys and 0 and it is only efficient for small keys (0 - ~100), but
+ * therefore provides fast operations for small keys.
+ */
+internal class IntIndexedMap<T> {
+ private val arrayList = ArrayList<T?>()
+ private var _size = 0
+ val size
+ get() = _size
+
+ /** Returns the value at [key] or null if the key is not present. */
+ operator fun get(key: Int): T? {
+ if (key < 0 || key >= arrayList.size) return null
+ return arrayList[key]
+ }
+
+ /**
+ * Sets the value at [key] to [value]. If [key] is larger than the current size of the map, this
+ * operation may take up to O(key) time and space. Therefore this data structure is only
+ * efficient for small [key] sizes.
+ */
+ operator fun set(key: Int, value: T?) {
+ if (key < 0)
+ throw UnsupportedOperationException("This map can only hold positive keys and 0.")
+ if (key < arrayList.size) {
+ if (arrayList[key] != null && value == null) _size--
+ if (arrayList[key] == null && value != null) _size++
+ arrayList[key] = value
+ } else {
+ if (value == null) return
+ while (key > arrayList.size) {
+ arrayList.add(null)
+ }
+ _size++
+ arrayList.add(value)
+ }
+ }
+
+ /** Remove value at [key] */
+ fun remove(key: Int) {
+ if (key >= arrayList.size) return
+ this[key] = null
+ }
+
+ /** Get the [value] with the smallest [key] of the map. */
+ fun first(): T {
+ for (i in 0 until arrayList.size) {
+ return arrayList[i] ?: continue
+ }
+ throw NoSuchElementException("The map is empty.")
+ }
+}
diff --git a/packages/SystemUI/compose/scene/tests/AndroidManifest.xml b/packages/SystemUI/compose/scene/tests/AndroidManifest.xml
index 174ad30a8f1d..2b76d7ba267e 100644
--- a/packages/SystemUI/compose/scene/tests/AndroidManifest.xml
+++ b/packages/SystemUI/compose/scene/tests/AndroidManifest.xml
@@ -18,7 +18,8 @@
package="com.android.compose.animation.scene.tests" >
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
- <application>
+ <application
+ android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
<uses-library android:name="android.test.runner" />
</application>
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedSharedElementTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedSharedElementTest.kt
new file mode 100644
index 000000000000..c6ef8cff1a66
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedSharedElementTest.kt
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compose.animation.scene.transformation
+
+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.offset
+import androidx.compose.foundation.layout.size
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.alpha
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.test.SemanticsNodeInteraction
+import androidx.compose.ui.test.assertIsNotDisplayed
+import androidx.compose.ui.test.assertPositionInRootIsEqualTo
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.compose.animation.scene.AutoTransitionTestAssertionScope
+import com.android.compose.animation.scene.ContentScope
+import com.android.compose.animation.scene.Default4FrameLinearTransition
+import com.android.compose.animation.scene.Edge
+import com.android.compose.animation.scene.MutableSceneTransitionLayoutState
+import com.android.compose.animation.scene.SceneKey
+import com.android.compose.animation.scene.TestElements
+import com.android.compose.animation.scene.TestScenes
+import com.android.compose.animation.scene.inScene
+import com.android.compose.animation.scene.testTransition
+import com.android.compose.animation.scene.transitions
+import com.android.compose.test.assertSizeIsEqualTo
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class NestedSharedElementTest {
+ @get:Rule val rule = createComposeRule()
+
+ private object Scenes {
+ val NestedSceneA = SceneKey("NestedSceneA")
+ val NestedSceneB = SceneKey("NestedSceneB")
+ val NestedNestedSceneA = SceneKey("NestedNestedSceneA")
+ val NestedNestedSceneB = SceneKey("NestedNestedSceneB")
+ }
+
+ private val elementVariant1 = SharedElement(0.dp, 0.dp, 100.dp, 100.dp, Color.Red)
+ private val elementVariant2 = SharedElement(40.dp, 80.dp, 60.dp, 20.dp, Color.Blue)
+ private val elementVariant3 = SharedElement(80.dp, 40.dp, 140.dp, 180.dp, Color.Yellow)
+ private val elementVariant4 = SharedElement(120.dp, 240.dp, 20.dp, 140.dp, Color.Green)
+
+ private class SharedElement(
+ val x: Dp,
+ val y: Dp,
+ val width: Dp,
+ val height: Dp,
+ val color: Color = Color.Black,
+ val alpha: Float = 0.8f,
+ )
+
+ @Composable
+ private fun ContentScope.SharedElement(element: SharedElement) {
+ Box(Modifier.fillMaxSize()) {
+ Box(
+ Modifier.offset(element.x, element.y)
+ .element(TestElements.Foo)
+ .size(element.width, element.height)
+ .background(element.color)
+ .alpha(element.alpha)
+ )
+ }
+ }
+
+ private val contentWithSharedElement: @Composable ContentScope.() -> Unit = {
+ SharedElement(elementVariant1)
+ }
+
+ private val nestedState: MutableSceneTransitionLayoutState =
+ rule.runOnUiThread {
+ MutableSceneTransitionLayoutState(
+ Scenes.NestedSceneA,
+ transitions {
+ from(
+ from = Scenes.NestedSceneA,
+ to = Scenes.NestedSceneB,
+ builder = Default4FrameLinearTransition,
+ )
+ },
+ )
+ }
+
+ private val nestedNestedState: MutableSceneTransitionLayoutState =
+ rule.runOnUiThread {
+ MutableSceneTransitionLayoutState(
+ Scenes.NestedNestedSceneA,
+ transitions {
+ from(
+ from = Scenes.NestedNestedSceneA,
+ to = Scenes.NestedNestedSceneB,
+ builder = Default4FrameLinearTransition,
+ )
+ },
+ )
+ }
+
+ private val nestedStlWithSharedElement: @Composable ContentScope.() -> Unit = {
+ NestedSceneTransitionLayout(nestedState, modifier = Modifier) {
+ scene(Scenes.NestedSceneA) { SharedElement(elementVariant2) }
+ scene(Scenes.NestedSceneB) { SharedElement(elementVariant3) }
+ }
+ }
+
+ private val nestedNestedStlWithSharedElement: @Composable ContentScope.() -> Unit = {
+ NestedSceneTransitionLayout(nestedState, modifier = Modifier) {
+ scene(Scenes.NestedSceneA) {
+ NestedSceneTransitionLayout(state = nestedNestedState, modifier = Modifier) {
+ scene(Scenes.NestedNestedSceneA) { SharedElement(elementVariant4) }
+ scene(Scenes.NestedNestedSceneB) { SharedElement(elementVariant3) }
+ }
+ }
+ scene(Scenes.NestedSceneB) { SharedElement(elementVariant2) }
+ }
+ }
+
+ @Test
+ fun nestedSharedElementTransition_fromNestedSTLtoParentSTL() {
+ rule.testTransition(
+ fromSceneContent = nestedStlWithSharedElement,
+ toSceneContent = contentWithSharedElement,
+ ) {
+ before { onElement(TestElements.Foo).assertElementVariant(elementVariant2) }
+ atAllFrames(4) {
+ onElement(TestElements.Foo, TestScenes.SceneA).assertIsNotDisplayed()
+
+ onElement(TestElements.Foo, TestScenes.SceneB)
+ .assertBetweenElementVariants(elementVariant2, elementVariant1, this)
+ }
+ after { onElement(TestElements.Foo).assertElementVariant(elementVariant1) }
+ }
+ }
+
+ @Test
+ fun nestedSharedElementTransition_fromParentSTLtoNestedSTL() {
+ rule.testTransition(
+ fromSceneContent = contentWithSharedElement,
+ toSceneContent = nestedStlWithSharedElement,
+ ) {
+ before { onElement(TestElements.Foo).assertElementVariant(elementVariant1) }
+ atAllFrames(4) {
+ onElement(TestElements.Foo, TestScenes.SceneB).assertIsNotDisplayed()
+
+ onElement(TestElements.Foo, TestScenes.SceneA)
+ .assertBetweenElementVariants(elementVariant1, elementVariant2, this)
+ }
+ after { onElement(TestElements.Foo).assertElementVariant(elementVariant2) }
+ }
+ }
+
+ @Test
+ fun nestedSharedElementTransition_fromParentSTLtoNestedNestedSTL() {
+ rule.testTransition(
+ fromSceneContent = contentWithSharedElement,
+ toSceneContent = nestedNestedStlWithSharedElement,
+ ) {
+ before { onElement(TestElements.Foo).assertElementVariant(elementVariant1) }
+ atAllFrames(4) {
+ onElement(TestElements.Foo, TestScenes.SceneB).assertIsNotDisplayed()
+
+ onElement(TestElements.Foo, TestScenes.SceneA)
+ .assertBetweenElementVariants(elementVariant1, elementVariant4, this)
+ }
+ after { onElement(TestElements.Foo).assertElementVariant(elementVariant4) }
+ }
+ }
+
+ @Test
+ fun nestedSharedElementTransition_fromNestedNestedSTLtoNestedSTL() {
+ rule.testTransition(
+ fromSceneContent = nestedNestedStlWithSharedElement,
+ toSceneContent = { Box(modifier = Modifier.fillMaxSize()) },
+ changeState = { nestedState.setTargetScene(Scenes.NestedSceneB, this) },
+ ) {
+ before { onElement(TestElements.Foo).assertElementVariant(elementVariant4) }
+ atAllFrames(4) {
+ onElement(TestElements.Foo, Scenes.NestedSceneA).assertIsNotDisplayed()
+ onElement(TestElements.Foo, Scenes.NestedNestedSceneA).assertIsNotDisplayed()
+
+ onElement(TestElements.Foo, Scenes.NestedSceneB)
+ .assertBetweenElementVariants(elementVariant4, elementVariant2, this)
+ }
+ after { onElement(TestElements.Foo).assertElementVariant(elementVariant2) }
+ }
+ }
+
+ @Test
+ fun nestedSharedElement_sharedElementTransitionIsDisabled() {
+ rule.testTransition(
+ fromSceneContent = contentWithSharedElement,
+ toSceneContent = nestedStlWithSharedElement,
+ transition = {
+ spec = tween(16 * 4, easing = LinearEasing)
+
+ // Disable the shared element animation.
+ sharedElement(TestElements.Foo, enabled = false)
+
+ // In SceneA, Foo leaves to the left edge.
+ translate(TestElements.Foo.inScene(TestScenes.SceneA), Edge.Left, false)
+
+ // We can't reference the element inside the NestedSTL as of today
+ },
+ ) {
+ before { onElement(TestElements.Foo).assertElementVariant(elementVariant1) }
+ atAllFrames(4) {
+ onElement(TestElements.Foo, scene = TestScenes.SceneA)
+ .assertPositionInRootIsEqualTo(
+ interpolate(elementVariant1.x, 0.dp),
+ elementVariant1.y,
+ )
+ .assertSizeIsEqualTo(elementVariant1.width, elementVariant1.height)
+ }
+ after { onElement(TestElements.Foo).assertElementVariant(elementVariant2) }
+ }
+ }
+
+ @Test
+ fun nestedSharedElementTransition_transitionInsideNestedStl() {
+ rule.testTransition(
+ layoutModifier = Modifier.fillMaxSize(),
+ fromSceneContent = nestedStlWithSharedElement,
+ toSceneContent = contentWithSharedElement,
+ changeState = { nestedState.setTargetScene(Scenes.NestedSceneB, animationScope = this) },
+ ) {
+ before { onElement(TestElements.Foo).assertElementVariant(elementVariant2) }
+ atAllFrames(4) {
+ onElement(TestElements.Foo, Scenes.NestedSceneA).assertIsNotDisplayed()
+
+ onElement(TestElements.Foo, scene = Scenes.NestedSceneB)
+ .assertBetweenElementVariants(elementVariant2, elementVariant3, this)
+ }
+ after {
+ onElement(TestElements.Foo, Scenes.NestedSceneA).assertIsNotDisplayed()
+ onElement(TestElements.Foo).assertElementVariant(elementVariant3)
+ }
+ }
+ }
+
+ private fun SemanticsNodeInteraction.assertElementVariant(variant: SharedElement) {
+ assertPositionInRootIsEqualTo(variant.x, variant.y)
+ assertSizeIsEqualTo(variant.width, variant.height)
+ }
+
+ private fun SemanticsNodeInteraction.assertBetweenElementVariants(
+ from: SharedElement,
+ to: SharedElement,
+ assertScope: AutoTransitionTestAssertionScope,
+ ) {
+ assertPositionInRootIsEqualTo(
+ assertScope.interpolate(from.x, to.x),
+ assertScope.interpolate(from.y, to.y),
+ )
+ assertSizeIsEqualTo(
+ assertScope.interpolate(from.width, to.width),
+ assertScope.interpolate(from.height, to.height),
+ )
+ }
+}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/SharedElementTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/SharedElementTest.kt
index 2e3a934c2701..47c10f5ab3a3 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/SharedElementTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/SharedElementTest.kt
@@ -62,35 +62,14 @@ class SharedElementTest {
onElement(TestElements.Foo).assertPositionInRootIsEqualTo(10.dp, 50.dp)
onElement(TestElements.Foo).assertSizeIsEqualTo(20.dp, 80.dp)
}
- at(0) {
- // Shared elements are by default placed and drawn only in the scene with highest
- // zIndex.
+ atAllFrames(4) {
onElement(TestElements.Foo, TestScenes.SceneA).assertIsNotDisplayed()
-
- onElement(TestElements.Foo, TestScenes.SceneB)
- .assertPositionInRootIsEqualTo(10.dp, 50.dp)
- .assertSizeIsEqualTo(20.dp, 80.dp)
- }
- at(16) {
- onElement(TestElements.Foo, TestScenes.SceneA).assertIsNotDisplayed()
-
- onElement(TestElements.Foo, TestScenes.SceneB)
- .assertPositionInRootIsEqualTo(20.dp, 55.dp)
- .assertSizeIsEqualTo(17.5.dp, 70.dp)
- }
- at(32) {
- onElement(TestElements.Foo, TestScenes.SceneA).assertIsNotDisplayed()
-
- onElement(TestElements.Foo, TestScenes.SceneB)
- .assertPositionInRootIsEqualTo(30.dp, 60.dp)
- .assertSizeIsEqualTo(15.dp, 60.dp)
- }
- at(48) {
- onElement(TestElements.Foo, TestScenes.SceneA).assertIsNotDisplayed()
-
onElement(TestElements.Foo, TestScenes.SceneB)
- .assertPositionInRootIsEqualTo(40.dp, 65.dp)
- .assertSizeIsEqualTo(12.5.dp, 50.dp)
+ .assertPositionInRootIsEqualTo(
+ interpolate(10.dp, 50.dp),
+ interpolate(50.dp, 70.dp),
+ )
+ .assertSizeIsEqualTo(interpolate(20.dp, 10.dp), interpolate(80.dp, 40.dp))
}
after {
onElement(TestElements.Foo).assertPositionInRootIsEqualTo(50.dp, 70.dp)
@@ -132,29 +111,11 @@ class SharedElementTest {
},
) {
before { onElement(TestElements.Foo).assertPositionInRootIsEqualTo(10.dp, 50.dp) }
- at(0) {
- onElement(TestElements.Foo, scene = TestScenes.SceneA)
- .assertPositionInRootIsEqualTo(10.dp, 50.dp)
- onElement(TestElements.Foo, scene = TestScenes.SceneB)
- .assertPositionInRootIsEqualTo(50.dp, 100.dp)
- }
- at(16) {
- onElement(TestElements.Foo, scene = TestScenes.SceneA)
- .assertPositionInRootIsEqualTo(7.5.dp, 50.dp)
- onElement(TestElements.Foo, scene = TestScenes.SceneB)
- .assertPositionInRootIsEqualTo(50.dp, 90.dp)
- }
- at(32) {
- onElement(TestElements.Foo, scene = TestScenes.SceneA)
- .assertPositionInRootIsEqualTo(5.dp, 50.dp)
- onElement(TestElements.Foo, scene = TestScenes.SceneB)
- .assertPositionInRootIsEqualTo(50.dp, 80.dp)
- }
- at(48) {
+ atAllFrames(4) {
onElement(TestElements.Foo, scene = TestScenes.SceneA)
- .assertPositionInRootIsEqualTo(2.5.dp, 50.dp)
+ .assertPositionInRootIsEqualTo(interpolate(10.dp, 0.dp), 50.dp)
onElement(TestElements.Foo, scene = TestScenes.SceneB)
- .assertPositionInRootIsEqualTo(50.dp, 70.dp)
+ .assertPositionInRootIsEqualTo(50.dp, interpolate(100.dp, 60.dp))
}
after { onElement(TestElements.Foo).assertPositionInRootIsEqualTo(50.dp, 60.dp) }
}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/ui/util/IntIndexMapTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/ui/util/IntIndexMapTest.kt
new file mode 100644
index 000000000000..d7a9b9007be0
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/ui/util/IntIndexMapTest.kt
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compose.ui.util
+
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+
+class IntIndexMapTest {
+
+ @Test
+ fun testSetGetFirstAndSize() {
+ val map = IntIndexedMap<String>()
+
+ // Write first element at 10
+ map[10] = "1"
+ assertThat(map[10]).isEqualTo("1")
+ assertThat(map.size).isEqualTo(1)
+ assertThat(map.first()).isEqualTo("1")
+
+ // Write same element to same index
+ map[10] = "1"
+ assertThat(map[10]).isEqualTo("1")
+ assertThat(map.size).isEqualTo(1)
+
+ // Writing into larger index
+ map[12] = "2"
+ assertThat(map[12]).isEqualTo("2")
+ assertThat(map.size).isEqualTo(2)
+ assertThat(map.first()).isEqualTo("1")
+
+ // Overwriting existing index
+ map[10] = "3"
+ assertThat(map[10]).isEqualTo("3")
+ assertThat(map.size).isEqualTo(2)
+ assertThat(map.first()).isEqualTo("3")
+
+ // Writing into smaller index
+ map[0] = "4"
+ assertThat(map[0]).isEqualTo("4")
+ assert(map.size == 3)
+ assertThat(map.first()).isEqualTo("4")
+
+ // Writing null into non-null index
+ map[0] = null
+ assertThat(map[0]).isEqualTo(null)
+ assertThat(map.size).isEqualTo(2)
+ assertThat(map.first()).isEqualTo("3")
+
+ // Writing null into smaller null index
+ map[1] = null
+ assertThat(map[1]).isEqualTo(null)
+ assertThat(map.size).isEqualTo(2)
+
+ // Writing null into larger null index
+ map[15] = null
+ assertThat(map[15]).isEqualTo(null)
+ assertThat(map.size).isEqualTo(2)
+
+ // Remove existing element
+ map.remove(12)
+ assertThat(map[12]).isEqualTo(null)
+ assertThat(map.size).isEqualTo(1)
+
+ // Remove non-existing element
+ map.remove(17)
+ assertThat(map[17]).isEqualTo(null)
+ assertThat(map.size).isEqualTo(1)
+
+ // Remove all elements
+ assertThat(map.first()).isEqualTo("3")
+ map.remove(10)
+ map.remove(10)
+ map.remove(0)
+ assertThat(map.size).isEqualTo(0)
+ assertThat(map[10]).isEqualTo(null)
+ assertThat(map.size).isEqualTo(0)
+ }
+}
diff --git a/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestTransition.kt b/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestTransition.kt
index 0d2fcfc0b790..124b61e45ed6 100644
--- a/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestTransition.kt
+++ b/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestTransition.kt
@@ -16,6 +16,8 @@
package com.android.compose.animation.scene
+import androidx.compose.animation.core.LinearEasing
+import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
@@ -27,6 +29,9 @@ import androidx.compose.ui.semantics.SemanticsNode
import androidx.compose.ui.test.SemanticsNodeInteraction
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
import androidx.compose.ui.test.junit4.ComposeContentTestRule
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.lerp
+import androidx.compose.ui.util.lerp
import kotlinx.coroutines.CoroutineScope
import platform.test.motion.MotionTestRule
import platform.test.motion.RecordedMotion
@@ -62,6 +67,16 @@ interface TransitionTestBuilder {
fun at(timestamp: Long, builder: TransitionTestAssertionScope.() -> Unit)
/**
+ * Run the same assertion for all frames of a transition.
+ *
+ * @param totalFrames needs to be the exact number of frames of the transition that is run,
+ * otherwise the passed progress will be incorrect. That is the duration in ms divided by 16.
+ * @param builder is passed a progress Float which can be used to calculate values for the
+ * specific frame. Or use [AutoTransitionTestAssertionScope.interpolate].
+ */
+ fun atAllFrames(totalFrames: Int, builder: AutoTransitionTestAssertionScope.(Float) -> Unit)
+
+ /**
* Assert on the state of the layout after the transition finished.
*
* This should be called maximum once, after [before] or [at] is called.
@@ -82,6 +97,16 @@ interface TransitionTestAssertionScope {
fun onElement(element: ElementKey, scene: SceneKey? = null): SemanticsNodeInteraction
}
+interface AutoTransitionTestAssertionScope : TransitionTestAssertionScope {
+
+ /** Linear interpolate [from] and [to] with the current progress of the transition. */
+ fun <T> interpolate(from: T, to: T): T
+}
+
+val Default4FrameLinearTransition: TransitionBuilder.() -> Unit = {
+ spec = tween(16 * 4, easing = LinearEasing)
+}
+
/**
* Test the transition between [fromSceneContent] and [toSceneContent] at different points in time.
*
@@ -90,10 +115,13 @@ interface TransitionTestAssertionScope {
fun ComposeContentTestRule.testTransition(
fromSceneContent: @Composable ContentScope.() -> Unit,
toSceneContent: @Composable ContentScope.() -> Unit,
- transition: TransitionBuilder.() -> Unit,
+ transition: TransitionBuilder.() -> Unit = Default4FrameLinearTransition,
layoutModifier: Modifier = Modifier,
fromScene: SceneKey = TestScenes.SceneA,
toScene: SceneKey = TestScenes.SceneB,
+ changeState: CoroutineScope.(MutableSceneTransitionLayoutState) -> Unit = { state ->
+ state.setTargetScene(toScene, animationScope = this)
+ },
builder: TransitionTestBuilder.() -> Unit,
) {
testTransition(
@@ -104,7 +132,7 @@ fun ComposeContentTestRule.testTransition(
transitions { from(fromScene, to = toScene, builder = transition) },
)
},
- to = toScene,
+ changeState = changeState,
transitionLayout = { state ->
SceneTransitionLayout(state, layoutModifier) {
scene(fromScene, content = fromSceneContent)
@@ -293,13 +321,30 @@ fun ComposeContentTestRule.testTransition(
) {
val test = transitionTest(builder)
val assertionScope =
- object : TransitionTestAssertionScope {
+ object : AutoTransitionTestAssertionScope {
+ var progress = 0f
+
override fun onElement(
element: ElementKey,
scene: SceneKey?,
): SemanticsNodeInteraction {
return onNode(isElement(element, scene))
}
+
+ override fun <T> interpolate(from: T, to: T): T {
+ @Suppress("UNCHECKED_CAST")
+ return when {
+ from is Float && to is Float -> lerp(from, to, progress)
+ from is Int && to is Int -> lerp(from, to, progress)
+ from is Long && to is Long -> lerp(from, to, progress)
+ from is Dp && to is Dp -> lerp(from, to, progress)
+ else ->
+ throw UnsupportedOperationException(
+ "Interpolation not supported for this type"
+ )
+ }
+ as T
+ }
}
lateinit var coroutineScope: CoroutineScope
@@ -321,14 +366,28 @@ fun ComposeContentTestRule.testTransition(
mainClock.advanceTimeByFrame()
waitForIdle()
+ var currentTime = 0L
// Test the assertions at specific points in time.
test.timestamps.forEach { tsAssertion ->
if (tsAssertion.timestampDelta > 0L) {
mainClock.advanceTimeBy(tsAssertion.timestampDelta)
waitForIdle()
+ currentTime += tsAssertion.timestampDelta.toInt()
}
- tsAssertion.assertion(assertionScope)
+ assertionScope.progress = tsAssertion.progress
+ try {
+ tsAssertion.assertion(assertionScope, tsAssertion.progress)
+ } catch (assertionError: AssertionError) {
+ if (assertionScope.progress > 0) {
+ throw AssertionError(
+ "Transition assertion failed at ${currentTime}ms " +
+ "at progress: ${assertionScope.progress}f",
+ assertionError,
+ )
+ }
+ throw assertionError
+ }
}
// Go to the end state and test it.
@@ -371,7 +430,25 @@ private fun transitionTest(builder: TransitionTestBuilder.() -> Unit): Transitio
val delta = timestamp - currentTimestamp
currentTimestamp = timestamp
- timestamps.add(TimestampAssertion(delta, builder))
+ timestamps.add(TimestampAssertion(delta, { builder() }, 0f))
+ }
+
+ override fun atAllFrames(
+ totalFrames: Int,
+ builder: AutoTransitionTestAssertionScope.(Float) -> Unit,
+ ) {
+ check(after == null) { "atFrames(...) {} must be called before after {}" }
+ check(currentTimestamp == 0L) {
+ "atFrames(...) can't be called multiple times or after at(...)"
+ }
+
+ for (frame in 0 until totalFrames) {
+ val timestamp = frame * 16L
+ val delta = timestamp - currentTimestamp
+ val progress = frame.toFloat() / totalFrames
+ currentTimestamp = timestamp
+ timestamps.add(TimestampAssertion(delta, builder, progress))
+ }
}
override fun after(builder: TransitionTestAssertionScope.() -> Unit) {
@@ -396,5 +473,6 @@ private class TransitionTest(
private class TimestampAssertion(
val timestampDelta: Long,
- val assertion: TransitionTestAssertionScope.() -> Unit,
+ val assertion: AutoTransitionTestAssertionScope.(Float) -> Unit,
+ val progress: Float,
)
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderClient.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderClient.kt
index 34c4dfb4bc54..48af2d9f5542 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderClient.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderClient.kt
@@ -25,6 +25,7 @@ import android.database.ContentObserver
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.net.Uri
+import android.os.Bundle
import android.util.Log
import androidx.annotation.DrawableRes
import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
@@ -51,10 +52,7 @@ interface CustomizationProviderClient {
* selected affordances on the slot will move the selected affordance to the newest location in
* the slot.
*/
- suspend fun insertSelection(
- slotId: String,
- affordanceId: String,
- )
+ suspend fun insertSelection(slotId: String, affordanceId: String)
/** Returns all available slots supported by the device. */
suspend fun querySlots(): List<Slot>
@@ -63,6 +61,11 @@ interface CustomizationProviderClient {
suspend fun queryFlags(): List<Flag>
/**
+ * Returns [Bundle] where the keys are from [CustomizationProviderContract.RuntimeValuesTable]
+ */
+ suspend fun queryRuntimeValues(): Bundle
+
+ /**
* Returns [Flow] for observing the collection of slots.
*
* @see [querySlots]
@@ -77,6 +80,13 @@ interface CustomizationProviderClient {
fun observeFlags(): Flow<List<Flag>>
/**
+ * Returns [Flow] for observing the variables from the System UI.
+ *
+ * @see [queryRuntimeValues]
+ */
+ fun observeRuntimeValues(): Flow<Bundle>
+
+ /**
* Returns all available affordances supported by the device, regardless of current slot
* placement.
*/
@@ -100,15 +110,10 @@ interface CustomizationProviderClient {
fun observeSelections(): Flow<List<Selection>>
/** Unselects an affordance with the given ID from the slot with the given ID. */
- suspend fun deleteSelection(
- slotId: String,
- affordanceId: String,
- )
+ suspend fun deleteSelection(slotId: String, affordanceId: String)
/** Unselects all affordances from the slot with the given ID. */
- suspend fun deleteAllSelections(
- slotId: String,
- )
+ suspend fun deleteAllSelections(slotId: String)
/** Returns a [Drawable] with the given ID, loaded from the system UI package. */
suspend fun getAffordanceIcon(
@@ -200,10 +205,7 @@ class CustomizationProviderClientImpl(
private val backgroundDispatcher: CoroutineDispatcher,
) : CustomizationProviderClient {
- override suspend fun insertSelection(
- slotId: String,
- affordanceId: String,
- ) {
+ override suspend fun insertSelection(slotId: String, affordanceId: String) {
withContext(backgroundDispatcher) {
context.contentResolver.insert(
Contract.LockScreenQuickAffordances.SelectionTable.URI,
@@ -211,9 +213,9 @@ class CustomizationProviderClientImpl(
put(Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID, slotId)
put(
Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID,
- affordanceId
+ affordanceId,
)
- }
+ },
)
}
}
@@ -221,13 +223,7 @@ class CustomizationProviderClientImpl(
override suspend fun querySlots(): List<CustomizationProviderClient.Slot> {
return withContext(backgroundDispatcher) {
context.contentResolver
- .query(
- Contract.LockScreenQuickAffordances.SlotTable.URI,
- null,
- null,
- null,
- null,
- )
+ .query(Contract.LockScreenQuickAffordances.SlotTable.URI, null, null, null, null)
?.use { cursor ->
buildList {
val idColumnIndex =
@@ -252,42 +248,55 @@ class CustomizationProviderClientImpl(
}
}
}
- }
- ?: emptyList()
+ } ?: emptyList()
}
override suspend fun queryFlags(): List<CustomizationProviderClient.Flag> {
return withContext(backgroundDispatcher) {
- context.contentResolver
- .query(
- Contract.FlagsTable.URI,
- null,
- null,
- null,
- null,
- )
- ?.use { cursor ->
- buildList {
+ context.contentResolver.query(Contract.FlagsTable.URI, null, null, null, null)?.use {
+ cursor ->
+ buildList {
+ val nameColumnIndex = cursor.getColumnIndex(Contract.FlagsTable.Columns.NAME)
+ val valueColumnIndex = cursor.getColumnIndex(Contract.FlagsTable.Columns.VALUE)
+ if (nameColumnIndex == -1 || valueColumnIndex == -1) {
+ return@buildList
+ }
+
+ while (cursor.moveToNext()) {
+ add(
+ CustomizationProviderClient.Flag(
+ name = cursor.getString(nameColumnIndex),
+ value = cursor.getInt(valueColumnIndex) == 1,
+ )
+ )
+ }
+ }
+ }
+ } ?: emptyList()
+ }
+
+ override suspend fun queryRuntimeValues(): Bundle {
+ return withContext(backgroundDispatcher) {
+ Bundle().apply {
+ context.contentResolver
+ .query(Contract.RuntimeValuesTable.URI, null, null, null, null)
+ ?.use { cursor ->
val nameColumnIndex =
cursor.getColumnIndex(Contract.FlagsTable.Columns.NAME)
val valueColumnIndex =
cursor.getColumnIndex(Contract.FlagsTable.Columns.VALUE)
- if (nameColumnIndex == -1 || valueColumnIndex == -1) {
- return@buildList
- }
-
- while (cursor.moveToNext()) {
- add(
- CustomizationProviderClient.Flag(
- name = cursor.getString(nameColumnIndex),
- value = cursor.getInt(valueColumnIndex) == 1,
- )
- )
+ if (nameColumnIndex >= 0 && valueColumnIndex >= 0) {
+ while (cursor.moveToNext()) {
+ when (val name = cursor.getString(nameColumnIndex)) {
+ Contract.RuntimeValuesTable.KEY_IS_SHADE_LAYOUT_WIDE -> {
+ putBoolean(name, cursor.getInt(valueColumnIndex) == 1)
+ }
+ }
+ }
}
}
- }
+ }
}
- ?: emptyList()
}
override fun observeSlots(): Flow<List<CustomizationProviderClient.Slot>> {
@@ -298,6 +307,10 @@ class CustomizationProviderClientImpl(
return observeUri(Contract.FlagsTable.URI).map { queryFlags() }
}
+ override fun observeRuntimeValues(): Flow<Bundle> {
+ return observeUri(Contract.RuntimeValuesTable.URI).map { queryRuntimeValues() }
+ }
+
override suspend fun queryAffordances(): List<CustomizationProviderClient.Affordance> {
return withContext(backgroundDispatcher) {
context.contentResolver
@@ -375,22 +388,17 @@ class CustomizationProviderClientImpl(
enablementActionIntent =
cursor
.getString(enablementActionIntentColumnIndex)
- ?.toIntent(
- affordanceId = affordanceId,
- ),
+ ?.toIntent(affordanceId = affordanceId),
configureIntent =
cursor
.getString(configureIntentColumnIndex)
- ?.toIntent(
- affordanceId = affordanceId,
- ),
+ ?.toIntent(affordanceId = affordanceId),
)
)
}
}
}
- }
- ?: emptyList()
+ } ?: emptyList()
}
override fun observeAffordances(): Flow<List<CustomizationProviderClient.Affordance>> {
@@ -444,8 +452,7 @@ class CustomizationProviderClientImpl(
}
}
}
- }
- ?: emptyList()
+ } ?: emptyList()
}
override fun observeSelections(): Flow<List<CustomizationProviderClient.Selection>> {
@@ -454,34 +461,24 @@ class CustomizationProviderClientImpl(
}
}
- override suspend fun deleteSelection(
- slotId: String,
- affordanceId: String,
- ) {
+ override suspend fun deleteSelection(slotId: String, affordanceId: String) {
withContext(backgroundDispatcher) {
context.contentResolver.delete(
Contract.LockScreenQuickAffordances.SelectionTable.URI,
"${Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID} = ? AND" +
" ${Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID}" +
" = ?",
- arrayOf(
- slotId,
- affordanceId,
- ),
+ arrayOf(slotId, affordanceId),
)
}
}
- override suspend fun deleteAllSelections(
- slotId: String,
- ) {
+ override suspend fun deleteAllSelections(slotId: String) {
withContext(backgroundDispatcher) {
context.contentResolver.delete(
Contract.LockScreenQuickAffordances.SelectionTable.URI,
Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID,
- arrayOf(
- slotId,
- ),
+ arrayOf(slotId),
)
}
}
@@ -499,9 +496,7 @@ class CustomizationProviderClientImpl(
}
}
- private fun observeUri(
- uri: Uri,
- ): Flow<Unit> {
+ private fun observeUri(uri: Uri): Flow<Unit> {
return callbackFlow {
val observer =
object : ContentObserver(null) {
@@ -522,9 +517,7 @@ class CustomizationProviderClientImpl(
.flowOn(backgroundDispatcher)
}
- private fun String.toIntent(
- affordanceId: String,
- ): Intent? {
+ private fun String.toIntent(affordanceId: String): Intent? {
return try {
Intent.parseUri(this, Intent.URI_INTENT_SCHEME)
} catch (e: URISyntaxException) {
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt
index 8721c7885265..cb167eddcea9 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt
@@ -198,4 +198,27 @@ object CustomizationProviderContract {
const val VALUE = "value"
}
}
+
+ object RuntimeValuesTable {
+ const val TABLE_NAME = "runtime_values"
+ val URI: Uri = BASE_URI.buildUpon().path(TABLE_NAME).build()
+
+ /**
+ * This key corresponds to an Int value, where `1` means `true` and `0` means `false`.
+ *
+ * Whether the shade layout should be wide (true) or narrow (false).
+ *
+ * In a wide layout, notifications and quick settings each take up only half the screen
+ * width (whether they are shown at the same time or not). In a narrow layout, they can each
+ * be as wide as the entire screen.
+ */
+ const val KEY_IS_SHADE_LAYOUT_WIDE = "is_shade_layout_wide"
+
+ object Columns {
+ /** String. Unique ID for the value. */
+ const val NAME = "name"
+ /** Type depends on the key name. */
+ const val VALUE = "value"
+ }
+ }
}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/FakeCustomizationProviderClient.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/FakeCustomizationProviderClient.kt
index f5a955d450e3..47c5bda93c0e 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/FakeCustomizationProviderClient.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/FakeCustomizationProviderClient.kt
@@ -19,6 +19,7 @@ package com.android.systemui.shared.customization.data.content
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
+import android.os.Bundle
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -64,11 +65,13 @@ class FakeCustomizationProviderClient(
value = true,
)
),
+ runtimeValues: Bundle = Bundle(),
) : CustomizationProviderClient {
private val slots = MutableStateFlow(slots)
private val affordances = MutableStateFlow(affordances)
private val flags = MutableStateFlow(flags)
+ private val runtimeValues = MutableStateFlow(runtimeValues)
private val selections = MutableStateFlow<Map<String, List<String>>>(emptyMap())
@@ -93,6 +96,10 @@ class FakeCustomizationProviderClient(
return flags.value
}
+ override suspend fun queryRuntimeValues(): Bundle {
+ return runtimeValues.value
+ }
+
override fun observeSlots(): Flow<List<CustomizationProviderClient.Slot>> {
return slots.asStateFlow()
}
@@ -101,6 +108,10 @@ class FakeCustomizationProviderClient(
return flags.asStateFlow()
}
+ override fun observeRuntimeValues(): Flow<Bundle> {
+ return runtimeValues.asStateFlow()
+ }
+
override suspend fun queryAffordances(): List<CustomizationProviderClient.Affordance> {
return affordances.value
}
@@ -139,10 +150,7 @@ class FakeCustomizationProviderClient(
}
}
- fun setFlag(
- name: String,
- value: Boolean,
- ) {
+ fun setFlag(name: String, value: Boolean) {
flags.value =
flags.value.toMutableList().apply {
removeIf { it.name == name }
@@ -150,6 +158,10 @@ class FakeCustomizationProviderClient(
}
}
+ fun setRuntimeValues(runtimeValues: Bundle) {
+ this.runtimeValues.value = runtimeValues
+ }
+
fun setSlotCapacity(slotId: String, capacity: Int) {
slots.value =
slots.value.toMutableList().apply {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/fontscaling b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogDelegateTest.kt
index 0bd00fb0a0e9..f1401f18f1d9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/fontscaling
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogDelegateTest.kt
@@ -50,8 +50,8 @@ import org.mockito.ArgumentMatchers.anyLong
import org.mockito.Mock
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations
import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
private const val ON: Int = 1
private const val OFF: Int = 0
@@ -103,7 +103,7 @@ class FontScalingDialogDelegateTest : SysuiTestCase() {
systemClock,
userTracker,
mainHandler,
- backgroundDelayableExecutor
+ backgroundDelayableExecutor,
)
)
@@ -116,7 +116,7 @@ class FontScalingDialogDelegateTest : SysuiTestCase() {
sysuiState,
fakeBroadcastDispatcher,
mDialogTransitionAnimator,
- fontScalingDialogDelegate
+ fontScalingDialogDelegate,
)
whenever(dialogFactory.create(any(), any())).thenReturn(dialog)
@@ -132,7 +132,7 @@ class FontScalingDialogDelegateTest : SysuiTestCase() {
systemSettings.getFloatForUser(
Settings.System.FONT_SCALE,
/* def= */ 1.0f,
- userTracker.userId
+ userTracker.userId,
)
assertThat(currentScale).isEqualTo(fontSizeValueArray[progress].toFloat())
@@ -163,7 +163,7 @@ class FontScalingDialogDelegateTest : SysuiTestCase() {
systemSettings.getFloatForUser(
Settings.System.FONT_SCALE,
/* def= */ 1.0f,
- userTracker.userId
+ userTracker.userId,
)
assertThat(seekBar.getProgress()).isEqualTo(1)
assertThat(currentScale).isEqualTo(fontSizeValueArray[1].toFloat())
@@ -194,7 +194,7 @@ class FontScalingDialogDelegateTest : SysuiTestCase() {
systemSettings.getFloatForUser(
Settings.System.FONT_SCALE,
/* def= */ 1.0f,
- userTracker.userId
+ userTracker.userId,
)
assertThat(seekBar.getProgress()).isEqualTo(fontSizeValueArray.size - 2)
assertThat(currentScale)
@@ -211,7 +211,7 @@ class FontScalingDialogDelegateTest : SysuiTestCase() {
secureSettings.putIntForUser(
Settings.Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED,
OFF,
- userTracker.userId
+ userTracker.userId,
)
// Default seekbar progress for font size is 1, click start icon to decrease the progress
@@ -224,7 +224,7 @@ class FontScalingDialogDelegateTest : SysuiTestCase() {
secureSettings.getIntForUser(
Settings.Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED,
/* def = */ OFF,
- userTracker.userId
+ userTracker.userId,
)
assertThat(currentSettings).isEqualTo(ON)
@@ -256,7 +256,7 @@ class FontScalingDialogDelegateTest : SysuiTestCase() {
systemSettings.getFloatForUser(
Settings.System.FONT_SCALE,
/* def= */ 1.0f,
- userTracker.userId
+ userTracker.userId,
)
assertThat(systemScale).isEqualTo(1.0f)
@@ -269,7 +269,7 @@ class FontScalingDialogDelegateTest : SysuiTestCase() {
// SeekBar interaction is finalized.
changeListener.onUserInteractionFinalized(
seekBar,
- OnSeekBarWithIconButtonsChangeListener.ControlUnitType.SLIDER
+ OnSeekBarWithIconButtonsChangeListener.ControlUnitType.SLIDER,
)
backgroundDelayableExecutor.runAllReady()
backgroundDelayableExecutor.advanceClockToNext()
@@ -280,7 +280,7 @@ class FontScalingDialogDelegateTest : SysuiTestCase() {
systemSettings.getFloatForUser(
Settings.System.FONT_SCALE,
/* def= */ 1.0f,
- userTracker.userId
+ userTracker.userId,
)
assertThat(systemScale).isEqualTo(fontSizeValueArray[0].toFloat())
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 91f9cce5b69b..b8d4bb4b8e77 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -667,6 +667,7 @@ open class AuthContainerViewTest : SysuiTestCase() {
faceProps,
wakefulnessLifecycle,
userManager,
+ null /* authContextPlugins */,
lockPatternUtils,
interactionJankMonitor,
{ promptSelectorInteractor },
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java
index 2dcbdc80f695..2817f5573865 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -117,6 +117,7 @@ import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
import java.util.Random;
@RunWith(AndroidJUnit4.class)
@@ -1187,7 +1188,8 @@ public class AuthControllerTest extends SysuiTestCase {
TestableAuthController(Context context) {
super(context, null /* applicationCoroutineScope */,
mExecution, mCommandQueue, mActivityTaskManager, mWindowManager,
- mFingerprintManager, mFaceManager, () -> mUdfpsController, mDisplayManager,
+ mFingerprintManager, mFaceManager, Optional.empty(),
+ () -> mUdfpsController, mDisplayManager,
mWakefulnessLifecycle, mUserManager, mLockPatternUtils, () -> mUdfpsLogger,
() -> mLogContextInteractor, () -> mPromptSelectionInteractor,
() -> mCredentialViewModel, () -> mPromptViewModel, mInteractionJankMonitor,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index 21c6583d4e84..aeea99be40dd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -365,6 +365,25 @@ public class UdfpsControllerTest extends SysuiTestCase {
}
@Test
+ public void showUdfpsOverlay_invokedTwice_doesNotNotifyListenerSecondTime() throws RemoteException {
+ mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
+ BiometricRequestConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
+ mFgExecutor.runAllReady();
+
+ verify(mFingerprintManager).onUdfpsUiEvent(FingerprintManager.UDFPS_UI_OVERLAY_SHOWN,
+ TEST_REQUEST_ID, mOpticalProps.sensorId);
+
+ reset(mFingerprintManager);
+
+ // Second attempt should do nothing
+ mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
+ BiometricRequestConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
+ mFgExecutor.runAllReady();
+ verify(mFingerprintManager, never()).onUdfpsUiEvent(FingerprintManager.UDFPS_UI_OVERLAY_SHOWN,
+ TEST_REQUEST_ID, mOpticalProps.sensorId);
+ }
+
+ @Test
public void testSubscribesToOrientationChangesWhenShowingOverlay() throws Exception {
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
BiometricRequestConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerPredictiveBackTest.kt
index 97f2e56e6eec..b33a83cf202a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerPredictiveBackTest.kt
@@ -59,6 +59,7 @@ import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.rememberViewModel
import com.android.systemui.motion.createSysUiComposeMotionTestRule
+import com.android.systemui.qs.ui.viewmodel.fakeQsSceneAdapter
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.domain.startable.sceneContainerStartable
import com.android.systemui.scene.sceneContainerViewModelFactory
@@ -67,6 +68,7 @@ import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.sceneDataSourceDelegator
import com.android.systemui.scene.ui.composable.Scene
import com.android.systemui.scene.ui.composable.SceneContainer
+import com.android.systemui.scene.ui.composable.SceneContainerTransitions
import com.android.systemui.testKosmos
import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.awaitCancellation
@@ -114,7 +116,13 @@ class BouncerPredictiveBackTest : SysuiTestCase() {
private val Kosmos.initialSceneKey by Fixture { Scenes.Bouncer }
private val Kosmos.sceneContainerConfig by Fixture {
val navigationDistances = mapOf(Scenes.Lockscreen to 1, Scenes.Bouncer to 0)
- SceneContainerConfig(sceneKeys, initialSceneKey, emptyList(), navigationDistances)
+ SceneContainerConfig(
+ sceneKeys,
+ initialSceneKey,
+ SceneContainerTransitions,
+ emptyList(),
+ navigationDistances,
+ )
}
private val view = mock<View>()
@@ -181,8 +189,10 @@ class BouncerPredictiveBackTest : SysuiTestCase() {
Scenes.Bouncer to bouncerScene,
),
initialSceneKey = Scenes.Bouncer,
+ sceneTransitions = SceneContainerTransitions,
overlayByKey = emptyMap(),
dataSourceDelegator = kosmos.sceneDataSourceDelegator,
+ qsSceneAdapter = { kosmos.fakeQsSceneAdapter },
)
}
},
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModelTest.kt
index 3bf4460e0a4a..94f6769ba406 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModelTest.kt
@@ -34,6 +34,11 @@ import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.flags.Flags
import com.android.systemui.flags.fakeFeatureFlagsClassic
+import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
+import com.android.systemui.keyguard.shared.model.DismissAction
+import com.android.systemui.keyguard.shared.model.KeyguardDone
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testScope
import com.android.systemui.lifecycle.activateIn
import com.android.systemui.res.R
@@ -212,6 +217,25 @@ class BouncerSceneContentViewModelTest : SysuiTestCase() {
assertThat(isFoldSplitRequired).isTrue()
}
+ @Test
+ fun onUiDestroyed_clearsPendingDismissAction() =
+ kosmos.runTest {
+ val dismissAction by collectLastValue(fakeKeyguardRepository.dismissAction)
+ fakeKeyguardRepository.setDismissAction(
+ DismissAction.RunImmediately(
+ onDismissAction = { KeyguardDone.IMMEDIATE },
+ onCancelAction = {},
+ message = "",
+ willAnimateOnLockscreen = true,
+ )
+ )
+ assertThat(dismissAction).isNotEqualTo(DismissAction.None)
+
+ underTest.onUiDestroyed()
+
+ assertThat(dismissAction).isEqualTo(DismissAction.None)
+ }
+
private fun authMethodsToTest(): List<AuthenticationMethodModel> {
return listOf(None, Pin, Password, Pattern, Sim)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt
index 06b710eb86eb..b66727e492cf 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt
@@ -22,6 +22,7 @@ import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL
import android.app.admin.devicePolicyManager
import android.content.Intent
import android.content.pm.UserInfo
+import android.content.res.mainResources
import android.os.UserManager.USER_TYPE_PROFILE_MANAGED
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
@@ -29,6 +30,7 @@ import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
+import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.broadcastDispatcher
import com.android.systemui.communal.data.model.DisabledReason
@@ -53,7 +55,8 @@ import org.mockito.ArgumentMatchers.eq
@SmallTest
@RunWith(AndroidJUnit4::class)
class CommunalSettingsRepositoryImplTest : SysuiTestCase() {
- private val kosmos = testKosmos()
+ private val kosmos =
+ testKosmos().apply { mainResources = mContext.orCreateTestableResources.resources }
private val testScope = kosmos.testScope
private lateinit var underTest: CommunalSettingsRepository
@@ -67,6 +70,7 @@ class CommunalSettingsRepositoryImplTest : SysuiTestCase() {
}
@EnableFlags(FLAG_COMMUNAL_HUB)
+ @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
@Test
fun getFlagEnabled_bothEnabled() {
kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)
@@ -74,7 +78,7 @@ class CommunalSettingsRepositoryImplTest : SysuiTestCase() {
assertThat(underTest.getFlagEnabled()).isTrue()
}
- @DisableFlags(FLAG_COMMUNAL_HUB)
+ @DisableFlags(FLAG_COMMUNAL_HUB, FLAG_GLANCEABLE_HUB_V2)
@Test
fun getFlagEnabled_bothDisabled() {
kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, false)
@@ -82,7 +86,7 @@ class CommunalSettingsRepositoryImplTest : SysuiTestCase() {
assertThat(underTest.getFlagEnabled()).isFalse()
}
- @DisableFlags(FLAG_COMMUNAL_HUB)
+ @DisableFlags(FLAG_COMMUNAL_HUB, FLAG_GLANCEABLE_HUB_V2)
@Test
fun getFlagEnabled_onlyClassicFlagEnabled() {
kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)
@@ -91,6 +95,7 @@ class CommunalSettingsRepositoryImplTest : SysuiTestCase() {
}
@EnableFlags(FLAG_COMMUNAL_HUB)
+ @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
@Test
fun getFlagEnabled_onlyTrunkFlagEnabled() {
kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, false)
@@ -98,6 +103,57 @@ class CommunalSettingsRepositoryImplTest : SysuiTestCase() {
assertThat(underTest.getFlagEnabled()).isFalse()
}
+ @EnableFlags(FLAG_GLANCEABLE_HUB_V2)
+ @DisableFlags(FLAG_COMMUNAL_HUB)
+ @Test
+ fun getFlagEnabled_mobileConfigEnabled() {
+ mContext.orCreateTestableResources.addOverride(
+ com.android.internal.R.bool.config_glanceableHubEnabled,
+ true,
+ )
+
+ assertThat(underTest.getFlagEnabled()).isTrue()
+ }
+
+ @DisableFlags(FLAG_GLANCEABLE_HUB_V2, FLAG_COMMUNAL_HUB)
+ @Test
+ fun getFlagEnabled_onlyMobileConfigEnabled() {
+ mContext.orCreateTestableResources.addOverride(
+ com.android.internal.R.bool.config_glanceableHubEnabled,
+ true,
+ )
+
+ assertThat(underTest.getFlagEnabled()).isFalse()
+ }
+
+ @EnableFlags(FLAG_GLANCEABLE_HUB_V2)
+ @DisableFlags(FLAG_COMMUNAL_HUB)
+ @Test
+ fun getFlagEnabled_onlyMobileFlagEnabled() {
+ mContext.orCreateTestableResources.addOverride(
+ com.android.internal.R.bool.config_glanceableHubEnabled,
+ false,
+ )
+
+ assertThat(underTest.getFlagEnabled()).isFalse()
+ }
+
+ @EnableFlags(FLAG_GLANCEABLE_HUB_V2)
+ @DisableFlags(FLAG_COMMUNAL_HUB)
+ @Test
+ fun getFlagEnabled_oldFlagIgnored() {
+ // New config flag enabled.
+ mContext.orCreateTestableResources.addOverride(
+ com.android.internal.R.bool.config_glanceableHubEnabled,
+ true,
+ )
+
+ // Old config flag disabled.
+ kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, false)
+
+ assertThat(underTest.getFlagEnabled()).isTrue()
+ }
+
@EnableFlags(FLAG_COMMUNAL_HUB)
@Test
fun secondaryUserIsInvalid() =
@@ -134,7 +190,7 @@ class CommunalSettingsRepositoryImplTest : SysuiTestCase() {
kosmos.fakeSettings.putIntForUser(
Settings.Secure.GLANCEABLE_HUB_ENABLED,
0,
- PRIMARY_USER.id
+ PRIMARY_USER.id,
)
val enabledState by collectLastValue(underTest.getEnabledState(PRIMARY_USER))
assertThat(enabledState?.enabled).isFalse()
@@ -143,14 +199,14 @@ class CommunalSettingsRepositoryImplTest : SysuiTestCase() {
kosmos.fakeSettings.putIntForUser(
Settings.Secure.GLANCEABLE_HUB_ENABLED,
1,
- SECONDARY_USER.id
+ SECONDARY_USER.id,
)
assertThat(enabledState?.enabled).isFalse()
kosmos.fakeSettings.putIntForUser(
Settings.Secure.GLANCEABLE_HUB_ENABLED,
1,
- PRIMARY_USER.id
+ PRIMARY_USER.id,
)
assertThat(enabledState?.enabled).isTrue()
}
@@ -201,7 +257,7 @@ class CommunalSettingsRepositoryImplTest : SysuiTestCase() {
kosmos.fakeSettings.putIntForUser(
Settings.Secure.GLANCEABLE_HUB_ENABLED,
0,
- PRIMARY_USER.id
+ PRIMARY_USER.id,
)
setKeyguardFeaturesDisabled(PRIMARY_USER, KEYGUARD_DISABLE_WIDGETS_ALL)
@@ -228,7 +284,7 @@ class CommunalSettingsRepositoryImplTest : SysuiTestCase() {
kosmos.fakeSettings.putIntForUser(
GLANCEABLE_HUB_BACKGROUND_SETTING,
type.value,
- PRIMARY_USER.id
+ PRIMARY_USER.id,
)
assertWithMessage(
"Expected $type when $GLANCEABLE_HUB_BACKGROUND_SETTING is set to" +
@@ -253,12 +309,6 @@ class CommunalSettingsRepositoryImplTest : SysuiTestCase() {
UserInfo(/* id= */ 0, /* name= */ "primary user", /* flags= */ UserInfo.FLAG_MAIN)
val SECONDARY_USER = UserInfo(/* id= */ 1, /* name= */ "secondary user", /* flags= */ 0)
val WORK_PROFILE =
- UserInfo(
- 10,
- "work",
- /* iconPath= */ "",
- /* flags= */ 0,
- USER_TYPE_PROFILE_MANAGED,
- )
+ UserInfo(10, "work", /* iconPath= */ "", /* flags= */ 0, USER_TYPE_PROFILE_MANAGED)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractorImplTest.kt
new file mode 100644
index 000000000000..e1344caa8677
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractorImplTest.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.display.domain.interactor
+
+import android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR
+import android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR
+import android.view.layoutInflater
+import android.view.windowManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.display.data.repository.fakeDisplayWindowPropertiesRepository
+import com.android.systemui.display.shared.model.DisplayWindowProperties
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class DisplayWindowPropertiesInteractorImplTest : SysuiTestCase() {
+
+ private val kosmos = testKosmos()
+ private val repo = kosmos.fakeDisplayWindowPropertiesRepository
+
+ private val underTest = kosmos.displayWindowPropertiesInteractor
+
+ @Test
+ fun getForStatusBar_returnsPropertiesWithCorrectWindowType() {
+ val displayId = 123
+ val statusBarWindowProperties = createDisplayWindowProperties(displayId, TYPE_STATUS_BAR)
+ val navBarWindowProperties = createDisplayWindowProperties(displayId, TYPE_NAVIGATION_BAR)
+ repo.insert(statusBarWindowProperties)
+ repo.insert(navBarWindowProperties)
+
+ assertThat(underTest.getForStatusBar(displayId)).isEqualTo(statusBarWindowProperties)
+ }
+
+ private fun createDisplayWindowProperties(displayId: Int, windowType: Int) =
+ DisplayWindowProperties(
+ displayId,
+ windowType,
+ context,
+ kosmos.windowManager,
+ kosmos.layoutInflater,
+ )
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/InputShortcutsSourceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/InputShortcutsSourceTest.kt
index 715d907b7372..c9f703533e89 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/InputShortcutsSourceTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/InputShortcutsSourceTest.kt
@@ -17,21 +17,28 @@
package com.android.systemui.keyboard.shortcut.data.source
import android.content.res.mainResources
+import android.hardware.input.KeyGlyphMap
+import android.hardware.input.fakeInputManager
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.view.KeyEvent.KEYCODE_EMOJI_PICKER
import android.view.KeyboardShortcutGroup
import android.view.WindowManager.KeyboardShortcutsReceiver
import android.view.mockWindowManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_SHORTCUT_HELPER_KEY_GLYPH
import com.android.systemui.SysuiTestCase
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.Mockito.mock
+import org.mockito.kotlin.whenever
@SmallTest
@RunWith(AndroidJUnit4::class)
@@ -41,7 +48,8 @@ class InputShortcutsSourceTest : SysuiTestCase() {
private val testScope = kosmos.testScope
private val mockWindowManager = kosmos.mockWindowManager
- private val source = InputShortcutsSource(kosmos.mainResources, mockWindowManager)
+ private val inputManager = kosmos.fakeInputManager.inputManager
+ private val source = InputShortcutsSource(kosmos.mainResources, mockWindowManager, inputManager)
private var wmImeShortcutGroups: List<KeyboardShortcutGroup>? = null
@@ -88,6 +96,36 @@ class InputShortcutsSourceTest : SysuiTestCase() {
assertThat(groups).hasSize(4)
}
+ @Test
+ @EnableFlags(FLAG_SHORTCUT_HELPER_KEY_GLYPH)
+ fun shortcutGroups_flagEnabled_inputManagerReturnsKeyGlyph_returnsEmojiShortcut() =
+ testScope.runTest {
+ val mockKeyGlyph = mock(KeyGlyphMap::class.java)
+ whenever(mockKeyGlyph.functionRowKeys).thenReturn(intArrayOf(KEYCODE_EMOJI_PICKER))
+ whenever(inputManager.getKeyGlyphMap(TEST_DEVICE_ID)).thenReturn(mockKeyGlyph)
+ wmImeShortcutGroups = null
+
+ val groups = source.shortcutGroups(TEST_DEVICE_ID)
+
+ val keyCodes = groups[0].items.map { it.keycode }
+ assertThat(keyCodes).contains(KEYCODE_EMOJI_PICKER)
+ }
+
+ @Test
+ @DisableFlags(FLAG_SHORTCUT_HELPER_KEY_GLYPH)
+ fun shortcutGroups_flagDisabled_inputManagerReturnsKeyGlyph_returnsNoEmojiShortcut() =
+ testScope.runTest {
+ val mockKeyGlyph = mock(KeyGlyphMap::class.java)
+ whenever(mockKeyGlyph.functionRowKeys).thenReturn(intArrayOf(KEYCODE_EMOJI_PICKER))
+ whenever(inputManager.getKeyGlyphMap(TEST_DEVICE_ID)).thenReturn(mockKeyGlyph)
+ wmImeShortcutGroups = null
+
+ val groups = source.shortcutGroups(TEST_DEVICE_ID)
+
+ val keyCodes = groups[0].items.map { it.keycode }
+ assertThat(keyCodes).doesNotContain(KEYCODE_EMOJI_PICKER)
+ }
+
companion object {
private const val TEST_DEVICE_ID = 1234
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSourceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSourceTest.kt
new file mode 100644
index 000000000000..495e98d0edfb
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSourceTest.kt
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyboard.shortcut.data.source
+
+import android.content.res.mainResources
+import android.hardware.input.KeyGlyphMap
+import android.hardware.input.KeyGlyphMap.KeyCombination
+import android.hardware.input.fakeInputManager
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.view.KeyEvent
+import android.view.KeyEvent.KEYCODE_BACK
+import android.view.KeyEvent.KEYCODE_HOME
+import android.view.KeyEvent.KEYCODE_RECENT_APPS
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_SHORTCUT_HELPER_KEY_GLYPH
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.res.R
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.mock
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class SystemShortcutsSourceTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+
+ private val inputManager = kosmos.fakeInputManager.inputManager
+ private val source = SystemShortcutsSource(kosmos.mainResources, inputManager)
+ private val mockKeyGlyphMap = mock(KeyGlyphMap::class.java)
+ private val functionRowKeyCodes = listOf(KEYCODE_HOME, KEYCODE_BACK, KEYCODE_RECENT_APPS)
+
+ @Before
+ fun setUp() {
+ whenever(mockKeyGlyphMap.functionRowKeys).thenReturn(intArrayOf())
+ whenever(inputManager.getKeyGlyphMap(TEST_DEVICE_ID)).thenReturn(mockKeyGlyphMap)
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHORTCUT_HELPER_KEY_GLYPH)
+ fun shortcutGroups_flagEnabled_inputManagerReturnsNoFunctionRowKeys_returnsNoFunctionRowShortcuts() =
+ testScope.runTest {
+ val groups = source.shortcutGroups(TEST_DEVICE_ID)
+
+ val keyCodes = groups[0].items.map { it.keycode }
+ assertThat(keyCodes).containsNoneIn(functionRowKeyCodes)
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHORTCUT_HELPER_KEY_GLYPH)
+ fun shortcutGroups_flagEnabled_inputManagerReturnsFunctionRowKeys_returnsFunctionRowShortcuts() =
+ testScope.runTest {
+ whenever(mockKeyGlyphMap.functionRowKeys)
+ .thenReturn(intArrayOf(KEYCODE_HOME, KEYCODE_BACK, KEYCODE_RECENT_APPS))
+
+ val groups = source.shortcutGroups(TEST_DEVICE_ID)
+
+ val keyCodes = groups[0].items.map { it.keycode }
+ assertThat(keyCodes).containsAtLeastElementsIn(functionRowKeyCodes)
+ }
+
+ @Test
+ @DisableFlags(FLAG_SHORTCUT_HELPER_KEY_GLYPH)
+ fun shortcutGroups_flagDisabled_inputManagerReturnsNoFunctionRowKeys_returnsDefaultFunctionRowShortcuts() =
+ testScope.runTest {
+ val groups = source.shortcutGroups(TEST_DEVICE_ID)
+
+ val keyCodes = groups[0].items.map { it.keycode }
+ assertThat(keyCodes).containsAtLeastElementsIn(functionRowKeyCodes)
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHORTCUT_HELPER_KEY_GLYPH)
+ fun shortcutGroups_flagEnabled_inputManagerReturnsHardwareShortcuts_returnsHardwareShortcuts() =
+ testScope.runTest {
+ whenever(mockKeyGlyphMap.functionRowKeys).thenReturn(intArrayOf())
+ val hardwareShortcutMap =
+ mapOf(Pair(KeyCombination(KeyEvent.META_META_ON, KeyEvent.KEYCODE_1), KEYCODE_BACK))
+ whenever(mockKeyGlyphMap.hardwareShortcuts).thenReturn(hardwareShortcutMap)
+
+ val groups = source.shortcutGroups(TEST_DEVICE_ID)
+
+ val shortcuts = groups[0].items.map { c -> Triple(c.label, c.modifiers, c.keycode) }
+ val hardwareShortcut =
+ Triple(
+ context.getString(R.string.group_system_go_back),
+ KeyEvent.META_META_ON,
+ KeyEvent.KEYCODE_1,
+ )
+ assertThat(shortcuts).contains(hardwareShortcut)
+ }
+
+ @Test
+ @DisableFlags(FLAG_SHORTCUT_HELPER_KEY_GLYPH)
+ fun shortcutGroups_flagDisabled_inputManagerReturnsHardwareShortcuts_returnsNoHardwareShortcuts() =
+ testScope.runTest {
+ val hardwareShortcutMap =
+ mapOf(Pair(KeyCombination(KeyEvent.META_META_ON, KeyEvent.KEYCODE_1), KEYCODE_BACK))
+ whenever(mockKeyGlyphMap.hardwareShortcuts).thenReturn(hardwareShortcutMap)
+
+ val groups = source.shortcutGroups(TEST_DEVICE_ID)
+
+ val shortcuts = groups[0].items.map { c -> Triple(c.label, c.modifiers, c.keycode) }
+ val hardwareShortcut =
+ Triple(
+ context.getString(R.string.group_system_go_back),
+ KeyEvent.META_META_ON,
+ KeyEvent.KEYCODE_1,
+ )
+ assertThat(shortcuts).doesNotContain(hardwareShortcut)
+ }
+
+ companion object {
+ private const val TEST_DEVICE_ID = 1234
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
index 8466eab2aca6..6d22b4903920 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
@@ -87,6 +87,10 @@ object TestShortcuts {
key("Shift")
key("M")
}
+ contentDescription {
+ "${shortcutInfoWithRepeatedLabel.label}, " +
+ "Press key Meta plus H, or Meta plus L, or Shift plus M"
+ }
}
private val goHomeShortcutInfo =
@@ -109,6 +113,7 @@ object TestShortcuts {
key(R.drawable.ic_ksh_key_meta)
key("N")
}
+ contentDescription { "${standardShortcutInfo1.label}, Press key Meta plus N" }
}
private val customGoHomeShortcut =
@@ -119,6 +124,7 @@ object TestShortcuts {
key("A")
isCustom(true)
}
+ contentDescription { "Go to home screen, Press key Ctrl plus Alt plus A" }
}
private val standardShortcutInfo2 =
@@ -135,6 +141,7 @@ object TestShortcuts {
key("Shift")
key("Z")
}
+ contentDescription { "${standardShortcutInfo2.label}, Press key Alt plus Shift plus Z" }
}
private val standardShortcutInfo3 =
@@ -150,6 +157,7 @@ object TestShortcuts {
key("Ctrl")
key("J")
}
+ contentDescription { "${standardShortcutInfo3.label}, Press key Ctrl plus J" }
}
private val shortcutInfoWithUnsupportedModifiers =
@@ -205,6 +213,7 @@ object TestShortcuts {
key("Ctrl")
key("Space")
}
+ contentDescription { "Switch to next language, Press key Ctrl plus Space" }
}
private val switchToPreviousLanguageShortcut =
@@ -214,6 +223,9 @@ object TestShortcuts {
key("Shift")
key("Space")
}
+ contentDescription {
+ "Switch to previous language, Press key Ctrl plus Shift plus Space"
+ }
}
private val subCategoryForInputLanguageSwitchShortcuts =
@@ -292,6 +304,10 @@ object TestShortcuts {
key("A")
isCustom(true)
}
+ contentDescription {
+ "Go to home screen, Press key Ctrl plus Alt plus B, " +
+ "or Ctrl plus Alt plus A"
+ }
}
),
)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt
index f7c77017e239..c3cedba65340 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt
@@ -333,6 +333,42 @@ class ShortcutHelperCategoriesInteractorTest : SysuiTestCase() {
}
}
+ @Test
+ fun categories_addsSameContentDescriptionForShortcutsOfSameType() {
+ testScope.runTest {
+ setCustomInputGestures(listOf(customInputGestureTypeHome))
+ systemShortcutsSource.setGroups(groupWithGoHomeShortcutInfo)
+ helper.showFromActivity()
+
+ val categories by collectLastValue(interactor.shortcutCategories)
+ val contentDescriptions =
+ categories?.flatMap {
+ it.subCategories.flatMap { it.shortcuts.map { it.contentDescription } }
+ }
+
+ assertThat(contentDescriptions)
+ .containsExactly(
+ "Go to home screen, Press key Ctrl plus Alt plus B, or Ctrl plus Alt plus A",
+ "Standard shortcut 3, Press key Ctrl plus J",
+ "Standard shortcut 2, Press key Alt plus Shift plus Z",
+ "Standard shortcut 1, Press key Meta plus N",
+ "Standard shortcut 1, Press key Meta plus N",
+ "Standard shortcut 2, Press key Alt plus Shift plus Z",
+ "Standard shortcut 3, Press key Ctrl plus J",
+ "Switch to next language, Press key Ctrl plus Space",
+ "Switch to previous language, Press key Ctrl plus Shift plus Space",
+ "Standard shortcut 1, Press key Meta plus N",
+ "Standard shortcut 2, Press key Alt plus Shift plus Z",
+ "Standard shortcut 3, Press key Ctrl plus J",
+ "Standard shortcut 3, Press key Ctrl plus J",
+ "Standard shortcut 2, Press key Alt plus Shift plus Z",
+ "Standard shortcut 1, Press key Meta plus N",
+ "Standard shortcut 2, Press key Alt plus Shift plus Z",
+ "Standard shortcut 1, Press key Meta plus N",
+ )
+ }
+ }
+
private fun setCustomInputGestures(customInputGestures: List<InputGestureData>) {
whenever(fakeInputManager.inputManager.getCustomInputGestures(/* filter= */ anyOrNull()))
.thenReturn(customInputGestures)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt
index e1496879a34b..dadcf71a4723 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt
@@ -35,10 +35,9 @@ import com.android.systemui.keyguard.data.repository.keyguardRepository
import com.android.systemui.keyguard.shared.model.DismissAction
import com.android.systemui.keyguard.shared.model.KeyguardDone
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testScope
-import com.android.systemui.power.data.repository.fakePowerRepository
-import com.android.systemui.power.shared.model.WakeSleepReason
-import com.android.systemui.power.shared.model.WakefulnessState
import com.android.systemui.scene.data.repository.Idle
import com.android.systemui.scene.data.repository.Transition
import com.android.systemui.scene.data.repository.setSceneTransition
@@ -222,28 +221,6 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() {
}
@Test
- fun resetDismissAction() =
- testScope.runTest {
- kosmos.setSceneTransition(Idle(Scenes.Bouncer))
- var wasOnCancelInvoked = false
- startInteractor()
- keyguardRepository.setDismissAction(
- DismissAction.RunAfterKeyguardGone(
- dismissAction = {},
- onCancelAction = { wasOnCancelInvoked = true },
- message = "message",
- willAnimateOnLockscreen = true,
- )
- )
- assertThat(wasOnCancelInvoked).isFalse()
- kosmos.setSceneTransition(Idle(Scenes.Lockscreen))
- runCurrent()
-
- assertThat(wasOnCancelInvoked).isTrue()
- assertThat(keyguardRepository.dismissAction.value).isEqualTo(DismissAction.None)
- }
-
- @Test
fun doNotResetDismissActionOnUnlockedShade() =
testScope.runTest {
kosmos.setSceneTransition(Idle(Scenes.Bouncer))
@@ -272,37 +249,6 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() {
}
@Test
- fun resetDismissAction_onBouncer_OnAsleep() =
- testScope.runTest {
- kosmos.setSceneTransition(Idle(Scenes.Bouncer))
- kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
- AuthenticationMethodModel.None
- )
- var wasOnCancelInvoked = false
- startInteractor()
-
- keyguardRepository.setDismissAction(
- DismissAction.RunAfterKeyguardGone(
- dismissAction = {},
- onCancelAction = { wasOnCancelInvoked = true },
- message = "message",
- willAnimateOnLockscreen = true,
- )
- )
- assertThat(wasOnCancelInvoked).isFalse()
- kosmos.fakePowerRepository.updateWakefulness(
- rawState = WakefulnessState.ASLEEP,
- lastWakeReason = WakeSleepReason.POWER_BUTTON,
- lastSleepReason = WakeSleepReason.TIMEOUT,
- powerButtonLaunchGestureTriggered = false,
- )
- runCurrent()
-
- assertThat(wasOnCancelInvoked).isTrue()
- assertThat(keyguardRepository.dismissAction.value).isEqualTo(DismissAction.None)
- }
-
- @Test
fun setDismissAction_callsCancelRunnableOnPreviousDismissAction() =
testScope.runTest {
val dismissAction by collectLastValue(keyguardRepository.dismissAction)
@@ -410,6 +356,25 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() {
assertThat(wasCancelActionInvoked).isFalse()
}
+ @Test
+ fun clearDismissAction() =
+ kosmos.runTest {
+ val dismissAction by collectLastValue(fakeKeyguardRepository.dismissAction)
+ fakeKeyguardRepository.setDismissAction(
+ DismissAction.RunImmediately(
+ onDismissAction = { KeyguardDone.IMMEDIATE },
+ onCancelAction = {},
+ message = "",
+ willAnimateOnLockscreen = true,
+ )
+ )
+ assertThat(dismissAction).isNotEqualTo(DismissAction.None)
+
+ underTest.clearDismissAction()
+
+ assertThat(dismissAction).isEqualTo(DismissAction.None)
+ }
+
private fun TestScope.startInteractor() {
testScope.backgroundScope.launchTraced(
"KeyguardDismissActionInteractorTest#startInteractor"
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/navigationbar/views/NavigationBarTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/navigationbar/views/NavigationBarTest.java
index 2905a7329d21..555ba56e087f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/navigationbar/views/NavigationBarTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/navigationbar/views/NavigationBarTest.java
@@ -90,6 +90,7 @@ import com.android.systemui.accessibility.SystemActions;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.kosmos.KosmosJavaAdapter;
import com.android.systemui.model.SysUiState;
import com.android.systemui.navigationbar.NavBarHelper;
import com.android.systemui.navigationbar.NavigationBarController;
@@ -116,7 +117,7 @@ import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
-import com.android.systemui.statusbar.phone.AutoHideController;
+import com.android.systemui.statusbar.phone.AutoHideControllerStore;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.phone.LightBarTransitionsController;
@@ -147,6 +148,7 @@ import java.util.concurrent.Executor;
@SmallTest
public class NavigationBarTest extends SysuiTestCase {
private static final int EXTERNAL_DISPLAY_ID = 2;
+ private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
private NavigationBar mNavigationBar;
private NavigationBar mExternalDisplayNavigationBar;
@@ -210,10 +212,6 @@ public class NavigationBarTest extends SysuiTestCase {
@Mock
private LightBarController.Factory mLightBarcontrollerFactory;
@Mock
- private AutoHideController mAutoHideController;
- @Mock
- private AutoHideController.Factory mAutoHideControllerFactory;
- @Mock
private WindowManager mWindowManager;
@Mock
private ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager;
@@ -247,6 +245,8 @@ public class NavigationBarTest extends SysuiTestCase {
private DeviceConfigProxyFake mDeviceConfigProxyFake = new DeviceConfigProxyFake();
private TaskStackChangeListeners mTaskStackChangeListeners =
TaskStackChangeListeners.getTestInstance();
+ private final AutoHideControllerStore mAutoHideControllerStore =
+ mKosmos.getAutoHideControllerStore();
@Rule
public final LeakCheckedTest.SysuiLeakCheck mLeakCheck = new LeakCheckedTest.SysuiLeakCheck();
@@ -258,7 +258,6 @@ public class NavigationBarTest extends SysuiTestCase {
MockitoAnnotations.initMocks(this);
when(mLightBarcontrollerFactory.create(any(Context.class))).thenReturn(mLightBarController);
- when(mAutoHideControllerFactory.create(any(Context.class))).thenReturn(mAutoHideController);
when(mNavigationBarView.getHomeButton()).thenReturn(mHomeButton);
when(mNavigationBarView.getRecentsButton()).thenReturn(mRecentsButton);
when(mNavigationBarView.getAccessibilityButton()).thenReturn(mAccessibilityButton);
@@ -651,8 +650,7 @@ public class NavigationBarTest extends SysuiTestCase {
mNavBarHelper,
mLightBarController,
mLightBarcontrollerFactory,
- mAutoHideController,
- mAutoHideControllerFactory,
+ mAutoHideControllerStore,
Optional.of(mTelecomManager),
mInputMethodManager,
mDeadZone,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/AbstractQSFragmentComposeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/AbstractQSFragmentComposeViewModelTest.kt
index b5fc52f7a8d6..87e2fefde989 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/AbstractQSFragmentComposeViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/AbstractQSFragmentComposeViewModelTest.kt
@@ -16,11 +16,13 @@
package com.android.systemui.qs.composefragment.viewmodel
+import androidx.compose.runtime.snapshots.Snapshot
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.testing.TestLifecycleOwner
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.runCurrent
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.lifecycle.activateIn
@@ -36,7 +38,6 @@ import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.setMain
-import org.junit.After
import org.junit.Before
import org.junit.runner.RunWith
@@ -58,11 +59,14 @@ abstract class AbstractQSFragmentComposeViewModelTest : SysuiTestCase() {
@Before
fun setUp() {
Dispatchers.setMain(kosmos.testDispatcher)
- }
+ onTeardown { Dispatchers.resetMain() }
- @After
- fun teardown() {
- Dispatchers.resetMain()
+ val globalWriteObserverHandle =
+ Snapshot.registerGlobalWriteObserver {
+ Snapshot.sendApplyNotifications()
+ kosmos.runCurrent()
+ }
+ onTeardown { globalWriteObserverHandle.dispose() }
}
protected inline fun TestScope.testWithinLifecycle(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelTest.kt
index 921a8a610c37..111b3b65c05d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelTest.kt
@@ -20,7 +20,6 @@ import android.app.StatusBarManager
import android.content.testableContext
import android.graphics.Rect
import android.testing.TestableLooper.RunWithLooper
-import androidx.compose.runtime.snapshots.Snapshot
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
@@ -186,15 +185,12 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest()
val squishiness by collectLastValue(tileSquishinessInteractor.squishiness)
underTest.squishinessFraction = 0.3f
- Snapshot.sendApplyNotifications()
assertThat(squishiness).isWithin(epsilon).of(0.3f.constrainSquishiness())
underTest.squishinessFraction = 0f
- Snapshot.sendApplyNotifications()
assertThat(squishiness).isWithin(epsilon).of(0f.constrainSquishiness())
underTest.squishinessFraction = 1f
- Snapshot.sendApplyNotifications()
assertThat(squishiness).isWithin(epsilon).of(1f.constrainSquishiness())
}
}
@@ -328,13 +324,9 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest()
setMediaState(ACTIVE_MEDIA)
setConfigurationForMediaInRow(mediaInRow = false)
- Snapshot.sendApplyNotifications()
- runCurrent()
assertThat(underTest.qqsMediaHost.expansion).isEqualTo(MediaHostState.EXPANDED)
setConfigurationForMediaInRow(mediaInRow = true)
- Snapshot.sendApplyNotifications()
- runCurrent()
assertThat(underTest.qqsMediaHost.expansion).isEqualTo(MediaHostState.COLLAPSED)
}
}
@@ -347,13 +339,9 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest()
setMediaState(ACTIVE_MEDIA)
setConfigurationForMediaInRow(mediaInRow = false)
- Snapshot.sendApplyNotifications()
- runCurrent()
assertThat(underTest.qqsMediaHost.expansion).isEqualTo(MediaHostState.EXPANDED)
setConfigurationForMediaInRow(mediaInRow = true)
- Snapshot.sendApplyNotifications()
- runCurrent()
assertThat(underTest.qqsMediaHost.expansion).isEqualTo(MediaHostState.EXPANDED)
}
}
@@ -366,13 +354,9 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest()
setMediaState(ACTIVE_MEDIA)
setCollapsedMediaInLandscape(false)
- Snapshot.sendApplyNotifications()
- runCurrent()
assertThat(underTest.qqsMediaHost.expansion).isEqualTo(MediaHostState.EXPANDED)
setCollapsedMediaInLandscape(true)
- Snapshot.sendApplyNotifications()
- runCurrent()
assertThat(underTest.qqsMediaHost.expansion).isEqualTo(MediaHostState.COLLAPSED)
}
}
@@ -401,13 +385,11 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest()
underTest.squishinessFraction = 0.3f
underTest.shouldUpdateSquishinessOnMedia = true
- Snapshot.sendApplyNotifications()
runCurrent()
assertThat(underTest.qsMediaHost.squishFraction).isWithin(0.01f).of(0.3f)
underTest.shouldUpdateSquishinessOnMedia = false
- Snapshot.sendApplyNotifications()
runCurrent()
assertThat(underTest.qsMediaHost.squishFraction).isWithin(0.01f).of(1f)
}
@@ -421,20 +403,15 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest()
underTest.squishinessFraction = 0.3f
sysuiStatusBarStateController.setState(StatusBarState.SHADE)
- Snapshot.sendApplyNotifications()
runCurrent()
assertThat(underTest.qsMediaHost.squishFraction).isWithin(epsilon).of(0.3f)
sysuiStatusBarStateController.setState(StatusBarState.KEYGUARD)
runCurrent()
- Snapshot.sendApplyNotifications()
- runCurrent()
assertThat(underTest.qsMediaHost.squishFraction).isWithin(epsilon).of(1f)
sysuiStatusBarStateController.setState(StatusBarState.SHADE_LOCKED)
runCurrent()
- Snapshot.sendApplyNotifications()
- runCurrent()
assertThat(underTest.qsMediaHost.squishFraction).isWithin(epsilon).of(1f)
}
}
@@ -446,8 +423,6 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest()
setMediaState(ACTIVE_MEDIA)
setConfigurationForMediaInRow(false)
- Snapshot.sendApplyNotifications()
- runCurrent()
assertThat(underTest.qqsMediaHost.disappearParameters)
.isEqualTo(disappearParamsColumn)
@@ -455,8 +430,6 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest()
.isEqualTo(disappearParamsColumn)
setConfigurationForMediaInRow(true)
- Snapshot.sendApplyNotifications()
- runCurrent()
assertThat(underTest.qqsMediaHost.disappearParameters).isEqualTo(disappearParamsRow)
assertThat(underTest.qsMediaHost.disappearParameters).isEqualTo(disappearParamsRow)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
index b8745b3e95b2..2eb45902917d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
@@ -33,7 +33,6 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.media.controls.ui.controller.KeyguardMediaController;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
import com.android.systemui.statusbar.notification.collection.render.MediaContainerController;
import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -57,7 +56,6 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
@Mock private StatusBarStateController mStatusBarStateController;
@Mock private ConfigurationController mConfigurationController;
@Mock private KeyguardMediaController mKeyguardMediaController;
- @Mock private NotificationSectionsFeatureManager mSectionsFeatureManager;
@Mock private MediaContainerController mMediaContainerController;
@Mock private NotificationRoundnessManager mNotificationRoundnessManager;
@Mock private SectionHeaderController mIncomingHeaderController;
@@ -73,26 +71,10 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
@Before
public void setUp() {
- when(mSectionsFeatureManager.getNumberOfBuckets()).thenAnswer(
- invocation -> {
- int count = 2;
- if (mSectionsFeatureManager.isFilteringEnabled()) {
- count = 5;
- }
- if (mSectionsFeatureManager.isMediaControlsEnabled()) {
- if (!mSectionsFeatureManager.isFilteringEnabled()) {
- count = 5;
- } else {
- count += 1;
- }
- }
- return count;
- });
mSectionsManager =
new NotificationSectionsManager(
mConfigurationController,
mKeyguardMediaController,
- mSectionsFeatureManager,
mMediaContainerController,
mNotificationRoundnessManager,
mIncomingHeaderController,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 0eb620343e6a..d174484219ff 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -190,6 +190,8 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
private ArgumentCaptor<OnBackInvokedCallback> mBackCallbackCaptor;
@Captor
private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallback;
+ @Mock
+ private KeyguardDismissActionInteractor mKeyguardDismissActionInteractor;
@Rule
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
@@ -236,7 +238,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
mKeyguardTransitionInteractor,
mock(KeyguardDismissTransitionInteractor.class),
StandardTestDispatcher(null, null),
- () -> mock(KeyguardDismissActionInteractor.class),
+ () -> mKeyguardDismissActionInteractor,
mSelectedUserInteractor,
mock(JavaAdapter.class),
() -> mSceneInteractor,
@@ -968,4 +970,33 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
);
verify(mAlternateBouncerInteractor).hide();
}
+
+ @Test
+ public void hideAlternateBouncer_clearsDismissActionByDefault() {
+ clearInvocations(mKeyguardDismissActionInteractor);
+
+ mStatusBarKeyguardViewManager.hideAlternateBouncer(/* updateScrim= */ true);
+
+ verify(mKeyguardDismissActionInteractor).clearDismissAction();
+ }
+
+ @Test
+ public void hideAlternateBouncer_clearsDismissActionExplicitly() {
+ clearInvocations(mKeyguardDismissActionInteractor);
+
+ mStatusBarKeyguardViewManager.hideAlternateBouncer(
+ /* updateScrim= */ true, /* clearDismissAction= */ true);
+
+ verify(mKeyguardDismissActionInteractor).clearDismissAction();
+ }
+
+ @Test
+ public void hideAlternateBouncer_doNotClearDismissActionExplicitly() {
+ clearInvocations(mKeyguardDismissActionInteractor);
+
+ mStatusBarKeyguardViewManager.hideAlternateBouncer(
+ /* updateScrim= */ true, /* clearDismissAction= */ false);
+
+ verify(mKeyguardDismissActionInteractor, never()).clearDismissAction();
+ }
}
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 b9cdd06de5a2..7b04fc827d83 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
@@ -28,8 +28,6 @@ import android.view.View
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.coroutines.collectValues
import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
@@ -39,7 +37,9 @@ import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.testCase
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.collectValues
+import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.log.assertLogsWtf
@@ -52,6 +52,7 @@ import com.android.systemui.screenrecord.data.repository.screenRecordRepository
import com.android.systemui.shade.shadeTestUtil
import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.NORMAL_PACKAGE
import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.setUpPackageManagerForMediaProjection
+import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.assertIsScreenRecordChip
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.assertIsShareToAppChip
@@ -66,15 +67,17 @@ import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationSt
import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.Idle
import com.android.systemui.statusbar.notification.data.model.activeNotificationModel
import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore
+import com.android.systemui.statusbar.notification.data.repository.FakeHeadsUpRowRepository
import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor
+import com.android.systemui.statusbar.notification.stack.data.repository.headsUpNotificationRepository
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel.VisibilityModel
+import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -83,35 +86,22 @@ import org.junit.runner.RunWith
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(AndroidJUnit4::class)
class HomeStatusBarViewModelImplTest : SysuiTestCase() {
- private val kosmos =
- Kosmos().also {
- it.testCase = this
- it.testDispatcher = UnconfinedTestDispatcher()
- }
-
- private val testScope = kosmos.testScope
-
- private val statusBarModeRepository = kosmos.fakeStatusBarModeRepository
- private val activeNotificationListRepository = kosmos.activeNotificationListRepository
- private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
- private val disableFlagsRepository = kosmos.fakeDisableFlagsRepository
- private val systemStatusEventAnimationRepository = kosmos.systemStatusEventAnimationRepository
-
- private lateinit var underTest: HomeStatusBarViewModel
+ private val kosmos by lazy {
+ testKosmos().also { it.testDispatcher = UnconfinedTestDispatcher() }
+ }
+ private val Kosmos.underTest by Kosmos.Fixture { kosmos.homeStatusBarViewModel }
@Before
fun setUp() {
setUpPackageManagerForMediaProjection(kosmos)
- // Initialize here because some flags are checked when this class is constructed
- underTest = kosmos.homeStatusBarViewModel
}
@Test
fun isTransitioningFromLockscreenToOccluded_started_isTrue() =
- testScope.runTest {
+ kosmos.runTest {
val latest by collectLastValue(underTest.isTransitioningFromLockscreenToOccluded)
- keyguardTransitionRepository.sendTransitionStep(
+ fakeKeyguardTransitionRepository.sendTransitionStep(
TransitionStep(
KeyguardState.LOCKSCREEN,
KeyguardState.OCCLUDED,
@@ -125,10 +115,10 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
fun isTransitioningFromLockscreenToOccluded_running_isTrue() =
- testScope.runTest {
+ kosmos.runTest {
val latest by collectLastValue(underTest.isTransitioningFromLockscreenToOccluded)
- keyguardTransitionRepository.sendTransitionStep(
+ fakeKeyguardTransitionRepository.sendTransitionStep(
TransitionStep(
KeyguardState.LOCKSCREEN,
KeyguardState.OCCLUDED,
@@ -142,10 +132,10 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
fun isTransitioningFromLockscreenToOccluded_finished_isFalse() =
- testScope.runTest {
+ kosmos.runTest {
val latest by collectLastValue(underTest.isTransitioningFromLockscreenToOccluded)
- keyguardTransitionRepository.sendTransitionSteps(
+ fakeKeyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.LOCKSCREEN,
to = KeyguardState.OCCLUDED,
testScope.testScheduler,
@@ -156,10 +146,10 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
fun isTransitioningFromLockscreenToOccluded_canceled_isFalse() =
- testScope.runTest {
+ kosmos.runTest {
val latest by collectLastValue(underTest.isTransitioningFromLockscreenToOccluded)
- keyguardTransitionRepository.sendTransitionStep(
+ fakeKeyguardTransitionRepository.sendTransitionStep(
TransitionStep(
KeyguardState.LOCKSCREEN,
KeyguardState.OCCLUDED,
@@ -173,10 +163,10 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
fun isTransitioningFromLockscreenToOccluded_irrelevantTransition_isFalse() =
- testScope.runTest {
+ kosmos.runTest {
val latest by collectLastValue(underTest.isTransitioningFromLockscreenToOccluded)
- keyguardTransitionRepository.sendTransitionStep(
+ fakeKeyguardTransitionRepository.sendTransitionStep(
TransitionStep(
KeyguardState.AOD,
KeyguardState.LOCKSCREEN,
@@ -190,10 +180,10 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
fun isTransitioningFromLockscreenToOccluded_followsRepoUpdates() =
- testScope.runTest {
+ kosmos.runTest {
val latest by collectLastValue(underTest.isTransitioningFromLockscreenToOccluded)
- keyguardTransitionRepository.sendTransitionStep(
+ fakeKeyguardTransitionRepository.sendTransitionStep(
TransitionStep(
KeyguardState.LOCKSCREEN,
KeyguardState.OCCLUDED,
@@ -205,7 +195,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
assertThat(latest).isTrue()
// WHEN the repo updates the transition to finished
- keyguardTransitionRepository.sendTransitionStep(
+ fakeKeyguardTransitionRepository.sendTransitionStep(
TransitionStep(
KeyguardState.LOCKSCREEN,
KeyguardState.OCCLUDED,
@@ -220,10 +210,10 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
fun transitionFromLockscreenToDreamStartedEvent_started_emitted() =
- testScope.runTest {
+ kosmos.runTest {
val emissions by collectValues(underTest.transitionFromLockscreenToDreamStartedEvent)
- keyguardTransitionRepository.sendTransitionStep(
+ fakeKeyguardTransitionRepository.sendTransitionStep(
TransitionStep(
KeyguardState.LOCKSCREEN,
KeyguardState.DREAMING,
@@ -237,10 +227,10 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
fun transitionFromLockscreenToDreamStartedEvent_startedMultiple_emittedMultiple() =
- testScope.runTest {
+ kosmos.runTest {
val emissions by collectValues(underTest.transitionFromLockscreenToDreamStartedEvent)
- keyguardTransitionRepository.sendTransitionStep(
+ fakeKeyguardTransitionRepository.sendTransitionStep(
TransitionStep(
KeyguardState.LOCKSCREEN,
KeyguardState.DREAMING,
@@ -249,7 +239,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
)
)
- keyguardTransitionRepository.sendTransitionStep(
+ fakeKeyguardTransitionRepository.sendTransitionStep(
TransitionStep(
KeyguardState.LOCKSCREEN,
KeyguardState.DREAMING,
@@ -258,7 +248,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
)
)
- keyguardTransitionRepository.sendTransitionStep(
+ fakeKeyguardTransitionRepository.sendTransitionStep(
TransitionStep(
KeyguardState.LOCKSCREEN,
KeyguardState.DREAMING,
@@ -272,10 +262,10 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
fun transitionFromLockscreenToDreamStartedEvent_startedThenRunning_emittedOnlyOne() =
- testScope.runTest {
+ kosmos.runTest {
val emissions by collectValues(underTest.transitionFromLockscreenToDreamStartedEvent)
- keyguardTransitionRepository.sendTransitionStep(
+ fakeKeyguardTransitionRepository.sendTransitionStep(
TransitionStep(
KeyguardState.LOCKSCREEN,
KeyguardState.DREAMING,
@@ -287,7 +277,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
// WHEN the transition progresses through its animation by going through the RUNNING
// step with increasing fractions
- keyguardTransitionRepository.sendTransitionStep(
+ fakeKeyguardTransitionRepository.sendTransitionStep(
TransitionStep(
KeyguardState.LOCKSCREEN,
KeyguardState.DREAMING,
@@ -296,7 +286,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
)
)
- keyguardTransitionRepository.sendTransitionStep(
+ fakeKeyguardTransitionRepository.sendTransitionStep(
TransitionStep(
KeyguardState.LOCKSCREEN,
KeyguardState.DREAMING,
@@ -305,7 +295,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
)
)
- keyguardTransitionRepository.sendTransitionStep(
+ fakeKeyguardTransitionRepository.sendTransitionStep(
TransitionStep(
KeyguardState.LOCKSCREEN,
KeyguardState.DREAMING,
@@ -321,10 +311,10 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
fun transitionFromLockscreenToDreamStartedEvent_irrelevantTransition_notEmitted() =
- testScope.runTest {
+ kosmos.runTest {
val emissions by collectValues(underTest.transitionFromLockscreenToDreamStartedEvent)
- keyguardTransitionRepository.sendTransitionStep(
+ fakeKeyguardTransitionRepository.sendTransitionStep(
TransitionStep(
KeyguardState.LOCKSCREEN,
KeyguardState.OCCLUDED,
@@ -338,10 +328,10 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
fun transitionFromLockscreenToDreamStartedEvent_irrelevantTransitionState_notEmitted() =
- testScope.runTest {
+ kosmos.runTest {
val emissions by collectValues(underTest.transitionFromLockscreenToDreamStartedEvent)
- keyguardTransitionRepository.sendTransitionStep(
+ fakeKeyguardTransitionRepository.sendTransitionStep(
TransitionStep(
KeyguardState.LOCKSCREEN,
KeyguardState.DREAMING,
@@ -359,8 +349,8 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
@EnableFlags(NotificationsLiveDataStoreRefactor.FLAG_NAME)
fun areNotificationsLightsOut_lowProfileWithNotifications_true() =
- testScope.runTest {
- statusBarModeRepository.defaultDisplay.statusBarMode.value =
+ kosmos.runTest {
+ fakeStatusBarModeRepository.defaultDisplay.statusBarMode.value =
StatusBarMode.LIGHTS_OUT_TRANSPARENT
activeNotificationListRepository.activeNotifications.value =
activeNotificationsStore(testNotifications)
@@ -373,8 +363,8 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
@EnableFlags(NotificationsLiveDataStoreRefactor.FLAG_NAME)
fun areNotificationsLightsOut_lowProfileWithoutNotifications_false() =
- testScope.runTest {
- statusBarModeRepository.defaultDisplay.statusBarMode.value =
+ kosmos.runTest {
+ fakeStatusBarModeRepository.defaultDisplay.statusBarMode.value =
StatusBarMode.LIGHTS_OUT_TRANSPARENT
activeNotificationListRepository.activeNotifications.value =
activeNotificationsStore(emptyList())
@@ -387,8 +377,9 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
@EnableFlags(NotificationsLiveDataStoreRefactor.FLAG_NAME)
fun areNotificationsLightsOut_defaultStatusBarModeWithoutNotifications_false() =
- testScope.runTest {
- statusBarModeRepository.defaultDisplay.statusBarMode.value = StatusBarMode.TRANSPARENT
+ kosmos.runTest {
+ fakeStatusBarModeRepository.defaultDisplay.statusBarMode.value =
+ StatusBarMode.TRANSPARENT
activeNotificationListRepository.activeNotifications.value =
activeNotificationsStore(emptyList())
@@ -400,8 +391,9 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
@EnableFlags(NotificationsLiveDataStoreRefactor.FLAG_NAME)
fun areNotificationsLightsOut_defaultStatusBarModeWithNotifications_false() =
- testScope.runTest {
- statusBarModeRepository.defaultDisplay.statusBarMode.value = StatusBarMode.TRANSPARENT
+ kosmos.runTest {
+ fakeStatusBarModeRepository.defaultDisplay.statusBarMode.value =
+ StatusBarMode.TRANSPARENT
activeNotificationListRepository.activeNotifications.value =
activeNotificationsStore(testNotifications)
@@ -413,7 +405,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
@DisableFlags(NotificationsLiveDataStoreRefactor.FLAG_NAME)
fun areNotificationsLightsOut_requiresFlagEnabled() =
- testScope.runTest {
+ kosmos.runTest {
assertLogsWtf {
val flow = underTest.areNotificationsLightsOut(DISPLAY_ID)
assertThat(flow).isEqualTo(emptyFlow<Boolean>())
@@ -422,7 +414,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
fun primaryOngoingActivityChip_matchesViewModel() =
- testScope.runTest {
+ kosmos.runTest {
val latest by collectLastValue(underTest.primaryOngoingActivityChip)
kosmos.screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
@@ -441,7 +433,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
fun isHomeStatusBarAllowedByScene_sceneLockscreen_notOccluded_false() =
- testScope.runTest {
+ kosmos.runTest {
val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
@@ -452,7 +444,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
fun isHomeStatusBarAllowedByScene_sceneLockscreen_occluded_true() =
- testScope.runTest {
+ kosmos.runTest {
val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
@@ -463,7 +455,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
fun isHomeStatusBarAllowedByScene_sceneBouncer_false() =
- testScope.runTest {
+ kosmos.runTest {
val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
kosmos.sceneContainerRepository.snapToScene(Scenes.Bouncer)
@@ -473,7 +465,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
fun isHomeStatusBarAllowedByScene_sceneCommunal_false() =
- testScope.runTest {
+ kosmos.runTest {
val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
kosmos.sceneContainerRepository.snapToScene(Scenes.Communal)
@@ -483,7 +475,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
fun isHomeStatusBarAllowedByScene_sceneShade_false() =
- testScope.runTest {
+ kosmos.runTest {
val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
kosmos.sceneContainerRepository.snapToScene(Scenes.Shade)
@@ -493,7 +485,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
fun isHomeStatusBarAllowedByScene_sceneGone_true() =
- testScope.runTest {
+ kosmos.runTest {
val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
kosmos.sceneContainerRepository.snapToScene(Scenes.Gone)
@@ -503,35 +495,91 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
fun isClockVisible_allowedByDisableFlags_visible() =
- testScope.runTest {
+ kosmos.runTest {
val latest by collectLastValue(underTest.isClockVisible)
transitionKeyguardToGone()
- disableFlagsRepository.disableFlags.value =
+ fakeDisableFlagsRepository.disableFlags.value =
DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE)
assertThat(latest!!.visibility).isEqualTo(View.VISIBLE)
}
@Test
- fun isClockVisible_notAllowedByDisableFlags_gone() =
- testScope.runTest {
+ fun isClockVisible_notAllowedByDisableFlags_invisible() =
+ kosmos.runTest {
val latest by collectLastValue(underTest.isClockVisible)
transitionKeyguardToGone()
- disableFlagsRepository.disableFlags.value =
+ fakeDisableFlagsRepository.disableFlags.value =
DisableFlagsModel(DISABLE_CLOCK, DISABLE2_NONE)
- assertThat(latest!!.visibility).isEqualTo(View.GONE)
+ assertThat(latest!!.visibility).isEqualTo(View.INVISIBLE)
+ }
+
+ @Test
+ fun isClockVisible_allowedByFlags_hunActive_notVisible() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.isClockVisible)
+ transitionKeyguardToGone()
+
+ fakeDisableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE)
+ // there is an active HUN
+ headsUpNotificationRepository.setNotifications(
+ fakeHeadsUpRowRepository(isPinned = true)
+ )
+
+ assertThat(latest!!.visibility).isEqualTo(View.INVISIBLE)
+ }
+
+ @Test
+ fun isClockVisible_allowedByFlags_hunBecomesInactive_visibleAgain() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.isClockVisible)
+ transitionKeyguardToGone()
+
+ fakeDisableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE)
+ // there is an active HUN
+ headsUpNotificationRepository.setNotifications(
+ fakeHeadsUpRowRepository(isPinned = true)
+ )
+
+ // hun goes away
+ headsUpNotificationRepository.setNotifications(listOf())
+
+ assertThat(latest!!.visibility).isEqualTo(View.VISIBLE)
+ }
+
+ @Test
+ fun isClockVisible_disabledByFlags_hunBecomesInactive_neverVisible() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.isClockVisible)
+ transitionKeyguardToGone()
+
+ fakeDisableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(DISABLE_CLOCK, DISABLE2_NONE)
+ // there is an active HUN
+ headsUpNotificationRepository.setNotifications(
+ fakeHeadsUpRowRepository(isPinned = true)
+ )
+
+ assertThat(latest!!.visibility).isEqualTo(View.INVISIBLE)
+
+ // hun goes away
+ headsUpNotificationRepository.setNotifications(listOf())
+
+ assertThat(latest!!.visibility).isEqualTo(View.INVISIBLE)
}
@Test
fun isNotificationIconContainerVisible_allowedByDisableFlags_visible() =
- testScope.runTest {
+ kosmos.runTest {
val latest by collectLastValue(underTest.isNotificationIconContainerVisible)
transitionKeyguardToGone()
- disableFlagsRepository.disableFlags.value =
+ fakeDisableFlagsRepository.disableFlags.value =
DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE)
assertThat(latest!!.visibility).isEqualTo(View.VISIBLE)
@@ -539,23 +587,55 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
fun isNotificationIconContainerVisible_notAllowedByDisableFlags_gone() =
- testScope.runTest {
+ kosmos.runTest {
val latest by collectLastValue(underTest.isNotificationIconContainerVisible)
transitionKeyguardToGone()
- disableFlagsRepository.disableFlags.value =
+ fakeDisableFlagsRepository.disableFlags.value =
DisableFlagsModel(DISABLE_NOTIFICATION_ICONS, DISABLE2_NONE)
assertThat(latest!!.visibility).isEqualTo(View.GONE)
}
@Test
+ @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+ fun isNotificationIconContainerVisible_anyChipShowing_PromotedNotifsOn() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.isNotificationIconContainerVisible)
+ transitionKeyguardToGone()
+
+ kosmos.screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+
+ assertThat(latest!!.visibility).isEqualTo(View.GONE)
+
+ kosmos.screenRecordRepository.screenRecordState.value = ScreenRecordModel.DoingNothing
+
+ assertThat(latest!!.visibility).isEqualTo(View.VISIBLE)
+ }
+
+ @Test
+ @DisableFlags(StatusBarNotifChips.FLAG_NAME)
+ fun isNotificationIconContainerVisible_anyChipShowing_PromotedNotifsOff() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.isNotificationIconContainerVisible)
+ transitionKeyguardToGone()
+
+ kosmos.screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+
+ assertThat(latest!!.visibility).isEqualTo(View.GONE)
+
+ kosmos.screenRecordRepository.screenRecordState.value = ScreenRecordModel.DoingNothing
+
+ assertThat(latest!!.visibility).isEqualTo(View.VISIBLE)
+ }
+
+ @Test
fun isSystemInfoVisible_allowedByDisableFlags_visible() =
- testScope.runTest {
+ kosmos.runTest {
val latest by collectLastValue(underTest.systemInfoCombinedVis)
transitionKeyguardToGone()
- disableFlagsRepository.disableFlags.value =
+ fakeDisableFlagsRepository.disableFlags.value =
DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE)
assertThat(latest!!.baseVisibility.visibility).isEqualTo(View.VISIBLE)
@@ -563,11 +643,11 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
fun isSystemInfoVisible_notAllowedByDisableFlags_gone() =
- testScope.runTest {
+ kosmos.runTest {
val latest by collectLastValue(underTest.systemInfoCombinedVis)
transitionKeyguardToGone()
- disableFlagsRepository.disableFlags.value =
+ fakeDisableFlagsRepository.disableFlags.value =
DisableFlagsModel(DISABLE_SYSTEM_INFO, DISABLE2_NONE)
assertThat(latest!!.baseVisibility.visibility).isEqualTo(View.GONE)
@@ -575,7 +655,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
fun systemInfoCombineVis_animationsPassThrough() =
- testScope.runTest {
+ kosmos.runTest {
val latest by collectLastValue(underTest.systemInfoCombinedVis)
transitionKeyguardToGone()
@@ -601,18 +681,18 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
@DisableSceneContainer
fun lockscreenVisible_sceneFlagOff_noStatusBarViewsShown() =
- testScope.runTest {
+ kosmos.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
- keyguardTransitionRepository.sendTransitionSteps(
+ fakeKeyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.GONE,
to = KeyguardState.LOCKSCREEN,
- testScope = this,
+ testScope = testScope,
)
- assertThat(clockVisible!!.visibility).isEqualTo(View.GONE)
+ assertThat(clockVisible!!.visibility).isEqualTo(View.INVISIBLE)
assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE)
assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE)
}
@@ -620,14 +700,14 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
@EnableSceneContainer
fun lockscreenVisible_sceneFlagOn_noStatusBarViewsShown() =
- testScope.runTest {
+ kosmos.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
- assertThat(clockVisible!!.visibility).isEqualTo(View.GONE)
+ assertThat(clockVisible!!.visibility).isEqualTo(View.INVISIBLE)
assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE)
assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE)
}
@@ -635,18 +715,18 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
@DisableSceneContainer
fun bouncerVisible_sceneFlagOff_noStatusBarViewsShown() =
- testScope.runTest {
+ kosmos.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
- keyguardTransitionRepository.sendTransitionSteps(
+ fakeKeyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.LOCKSCREEN,
to = KeyguardState.PRIMARY_BOUNCER,
- testScope = this,
+ testScope = testScope,
)
- assertThat(clockVisible!!.visibility).isEqualTo(View.GONE)
+ assertThat(clockVisible!!.visibility).isEqualTo(View.INVISIBLE)
assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE)
assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE)
}
@@ -654,14 +734,14 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
@EnableSceneContainer
fun bouncerVisible_sceneFlagOn_noStatusBarViewsShown() =
- testScope.runTest {
+ kosmos.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
kosmos.sceneContainerRepository.snapToScene(Scenes.Bouncer)
- assertThat(clockVisible!!.visibility).isEqualTo(View.GONE)
+ assertThat(clockVisible!!.visibility).isEqualTo(View.INVISIBLE)
assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE)
assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE)
}
@@ -669,15 +749,15 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
@DisableSceneContainer
fun keyguardIsOccluded_sceneFlagOff_statusBarViewsShown() =
- testScope.runTest {
+ kosmos.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
- keyguardTransitionRepository.sendTransitionSteps(
+ fakeKeyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.LOCKSCREEN,
to = KeyguardState.OCCLUDED,
- testScope = this,
+ testScope = testScope,
)
assertThat(clockVisible!!.visibility).isEqualTo(View.VISIBLE)
@@ -688,7 +768,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
@EnableSceneContainer
fun keyguardIsOccluded_sceneFlagOn_statusBarViewsShown() =
- testScope.runTest {
+ kosmos.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
@@ -704,7 +784,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
@DisableSceneContainer
fun keyguardNotShown_sceneFlagOff_statusBarViewsShown() =
- testScope.runTest {
+ kosmos.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
@@ -719,7 +799,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
@DisableSceneContainer
fun shadeNotShown_sceneFlagOff_statusBarViewsShown() =
- testScope.runTest {
+ kosmos.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
@@ -735,7 +815,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
@EnableSceneContainer
fun keyguardNotShownAndShadeNotShown_sceneFlagOn_statusBarViewsShown() =
- testScope.runTest {
+ kosmos.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
@@ -750,7 +830,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
@DisableSceneContainer
fun shadeShown_sceneFlagOff_noStatusBarViewsShown() =
- testScope.runTest {
+ kosmos.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
@@ -758,7 +838,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
kosmos.shadeTestUtil.setShadeExpansion(1f)
- assertThat(clockVisible!!.visibility).isEqualTo(View.GONE)
+ assertThat(clockVisible!!.visibility).isEqualTo(View.INVISIBLE)
assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE)
assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE)
}
@@ -766,7 +846,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
@EnableSceneContainer
fun shadeShown_sceneFlagOn_noStatusBarViewsShown() =
- testScope.runTest {
+ kosmos.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
@@ -774,7 +854,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
kosmos.sceneContainerRepository.snapToScene(Scenes.Shade)
- assertThat(clockVisible!!.visibility).isEqualTo(View.GONE)
+ assertThat(clockVisible!!.visibility).isEqualTo(View.INVISIBLE)
assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE)
assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE)
}
@@ -782,20 +862,20 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
@DisableSceneContainer
fun secureCameraActive_sceneFlagOff_noStatusBarViewsShown() =
- testScope.runTest {
+ kosmos.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
// Secure camera is an occluding activity
- keyguardTransitionRepository.sendTransitionSteps(
+ fakeKeyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.LOCKSCREEN,
to = KeyguardState.OCCLUDED,
- testScope = this,
+ testScope = testScope,
)
kosmos.keyguardInteractor.onCameraLaunchDetected(CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP)
- assertThat(clockVisible!!.visibility).isEqualTo(View.GONE)
+ assertThat(clockVisible!!.visibility).isEqualTo(View.INVISIBLE)
assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE)
assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE)
}
@@ -803,7 +883,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
@EnableSceneContainer
fun secureCameraActive_sceneFlagOn_noStatusBarViewsShown() =
- testScope.runTest {
+ kosmos.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
@@ -813,21 +893,26 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true, taskInfo = null)
kosmos.keyguardInteractor.onCameraLaunchDetected(CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP)
- assertThat(clockVisible!!.visibility).isEqualTo(View.GONE)
+ assertThat(clockVisible!!.visibility).isEqualTo(View.INVISIBLE)
assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE)
assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE)
}
+ // Cribbed from [HeadsUpNotificationInteractorTest.kt]
+ private fun fakeHeadsUpRowRepository(key: String = "test key", isPinned: Boolean = false) =
+ FakeHeadsUpRowRepository(key = key, isPinned = isPinned)
+
private fun activeNotificationsStore(notifications: List<ActiveNotificationModel>) =
ActiveNotificationsStore.Builder()
.apply { notifications.forEach(::addIndividualNotif) }
.build()
- private val testNotifications =
+ private val testNotifications by lazy {
listOf(activeNotificationModel(key = "notif1"), activeNotificationModel(key = "notif2"))
+ }
- private suspend fun transitionKeyguardToGone() {
- keyguardTransitionRepository.sendTransitionSteps(
+ private suspend fun Kosmos.transitionKeyguardToGone() {
+ fakeKeyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.LOCKSCREEN,
to = KeyguardState.GONE,
testScope = testScope,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizerTest.kt
index 7d3ed92cecc6..7aa389a1739f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizerTest.kt
@@ -20,10 +20,12 @@ import android.view.MotionEvent
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.testKosmos
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.Finished
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.InProgress
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.NotStarted
import com.android.systemui.touchpad.tutorial.ui.gesture.MultiFingerGesture.Companion.SWIPE_DISTANCE
+import com.android.systemui.touchpad.ui.gesture.fakeVelocityTracker
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
@@ -33,12 +35,24 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class HomeGestureRecognizerTest : SysuiTestCase() {
+ companion object {
+ const val THRESHOLD_VELOCITY_PX_PER_MS = 1f
+ const val SLOW = THRESHOLD_VELOCITY_PX_PER_MS - 0.01f
+ const val FAST = THRESHOLD_VELOCITY_PX_PER_MS + 0.01f
+ }
+
private var gestureState: GestureState = GestureState.NotStarted
+ private var velocityTracker = testKosmos().fakeVelocityTracker
private val gestureRecognizer =
- HomeGestureRecognizer(gestureDistanceThresholdPx = SWIPE_DISTANCE.toInt())
+ HomeGestureRecognizer(
+ gestureDistanceThresholdPx = SWIPE_DISTANCE.toInt(),
+ velocityThresholdPxPerMs = THRESHOLD_VELOCITY_PX_PER_MS,
+ velocityTracker = velocityTracker,
+ )
@Before
fun before() {
+ velocityTracker.setVelocity(Velocity(FAST))
gestureRecognizer.addGestureStateCallback { gestureState = it }
}
@@ -48,6 +62,12 @@ class HomeGestureRecognizerTest : SysuiTestCase() {
}
@Test
+ fun doesntTriggerGestureFinished_onGestureSpeedTooSlow() {
+ velocityTracker.setVelocity(Velocity(SLOW))
+ assertStateAfterEvents(events = ThreeFingerGesture.swipeUp(), expectedState = NotStarted)
+ }
+
+ @Test
fun triggersGestureProgressForThreeFingerGestureStarted() {
assertStateAfterEvents(
events = ThreeFingerGesture.startEvents(x = 0f, y = 0f),
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizerTest.kt
index c5c0d59ea48b..cb74e6569b3f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizerTest.kt
@@ -17,21 +17,19 @@
package com.android.systemui.touchpad.tutorial.ui.gesture
import android.view.MotionEvent
-import androidx.compose.ui.input.pointer.util.VelocityTracker1D
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.testKosmos
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.Finished
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.InProgress
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.NotStarted
import com.android.systemui.touchpad.tutorial.ui.gesture.MultiFingerGesture.Companion.SWIPE_DISTANCE
+import com.android.systemui.touchpad.ui.gesture.fakeVelocityTracker
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.kotlin.doReturn
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.whenever
@SmallTest
@RunWith(AndroidJUnit4::class)
@@ -39,26 +37,23 @@ class RecentAppsGestureRecognizerTest : SysuiTestCase() {
companion object {
const val THRESHOLD_VELOCITY_PX_PER_MS = 0.1f
- // multiply by 1000 to get px/ms instead of px/s which is unit used by velocity tracker
- const val SLOW = THRESHOLD_VELOCITY_PX_PER_MS * 1000 - 1
- const val FAST = THRESHOLD_VELOCITY_PX_PER_MS * 1000 + 1
+ const val SLOW = THRESHOLD_VELOCITY_PX_PER_MS - 0.01f
+ const val FAST = THRESHOLD_VELOCITY_PX_PER_MS + 0.01f
}
+ private var velocityTracker = testKosmos().fakeVelocityTracker
+
private var gestureState: GestureState = GestureState.NotStarted
- private val velocityTracker1D =
- mock<VelocityTracker1D> {
- // by default return correct speed for the gesture - as if pointer is slowing down
- on { calculateVelocity() } doReturn SLOW
- }
private val gestureRecognizer =
RecentAppsGestureRecognizer(
gestureDistanceThresholdPx = SWIPE_DISTANCE.toInt(),
velocityThresholdPxPerMs = THRESHOLD_VELOCITY_PX_PER_MS,
- velocityTracker = VerticalVelocityTracker(velocityTracker1D),
+ velocityTracker = velocityTracker,
)
@Before
fun before() {
+ velocityTracker.setVelocity(Velocity(SLOW))
gestureRecognizer.addGestureStateCallback { gestureState = it }
}
@@ -69,7 +64,7 @@ class RecentAppsGestureRecognizerTest : SysuiTestCase() {
@Test
fun doesntTriggerGestureFinished_onGestureSpeedTooHigh() {
- whenever(velocityTracker1D.calculateVelocity()).thenReturn(FAST)
+ velocityTracker.setVelocity(Velocity(FAST))
assertStateAfterEvents(events = ThreeFingerGesture.swipeUp(), expectedState = NotStarted)
}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/AuthContextPlugin.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/AuthContextPlugin.kt
new file mode 100644
index 000000000000..773c2a2d5e78
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/AuthContextPlugin.kt
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.plugins
+
+import android.os.IBinder
+import android.view.View
+import com.android.systemui.plugins.annotations.ProvidesInterface
+
+/**
+ * Plugin for experimental "Contextual Auth" features.
+ *
+ * These plugins will get raw access to low-level events about the user's environment, such as
+ * moving in/out of trusted locations, connection status of trusted devices, auth attempts, etc.
+ * They will also receive callbacks related to system events & transitions to enable prototypes on
+ * sensitive surfaces like lock screen and BiometricPrompt.
+ *
+ * Note to rebuild the plugin jar run: m PluginDummyLib
+ */
+@ProvidesInterface(action = AuthContextPlugin.ACTION, version = AuthContextPlugin.VERSION)
+interface AuthContextPlugin : Plugin {
+
+ /**
+ * Called in the background when the plugin is enabled.
+ *
+ * This is a good time to ask your friendly [saucier] to cook up something special. The
+ * [Plugin.onCreate] can also be used for initialization.
+ */
+ fun activated(saucier: Saucier)
+
+ /**
+ * Called when a [SensitiveSurface] is first shown.
+ *
+ * This may be called repeatedly if the state of the surface changes after it is shown. For
+ * example, [SensitiveSurface.BiometricPrompt.isCredential] will change if the user falls back
+ * to a credential-based auth method.
+ */
+ fun onShowingSensitiveSurface(surface: SensitiveSurface)
+
+ /**
+ * Called when a [SensitiveSurface] sensitive surface is hidden.
+ *
+ * This method may still be called without [onShowingSensitiveSurface] in cases of rapid
+ * dismissal and plugins implementations should typically be idempotent.
+ */
+ fun onHidingSensitiveSurface(surface: SensitiveSurface)
+
+ companion object {
+ /** Plugin action. */
+ const val ACTION = "com.android.systemui.action.PLUGIN_AUTH_CONTEXT"
+ /** Plugin version. */
+ const val VERSION = 1
+ }
+
+ /** Information about a sensitive surface in the framework, which the Plugin may augment. */
+ sealed interface SensitiveSurface {
+
+ /** Information about the BiometricPrompt that is being shown to the user. */
+ data class BiometricPrompt(val view: View? = null, val isCredential: Boolean = false) :
+ SensitiveSurface
+
+ /** Information about bouncer. */
+ data class LockscreenBouncer(val view: View? = null) : SensitiveSurface
+ }
+
+ /** Ask for the special. */
+ interface Saucier {
+
+ /** What [flavor] would you like? */
+ fun getSauce(flavor: String): IBinder?
+ }
+}
diff --git a/packages/SystemUI/res/layout/controls_management.xml b/packages/SystemUI/res/layout/controls_management.xml
index d8967d4706ce..e90471e75287 100644
--- a/packages/SystemUI/res/layout/controls_management.xml
+++ b/packages/SystemUI/res/layout/controls_management.xml
@@ -22,7 +22,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
- android:paddingTop="@dimen/controls_management_top_padding"
android:paddingStart="@dimen/controls_management_side_padding"
android:paddingEnd="@dimen/controls_management_side_padding" >
diff --git a/packages/SystemUI/res/layout/notification_2025_hybrid_conversation.xml b/packages/SystemUI/res/layout/notification_2025_hybrid_conversation.xml
index ff5d9d3567f6..a338e4c70cfa 100644
--- a/packages/SystemUI/res/layout/notification_2025_hybrid_conversation.xml
+++ b/packages/SystemUI/res/layout/notification_2025_hybrid_conversation.xml
@@ -29,16 +29,18 @@
android:layout_height="@dimen/notification_2025_single_line_face_pile_size"
android:layout_marginEnd="8dp"
>
- <ImageView
+ <com.android.internal.widget.CachingIconView
android:id="@*android:id/conversation_icon"
android:layout_width="@dimen/notification_2025_single_line_avatar_size"
android:layout_height="@dimen/notification_2025_single_line_avatar_size"
android:layout_gravity="center_vertical|end"
+ android:background="@*android:drawable/notification_icon_circle"
+ android:clipToOutline="true"
/>
<ViewStub
android:id="@*android:id/conversation_face_pile"
- android:layout="@*android:layout/conversation_face_pile_layout"
+ android:layout="@*android:layout/notification_2025_conversation_face_pile_layout"
android:layout_width="@dimen/notification_2025_single_line_face_pile_size"
android:layout_height="@dimen/notification_2025_single_line_face_pile_size"
android:layout_gravity="center_vertical|end"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index ebee1576342a..f095c0e14271 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Sluitskermlegstukke"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Om ’n app met ’n legstuk oop te maak, sal jy moet verifieer dat dit jy is. Hou ook in gedagte dat enigeen dit kan bekyk, selfs wanneer jou tablet gesluit is. Sommige legstukke is moontlik nie vir jou sluitskerm bedoel nie en dit kan onveilig wees om dit hier by te voeg."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Het dit"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Wissel gebruiker"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"aftrekkieslys"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle programme en data in hierdie sessie sal uitgevee word."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Word aan die bokant van gesprekskennisgewings en as \'n profielfoto op sluitskerm gewys, verskyn as \'n borrel, onderbreek Moenie Steur Nie"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioriteit"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> steun nie gesprekskenmerke nie"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Hierdie kennisgewings kan nie gewysig word nie."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Oproepkennisgewings kan nie gewysig word nie."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Hierdie groep kennisgewings kan nie hier opgestel word nie"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Keer die foon om vir hoër resolusie"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Voubare toestel word ontvou"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Voubare toestel word omgekeer"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Voorste skerm is aangeskakel"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"gevou"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"oopgevou"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Toeganklikheid"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Kortpadsleutels"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Pasmaak kortpadsleutels"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Druk sleutel om kortpad toe te wys"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Soekkortpaaie"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Geen soekresultate nie"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Vou ikoon in"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Sleephandvatsel"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Sleutelbordinstellings"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Stel kortpad"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Kanselleer"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Druk sleutel"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Sleutelkombinasie is reeds in gebruik. Probeer ’n ander sleutel."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigeer met jou sleutelbord"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Leer kortpadsleutels"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigeer met jou raakpaneel"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 0351c7508703..0bd9f1ded56c 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"የማያ ገፅ ቁልፍ ምግብሮች"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ምግብር በመጠቀም መተግበሪያ ለመክፈት እርስዎ መሆንዎን ማረጋገጥ አለብዎት። እንዲሁም የእርስዎ ጡባዊ በተቆለፈበት ጊዜ እንኳን ማንኛውም ሰው እነሱን ማየት እንደሚችል ከግምት ውስጥ ያስገቡ። አንዳንድ ምግብሮች ለማያ ገፅ ቁልፍዎ የታሰቡ ላይሆኑ ይችላሉ እና እዚህ ለማከል አስተማማኝ ላይሆኑ ይችላሉ።"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ገባኝ"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ተጠቃሚ ቀይር"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ወደታች ተጎታች ምናሌ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"በዚህ ክፍለ-ጊዜ ውስጥ ያሉ ሁሉም መተግበሪያዎች እና ውሂብ ይሰረዛሉ።"</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"በውይይት ማሳወቂያዎች አናት ላይ እና በማያ ገፅ መቆለፊያ ላይ እንደ መገለጫ ምስል ይታያል፣ እንደ አረፋ ሆኖ ይታያል፣ አትረብሽን ያቋርጣል"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"ቅድሚያ"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> የውይይት ባህሪያትን አይደግፍም"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"እነዚህ ማሳወቂያዎች ሊሻሻሉ አይችሉም።"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"የጥሪ ማሳወቂያዎች ሊቀየሩ አይችሉም።"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"የማሳወቂያዎች ይህ ቡድን እዚህ ላይ ሊዋቀር አይችልም"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ለከፍተኛ ጥራት ስልኩን ይቀይሩ"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"መታጠፍ የሚችል መሣሪያ እየተዘረጋ ነው"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"መታጠፍ የሚችል መሣሪያ እየተገለበጠ ነው"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"የፊት ለፊት ማያ ገፅ በርቷል"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"የታጠፈ"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"የተዘረጋ"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ተደራሽነት"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"የቁልፍ ሰሌዳ አቋራጮች"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"የቁልፍ ሰሌዳ አቋራጮችን ያብጁ"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"አቋራጭ ለመመደብ ቁልፍ ይጫኑ"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"የፍለጋ አቋራጮች"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ምንም የፍለጋ ውጤቶች የሉም"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"መሰብሰቢያ አዶ"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"መያዣ ይጎትቱ"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"የቁልፍ ሰሌዳ ቅንብሮች"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"አቋራጭ አቀናብር"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ይቅር"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ቁልፍ ይጫኑ"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"የቁልፍ ጥምረት አስቀድሞ በሥራ ላይ ነው። ሌላ ቁልፍ ይሞክሩ።"</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"የቁልፍ ሰሌዳዎን በመጠቀም ያስሱ"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"የቁልፍ ሰሌዳ አቋራጮችን ይወቁ"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"የመዳሰሻ ሰሌዳዎን በመጠቀም ያስሱ"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 645d88008b21..bdd6139ddf18 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -113,7 +113,7 @@
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"تسجيل شاشة تطبيق واحد"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"تسجيل الشاشة بكاملها"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"‏تسجيل محتوى الشاشة بالكامل: %s"</string>
- <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"أثناء تسجيل محتوى الشاشة بالكامل، يتم تسجيل كل المحتوى المعروض على شاشتك. لذا يُرجى توخي الحذر بشأن المعلومات، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور وملفات الصوت والفيديو."</string>
+ <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"أثناء تسجيل محتوى الشاشة بالكامل، يتم تسجيل كل المحتوى المعروض على شاشتك، لذا يُرجى توخي الحذر بشأن المعلومات الظاهرة، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور والمقاطع الصوتية والفيديوهات."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"سيتم تسجيل كل المحتوى المعروض أو المشغَّل على شاشة التطبيق، لذا يُرجى توخي الحذر بشأن المعلومات الظاهرة، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور والمقاطع الصوتية والفيديوهات."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"تسجيل الشاشة"</string>
<string name="screenrecord_app_selector_title" msgid="3854492366333954736">"يُرجى اختيار تطبيق لتسجيل شاشته"</string>
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"التطبيقات المصغّرة المصمَّمة لشاشة القفل"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"لفتح تطبيق باستخدام تطبيق مصغَّر، عليك إثبات هويتك. يُرجى ملاحظة أنّ أي شخص يمكنه الاطّلاع محتوى التطبيقات المصغَّرة، حتى وإن كان جهازك اللوحي مُقفلاً. بعض التطبيقات المصغّرة قد لا تكون مُصمَّمة لإضافتها إلى شاشة القفل، وقد يكون هذا الإجراء غير آمن."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"حسنًا"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"تبديل المستخدم"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"القائمة المنسدلة"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"سيتم حذف كل التطبيقات والبيانات في هذه الجلسة."</string>
@@ -695,10 +699,10 @@
<string name="volume_stream_content_description_mute" msgid="4079046784917920984">"‏%1$s. انقر للتجاهل. قد يتم تجاهل خدمات \"سهولة الاستخدام\"."</string>
<string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"‏%1$s. انقر للتعيين على الاهتزاز."</string>
<string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"‏%1$s. انقر لكتم الصوت."</string>
- <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"التحكُّم في مستوى الضوضاء"</string>
+ <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"التحكّم بالضوضاء"</string>
<string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"الصوت المكاني"</string>
- <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"غير مفعّل"</string>
- <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"تفعيل"</string>
+ <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"عدم التفعيل"</string>
+ <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"التفعيل بدون تتبّع"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"تتبُّع حركة الرأس"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"انقر لتغيير وضع الرنين."</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"وضع الرنين"</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"تظهر في أعلى إشعارات المحادثات وكصورة ملف شخصي على شاشة القفل وتظهر على شكل فقاعة لمقاطعة ميزة \"عدم الإزعاج\"."</string>
<string name="notification_priority_title" msgid="2079708866333537093">"الأولوية"</string>
<string name="no_shortcut" msgid="8257177117568230126">"لا يدعم تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> ميزات المحادثات."</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"يتعذّر تعديل هذه الإشعارات."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"لا يمكن تعديل إشعارات المكالمات."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"يتعذّر ضبط مجموعة الإشعارات هذه هنا."</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"يجب استخدام أقل من <xliff:g id="LENGTH">%1$d</xliff:g> حرف."</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"رقم الإصدار"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"تم نسخ رقم الإصدار إلى الحافظة."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"نسخ المحتوى إلى الحافظة"</string>
<string name="basic_status" msgid="2315371112182658176">"محادثة مفتوحة"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"التطبيقات المصغّرة للمحادثات"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"انقر على محادثة لإضافتها إلى \"الشاشة الرئيسية\""</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"للحصول على درجة دقة أعلى، اقلِب الهاتف."</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"جهاز قابل للطي يجري فتحه"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"جهاز قابل للطي يجري قلبه"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"تم تفعيل الشاشة الأمامية"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"مطوي"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"غير مطوي"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"‫%1$s / %2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"تسهيل الاستخدام"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"اختصارات لوحة المفاتيح"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"تخصيص اختصارات لوحة المفاتيح"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"اضغط على مفتاح لتخصيص الاختصار"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"البحث في الاختصارات"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ما مِن نتائج بحث"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"رمز التصغير"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"مقبض السحب"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"إعدادات لوحة المفاتيح"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ضبط الاختصار"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"إلغاء"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"اضغط على مفتاح"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"يتم حاليًا استخدام مجموعة المفاتيح هذه. يُرجى تجربة مفتاح آخر."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"التنقّل باستخدام لوحة المفاتيح"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"تعرَّف على اختصارات لوحة المفاتيح"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"التنقّل باستخدام لوحة اللمس"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index e14f4ccdece6..631c43dda9f1 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"লক স্ক্ৰীন ৱিজেট"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"এটা ৱিজেট ব্যৱহাৰ কৰি কোনো এপ্ খুলিবলৈ, এয়া আপুনিয়েই বুলি সত্যাপন পৰীক্ষা কৰিব লাগিব। লগতে, মনত ৰাখিব যে যিকোনো লোকেই সেইবোৰ চাব পাৰে, আনকি আপোনাৰ টেবলেটটো লক হৈ থাকিলেও। কিছুমান ৱিজেট হয়তো আপোনাৰ লক স্ক্ৰীনৰ বাবে কৰা হোৱা নাই আৰু ইয়াত যোগ কৰাটো অসুৰক্ষিত হ’ব পাৰে।"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"বুজি পালোঁ"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ব্যৱহাৰকাৰী সলনি কৰক"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"পুল-ডাউনৰ মেনু"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই ছেশ্বনৰ আটাইবোৰ এপ্ আৰু ডেটা মচা হ\'ব।"</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"বাৰ্তালাপৰ জাননীৰ শীৰ্ষত আৰু প্ৰ’ফাইল চিত্ৰ হিচাপে লক স্ক্ৰীনত দেখুৱায়, এটা বাবল হিচাপে দেখা পোৱা যায়, অসুবিধা নিদিব ম’ডত ব্যাঘাত জন্মায়"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"অগ্ৰাধিকাৰ"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ বাৰ্তালাপৰ সুবিধাসমূহ সমৰ্থন নকৰে"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"এই জাননীসমূহ সংশোধন কৰিব নোৱাৰি।"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"কলৰ জাননীসমূহ সংশোধন কৰিব নোৱাৰি।"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"এই ধৰণৰ জাননীবোৰ ইয়াত কনফিগাৰ কৰিব পৰা নাযায়"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"অধিক ৰিজ’লিউশ্বনৰ বাবে, ফ’নটো লুটিয়াই দিয়ক"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"জপাব পৰা ডিভাইচৰ জাপ খুলি থকা হৈছে"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"জপাব পৰা ডিভাইচৰ ওলোটাই থকা হৈছে"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"সন্মুখৰ স্ক্ৰীনখন অন কৰা হৈছে"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ফ’ল্ড কৰা"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"আনফ’ল্ড কৰা"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"সাধ্য সুবিধা"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"কীব’ৰ্ডৰ শ্বৰ্টকাট"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"কীব’ৰ্ডৰ শ্বৰ্টকাট কাষ্টমাইজ কৰক"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"শ্বৰ্টকাটৰ ভূমিকা অৰ্পণ কৰিবলৈ কী টিপক"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"সন্ধানৰ শ্বৰ্টকাট"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"সন্ধানৰ কোনো ফলাফল নাই"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"সংকোচন কৰাৰ চিহ্ন"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ড্ৰেগ হেণ্ডেল"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"কীব’ৰ্ডৰ ছেটিং"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"শ্বৰ্টকাট ছেট কৰক"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"বাতিল কৰক"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"কী টিপক"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"কীৰ মিশ্ৰণ ইতিমধ্যে ব্যৱহাৰ হৈ আছে। অন্য এটা কী ব্যৱহাৰ কৰি চাওক।"</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"কীব’ৰ্ড ব্যৱহাৰ কৰি নেভিগে’ট কৰক"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"কীব’ৰ্ডৰ শ্বৰ্টকাটসমূহৰ বিষয়ে জানক"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"আপোনাৰ টাচ্চপেড ব্যৱহাৰ কৰি নেভিগে’ট কৰক"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 90168703b896..2b61f0162dbf 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Kilid ekranı vidcetləri"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Vidcetdən istifadə edərək tətbiqi açmaq üçün kimliyi doğrulamalısınız. Planşet kilidli olsa da, hər kəs vidcetlərə baxa bilər. Bəzi vidcetlər kilid ekranı üçün nəzərdə tutulmayıb və bura əlavə etmək təhlükəli ola bilər."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Anladım"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"aşağı çəkilən menyu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bu sessiyada bütün tətbiqlər və data silinəcək."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Söhbət bildirişlərinin yuxarısında və kilid ekranında profil şəkli kimi göstərilir, baloncuq kimi görünür, Narahat Etməyin rejimini kəsir"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> söhbət funksiyalarını dəstəkləmir"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Bu bildirişlər dəyişdirilə bilməz."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Zəng bildirişləri dəyişdirilə bilməz."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Bu bildiriş qrupunu burada konfiqurasiya etmək olmaz"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Daha yüksək ayırdetmə dəqiqliyi üçün telefonu çevirin"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Qatlana bilən cihaz açılır"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Qatlana bilən cihaz fırladılır"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Ön ekran aktiv edildi"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"qatlanmış"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"açıq"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Xüsusi imkanlar"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klaviatura qısayolları"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Klaviatura qısayollarını fərdiləşdirin"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Qısayol təyin etmək üçün düyməni basın"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Axtarış qısayolları"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Axtarış nəticəsi yoxdur"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"İkonanı yığcamlaşdırın"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Dəstəyi çəkin"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Klaviatura ayarları"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Qısayol ayarlayın"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Ləğv edin"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Düyməni basın"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Düymə kombinasiyası artıq istifadə olunur. Başqa düyməni sınayın."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Klaviaturadan istifadə edərək hərəkət edin"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Klaviatura qısayolları haqqında öyrənin"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Taçpeddən istifadə edərək hərəkət edin"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index d2636c050db0..c52824f8e487 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Vidžeti za zaključani ekran"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Da biste otvorili aplikaciju koja koristi vidžet, treba da potvrdite da ste to vi. Imajte u vidu da svako može da ga vidi, čak i kada je tablet zaključan. Neki vidžeti možda nisu namenjeni za zaključani ekran i možda nije bezbedno da ih tamo dodate."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Važi"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Zameni korisnika"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući meni"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji će biti izbrisani."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Prikazuje se u vrhu obaveštenja o konverzacijama i kao slika profila na zaključanom ekranu, pojavljuje se kao oblačić, prekida režim Ne uznemiravaj"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritetno"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava funkcije konverzacije"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Ova obaveštenja ne mogu da se menjaju."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Obaveštenja o pozivima ne mogu da se menjaju."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Ova grupa obaveštenja ne može da se konfiguriše ovde"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Koristite manji broj znakova od <xliff:g id="LENGTH">%1$d</xliff:g>"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u privremenu memoriju."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"kopirajte u privremenu memoriju."</string>
<string name="basic_status" msgid="2315371112182658176">"Otvorite konverzaciju"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Vidžeti za konverzaciju"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Dodirnite konverzaciju da biste je dodali na početni ekran"</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Za veću rezoluciju obrnite telefon"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Uređaj na preklop se otvara"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Uređaj na preklop se obrće"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Prednji ekran je uključen"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"zatvoreno"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"otvoreno"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tasterske prečice"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagodite tasterske prečice"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pritisnite taster da biste dodelili prečicu"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pretražite prečice"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nema rezultata pretrage"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za skupljanje"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Marker za prevlačenje"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Podešavanja tastature"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Podesi prečicu"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Otkaži"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pritisnite taster"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinacija tastera se već koristi. Probajte sa drugim tasterom."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Krećite se pomoću tastature"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Saznajte više o tasterskim prečicama"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Krećite se pomoću tačpeda"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 388950cb7bdd..a58b47cc3b1b 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Віджэты на экране блакіроўкі"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Каб адкрыць праграму з дапамогай віджэта, вам неабходна будзе пацвердзіць сваю асобу. Таксама памятайце, што такія віджэты могуць пабачыць іншыя людзі, нават калі экран планшэта заблакіраваны. Некаторыя віджэты могуць не падыходзіць для выкарыстання на экране блакіроўкі, і дадаваць іх сюды можа быць небяспечна."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Зразумела"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Перайсці да іншага карыстальніка"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"высоўнае меню"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Усе праграмы і даныя гэтага сеанса будуць выдалены."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"З’яўляецца ўверсе раздзела размоў як усплывальнае апавяшчэнне, якое перарывае рэжым \"Не турбаваць\" і паказвае на экране блакіроўкі відарыс профілю"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Прыярытэт"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не падтрымлівае функцыі размовы"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Гэтыя апавяшчэнні нельга змяніць."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Апавяшчэнні пра выклікі нельга змяніць."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Тут канфігурыраваць гэту групу апавяшчэнняў забаронена"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Каб зрабіць фота з больш высокай раздзяляльнасцю, павярніце тэлефон"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Складная прылада ў раскладзеным выглядзе"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Перавернутая складная прылада"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Пярэдні экран уключаны"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"складзена"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"раскладзена"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Спецыяльныя магчымасці"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Спалучэнні клавіш"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Наладзіць спалучэнні клавіш"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Націсніце клавішу, каб прызначыць спалучэнне клавіш"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Пошук спалучэнняў клавіш"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Няма вынікаў пошуку"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Значок \"Згарнуць\""</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Маркер перацягвання"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Налады клавіятуры"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Наладзіць спалучэнне клавіш"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Скасаваць"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Націсніце клавішу"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Гэта спалучэнне клавіш ужо выкарыстоўваецца. Паспрабуйце іншую клавішу."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Навігацыя з дапамогай клавіятуры"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Азнаёмцеся са спалучэннямі клавіш"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Навігацыя з дапамогай сэнсарнай панэлі"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 2d68f9190a30..e8478053bc1e 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Приспособления за заключения екран"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"За да отворите дадено приложение посредством приспособление, ще трябва да потвърдите, че това сте вие. Също така имайте предвид, че всеки ще вижда приспособленията дори когато таблетът ви е заключен. Възможно е някои от тях да не са предназначени за заключения екран и добавянето им на него може да е опасно."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Разбрах"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Превключване между потребителите"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"падащо меню"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Всички приложения и данни в тази сесия ще бъдат изтрити."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Показва се в горната част на известията за разговори и като снимка на потребителския профил на заключения екран, изглежда като балонче, прекъсва режима „Не безпокойте“"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Приоритет"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не поддържа функциите за разговор"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Тези известия не могат да бъдат променяни."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Известията за обаждания не могат да бъдат променяни."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Тази група от известия не може да бъде конфигурирана тук"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Използвайте по-малко от <xliff:g id="LENGTH">%1$d</xliff:g> знака"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер на компилацията"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Номерът на компилацията е копиран в буферната памет."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"копиране в буферната памет."</string>
<string name="basic_status" msgid="2315371112182658176">"Отворен разговор"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Приспособления за разговор"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Докоснете разговор, за да го добавите към началния си екран"</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"За по-висока разделителна способност обърнете телефона"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Разгъване на сгъваемо устройство"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Обръщане на сгъваемо устройство"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Предният екран е включен"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"затворено"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"отворено"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Достъпност"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Клавишни комбинации"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Персонализиране на клавишните комбинации"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Натиснете клавиш, за да зададете клавишна комбинация"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Търсете клавишни комбинации"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Няма резултати от търсенето"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Икона за свиване"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Манипулатор за преместване с плъзгане"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Настройки на клавиатурата"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Задаване на клавишна комбинация"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Отказ"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Натиснете клавиш"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Клавишната комбинация вече се използва. Опитайте с друг клавиш."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Навигирайте посредством клавиатурата си"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Научете за клавишните комбинации"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Навигирайте посредством сензорния панел"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 4281ea111b03..557edbefab47 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"লক স্ক্রিন উইজেট"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"উইজেট ব্যবহার করে কোনও অ্যাপ খুলতে, আপনাকে নিজের পরিচয় যাচাই করতে হবে। এছাড়াও, মনে রাখবেন, আপনার ট্যাবলেট লক থাকলেও যেকেউ তা দেখতে পারবেন। কিছু উইজেট আপনার লক স্ক্রিনের উদ্দেশ্যে তৈরি করা হয়নি এবং এখানে যোগ করা নিরাপদ নাও হতে পারে।"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"বুঝেছি"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ব্যবহারকারী পাল্টে দিন"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"পুলডাউন মেনু"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই সেশনের সব অ্যাপ ও ডেটা মুছে ফেলা হবে।"</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"কথোপকথনের বিজ্ঞপ্তির উপরের দিকে এবং প্রোফাইল ছবি হিসেবে লক স্ক্রিনে দেখানো হয়, বাবল হিসেবেও এটি দেখা যায় এবং এর ফলে \'বিরক্ত করবে না\' মোডে কাজ করতে অসুবিধা হয়"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"অগ্রাধিকার"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>-এ কথোপকথন ফিচার কাজ করে না"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"এই বিজ্ঞপ্তিগুলি পরিবর্তন করা যাবে না।"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"কল বিজ্ঞপ্তি পরিবর্তন করা যাবে না।"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"এই সমস্ত বিজ্ঞপ্তিকে এখানে কনফিগার করা যাবে না"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"আরও বেশি রেজোলিউশনের জন্য, ফোন ফ্লিপ করুন"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ফোল্ড করা যায় এমন ডিভাইস খোলা হচ্ছে"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ফোল্ড করা যায় এমন ডিভাইস উল্টানো হচ্ছে"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"ফ্রন্ট স্ক্রিন চালু আছে"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ফোল্ড করা রয়েছে"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ফোল্ড করা নেই"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"অ্যাক্সেসিবিলিটি"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"কীবোর্ড শর্টকাট"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"কীবোর্ড শর্টকাট কাস্টমাইজ করুন"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"শর্টকাট অ্যাসাইন করতে কী প্রেস করুন"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"শর্টকাট সার্চ করুন"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"কোনও সার্চ ফলাফল নেই"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"আইকন আড়াল করুন"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"টেনে আনার হ্যান্ডেল"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"কীবোর্ড সেটিংস"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"শর্টকাট সেট করুন"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"বাতিল করুন"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"কী প্রেস করুন"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"কী কম্বিনেশন আগে থেকে ব্যবহার হচ্ছে। অন্য কী ব্যবহার করে দেখুন।"</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"আপনার কীবোর্ড ব্যবহার করে নেভিগেট করুন"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"কীবোর্ড শর্টকাট সম্পর্কে জানুন"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"আপনার টাচপ্যাড ব্যবহার করে নেভিগেট করুন"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 9d9bf7f004a2..ac4099f169d5 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Vidžeti na zaključanom ekranu"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Da otvorite aplikaciju pomoću vidžeta, morat ćete potvrditi identitet. Također imajte na umu da ih svako može pregledati, čak i ako je tablet zaključan. Neki vidžeti možda nisu namijenjeni za vaš zaključani ekran i njihovo dodavanje ovdje možda nije sigurno."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Razumijem"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Zamijeni korisnika"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući meni"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci iz ove sesije će se izbrisati."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Prikazuje se na vrhu obavještenja u razgovorima i kao slika profila na zaključanom ekranu, izgleda kao oblačić, prekida funkciju Ne ometaj"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritetno"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava funkcije razgovora"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Ta obavještenja se ne mogu izmijeniti."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Nije moguće izmijeniti obavještenja o pozivima."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Ovu grupu obavještenja nije moguće konfigurirati ovdje"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Za višu rezoluciju obrnite telefon"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Sklopivi uređaj se rasklapa"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Sklopivi uređaj se obrće"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Prednji ekran je uključen"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"sklopljeno"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"otklopljeno"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Prečice tastature"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagodite prečice na tastaturi"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pritisnite tipku da dodijelite prečicu"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prečica pretraživanja"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nema rezultata pretraživanja"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona sužavanja"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ručica za prevlačenje"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Postavke tastature"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Postavi prečicu"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Otkaži"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pritisnite tipku"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Ta se kombinacija tipki već koristi. Pokušajte s drugom tipkom."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Krećite se pomoću tastature"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Saznajte više o prečicama tastature"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Krećite se pomoću dodirne podloge"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 0be3d80edcb7..b5396da8f80a 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets de la pantalla de bloqueig"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Per obrir una aplicació utilitzant un widget, necessitaràs verificar la teva identitat. També has de tenir en compte que qualsevol persona pot veure els widgets, fins i tot quan la tauleta està bloquejada. És possible que alguns widgets no estiguin pensats per a la pantalla de bloqueig i que no sigui segur afegir-los-hi."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entesos"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Canvia d\'usuari"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú desplegable"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Totes les aplicacions i les dades d\'aquesta sessió se suprimiran."</string>
@@ -715,7 +719,7 @@
<string name="volume_panel_hint_muted" msgid="1124844870181285320">"silenciat"</string>
<string name="volume_panel_hint_vibrate" msgid="4136223145435914132">"vibra"</string>
<string name="media_output_label_title" msgid="872824698593182505">"S\'està reproduint <xliff:g id="LABEL">%s</xliff:g> a"</string>
- <string name="media_output_title_without_playing" msgid="3825663683169305013">"Es reproduirà a"</string>
+ <string name="media_output_title_without_playing" msgid="3825663683169305013">"L\'àudio es reproduirà a"</string>
<string name="media_output_title_ongoing_call" msgid="208426888064112006">"Trucant des de"</string>
<string name="system_ui_tuner" msgid="1471348823289954729">"Personalitzador d\'interfície d\'usuari"</string>
<string name="status_bar" msgid="4357390266055077437">"Barra d\'estat"</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Es mostra a la part superior de les notificacions de les converses i com a foto de perfil a la pantalla de bloqueig, apareix com una bombolla, interromp el mode No molestis"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritat"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> no admet les funcions de converses"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Aquestes notificacions no es poden modificar."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Les notificacions de trucades no es poden modificar."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Aquest grup de notificacions no es pot configurar aquí"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Utilitza menys de <xliff:g id="LENGTH">%1$d</xliff:g> caràcters"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilació"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"El número de compilació s\'ha copiat al porta-retalls."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"copiar al porta-retalls."</string>
<string name="basic_status" msgid="2315371112182658176">"Conversa oberta"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Toca una conversa per afegir-la a la teva pantalla d\'inici"</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Per a una resolució més alta, gira el telèfon"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositiu plegable desplegant-se"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositiu plegable girant"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"La pantalla frontal està activada"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"plegat"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"desplegat"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilitat"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tecles de drecera"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalitza les tecles de drecera"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Prem la tecla per assignar la drecera"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Dreceres de cerca"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No hi ha cap resultat de la cerca"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Replega la icona"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ansa per arrossegar"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Configuració del teclat"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Configura la drecera"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancel·la"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Prem una tecla"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"La combinació de tecles ja s\'està utilitzant. Prova-ho amb una altra tecla."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navega amb el teclat"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprèn les tecles de drecera"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navega amb el ratolí tàctil"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 1bbef7bce160..a6f0e6141801 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgety na obrazovce uzamčení"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"K otevření aplikace pomocí widgetu budete muset ověřit svou totožnost. Také mějte na paměti, že widgety uvidí kdokoli, i když tablet bude uzamčen. Některé widgety nemusí být pro obrazovku uzamčení určeny a nemusí být bezpečné je na ni přidat."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Rozumím"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Přepnout uživatele"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rozbalovací nabídka"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Veškeré aplikace a data v této relaci budou vymazána."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Zobrazuje se v horní části sekce konverzací a na obrazovce uzamčení se objevuje jako profilová fotka, má podobu bubliny a deaktivuje režim Nerušit"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritní"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> funkce konverzace nepodporuje"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Tato oznámení nelze upravit."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Upozornění na hovor nelze upravit."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Tuto skupinu oznámení tady nelze nakonfigurovat"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Použijte méně než <xliff:g id="LENGTH">%1$d</xliff:g> znaků"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo sestavení"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Číslo sestavení bylo zkopírováno do schránky."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"zkopírovat do schránky"</string>
<string name="basic_status" msgid="2315371112182658176">"Otevřít konverzaci"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widgety konverzací"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Klepnutím na konverzaci ji přidáte na plochu"</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Otočte telefon, abyste dosáhli vyššího rozlišení"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rozkládání rozkládacího zařízení"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Otáčení rozkládacího zařízení"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Přední obrazovka je zapnutá"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"složené"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"rozložené"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Přístupnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klávesové zkratky"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Přizpůsobení klávesových zkratek"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Nastavte zkratku stisknutím klávesy"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Vyhledat zkratky"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Žádné výsledky hledání"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona sbalení"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Úchyt pro přetažení"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Nastavení klávesnice"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Nastavit zkratku"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Zrušit"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Stiskněte klávesu"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinace kláves se už používá. Použijte jinou klávesu."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigujte pomocí klávesnice"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Naučte se klávesové zkratky"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigujte pomocí touchpadu"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index b2e17a929900..f5d36d71deb2 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets på låseskærmen"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Hvis du vil åbne en app ved hjælp af en widget, skal du verificere din identitet. Husk også, at alle kan se dem, også når din tablet er låst. Nogle widgets er muligvis ikke beregnet til låseskærmen, og det kan være usikkert at tilføje dem her."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Skift bruger"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rullemenu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps og data i denne session slettes."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Vises øverst i samtalenotifikationer og som et profilbillede på låseskærmen. Vises som en boble, der afbryder Forstyr ikke"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> understøtter ikke samtalefunktioner"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Disse notifikationer kan ikke redigeres."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Opkaldsnotifikationer kan ikke redigeres."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Du kan ikke konfigurere denne gruppe notifikationer her"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Vend telefonen for at få højere opløsning"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldbar enhed foldes ud"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldbar enhed vendes om"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Frontskærmen er aktiveret"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"foldet"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"foldet ud"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Hjælpefunktioner"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tastaturgenveje"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tilpas tastaturgenveje"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Tryk på en tast for at tildele genvejen"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Genveje til søgning"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Der er ingen søgeresultater"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikon for Skjul"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Håndtag"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Tastaturindstillinger"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Konfigurer genvej"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Annuller"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Tryk på en tast"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Tastekombinationen er allerede i brug. Prøv en anden tast."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naviger ved hjælp af dit tastatur"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Se tastaturgenveje"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naviger ved hjælp af din touchplade"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 5f7128e804d0..1573cb02e113 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Sperrbildschirm-Widgets"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Wenn du eine App mit einem Widget öffnen möchtest, musst du deine Identität bestätigen. Beachte auch, dass jeder die Widgets sehen kann, auch wenn dein Tablet gesperrt ist. Einige Widgets sind möglicherweise nicht für den Sperrbildschirm vorgesehen, sodass es unsicher sein kann, sie hier hinzuzufügen."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ok"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Nutzer wechseln"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"Pull-down-Menü"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle Apps und Daten in dieser Sitzung werden gelöscht."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Wird oben im Bereich „Unterhaltungen“ sowie als Profilbild auf dem Sperrbildschirm angezeigt, erscheint als Bubble, unterbricht „Bitte nicht stören“"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Priorität"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> unterstützt keine Funktionen für Unterhaltungen"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Diese Benachrichtigungen können nicht geändert werden."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Anrufbenachrichtigungen können nicht geändert werden."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Die Benachrichtigungsgruppe kann hier nicht konfiguriert werden"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Für höhere Auflösung Smartphone umdrehen"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Faltbares Gerät wird geöffnet"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Faltbares Gerät wird umgeklappt"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Frontdisplay aktiviert"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"zugeklappt"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"aufgeklappt"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Bedienungshilfen"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tastenkürzel"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tastenkombinationen anpassen"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Drücke eine Taste, um eine Tastenkombination festzulegen"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Tastenkürzel suchen"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Keine Suchergebnisse"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Symbol „Minimieren“"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ziehpunkt"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Tastatureinstellungen"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Tastenkombination festlegen"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Abbrechen"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Taste drücken"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Diese Tastenkombination wird bereits verwendet. Versuche es mit einer anderen Taste."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigation mit der Tastatur"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Informationen zu Tastenkombinationen"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigation mit dem Touchpad"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index fd8e37a34030..8da32147896c 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Γραφικά στοιχεία οθόνης κλειδώματος"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Για να ανοίξετε μια εφαρμογή χρησιμοποιώντας ένα γραφικό στοιχείο, θα πρέπει να επαληθεύσετε την ταυτότητά σας. Επίσης, λάβετε υπόψη ότι η προβολή τους είναι δυνατή από οποιονδήποτε, ακόμα και όταν το tablet σας είναι κλειδωμένο. Ορισμένα γραφικά στοιχεία μπορεί να μην προορίζονται για την οθόνη κλειδώματος και η προσθήκη τους εδώ ενδέχεται να μην είναι ασφαλής."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Το κατάλαβα"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Εναλλαγή χρήστη"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"αναπτυσσόμενο μενού"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Όλες οι εφαρμογές και τα δεδομένα αυτής της περιόδου σύνδεσης θα διαγραφούν."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Εμφανίζεται στην κορυφή των ειδοποιήσεων συζήτησης και ως φωτογραφία προφίλ στην οθόνη κλειδώματος, εμφανίζεται ως συννεφάκι, διακόπτει τη λειτουργία Μην ενοχλείτε"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Προτεραιότητα"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> δεν υποστηρίζει τις λειτουργίες συζήτησης"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Δεν είναι δυνατή η τροποποίηση αυτών των ειδοποιήσεων"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Δεν είναι δυνατή η τροποποίηση των ειδοποιήσεων κλήσεων."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Δεν είναι δυνατή η διαμόρφωση αυτής της ομάδας ειδοποιήσεων εδώ"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Χρησιμοποιήστε λιγότερους από <xliff:g id="LENGTH">%1$d</xliff:g> χαρακτήρες"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Αριθμός έκδοσης"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Ο αριθμός έκδοσης αντιγράφηκε στο πρόχειρο."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"αντιγραφή στο πρόχειρο."</string>
<string name="basic_status" msgid="2315371112182658176">"Άνοιγμα συνομιλίας"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Γραφικά στοιχεία συνομιλίας"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Πατήστε μια συνομιλία για να την προσθέσετε στην αρχική οθόνη"</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Για υψηλότερη ανάλυση, αναστρέψτε το τηλέφωνο"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Αναδιπλούμενη συσκευή που ξεδιπλώνει"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Αναδιπλούμενη συσκευή που διπλώνει"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Η μπροστινή οθόνη ενεργοποιήθηκε"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"διπλωμένη"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ξεδιπλωμένη"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Προσβασιμότητα"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Συντομεύσεις πληκτρολογίου"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Προσαρμογή συντομεύσεων πληκτρολογίου"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Πατήστε το πλήκτρο για εκχώρηση της συντόμευσης"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Συντομεύσεις αναζήτησης"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Κανένα αποτέλεσμα αναζήτησης"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Εικονίδιο σύμπτυξης"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Λαβή μεταφοράς"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Ρυθμίσεις πληκτρολογίου"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ορισμός συντόμευσης"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Ακύρωση"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Πατήστε ένα πλήκτρο"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Ο συνδυασμός πλήκτρων χρησιμοποιείται ήδη. Δοκιμάστε άλλο πλήκτρο."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Πλοήγηση με το πληκτρολόγιο"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Μάθετε συντομεύσεις πληκτρολογίου"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Πλοήγηση με την επιφάνεια αφής"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 4280ff2ad994..e92783d6d1e5 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lock screen widgets"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"To open an app using a widget, you\'ll need to verify that it\'s you. Also, bear in mind that anyone can view them, even when your tablet\'s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Got it"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble, interrupts Do Not Disturb"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Priority"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Call notifications can\'t be modified."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"This group of notifications cannot be configured here"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Use fewer than <xliff:g id="LENGTH">%1$d</xliff:g> characters"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"copy to clipboard."</string>
<string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Conversation widgets"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your home screen"</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"For higher resolution, flip the phone"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Front screen turned on"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"folded"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"unfolded"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Customise keyboard shortcuts"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Press key to assign shortcut"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Search shortcuts"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No search results"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Collapse icon"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Drag handle"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Keyboard settings"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Set shortcut"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancel"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Press key"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Key combination already in use. Try another key."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigate using your keyboard"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Learn keyboards shortcuts"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigate using your touchpad"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 3b009a1f1d14..b434c6e74a3b 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -528,6 +528,8 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lock screen widgets"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"To open an app using a widget, you’ll need to verify it’s you. Also, keep in mind that anyone can view them, even when your tablet’s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Got it"</string>
+ <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Widgets"</string>
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="511359420883794513">"To add Widgets on the lock screen as a shortcut, make sure it is enabled in settings."</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
@@ -780,6 +782,7 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble, interrupts Do Not Disturb"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Priority"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
+ <string name="notification_guts_bundle_feedback" msgid="5393570876655201459">"Provide Bundle Feedback"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Call notifications can\'t be modified."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"This group of notifications cannot be configured here"</string>
@@ -1220,8 +1223,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Use fewer than <xliff:g id="LENGTH">%1$d</xliff:g> characters"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"copy to clipboard."</string>
<string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Conversation widgets"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your Home screen"</string>
@@ -1417,7 +1419,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Customize keyboard shortcuts"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Press key to assign shortcut"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Search shortcuts"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No search results"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Collapse icon"</string>
@@ -1430,9 +1437,13 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Drag handle"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Keyboard Settings"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Set shortcut"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancel"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Press key"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Key combination already in use. Try another key."</string>
+ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Key combination already in use. Try another key."</string>
+ <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Shortcut cannot be set."</string>
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigate using your keyboard"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Learn keyboards shortcuts"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigate using your touchpad"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 4280ff2ad994..e92783d6d1e5 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lock screen widgets"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"To open an app using a widget, you\'ll need to verify that it\'s you. Also, bear in mind that anyone can view them, even when your tablet\'s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Got it"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble, interrupts Do Not Disturb"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Priority"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Call notifications can\'t be modified."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"This group of notifications cannot be configured here"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Use fewer than <xliff:g id="LENGTH">%1$d</xliff:g> characters"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"copy to clipboard."</string>
<string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Conversation widgets"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your home screen"</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"For higher resolution, flip the phone"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Front screen turned on"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"folded"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"unfolded"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Customise keyboard shortcuts"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Press key to assign shortcut"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Search shortcuts"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No search results"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Collapse icon"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Drag handle"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Keyboard settings"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Set shortcut"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancel"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Press key"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Key combination already in use. Try another key."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigate using your keyboard"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Learn keyboards shortcuts"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigate using your touchpad"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 4280ff2ad994..e92783d6d1e5 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lock screen widgets"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"To open an app using a widget, you\'ll need to verify that it\'s you. Also, bear in mind that anyone can view them, even when your tablet\'s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Got it"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble, interrupts Do Not Disturb"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Priority"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Call notifications can\'t be modified."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"This group of notifications cannot be configured here"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Use fewer than <xliff:g id="LENGTH">%1$d</xliff:g> characters"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"copy to clipboard."</string>
<string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Conversation widgets"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your home screen"</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"For higher resolution, flip the phone"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Front screen turned on"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"folded"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"unfolded"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Customise keyboard shortcuts"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Press key to assign shortcut"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Search shortcuts"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No search results"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Collapse icon"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Drag handle"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Keyboard settings"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Set shortcut"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancel"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Press key"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Key combination already in use. Try another key."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigate using your keyboard"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Learn keyboards shortcuts"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigate using your touchpad"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index ad403b1658ee..4ab2f2b56f8a 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets en la pantalla de bloqueo"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir una app usando un widget, debes verificar tu identidad. Además, ten en cuenta que cualquier persona podrá verlo, incluso cuando la tablet esté bloqueada. Es posible que algunos widgets no se hayan diseñados para la pantalla de bloqueo y podría ser peligroso agregarlos allí."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendido"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar usuario"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú expandible"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán las aplicaciones y los datos de esta sesión."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Aparece en forma de burbuja y como foto de perfil en la parte superior de las notificaciones de conversación, en la pantalla de bloqueo, y detiene el modo No interrumpir"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritaria"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> no admite funciones de conversación"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"No se pueden modificar estas notificaciones."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"No se pueden modificar las notificaciones de llamada."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"No se puede configurar aquí este grupo de notificaciones"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Usa menos de <xliff:g id="LENGTH">%1$d</xliff:g> caracteres"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Se copió el número de compilación en el portapapeles."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"copiar en el portapapeles."</string>
<string name="basic_status" msgid="2315371112182658176">"Conversación abierta"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversación"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Presiona una conversación para agregarla a tu pantalla principal"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidad"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Combinaciones de teclas"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personaliza las combinaciones de teclas"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Presiona la tecla para asignar el acceso directo"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Buscar combinaciones de teclas"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"La búsqueda no arrojó resultados"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícono de contraer"</string>
@@ -1431,9 +1441,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Controlador de arrastre"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Configuración del teclado"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Establecer combinación de teclas"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancelar"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Presiona una tecla"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"La combinación de teclas ya está en uso. Prueba con otra."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navega con el teclado"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprende combinaciones de teclas"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navega con el panel táctil"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 50de6d2e452a..861d21e0f502 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets para la pantalla de bloqueo"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir una aplicación usando un widget, deberás verificar que eres tú. Además, ten en cuenta que cualquier persona podrá verlos, incluso aunque tu tablet esté bloqueada. Es posible que algunos widgets no estén pensados para la pantalla de bloqueo y no sea seguro añadirlos aquí."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendido"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar de usuario"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú desplegable"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán todas las aplicaciones y datos de esta sesión."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Se muestra encima de las notificaciones de conversaciones y como imagen de perfil en la pantalla de bloqueo, aparece como burbuja e interrumpe el modo No molestar"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioridad"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> no admite funciones de conversación"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Estas notificaciones no se pueden modificar."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Las notificaciones de llamada no se pueden modificar."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Este grupo de notificaciones no se puede configurar aquí"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para una mayor resolución, gira el teléfono"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo plegable desplegándose"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo plegable mostrado desde varios ángulos"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Pantalla frontal encendida"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"plegado"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"desplegado"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidad"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Combinaciones de teclas"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizar las combinaciones de teclas"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pulsa una tecla para asignar una combinación de teclas"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Atajos de búsqueda"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No hay resultados de búsqueda"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icono de contraer"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Controlador de arrastre"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Ajustes del teclado"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Establecer combinación de teclas"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancelar"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pulsa una tecla"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"La combinación de teclas ya se está usando. Prueba con otra tecla."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Desplázate con el teclado"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprende combinaciones de teclas"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Desplázate con el panel táctil"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 9c0d56dad8c3..c2b140587b63 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lukustuskuva vidinad"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Rakenduse avamiseks vidina abil peate kinnitama, et see olete teie. Samuti pidage meeles, et kõik saavad vidinaid vaadata, isegi kui teie tahvelarvuti on lukus. Mõni vidin ei pruugi olla ette nähtud teie lukustuskuva jaoks ja seda pole turvaline siia lisada."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Selge"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Kasutaja vahetamine"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rippmenüü"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Seansi kõik rakendused ja andmed kustutatakse."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Kuvatakse mullina vestluste märguannete ülaosas ja profiilipildina lukustuskuval ning katkestab režiimi Mitte segada"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioriteetne"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei toeta vestlusfunktsioone"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Neid märguandeid ei saa muuta."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Kõnemärguandeid ei saa muuta."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Seda märguannete rühma ei saa siin seadistada"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Kasutage vähem kui <xliff:g id="LENGTH">%1$d</xliff:g> tähemärki"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Järgunumber"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Järgunumber kopeeriti lõikelauale."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"lõikelauale kopeerimine."</string>
<string name="basic_status" msgid="2315371112182658176">"Avage vestlus"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Vestlusvidinad"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Puudutage vestlust, et lisada see oma avakuvale"</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Suurema eraldusvõime saavutamiseks pöörake telefon ümber"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Volditava seadme lahtivoltimine"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Volditava seadme ümberpööramine"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Esiekraan on sisse lülitatud"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"kokku volditud"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"lahti volditud"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Juurdepääsetavus"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klaviatuuri otseteed"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Klaviatuuri otseteede kohandamine"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Otsetee lisamiseks vajutage klahvi"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Otsige otseteid"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Otsingutulemused puuduvad"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ahendamisikoon"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Lohistamispide"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Klaviatuuri seaded"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Määrake otsetee"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Tühista"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Vajutage klahvi"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Klahvikombinatsioon juba kasutusel. Proovige mõnda muud klahvi."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigeerige klaviatuuri abil"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Õppige klaviatuuri otseteid"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigeerige puuteplaadi abil"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index a971d1c25a16..7b9a0ea69d29 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Pantaila blokeatuko widgetak"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Aplikazio bat widget baten bidez irekitzeko, zeu zarela egiaztatu beharko duzu. Gainera, kontuan izan edonork ikusi ahalko dituela halako widgetak, tableta blokeatuta badago ere. Baliteke widget batzuk pantaila blokeaturako egokiak ez izatea, eta agian ez da segurua haiek bertan gehitzea."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ados"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Aldatu erabiltzailea"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"zabaldu menua"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Saioko aplikazio eta datu guztiak ezabatuko dira."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Elkarrizketen jakinarazpenen goialdean eta profileko argazki gisa agertzen da pantaila blokeatuan, burbuila batean, eta ez molestatzeko modua eteten du"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Lehentasuna"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioak ez ditu onartzen elkarrizketetarako eginbideak"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Jakinarazpen horiek ezin dira aldatu."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Deien jakinarazpenak ezin dira aldatu."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Jakinarazpen talde hau ezin da konfiguratu hemen"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Irauli telefonoa bereizmen handiago a lortzeko"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Gailu tolesgarria zabaltzen"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Gailu tolesgarria biratzen"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Aurreko pantaila piztuta dago"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"tolestuta"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"tolestu gabe"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Erabilerraztasuna"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Lasterbideak"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Pertsonalizatu lasterbideak"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Sakatu tekla lasterbidea esleitzeko"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Bilatu lasterbideak"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ez dago bilaketa-emaitzarik"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Tolesteko ikonoa"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Arrastatzeko kontrol-puntua"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Teklatuaren ezarpenak"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ezarri lasterbidea"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Utzi"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Sakatu tekla"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Tekla-konbinazio hori erabili da dagoeneko. Probatu beste tekla bat."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Nabigatu teklatua erabilita"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Ikasi lasterbideak"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Nabigatu ukipen-panela erabilita"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index bf7ccf0d8079..5401698fe3b6 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ابزاره‌های صفحه قفل"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"برای باز کردن برنامه بااستفاده از ابزاره، باید هویت خودتان را به‌تأیید برسانید. همچنین، به‌خاطر داشته باشید که همه می‌توانند آن‌ها را مشاهده کنند، حتی وقتی رایانه لوحی‌تان قفل است. برخی‌از ابزاره‌ها ممکن است برای صفحه قفل درنظر گرفته نشده باشند و ممکن است اضافه کردن آن‌ها در اینجا ناامن باشد."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"متوجه‌ام"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"تغییر کاربر"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"منوی پایین‌پر"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"همه برنامه‌ها و داده‌های این جلسه حذف خواهد شد."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"در بالای اعلان‌های مکالمه و به‌صورت عکس نمایه در صفحه قفل نشان داده می‌شود، به‌صورت حبابک ظاهر می‌شود، در حالت «مزاحم نشوید» وقفه ایجاد می‌کند"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"اولویت"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> از ویژگی‌های مکالمه پشتیبانی نمی‌کند"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"این اعلان‌ها قابل اصلاح نیستند."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"این اعلان‌ها قابل‌اصلاح نیستند."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"نمی‌توانید این گروه اعلان‌ها را در اینجا پیکربندی کنید"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"از کمتر از <xliff:g id="LENGTH">%1$d</xliff:g> نویسه استفاده کنید"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"شماره ساخت"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"شماره ساخت در بریده‌دان کپی شد."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"کپی کردن در بریده‌دان."</string>
<string name="basic_status" msgid="2315371112182658176">"باز کردن مکالمه"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"ابزارک‌های مکالمه"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"روی مکالمه‌ای تک‌ضرب بزنید تا به «صفحه اصلی» اضافه شود"</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"برای وضوح بیشتر، تلفن را بچرخانید"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"دستگاه تاشو درحال باز شدن"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"دستگاه تاشو درحال چرخش به اطراف"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"صفحه‌نمایش جلو روشن شد"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"تاشده"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"تانشده"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"دسترس‌پذیری"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"میان‌برهای صفحه‌کلید"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"سفارشی‌سازی کردن میان‌برهای صفحه‌کلید"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"برای اختصاص دادن میان‌بر، کلید را فشار دهید"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"جستجوی میان‌برها"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"نتیجه‌ای برای جستجو پیدا نشد"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"نماد جمع کردن"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"دستگیره کشاندن"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"تنظیمات صفحه‌کلید"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"تنظیم میان‌بر"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"لغو"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"کلید را فشار دهید"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"ترکیب کلید ازقبل درحال استفاده است. کلید دیگری را امتحان کنید."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"پیمایش کردن بااستفاده از صفحه‌کلید"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"آشنایی با میان‌برهای صفحه‌کلید"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"پیمایش کردن بااستفاده از صفحه لمسی"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 89ed95f0115f..58b86faaa32f 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lukitusnäytön widgetit"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Jos haluat avata sovelluksen käyttämällä widgetiä, sinun täytyy vahvistaa henkilöllisyytesi. Muista myös, että widgetit näkyvät kaikille, vaikka tabletti olisi lukittuna. Jotkin widgetit on ehkä tarkoitettu lukitusnäytölle, ja niiden lisääminen tänne ei välttämättä ole turvallista."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Selvä"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Vaihda käyttäjää"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"alasvetovalikko"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Kaikki sovellukset ja tämän istunnon tiedot poistetaan."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Näkyy keskusteluilmoitusten yläosassa ja profiilikuvana lukitusnäytöllä, näkyy kuplana, keskeyttää Älä häiritse ‑tilan"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Tärkeä"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei tue keskusteluominaisuuksia"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Näitä ilmoituksia ei voi muokata"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Puheluilmoituksia ei voi muokata."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Tätä ilmoitusryhmää ei voi määrittää tässä"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Resoluutio on parempi, kun käännät puhelimen"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Taitettava laite taitetaan"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Taitettava laite käännetään ympäri"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Etunäyttö päällä"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"taitettu"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"taittamaton"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Saavutettavuus"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Pikanäppäimet"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Pikanäppäimien muokkaaminen"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Määritä pikanäppäin painamalla näppäintä"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pikahaut"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ei hakutuloksia"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Tiivistyskuvake"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Vetokahva"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Näppäimistön asetukset"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Valitse pikanäppäin"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Peru"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Paina näppäintä"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Näppäinyhdistelmä on jo käytössä. Kokeile toista näppäintä."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Siirry käyttämällä näppäimistöä"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Opettele pikanäppäimiä"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Siirry käyttämällä kosketuslevyä"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 708d8b910306..ff3da656020a 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets de l\'écran de verrouillage"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Pour ouvrir une appli à l\'aide d\'un widget, vous devrez confirmer votre identité. En outre, gardez à l\'esprit que tout le monde peut voir les widgets, même lorsque votre tablette est verrouillée. Certains widgets n\'ont peut-être pas été conçus pour votre écran de verrouillage, et il pourrait être dangereux de les ajouter ici."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Changer d\'utilisateur"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu déroulant"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applis et les données de cette session seront supprimées."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"S\'affiche dans le haut des notifications de conversation et comme photo de profil à l\'écran de verrouillage, s\'affiche comme bulle, interrompt le mode Ne pas déranger"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritaire"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ne prend pas en charge les fonctionnalités de conversation"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Ces notifications ne peuvent pas être modifiées"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Les notifications d\'appel ne peuvent pas être modifiées."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Ce groupe de notifications ne peut pas être configuré ici"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Pour une meilleure résolution, retournez le téléphone"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Appareil pliable en cours de dépliage"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Appareil pliable en train d\'être retourné"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Écran avant activé"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"plié"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"déplié"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilité"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Raccourcis-clavier"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personnaliser les raccourcis-clavier"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Appuyez sur la touche pour attribuer un raccourci"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Rechercher des raccourcis"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Aucun résultat de recherche"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icône Réduire"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Poignée de déplacement"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Paramètres du clavier"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Définir un raccourci"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Annuler"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Appuyez sur la touche"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Combinaison de touches déjà utilisée. Essayez une autre touche."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naviguer à l\'aide de votre clavier"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Apprenez à utiliser les raccourcis-clavier"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naviguer à l\'aide de votre pavé tactile"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 41bd9106fb45..e51cb07869a7 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets pour l\'écran de verrouillage"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Pour ouvrir une appli à l\'aide d\'un widget, vous devez confirmer qu\'il s\'agit bien de vous. N\'oubliez pas non plus que tout le monde peut voir vos widgets, même lorsque votre tablette est verrouillée. Certains d\'entre eux n\'ont pas été conçus pour l\'écran de verrouillage et les ajouter à cet endroit peut s\'avérer dangereux."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Changer d\'utilisateur"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu déroulant"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"S\'affiche en haut des notifications de conversation et en tant que photo de profil sur l\'écran de verrouillage, apparaît sous forme de bulle, interrompt le mode Ne pas déranger"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritaire"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas compatible avec les fonctionnalités de conversation"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Impossible de modifier ces notifications."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Impossible de modifier les notifications d\'appel."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Vous ne pouvez pas configurer ce groupe de notifications ici"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Pour une résolution plus élevée, retournez le téléphone"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Appareil pliable qui est déplié"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Appareil pliable qui est retourné"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Écran avant activé"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"plié"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"déplié"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilité"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Raccourcis clavier"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personnaliser les raccourcis clavier"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Appuyez sur une touche pour attribuer un raccourci"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Rechercher des raccourcis"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Aucun résultat de recherche"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icône Réduire"</string>
@@ -1431,15 +1441,22 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Poignée de déplacement"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Paramètres du clavier"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Définir un raccourci"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Annuler"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Appuyez sur la touche"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Combinaison de touches déjà utilisée. Essayez une autre touche."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naviguer à l\'aide du clavier"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Apprenez à utiliser les raccourcis clavier"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naviguer à l\'aide de votre pavé tactile"</string>
<string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Découvrez les gestes au pavé tactile"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Naviguer à l\'aide de votre clavier et de votre pavé tactile"</string>
- <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Découvrir les gestes au pavé tactile, les raccourcis clavier et plus encore"</string>
+ <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Découvrir les gestes du pavé tactile, les raccourcis clavier et plus encore"</string>
<string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"Retour"</string>
<string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Retour à l\'accueil"</string>
<string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Afficher les applis récentes"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 398360689afe..6a1aced1ebf6 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets da pantalla de bloqueo"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir unha aplicación mediante un widget, tes que verificar a túa identidade. Ten en conta que pode velos calquera persoa, mesmo coa tableta bloqueada. Pode ser que algúns widgets non estean pensados para a túa pantalla de bloqueo, polo que talvez non sexa seguro engadilos aquí."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendido"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar usuario"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú despregable"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Eliminaranse todas as aplicacións e datos desta sesión."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Móstrase na parte superior das notificacións das conversas e como imaxe do perfil na pantalla de bloqueo, aparece como unha burbulla e interrompe o modo Non molestar"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioridade"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> non admite funcións de conversa"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Estas notificacións non se poden modificar."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"As notificacións de chamadas non se poden modificar."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Aquí non se pode configurar este grupo de notificacións"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Dálle a volta ao teléfono para gozar dunha maior resolución"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo pregable abríndose"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo pregable xirando"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Activouse a pantalla dianteira"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"dispositivo pregado"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"dispositivo despregado"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidade"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Atallos de teclado"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizar os atallos de teclado"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Preme a tecla para asignar o atallo"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Busca atallos"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Non hai resultados de busca"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icona de contraer"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Controlador de arrastre"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Configuración do teclado"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Definir atallo"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancelar"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Preme unha tecla"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Xa se está usando esta combinación de teclas. Proba con outra."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navega co teclado"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprende a usar os atallos de teclado"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navega co panel táctil"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 89012697cfac..566ccd0600f5 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"લૉક સ્ક્રીન વિજેટ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"વિજેટનો ઉપયોગ કરીને ઍપ ખોલવા માટે, તમારે એ ચકાસણી કરવાની જરૂર રહેશે કે આ તમે જ છો. તે ઉપરાંત, ધ્યાનમાં રાખો કે તમારું ટૅબ્લેટ લૉક કરેલું હોય તો પણ કોઈપણ વ્યક્તિ તેમને જોઈ શકે છે. અમુક વિજેટ કદાચ તમારી લૉક સ્ક્રીન માટે બનાવવામાં આવ્યા ન હોઈ શકે છે અને તેમને અહીં ઉમેરવાનું અસલામત હોઈ શકે છે."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"સમજાઈ ગયું"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"વપરાશકર્તા સ્વિચ કરો"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"પુલડાઉન મેનૂ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"આ સત્રમાંની તમામ ઍપ અને ડેટા કાઢી નાખવામાં આવશે."</string>
@@ -672,9 +676,9 @@
<string name="screen_pinning_negative" msgid="6882816864569211666">"ના, આભાર"</string>
<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_voice_call" msgid="7468348170702375660">"કૉલ"</string>
<string name="stream_system" msgid="7663148785370565134">"સિસ્ટમ"</string>
- <string name="stream_ring" msgid="7550670036738697526">"રિંગ વગાડો"</string>
+ <string name="stream_ring" msgid="7550670036738697526">"રિંગ"</string>
<string name="stream_music" msgid="2188224742361847580">"મીડિયા"</string>
<string name="stream_alarm" msgid="16058075093011694">"અલાર્મ"</string>
<string name="stream_notification" msgid="7930294049046243939">"નોટિફિકેશન"</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"વાતચીતના નોટિફિકેશન વિભાગની ટોચ પર અને લૉક કરેલી સ્ક્રીન પર પ્રોફાઇલ ફોટો તરીકે બતાવે છે, બબલ તરીકે દેખાય છે, ખલેલ પાડશો નહીં મોડમાં વિક્ષેપ ઊભો કરે છે"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"પ્રાધાન્યતા"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> વાતચીતની સુવિધાઓને સપોર્ટ આપતી નથી"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"આ નોટિફિકેશનમાં કોઈ ફેરફાર થઈ શકશે નહીં."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"કૉલના નોટિફિકેશનમાં કોઈ ફેરફાર કરી શકાતો નથી."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"નોટિફિકેશનના આ ગ્રૂપની ગોઠવણી અહીં કરી શકાશે નહીં"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"વધુ રિઝોલ્યુશન માટે, ફોનને ફ્લિપ કરો"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ફોલ્ડ કરી શકાય એવું ડિવાઇસ અનફોલ્ડ કરવામાં આવી રહ્યું છે"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ફોલ્ડ કરી શકાય એવું ડિવાઇસ ફ્લિપ કરવામાં આવી રહ્યું છે"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"ફ્રન્ટ સ્ક્રીનની સુવિધા ચાલુ કરેલી છે"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ફોલ્ડ કરેલું"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"અનફોલ્ડ કરેલું"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ઍક્સેસિબિલિટી"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"કીબોર્ડ શૉર્ટકટ"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"કીબોર્ડ શૉર્ટકટને કસ્ટમાઇઝ કરો"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"શૉર્ટકટ સોંપવા માટે દી દબાવો"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"શૉર્ટકટ શોધો"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"કોઈ શોધ પરિણામો નથી"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"\'નાનું કરો\'નું આઇકન"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ઑબ્જેક્ટ ખેંચવાનું હૅન્ડલ"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"કીબોર્ડના સેટિંગ"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"શૉર્ટકટ સેટ કરો"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"રદ કરો"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"કી દબાવો"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"કી સંયોજન પેહલેથી ઉપયોગમાં છે. અન્ય કી અજમાવી જુઓ."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"તમારા કીબોર્ડ વડે નૅવિગેટ કરો"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"કીબોર્ડ શૉર્ટકર્ટ જાણો"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"તમારા ટચપૅડ વડે નૅવિગેટ કરો"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 241e2e630013..255fdc5b571d 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"लॉक स्क्रीन विजेट"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"किसी विजेट से कोई ऐप्लिकेशन खोलने के लिए, आपको अपनी पहचान की पुष्टि करनी होगी. ध्यान रखें कि आपके टैबलेट के लॉक होने पर भी, कोई व्यक्ति विजेट देख सकता है. ऐसा हो सकता है कि कुछ विजेट, लॉक स्क्रीन पर दिखाने के लिए न बने हों. इन्हें लॉक स्क्रीन पर जोड़ना असुरक्षित हो सकता है."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ठीक है"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"उपयोगकर्ता बदलें"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"पुलडाउन मेन्यू"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"इस सेशन के सभी ऐप्लिकेशन और डेटा को हटा दिया जाएगा."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"यह कई तरीकों से दिखती है, जैसे कि बातचीत वाली सूचनाओं में सबसे ऊपर, बबल के तौर पर, और लॉक स्क्रीन पर प्रोफ़ाइल फ़ोटो के तौर पर. साथ ही, यह \'परेशान न करें\' मोड को बायपास कर सकती है"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"प्राथमिकता"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> पर बातचीत की सुविधाएं काम नहीं करतीं"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ये सूचनाएं नहीं बदली जा सकती हैं."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"कॉल से जुड़ी सूचनाओं को ब्लॉक नहीं किया जा सकता."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"सूचनाओं के इस समूह को यहां कॉन्फ़िगर नहीं किया जा सकता"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> वर्ण से कम इस्तेमाल करें"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नंबर"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नंबर को क्लिपबोर्ड पर कॉपी किया गया."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"क्लिपबोर्ड पर कॉपी करें."</string>
<string name="basic_status" msgid="2315371112182658176">"ऐसी बातचीत जिसमें इंटरैक्शन डेटा मौजूद नहीं है"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"बातचीत वाला विजेट"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"किसी बातचीत को होम स्क्रीन पर जोड़ने के लिए, उस बातचीत पर टैप करें"</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"बेहतर रिज़ॉल्यूशन वाली फ़ोटो खींचने के लिए, फ़ोन को फ़्लिप करें"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फ़ोल्ड किया जा सकने वाला डिवाइस अनफ़ोल्ड किया जा रहा है"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फ़ोल्ड किया जा सकने वाला डिवाइस पलटा जा रहा है"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"फ़्रंट स्क्रीन चालू है"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"डिवाइस फ़ोल्ड किया गया"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"डिवाइस अनफ़ोल्ड किया गया"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"सुलभता"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"कीबोर्ड शॉर्टकट"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"कीबोर्ड शॉर्टकट को पसंद के मुताबिक बनाएं"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"शॉर्टकट असाइन करने के लिए बटन दबाएं"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"शॉर्टकट खोजें"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"खोज का कोई नतीजा नहीं मिला"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"छोटा करने का आइकॉन"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"खींचकर छोड़ने वाला हैंडल"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"कीबोर्ड सेटिंग"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"शॉर्टकट सेट करें"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"रद्द करें"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"बटन दबाएं"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"बटन का यह कॉम्बिनेशन पहले से इस्तेमाल किया जा रहा है. कोई दूसरा कॉम्बिनेशन आज़माएं."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"कीबोर्ड का इस्तेमाल करके नेविगेट करें"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"कीबोर्ड शॉर्टकट के बारे में जानें"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"टचपैड का इस्तेमाल करके नेविगेट करें"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index a179649922d2..ef5cf7316bda 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgeti na zaključanom zaslonu"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Da biste otvorili aplikaciju pomoću widgeta, trebate potvrditi da ste to vi. Također napominjemo da ih svatko može vidjeti, čak i ako je vaš tablet zaključan. Neki widgeti možda nisu namijenjeni za zaključani zaslon, pa ih možda nije sigurno dodati ovdje."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Shvaćam"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Promjena korisnika"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući izbornik"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Izbrisat će se sve aplikacije i podaci u ovoj sesiji."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Prikazuje se pri vrhu obavijesti razgovora i kao profilna slika na zaključanom zaslonu, izgleda kao oblačić, prekida Ne uznemiravaj"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritetno"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava značajke razgovora"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Te se obavijesti ne mogu izmijeniti."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Obavijesti o pozivima ne mogu se izmijeniti."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Ta se grupa obavijesti ne može konfigurirati ovdje"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Za višu razlučivost okrenite telefon"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rasklopljen sklopivi uređaj"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Okretanje sklopivog uređaja sa svih strana"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Prednji zaslon je uključen"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"zatvoreno"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"otvoreno"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tipkovni prečaci"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagodba tipkovnih prečaca"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pritisnite tipku da biste dodijelili prečac"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prečaci za pretraživanje"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nema rezultata pretraživanja"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za sažimanje"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Marker za povlačenje"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Postavke tipkovnice"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Postavite prečac"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Odustani"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pritisnite tipku"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinacija tipki već se upotrebljava. Pokušajte s drugom tipkom."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Krećite se pomoću tipkovnice"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Saznajte više o tipkovnim prečacima"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Krećite se pomoću dodirne podloge"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 4b5b9162b01b..350dc4fcb8ca 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"A lezárási képernyő moduljai"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Ha modul használatával szeretne megnyitni egy alkalmazást, igazolnia kell a személyazonosságát. Ne felejtse továbbá, hogy bárki megtekintheti a modulokat, még akkor is, amikor zárolva van a táblagép. Előfordulhat, hogy bizonyos modulokat nem a lezárási képernyőn való használatra terveztek, ezért nem biztonságos a hozzáadásuk."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Értem"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Felhasználóváltás"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"lehúzható menü"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"A munkamenetben található összes alkalmazás és adat törlődni fog."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"A beszélgetésekre vonatkozó értesítések tetején, lebegő buborékként látható, megjeleníti a profilképet a lezárási képernyőn, és megszakítja a Ne zavarjanak funkciót"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritás"</string>
<string name="no_shortcut" msgid="8257177117568230126">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> nem támogatja a beszélgetési funkciókat"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Ezeket az értesítéseket nem lehet módosítani."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"A hívásértesítéseket nem lehet módosítani."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Az értesítések jelen csoportját itt nem lehet beállítani"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"A nagyobb felbontás érdekében fordítsa meg a telefont"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Összehajtható eszköz kihajtása"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Összehajtható eszköz körbeforgatása"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Előlapi képernyő bekapcsolva"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"összehajtva"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"kihajtva"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Kisegítő lehetőségek"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Billentyűparancsok"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"A billentyűparancsok személyre szabása"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Nyomja meg a billentyűt a parancsikon hozzárendeléséhez"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Billentyűparancsok keresése"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nincsenek keresési találatok"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Összecsukás ikon"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Fogópont"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Billentyűzetbeállítások"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Billentyűparancs beállítása"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Mégse"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Nyomja le a billentyűt"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"A billentyűkombináció már használatban van. Próbálkozzon másik kulccsal."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigáció a billentyűzet segítségével"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Billentyűparancsok megismerése"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigálás az érintőpaddal"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index a06209867663..9c833011ee21 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Կողպէկրանի վիջեթներ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Վիջեթի միջոցով հավելված բացելու համար դուք պետք է հաստատեք ձեր ինքնությունը։ Նաև նկատի ունեցեք, որ ցանկացած ոք կարող է դիտել վիջեթները, նույնիսկ երբ ձեր պլանշետը կողպված է։ Որոշ վիջեթներ կարող են նախատեսված չլինել ձեր կողպէկրանի համար, և այստեղ դրանց ավելացնելը կարող է վտանգավոր լինել։"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Եղավ"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Անջատել օգտվողին"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"իջնող ընտրացանկ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Այս աշխատաշրջանի բոլոր հավելվածներն ու տվյալները կջնջվեն:"</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Ցուցադրվում է զրույցների ծանուցումների վերևում, ինչպես նաև կողպէկրանին որպես պրոֆիլի նկար, հայտնվում է ամպիկի տեսքով, ընդհատում է «Չանհանգստացնել» ռեժիմը"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Կարևոր"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը զրույցի գործառույթներ չի աջակցում"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Այս ծանուցումները չեն կարող փոփոխվել:"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Զանգերի մասին ծանուցումները հնարավոր չէ փոփոխել։"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Ծանուցումների տվյալ խումբը հնարավոր չէ կարգավորել այստեղ"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Օգտագործեք մինչև <xliff:g id="LENGTH">%1$d</xliff:g> նիշ"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Կառուցման համարը"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Կառուցման համարը պատճենվեց սեղմատախտակին։"</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"պատճենել սեղմատախտակին։"</string>
<string name="basic_status" msgid="2315371112182658176">"Բաց զրույց"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Զրույցի վիջեթներ"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Հպեք զրույցին՝ այն հիմնական էկրանին ավելացնելու համար"</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Ավելի մեծ լուծաչափի համար շրջեք հեռախոսը"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ծալովի սարք՝ բացված վիճակում"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Ծալովի սարք՝ շրջված վիճակում"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Առջևի էկրանը միացված է"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ծալված"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"բացված"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Հատուկ գործառույթներ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Ստեղնային դյուրանցումներ"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Կարգավորեք ստեղնային դյուրանցումներ"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Սեղմեք որևէ ստեղն՝ դյուրանցում նշանակելու համար"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Դյուրանցումների որոնում"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Որոնման արդյունքներ չկան"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ծալել պատկերակը"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Տեղափոխման նշիչ"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Ստեղնաշարի կարգավորումներ"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ստեղծել դյուրանցում"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Չեղարկել"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Սեղմեք որևէ ստեղն"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Ստեղների համակցությունն արդեն օգտագործվում է։ Ընտրեք այլ ստեղն։"</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Կողմնորոշվեք ձեր ստեղնաշարի օգնությամբ"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Սովորեք օգտագործել ստեղնային դյուրանցումները"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Կողմնորոշվեք ձեր հպահարթակի օգնությամբ"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index cf9b093a1d43..58009872e1ae 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widget layar kunci"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Untuk membuka aplikasi menggunakan widget, Anda perlu memverifikasi diri Anda. Selain itu, harap ingat bahwa siapa saja dapat melihatnya, bahkan saat tablet Anda terkunci. Beberapa widget mungkin tidak dirancang untuk layar kunci Anda dan mungkin tidak aman untuk ditambahkan di sini."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Oke"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Beralih pengguna"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu pulldown"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua aplikasi dan data dalam sesi ini akan dihapus."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Muncul teratas di notifikasi percakapan dan sebagai foto profil di layar kunci, ditampilkan sebagai balon, menimpa mode Jangan Ganggu"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritas"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak mendukung fitur percakapan"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Notifikasi ini tidak dapat diubah."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Notifikasi panggilan tidak dapat diubah."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Grup notifikasi ini tidak dapat dikonfigurasi di sini"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Untuk resolusi lebih tinggi, balik ponsel"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Perangkat foldable sedang dibentangkan"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Perangkat foldable sedang dibalik"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Layar depan diaktifkan"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ditutup"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"dibuka"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Aksesibilitas"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Pintasan keyboard"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Menyesuaikan pintasan keyboard"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Tekan tombol untuk menetapkan pintasan"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Telusuri pintasan"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Tidak ada hasil penelusuran"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikon ciutkan"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Handel geser"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Setelan Keyboard"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Setel pintasan"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Batal"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Tekan tombol"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinasi tombol sudah digunakan. Coba tombol lain."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Menggunakan keyboard untuk navigasi"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Pelajari pintasan keyboard"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Menavigasi menggunakan touchpad"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index fe32aba3d75b..3a3659013f84 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Græjur fyrir lásskjá"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Þú þarft að staðfesta að þetta sért þú til að geta opnað forrit með græju. Hafðu einnig í huga að hver sem er getur skoðað þær, jafnvel þótt spjaldtölvan sé læst. Sumar græjur eru hugsanlega ekki ætlaðar fyrir lásskjá og því gæti verið óöruggt að bæta þeim við hér."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ég skil"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Skipta um notanda"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"Fellivalmynd"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Öllum forritum og gögnum í þessari lotu verður eytt."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Birtist efst í samtalstilkynningum og sem prófílmynd á lásskjánum. Birtist sem blaðra sem truflar „Ónáðið ekki“"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Forgangur"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> styður ekki samtalseiginleika"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Ekki er hægt að breyta þessum tilkynningum."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Ekki er hægt að breyta tilkynningum um símtöl."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Ekki er hægt að stilla þessar tilkynningar hér"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Snúðu símanum til að fá betri upplausn"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Samanbrjótanlegt tæki opnað"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Samanbrjótanlegu tæki snúið við"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Kveikt á fremri skjá"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"samanbrotið"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"opið"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Aðgengi"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Flýtilyklar"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sérsníddu flýtilykla"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Ýttu á lykil til að stilla flýtileið"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Leita að flýtileiðum"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Engar leitarniðurstöður"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Minnka tákn"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Dragkló"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Stillingar lyklaborðs"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Stilltu flýtileið"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Hætta við"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Ýttu á lykil"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Lyklasamsetning er þegar í notkun. Prófaðu annan lykil."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Flettu með því að nota lyklaborðið"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Kynntu þér flýtilykla"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Flettu með því að nota snertiflötinn"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index a66ea91eb396..12a01ebd003d 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -167,7 +167,7 @@
<string name="issuerecord_start_error" msgid="3402782952722871190">"Impossibile avviare la registrazione del problema"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Visualizzazione a schermo intero"</string>
<string name="immersive_cling_description" msgid="2717426731830851921">"Per uscire, scorri verso il basso dalla parte superiore dello schermo"</string>
- <string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string>
+ <string name="immersive_cling_positive" msgid="3076681691468978568">"Ok"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Indietro"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Home"</string>
<string name="accessibility_menu" msgid="2701163794470513040">"Menu"</string>
@@ -528,6 +528,8 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widget della schermata di blocco"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Per aprire un\'app utilizzando un widget, dovrai verificare la tua identità. Inoltre tieni presente che chiunque può vederlo, anche quando il tablet è bloccato. Alcuni widget potrebbero non essere stati progettati per la schermata di blocco e potrebbe non essere sicuro aggiungerli qui."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ok"</string>
+ <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Widget"</string>
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="511359420883794513">"Per aggiungere Widget alla schermata di blocco come scorciatoia, assicurati che sia abilitata nelle impostazioni."</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambio utente"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu a discesa"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tutte le app e i dati di questa sessione verranno eliminati."</string>
@@ -668,7 +670,7 @@
<string name="screen_pinning_toast" msgid="8177286912533744328">"Per sbloccare questa app, tocca e tieni premuti i pulsanti Indietro e Panoramica"</string>
<string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Per sbloccare questa app, tocca e tieni premuti i pulsanti Indietro e Home"</string>
<string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Per sbloccare questa app, scorri verso l\'alto e tieni premuto"</string>
- <string name="screen_pinning_positive" msgid="3285785989665266984">"OK"</string>
+ <string name="screen_pinning_positive" msgid="3285785989665266984">"Ok"</string>
<string name="screen_pinning_negative" msgid="6882816864569211666">"No, grazie"</string>
<string name="screen_pinning_start" msgid="7483998671383371313">"App bloccata"</string>
<string name="screen_pinning_exit" msgid="4553787518387346893">"App sbloccata"</string>
@@ -751,7 +753,7 @@
<string name="tuner_warning_title" msgid="7721976098452135267">"Il divertimento riservato a pochi eletti"</string>
<string name="tuner_warning" msgid="1861736288458481650">"L\'Ottimizzatore UI di sistema mette a disposizione altri metodi per modificare e personalizzare l\'interfaccia utente di Android. Queste funzioni sperimentali potrebbero cambiare, interrompersi o scomparire nelle versioni successive. Procedi con cautela."</string>
<string name="tuner_persistent_warning" msgid="230466285569307806">"Queste funzioni sperimentali potrebbero cambiare, interrompersi o scomparire nelle versioni successive. Procedi con cautela."</string>
- <string name="got_it" msgid="477119182261892069">"OK"</string>
+ <string name="got_it" msgid="477119182261892069">"Ok"</string>
<string name="tuner_toast" msgid="3812684836514766951">"Complimenti! L\'Ottimizzatore UI di sistema è stato aggiunto alle impostazioni."</string>
<string name="remove_from_settings" msgid="633775561782209994">"Rimuovi dalle impostazioni"</string>
<string name="remove_from_settings_prompt" msgid="551565437265615426">"Vuoi rimuovere l\'Ottimizzatore UI di sistema dalle impostazioni e smettere di utilizzare tutte le sue funzioni?"</string>
@@ -780,6 +782,7 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Appare in cima alle notifiche delle conversazioni, come immagine del profilo nella schermata di blocco e sotto forma di bolla, inoltre interrompe la modalità Non disturbare"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Priorità"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> non supporta le funzionalità delle conversazioni"</string>
+ <string name="notification_guts_bundle_feedback" msgid="5393570876655201459">"Fornisci feedback sul bundle"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Impossibile modificare queste notifiche."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Impossibile modificare gli avvisi di chiamata."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Qui non è possibile configurare questo gruppo di notifiche"</string>
@@ -1357,8 +1360,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Gira il telefono per una maggiore risoluzione"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo pieghevole che viene aperto"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo pieghevole che viene capovolto"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Schermo frontale attivato"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"Piegato"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"Non piegato"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1420,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilità"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Scorciatoie da tastiera"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizza scorciatoie da tastiera"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Premi un tasto per assegnare una scorciatoia"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Scorciatoie per la ricerca"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nessun risultato di ricerca"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icona Comprimi"</string>
@@ -1431,15 +1438,20 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Punto di trascinamento"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Impostazioni tastiera"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Imposta scorciatoia"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Annulla"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Premi un tasto"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Combinazione di tasti già in uso. Prova con un altro tasto."</string>
+ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Combinazione di tasti già in uso. Prova con un altro tasto."</string>
+ <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Impossibile impostare la scorciatoia."</string>
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naviga usando la tastiera"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Informazioni sulle scorciatoie da tastiera"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naviga usando il touchpad"</string>
<string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Impara i gesti con il touchpad"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Naviga usando la tastiera e il touchpad"</string>
- <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Scopri gesti con il touchpad, scorciatoie da tastiera e altro ancora"</string>
+ <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Impara i gesti con il touchpad, le scorciatoie da tastiera e altro ancora"</string>
<string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"Indietro"</string>
<string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Vai alla schermata Home"</string>
<string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Visualizza app recenti"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 7b4245ee1c1e..0a14717645e6 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -310,7 +310,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"נשמר"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ניתוק"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"הפעלה"</string>
- <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"הפעלה אוטומטית מחר"</string>
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"הפעלה אוטומטית ביום הבא"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"‏תכונות כמו \'שיתוף מהיר\' ו\'איפה המכשיר שלי\' משתמשות ב-Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"‏חיבור ה-Bluetooth יופעל מחר בבוקר"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"שיתוף האודיו"</string>
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ווידג\'טים במסך הנעילה"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"כדי לפתוח אפליקציה באמצעות ווידג\'ט, עליך לאמת את זהותך. בנוסף, כדאי לזכור שכל אחד יכול לראות את הווידג\'טים גם כשהטאבלט שלך נעול. יכול להיות שחלק מהווידג\'טים לא נועדו למסך הנעילה ושלא בטוח להוסיף אותם לכאן."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"הבנתי"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"החלפת משתמש"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"תפריט במשיכה למטה"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"כל האפליקציות והנתונים בסשן הזה יימחקו."</string>
@@ -699,7 +703,7 @@
<string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"אודיו מרחבי"</string>
<string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"השבתה"</string>
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"מצב סטטי"</string>
- <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"מעקב אחר תנועות הראש"</string>
+ <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"מעקב ראש"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"יש להקיש כדי לשנות את מצב תוכנת הצלצול"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"מצב תוכנת הצלצול"</string>
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"השתקה"</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"מוצגת בחלק העליון של קטע התראות השיחה וכתמונת פרופיל במסך הנעילה, מופיעה בבועה צפה ומפריעה במצב \'נא לא להפריע\'"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"בעדיפות גבוהה"</string>
<string name="no_shortcut" msgid="8257177117568230126">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> לא תומכת בתכונות השיחה"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"לא ניתן לשנות את ההתראות האלה."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"לא ניתן לשנות את התראות השיחה."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"לא ניתן להגדיר כאן את קבוצת ההתראות הזו"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"כדי לצלם תמונה ברזולוציה גבוהה יותר, כדאי להפוך את הטלפון"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"מכשיר מתקפל עובר למצב לא מקופל"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"מכשיר מתקפל עובר למצב מהופך"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"המסך הקדמי מופעל"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"מצב מקופל"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"מצב לא מקופל"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"‏%1$s‏ / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"נגישות"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"מקשי קיצור"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"התאמה אישית של מקשי הקיצור"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"יש ללחוץ על מקש כדי להקצות מקש קיצור"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"קיצורי דרך לחיפוש"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"אין תוצאות חיפוש"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"סמל הכיווץ"</string>
@@ -1431,15 +1441,22 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"נקודת האחיזה לגרירה"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"הגדרות המקלדת"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"הגדרה של מקש קיצור"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ביטול"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"יש ללחוץ על מקש"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"שילוב המקשים הזה כבר בשימוש. אפשר לנסות מקש אחר."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ניווט באמצעות המקלדת"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"מידע על מקשי קיצור"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ניווט באמצעות לוח המגע"</string>
<string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"מידע על התנועות בלוח המגע"</string>
- <string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"ניווט באמצעות המקלדת ולוח המגע"</string>
- <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"מידע על התנועות בלוח המגע, מקשי קיצור ועוד"</string>
+ <string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"ניווט עם המקלדת ולוח המגע"</string>
+ <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"כאן אפשר לקרוא איך מפעילים תנועות בלוח המגע, מקשי קיצור ועוד"</string>
<string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"חזרה"</string>
<string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"חזרה לדף הבית"</string>
<string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"הצגת האפליקציות האחרונות"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index c4fd62b355f6..1c106cfc4b0b 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ロック画面ウィジェット"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ウィジェットを使用してアプリを起動するには、本人確認が必要です。タブレットがロックされた状態でも他のユーザーにウィジェットが表示されますので、注意してください。一部のウィジェットについてはロック画面での使用を想定していないため、ロック画面への追加は危険な場合があります。"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ユーザーを切り替える"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"プルダウン メニュー"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"このセッションでのアプリとデータはすべて削除されます。"</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"会話通知の一番上に表示されると同時に、ロック画面にプロフィール写真として表示されるほか、バブルとして表示され、サイレント モードが中断されます"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"優先"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>は会話機能に対応していません"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"これらの通知は変更できません。"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"着信通知は変更できません。"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"このグループの通知はここでは設定できません"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"使用できる文字数は <xliff:g id="LENGTH">%1$d</xliff:g> 文字未満です"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ビルド番号"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ビルド番号をクリップボードにコピーしました。"</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"クリップボードにコピー。"</string>
<string name="basic_status" msgid="2315371112182658176">"空の会話"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"会話ウィジェット"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"会話をタップするとホーム画面に追加されます"</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"高解像度で撮るにはスマートフォンを裏返してください"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"折りたたみ式デバイスが広げられている"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"折りたたみ式デバイスがひっくり返されている"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"フロント画面が ON になりました"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"折りたたんだ状態"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"広げた状態"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ユーザー補助"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"キーボード ショートカット"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"キーボード ショートカットをカスタマイズする"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ショートカットを割り当てるキーを押してください"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"検索ショートカット"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"検索結果がありません"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"閉じるアイコン"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ドラッグ ハンドル"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"キーボードの設定"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ショートカットの設定"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"キャンセル"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"キーを押してください"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"このキーの組み合わせはすでに使用されています。別のキーを試してください。"</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"キーボードを使用して移動する"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"キーボード ショートカットの詳細"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"タッチパッドを使用して移動する"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 7cb3c8a99303..962a62c25cf6 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"დაბლოკილი ეკრანის ვიჯეტები"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"უნდა დაადასტუროთ თქვენი ვინაობა, რათა გახსნათ აპი ვიჯეტის გამოყენებით. გაითვალისწინეთ, რომ ნებისმიერს შეუძლია მათი ნახვა, მაშინაც კი, როცა ტაბლეტი დაბლოკილია. ზოგი ვიჯეტი შეიძლება არ იყოს გათვლილი თქვენი დაბლოკილი ეკრანისთვის და მათი აქ დამატება შეიძლება სახიფათო იყოს."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"გასაგებია"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"მომხმარებლის გადართვა"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ჩამოშლადი მენიუ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ამ სესიის ყველა აპი და მონაცემი წაიშლება."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"გამოჩნდება საუბრის შეტყობინებების თავში და პროფილის სურათის სახით ჩაკეტილ ეკრანზე, ჩნდება ბუშტის სახით, წყვეტს ფუნქციას „არ შემაწუხოთ“"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"პრიორიტეტი"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ს არ აქვს მიმოწერის ფუნქციების მხარდაჭერა"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ამ შეტყობინებების შეცვლა შეუძლებელია."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"ზარის შეტყობინებების შეცვლა შეუძლებელია."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"შეტყობინებების ამ ჯგუფის კონფიგურირება აქ შეუძლებელია"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"მაღალი გარჩევადობისთვის ამოაბრუნეთ ტელეფონი"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"დასაკეცი მოწყობილობა იხსნება"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"დასაკეცი მოწყობილობა ტრიალებს"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"წინა ეკრანი ჩართულია"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"დაკეცილი"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"გაშლილი"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"მისაწვდომობა"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"კლავიატურის მალსახმობები"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"კლავიატურის მალსახმობების მორგება"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"მალსახმობის მინიჭებისთვის დააჭირეთ კლავიშს"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ძიების მალსახმობები"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ძიების შედეგები არ არის"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ხატულის ჩაკეცვა"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"სახელური ჩავლებისთვის"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"კლავიატურის პარამეტრები"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"მალსახმობის დაყენება"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"გაუქმება"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"დააჭირეთ კლავიშს"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"კლავიშების კომბინაცია უკვე გამოიყენება. ცადეთ სხვა კლავიში."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ნავიგაცია კლავიატურის გამოყენებით"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"კლავიატურის მალსახმობების სწავლა"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ნავიგაცია სენსორული პანელის გამოყენებით"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 4122eeef9d59..ec1f09693eec 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Құлып экранының виджеттері"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Қолданбаны виджет көмегімен ашу үшін жеке басыңызды растауыңыз керек. Сондай-ақ басқалар оларды планшетіңіз құлыптаулы кезде де көре алатынын ескеріңіз. Кейбір виджеттер құлып экранына арналмаған болады, сондықтан оларды мұнда қосу қауіпсіз болмауы мүмкін."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Түсінікті"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Пайдаланушыны ауыстыру"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ашылмалы мәзір"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Осы сеанстағы барлық қолданба мен дерек жойылады."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Әңгіме туралы хабарландырулардың жоғарғы жағында тұрады және құлыптаулы экранда профиль суреті болып көрсетіледі, қалқыма хабар түрінде шығады, Мазаламау режимін тоқтатады."</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Маңызды"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> әңгіме функцияларын қолдамайды."</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Бұл хабарландыруларды өзгерту мүмкін емес."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Қоңырау туралы хабарландыруларды өзгерту мүмкін емес."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Мұндай хабарландырулар бұл жерде конфигурацияланбайды."</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Жоғары ажыратымдылық үшін телефонды айналдырыңыз."</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Бүктемелі құрылғы ашылып жатыр."</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Бүктемелі құрылғы аударылып жатыр."</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Алдыңғы экран қосылды."</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"жабық"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ашық"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Арнайы мүмкіндіктер"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Перне тіркесімдері"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Пернелер тіркесімін бейімдеу"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Жылдам пәрменді тағайындау үшін пернені басыңыз."</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Іздеу жылдам пәрмендері"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Іздеу нәтижелері жоқ."</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Жию белгішесі"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Сүйрейтін тетік"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Пернетақта параметрлері"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Жылдам пәрменді орнату"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Бас тарту"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Пернені басыңыз"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Бұл пернелер тіркесімі қазір қолданыста. Басқа пернені таңдаңыз."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Пернетақтамен жұмыс істеңіз"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Перне тіркесімдерін үйреніңіз."</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Сенсорлық тақтамен жұмыс істеңіз"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index f9ec58f2fba8..2533f98132a5 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ធាតុ​ក្រាហ្វិកលើអេក្រង់ចាក់សោ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ដើម្បីបើកកម្មវិធីដោយប្រើធាតុ​ក្រាហ្វិក អ្នកនឹងត្រូវផ្ទៀងផ្ទាត់ថាជាអ្នក។ ទន្ទឹមនឹងនេះ សូមចងចាំថា នរណាក៏អាចមើលធាតុក្រាហ្វិកបាន សូម្បីពេលថេប្លេតរបស់អ្នកជាប់សោក៏ដោយ។ ធាតុ​ក្រាហ្វិកមួយចំនួនប្រហែលមិនត្រូវបានរចនាឡើងសម្រាប់អេក្រង់ចាក់សោរបស់អ្នកទេ និងមិនមានសុវត្ថិភាពឡើយ បើបញ្ចូលទៅទីនេះ។"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"យល់ហើយ"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ប្ដូរ​អ្នក​ប្រើ"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ម៉ឺនុយ​ទាញចុះ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"កម្មវិធី និងទិន្នន័យ​ទាំងអស់​ក្នុង​វគ្គ​នេះ​នឹង​ត្រូវ​លុប។"</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"បង្ហាញនៅខាងលើ​ការជូនដំណឹងអំពីការសន្ទនា និងជារូបភាព​កម្រង​ព័ត៌មាននៅលើអេក្រង់ចាក់សោ បង្ហាញជាពពុះ បង្អាក់មុខងារកុំ​រំខាន"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"អាទិភាព"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> មិនអាចប្រើ​មុខងារ​សន្ទនា​បានទេ"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"មិនអាច​កែប្រែ​ការជូនដំណឹង​ទាំងនេះ​បានទេ។"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"មិនអាច​កែប្រែ​ការជូនដំណឹងអំពីការហៅទូរសព្ទបានទេ។"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"មិនអាច​កំណត់​រចនាសម្ព័ន្ធ​ក្រុមការជូនដំណឹងនេះ​នៅទីនេះ​បានទេ"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"សម្រាប់កម្រិតគុណភាពកាន់តែខ្ពស់ សូមត្រឡប់ទូរសព្ទ"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ឧបករណ៍អាច​បត់បានកំពុងត្រូវបានលា"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ឧបករណ៍អាច​បត់បានកំពុងត្រូវបានលា"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"បានបើកអេក្រង់ខាងមុខ"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"បត់"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"លា"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ភាពងាយស្រួល"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"ផ្លូវកាត់​ក្ដារ​ចុច"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ប្ដូរ​ផ្លូវកាត់​ក្ដារ​ចុចតាម​បំណង"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ចុចគ្រាប់ចុច ដើម្បីកំណត់ផ្លូវ​កាត់"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ស្វែងរកផ្លូវ​កាត់"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"គ្មាន​លទ្ធផល​ស្វែងរក​ទេ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"រូបតំណាង \"បង្រួម\""</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ដង​អូស"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"ការកំណត់​ក្ដារចុច"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"កំណត់ផ្លូវ​កាត់"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"បោះបង់"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ចុចគ្រាប់ចុច"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"កំពុងប្រើបន្សំគ្រាប់ចុចស្រាប់ហើយ។ សាកល្បងប្រើគ្រាប់ចុចផ្សេង។"</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"រុករកដោយប្រើក្ដារចុចរបស់អ្នក"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ស្វែងយល់អំពីផ្លូវកាត់​ក្ដារ​ចុច"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"រុករកដោយប្រើផ្ទាំងប៉ះរបស់អ្នក"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index f3155704c55f..201c9950741b 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ಲಾಕ್ ಸ್ಕ್ರೀನ್ ವಿಜೆಟ್‌ಗಳು"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ವಿಜೆಟ್ ಅನ್ನು ಬಳಸಿಕೊಂಡು ಆ್ಯಪ್ ತೆರೆಯಲು, ಇದು ನೀವೇ ಎಂದು ನೀವು ದೃಢೀಕರಿಸಬೇಕಾಗುತ್ತದೆ. ಅಲ್ಲದೆ, ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಲಾಕ್ ಆಗಿದ್ದರೂ ಸಹ ಯಾರಾದರೂ ಅವುಗಳನ್ನು ವೀಕ್ಷಿಸಬಹುದು ಎಂಬುದನ್ನು ನೆನಪಿನಲ್ಲಿಡಿ. ಕೆಲವು ವಿಜೆಟ್‌ಗಳು ನಿಮ್ಮ ಲಾಕ್ ಸ್ಕ್ರೀನ್‌ಗಾಗಿ ಉದ್ದೇಶಿಸದೇ ಇರಬಹುದು ಮತ್ತು ಇಲ್ಲಿ ಸೇರಿಸುವುದು ಸುರಕ್ಷಿತವಲ್ಲದಿರಬಹುದು."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ಅರ್ಥವಾಯಿತು"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ಬಳಕೆದಾರರನ್ನು ಬದಲಿಸಿ"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ಪುಲ್‌ಡೌನ್ ಮೆನು"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ಈ ಸೆಶನ್‌ನಲ್ಲಿನ ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"ಸಂಭಾಷಣೆ ಅಧಿಸೂಚನೆಗಳ ಮೇಲ್ಭಾಗದಲ್ಲಿ ಹಾಗೂ ಲಾಕ್ ಸ್ಕ್ರೀನ್‌ನ ಮೇಲೆ ಪ್ರೊಫೈಲ್ ಚಿತ್ರವಾಗಿ ತೋರಿಸುತ್ತದೆ, ಬಬಲ್‌ನಂತೆ ಗೋಚರಿಸುತ್ತದೆ, ಅಡಚಣೆ ಮಾಡಬೇಡ ಮೋಡ್‌ಗೆ ಅಡ್ಡಿಯುಂಟುಮಾಡುತ್ತದೆ"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"ಆದ್ಯತೆ"</string>
<string name="no_shortcut" msgid="8257177117568230126">"ಸಂವಾದ ಫೀಚರ್‌ಗಳನ್ನು <xliff:g id="APP_NAME">%1$s</xliff:g> ಬೆಂಬಲಿಸುವುದಿಲ್ಲ"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"ಕರೆ ಅಧಿಸೂಚನೆಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"ಈ ಗುಂಪಿನ ಅಧಿಸೂಚನೆಗಳನ್ನು ಇಲ್ಲಿ ಕಾನ್ಫಿಗರ್‌ ಮಾಡಲಾಗಿರುವುದಿಲ್ಲ"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ಅಧಿಕ ರೆಸಲ್ಯೂಷನ್‌ಗಾಗಿ, ಫೋನ್ ಅನ್ನು ಫ್ಲಿಪ್ ಮಾಡಿ"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ಫೋಲ್ಡ್ ಮಾಡಬಹುದಾದ ಸಾಧನವನ್ನು ಅನ್‌ಫೋಲ್ಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ಫೋಲ್ಡ್ ಮಾಡಬಹುದಾದ ಸಾಧನವನ್ನು ಸುತ್ತಲೂ ತಿರುಗಿಸಲಾಗುತ್ತಿದೆ"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"ಫ್ರಂಟ್ ಸ್ಕ್ರೀನ್ ಆನ್ ಆಗಿದೆ"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ಫೋಲ್ಡ್ ಮಾಡಿರುವುದು"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ಅನ್‌ಫೋಲ್ಡ್ ಮಾಡಿರುವುದು"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಿ"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ಶಾರ್ಟ್‌ಕಟ್ ಅನ್ನು ನಿಯೋಜಿಸಲು ಕೀಯನ್ನು ಒತ್ತಿರಿ"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ಹುಡುಕಾಟದ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ಯಾವುದೇ ಹುಡುಕಾಟ ಫಲಿತಾಂಶಗಳಿಲ್ಲ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ಕುಗ್ಗಿಸುವ ಐಕಾನ್"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ಡ್ರ್ಯಾಗ್‌ ಹ್ಯಾಂಡಲ್‌"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"ಕೀಬೋರ್ಡ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ಶಾರ್ಟ್‌ಕಟ್ ಸೆಟ್ ಮಾಡಿ"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ರದ್ದುಮಾಡಿ"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ಕೀ ಅನ್ನು ಒತ್ತಿರಿ"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"ಕೀ ಸಂಯೋಜನೆಯು ಈಗಾಗಲೇ ಬಳಕೆಯಲ್ಲಿದೆ. ಮತ್ತೊಂದು ಕೀ ಬಳಸಿ ನೋಡಿ."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ನಿಮ್ಮ ಕೀಬೋರ್ಡ್ ಬಳಸಿ ನ್ಯಾವಿಗೇಟ್ ಮಾಡಿ"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಕಲಿಯಿರಿ"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ನಿಮ್ಮ ಟಚ್‌ಪ್ಯಾಡ್ ಬಳಸಿ ನ್ಯಾವಿಗೇಟ್ ಮಾಡಿ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 931066b3d749..3303932a5bc2 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"잠금 화면 위젯"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"위젯을 사용하여 앱을 열려면 본인 인증을 해야 합니다. 또한 태블릿이 잠겨 있더라도 누구나 볼 수 있다는 점을 유의해야 합니다. 일부 위젯은 잠금 화면에 적합하지 않고 여기에 추가하기에 안전하지 않을 수 있습니다."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"확인"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"사용자 전환"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"풀다운 메뉴"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"이 세션에 있는 모든 앱과 데이터가 삭제됩니다."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"대화 알림 상단에 표시, 잠금 화면에 프로필 사진으로 표시, 대화창으로 표시, 방해 금지 모드를 무시함"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"우선순위"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> 앱은 대화 기능을 지원하지 않습니다."</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"이 알림은 수정할 수 없습니다."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"전화 알림은 수정할 수 없습니다."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"이 알림 그룹은 여기에서 설정할 수 없습니다."</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"해상도를 높이려면 후면 카메라를 사용하세요."</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"폴더블 기기를 펼치는 모습"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"폴더블 기기를 뒤집는 모습"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"전면 화면 켜짐"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"접은 상태"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"펼친 상태"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"접근성"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"단축키"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"단축키 맞춤설정"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"키를 눌러 단축키 지정"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"검색 바로가기"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"검색 결과 없음"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"접기 아이콘"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"드래그 핸들"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"키보드 설정"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"단축키 설정"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"취소"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"키를 누르세요."</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"이미 사용 중인 키 조합입니다. 다른 키를 사용해 보세요."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"키보드를 사용하여 이동"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"단축키에 관해 알아보세요."</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"터치패드를 사용하여 이동"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index fc16164b6874..fb1b71330c27 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Кулпуланган экрандагы виджеттер"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Колдонмону виджет аркылуу ачуу үчүн өзүңүздү ырасташыңыз керек. Алар кулпуланган планшетиңизде да көрүнүп турат. Кээ бир виджеттерди кулпуланган экранда колдоно албайсыз, андыктан аларды ал жерге кошпой эле койгонуңуз оң."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Түшүндүм"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Колдонуучуну которуу"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ылдый түшүүчү меню"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Бул сеанстагы бардык колдонмолор жана аларга байланыштуу нерселер өчүрүлөт."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Cүйлөшүүлөр тууралуу билдирмелердин жогору жагында жана кулпуланган экранда профилдин сүрөтү, ошондой эле калкып чыкма билдирме түрүндө көрүнүп, \"Тынчымды алба\" режимин токтотот"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Маанилүүлүгү"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосунда оозеки сүйлөшкөнгө болбойт"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Бул билдирмелерди өзгөртүүгө болбойт."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Чалуу билдирмелерин өзгөртүүгө болбойт."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Бул билдирмелердин тобун бул жерде конфигурациялоого болбойт"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Жогорку дааналык үчүн телефондун арткы камерасын колдонуңуз"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ачылып турган бүктөлмө түзмөк"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Оодарылып жаткан бүктөлмө түзмөк"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Маңдайкы экран күйгүзүлдү"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"бүктөлгөн"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ачылган"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Атайын мүмкүнчүлүктөр"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Ыкчам баскычтар"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Ыкчам баскычтарды ыңгайлаштыруу"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Ыкчам баскычты дайындоо үчүн баскычты басыңыз"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Ыкчам баскычтарды издөө"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Эч нерсе табылган жок"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Жыйыштыруу сүрөтчөсү"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Cүйрөө маркери"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Баскычтоп параметрлери"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ыкчам баскычты тууралоо"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancel"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Баскычты басыңыз"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Ачкыч айкалышы колдонулууда. Башка ачкычты байкап көрүңүз."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Керектүү нерселерге баскычтоп аркылуу өтүү"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Ыкчам баскычтар тууралуу билип алыңыз"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Керектүү жерге сенсордук такта аркылуу өтөсүз"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 3a8c682bce0e..d2e4763fbcd3 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ວິດເຈັດໃນໜ້າຈໍລັອກ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ເພື່ອເປີດແອັບໂດຍໃຊ້ວິດເຈັດ, ທ່ານຈະຕ້ອງຢັ້ງຢືນວ່າແມ່ນທ່ານ. ນອກຈາກນັ້ນ, ກະລຸນາຮັບຊາບວ່າທຸກຄົນສາມາດເບິ່ງຂໍ້ມູນດັ່ງກ່າວໄດ້, ເຖິງແມ່ນວ່າແທັບເລັດຂອງທ່ານຈະລັອກຢູ່ກໍຕາມ. ວິດເຈັດບາງຢ່າງອາດບໍ່ໄດ້ມີໄວ້ສຳລັບໜ້າຈໍລັອກຂອງທ່ານ ແລະ ອາດບໍ່ປອດໄພທີ່ຈະເພີ່ມໃສ່ບ່ອນນີ້."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ເຂົ້າໃຈແລ້ວ"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ສະຫຼັບຜູ້ໃຊ້"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ເມນູແບບດຶງລົງ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ແອັບຯ​ແລະ​ຂໍ້​ມູນ​ທັງ​ໝົດ​ໃນ​ເຊດ​ຊັນ​ນີ້​ຈະ​ຖືກ​ລຶບ​ອອກ."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"ສະແດງຢູ່ເທິງສຸດຂອງການແຈ້ງເຕືອນການສົນທະນາ ແລະ ເປັນຮູບໂປຣໄຟລ໌ຢູ່ໜ້າຈໍລັອກ, ປາກົດເປັນຟອງ, ສະແດງໃນໂໝດຫ້າມລົບກວນໄດ້"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"ສຳຄັນ"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ່ຮອງຮັບຄຸນສົມບັດການສົນທະນາ"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ບໍ່ສາມາດແກ້ໄຂການແຈ້ງເຕືອນເຫຼົ່ານີ້ໄດ້."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"ບໍ່ສາມາດແກ້ໄຂການແຈ້ງເຕືອນການໂທໄດ້."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"ບໍ່ສາມາດຕັ້ງຄ່າກຸ່ມການແຈ້ງເຕືອນນີ້ຢູ່ບ່ອນນີ້ໄດ້"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"ໃຊ້ໜ້ອຍກວ່າ <xliff:g id="LENGTH">%1$d</xliff:g> ຕົວອັກສອນ"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ໝາຍເລກສ້າງ"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ສຳເນົາໝາຍເລກສ້າງໄປໃສ່ຄລິບບອດແລ້ວ."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"ສຳເນົາໄປໃສ່ຄລິບບອດ."</string>
<string name="basic_status" msgid="2315371112182658176">"ເປີດການສົນທະນາ"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"ວິດເຈັດການສົນທະນາ"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"ແຕະໃສ່ການສົນທະນາໃດໜຶ່ງເພື່ອເພີ່ມມັນໃສ່ໂຮມສະກຣີນຂອງທ່ານ"</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ເພື່ອຄວາມລະອຽດທີ່ສູງຂຶ້ນ, ໃຫ້ປີ້ນໂທລະສັບ"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ອຸປະກອນທີ່ພັບໄດ້ກຳລັງກາງອອກ"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ອຸປະກອນທີ່ພັກໄດ້ກຳລັງປີ້ນໄປມາ"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"ເປີດໜ້າຈໍດ້ານໜ້າແລ້ວ"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ພັບແລ້ວ"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ກາງອອກແລ້ວ"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ການຊ່ວຍເຂົ້າເຖິງ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"ຄີລັດ"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ປັບແຕ່ງຄີລັດ"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ກົດປຸ່ມເພື່ອກໍານົດທາງລັດ"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ທາງລັດການຊອກຫາ"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ບໍ່ມີຜົນການຊອກຫາ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ໄອຄອນຫຍໍ້ລົງ"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ບ່ອນຈັບລາກ"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"ການຕັ້ງຄ່າແປ້ນພິມ"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ຕັ້ງທາງລັດ"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ຍົກເລີກ"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ກົດປຸ່ມ"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"ນໍາໃຊ້ປຸ່ມປະສົມຢູ່ແລ້ວ. ໃຫ້ລອງປຸ່ມອື່ນ."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ນຳທາງໂດຍໃຊ້ແປ້ນພິມຂອງທ່ານ"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ສຶກສາຄີລັດ"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ນຳທາງໂດຍໃຊ້ແຜ່ນສຳຜັດຂອງທ່ານ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index ae85ed2060c6..64f37aec5d77 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -528,6 +528,8 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Užrakinimo ekrano valdikliai"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Kad galėtumėte atidaryti programą naudodami valdiklį, turėsite patvirtinti savo tapatybę. Be to, atminkite, kad bet kas gali peržiūrėti valdiklius net tada, kai planšetinis kompiuteris užrakintas. Kai kurie valdikliai gali būti neskirti jūsų užrakinimo ekranui ir gali būti nesaugu juos čia pridėti."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Supratau"</string>
+ <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Valdikliai"</string>
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="511359420883794513">"Jei norite pridėti valdiklių šaukinį užrakinimo ekrane, įsitikinkite, kad tai įgalinta nustatymuose."</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Perjungti naudotoją"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"išplečiamasis meniu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bus ištrintos visos šios sesijos programos ir duomenys."</string>
@@ -674,7 +676,7 @@
<string name="screen_pinning_exit" msgid="4553787518387346893">"Programa atsegta"</string>
<string name="stream_voice_call" msgid="7468348170702375660">"Skambutis"</string>
<string name="stream_system" msgid="7663148785370565134">"Sistema"</string>
- <string name="stream_ring" msgid="7550670036738697526">"Skambutis"</string>
+ <string name="stream_ring" msgid="7550670036738697526">"Skambėjimas"</string>
<string name="stream_music" msgid="2188224742361847580">"Medija"</string>
<string name="stream_alarm" msgid="16058075093011694">"Signalas"</string>
<string name="stream_notification" msgid="7930294049046243939">"Pranešimas"</string>
@@ -780,6 +782,7 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Rodoma pokalbių pranešimų viršuje ir kaip profilio nuotrauka užrakinimo ekrane, burbule, pertraukia netrukdymo režimą"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritetiniai"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ nepalaiko pokalbių funkcijų"</string>
+ <string name="notification_guts_bundle_feedback" msgid="5393570876655201459">"Pateikti atsiliepimą apie rinkinį"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Šių pranešimų keisti negalima."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Skambučių pranešimų keisti negalima."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Šios grupės pranešimai čia nekonfigūruojami"</string>
@@ -1357,8 +1360,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Kad raiška būtų geresnė, apverskite telefoną"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Lankstomasis įrenginys išlankstomas"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Lankstomasis įrenginys apverčiamas"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Priekinis ekranas įjungtas"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"sulenkta"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"nesulenkta"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1420,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pritaikomumas"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Spartieji klavišai"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sparčiųjų klavišų tinkinimas"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Paspauskite klavišą, kad priskirtumėte spartųjį klavišą"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Ieškoti sparčiųjų klavišų"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nėra jokių paieškos rezultatų"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Sutraukimo piktograma"</string>
@@ -1431,9 +1438,14 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Vilkimo rankenėlė"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Klaviatūros nustatymai"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Nustatyti spartųjį klavišą"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Atšaukti"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Paspauskite klavišą"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Klavišų derinys jau naudojamas. Bandykite naudoti kitą klavišą."</string>
+ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Klavišų derinys jau naudojamas. Bandykite naudoti kitą klavišą."</string>
+ <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Sparčiojo klavišo nustatyti negalima."</string>
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naršykite naudodamiesi klaviatūra"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Sužinokite apie sparčiuosius klavišus"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naršykite naudodamiesi jutikline dalimi"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index b20ab36a3896..dc1c4ba28d0b 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Bloķēšanas ekrāna logrīki"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Lai atvērtu lietotni, izmantojot logrīku, jums būs jāapstiprina sava identitāte. Turklāt ņemiet vērā, ka ikviens var skatīt logrīkus, pat ja planšetdators ir bloķēts. Iespējams, daži logrīki nav paredzēti izmantošanai bloķēšanas ekrānā, un var nebūt droši tos šeit pievienot."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Labi"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Mainīt lietotāju"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"novelkamā izvēlne"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tiks dzēstas visas šīs sesijas lietotnes un dati."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Parādās sarunu paziņojumu augšdaļā un kā profila attēls bloķēšanas ekrānā, arī kā burbulis, pārtrauc režīmu “Netraucēt”."</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritārs"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Lietotnē <xliff:g id="APP_NAME">%1$s</xliff:g> netiek atbalstītas sarunu funkcijas."</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Šos paziņojumus nevar modificēt."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Paziņojumus par zvaniem nevar modificēt."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Šeit nevar konfigurēt šo paziņojumu grupu."</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Lai izmantotu augstāku izšķirtspēju, apvērsiet tālruni"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Salokāma ierīce tiek atlocīta"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Salokāma ierīce tiek apgriezta"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Priekšējais ekrāns ir ieslēgts"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"aizvērta"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"atvērta"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pieejamība"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Īsinājumtaustiņi"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Īsinājumtaustiņu pielāgošana"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Lai piešķirtu īsinājumtaustiņu, nospiediet taustiņu"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Meklēt saīsnes"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nav meklēšanas rezultātu"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Sakļaušanas ikona"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Vilkšanas turis"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Tastatūras iestatījumi"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Iestatīt īsinājumtaustiņu"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Atcelt"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Nospiediet taustiņu"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Taustiņu kombinācija jau tiek izmantota. Izmēģiniet citu taustiņu."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Pārvietošanās, izmantojot tastatūru"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Uzziniet par īsinājumtaustiņiem."</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Pārvietošanās, izmantojot skārienpaliktni"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index f8bfcf9296ca..94f295fbcddb 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Виџети на заклучен екран"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"За да отворите апликација со помош на виџет, ќе треба да потврдите дека сте вие. Покрај тоа, имајте предвид дека секој може да ги гледа виџетите, дури и кога вашиот таблет е заклучен. Некои виџети можеби не се наменети за вашиот заклучен екран, па можеби не е безбедно да се додадат овде."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Сфатив"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Промени го корисникот"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"паѓачко мени"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Сите апликации и податоци во сесијава ќе се избришат."</string>
@@ -698,7 +702,7 @@
<string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Контрола на шум"</string>
<string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Просторен звук"</string>
<string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Исклучено"</string>
- <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Фиксно"</string>
+ <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Фиксирано"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Следење на главата"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Допрете за да го промените режимот на ѕвончето"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"режим на ѕвонче"</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Се прикажува најгоре во известувањата за разговор и како профилна слика на заклучен екран, се појавува како балонче, го прекинува „Не вознемирувај“"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Приоритетно"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не поддржува функции за разговор"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Овие известувања не може да се изменат"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Известувањата за повици не може да се изменат."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Оваа група известувања не може да се конфигурира тука"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Отворете го телефонот за да добиете повисока резолуција"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Преклопувачки уред се отклопува"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Преклопувачки уред се врти"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Предниот екран е вклучен"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"затворен"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"отворен"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Пристапност"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Кратенки од тастатура"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Приспособете ги кратенките од тастатурата"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Притиснете го копчето за да доделите кратенка"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Пребарувајте кратенки"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Нема резултати од пребарување"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Икона за собирање"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Рачка за влечење"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Поставки за тастатурата"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Поставете кратенка"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Откажи"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Притиснете го копчето"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Комбинацијата на копчиња веќе се користи. Обидете се со друго копче."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Движете се со користење на тастатурата"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Научете ги кратенките од тастатурата"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Движете се со користење на допирната подлога"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 54364c804581..85bc7017b378 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ലോക്ക് സ്‌ക്രീൻ വിജറ്റുകൾ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"വിജറ്റ് ഉപയോഗിച്ച് ഒരു ആപ്പ് തുറക്കാൻ, ഇത് നിങ്ങൾ തന്നെയാണെന്ന് പരിശോധിച്ചുറപ്പിക്കേണ്ടതുണ്ട്. നിങ്ങളുടെ ടാബ്‌ലെറ്റ് ലോക്കായിരിക്കുമ്പോഴും എല്ലാവർക്കും അത് കാണാനാകുമെന്നതും ഓർക്കുക. ചില വിജറ്റുകൾ നിങ്ങളുടെ ലോക്ക് സ്‌ക്രീനിന് ഉള്ളതായിരിക്കില്ല, അവ ഇവിടെ ചേർക്കുന്നത് സുരക്ഷിതവുമായിരിക്കില്ല."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"മനസ്സിലായി"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ഉപയോക്താവ് മാറുക"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"പുൾഡൗൺ മെനു"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ഈ സെഷനിലെ എല്ലാ ആപ്പുകളും ഡാറ്റയും ഇല്ലാതാക്കും."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"സംഭാഷണ അറിയിപ്പുകളുടെ മുകളിലും സ്ക്രീൻ ലോക്കായിരിക്കുമ്പോൾ ഒരു പ്രൊഫൈൽ ചിത്രമായും ബബിൾ രൂപത്തിൽ ദൃശ്യമാകുന്നു, ശല്യപ്പെടുത്തരുത് മോഡ് തടസ്സപ്പെടുത്തുന്നു"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"മുൻഗണന"</string>
<string name="no_shortcut" msgid="8257177117568230126">"സംഭാഷണ ഫീച്ചറുകളെ <xliff:g id="APP_NAME">%1$s</xliff:g> പിന്തുണയ്‌ക്കുന്നില്ല"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ഈ അറിയിപ്പുകൾ പരിഷ്ക്കരിക്കാനാവില്ല."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"കോൾ അറിയിപ്പുകൾ പരിഷ്‌കരിക്കാനാകുന്നില്ല."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"അറിയിപ്പുകളുടെ ഈ ഗ്രൂപ്പ് ഇവിടെ കോണ്‍ഫിഗര്‍ ചെയ്യാൻ കഴിയില്ല"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g>-ൽ കുറവ് പ്രതീകങ്ങൾ ഉപയോഗിക്കുക"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ബിൽഡ് നമ്പർ"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ക്ലിപ്പ്ബോർഡിലേക്ക് ബിൽഡ് നമ്പർ പകർത്തി."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"ക്ലിപ്പ്ബോർഡിലേക്ക് പകർത്തുക."</string>
<string name="basic_status" msgid="2315371112182658176">"സംഭാഷണം തുറക്കുക"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"സംഭാഷണ വിജറ്റുകൾ"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"നിങ്ങളുടെ ഹോം സ്‌ക്രീനിൽ ചേർക്കാൻ സംഭാഷണത്തിൽ ടാപ്പ് ചെയ്യുക"</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ഉയർന്ന റെസല്യൂഷന്, ഫോൺ ഫ്ലിപ്പ് ചെയ്യുക"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ഫോൾഡ് ചെയ്യാവുന്ന ഉപകരണം അൺഫോൾഡ് ആകുന്നു"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ഫോൾഡ് ചെയ്യാവുന്ന ഉപകരണം, കറങ്ങുന്ന വിധത്തിൽ ഫ്ലിപ്പ് ആകുന്നു"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"ഫ്രണ്ട് സ്ക്രീൻ ഓണാക്കി"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ഫോൾഡ് ചെയ്തത്"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"അൺഫോൾഡ് ചെയ്തത്"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ഉപയോഗസഹായി"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"കീബോഡ് കുറുക്കുവഴികൾ"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"കീബോർഡ് കുറുക്കുവഴികൾ ഇഷ്ടാനുസൃതമാക്കുക"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"കുറുക്കുവഴി അസൈൻ ചെയ്യാൻ കീ അമർത്തുക"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"തിരയൽ കുറുക്കുവഴികൾ"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"തിരയൽ ഫലങ്ങളൊന്നുമില്ല"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ചുരുക്കൽ ഐക്കൺ"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"വലിച്ചിടുന്നതിനുള്ള ഹാൻഡിൽ"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"കീബോർഡ് ക്രമീകരണം"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"കുറുക്കുവഴി സജ്ജീകരിക്കുക"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"റദ്ദാക്കുക"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"കീ അമർത്തുക"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"കീ കോമ്പിനേഷൻ ഇതിനകം ഉപയോഗത്തിലുണ്ട്. മറ്റൊരു കീ പരീക്ഷിക്കുക."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"നിങ്ങളുടെ കീബോർഡ് ഉപയോഗിച്ച് നാവിഗേറ്റ് ചെയ്യുക"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"കീബോർഡ് കുറുക്കുവഴികൾ മനസ്സിലാക്കുക"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"നിങ്ങളുടെ ടച്ച്‌പാഡ് ഉപയോഗിച്ച് നാവിഗേറ്റ് ചെയ്യുക"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 0e2dc23e88c1..78b2ddab02ac 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Түгжээтэй дэлгэцийн виджет"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Виджет ашиглан аппыг нээхийн тулд та өөрийгөө мөн болохыг баталгаажуулах шаардлагатай болно. Мөн таны таблет түгжээтэй байсан ч тэдгээрийг дурын хүн үзэж болохыг санаарай. Зарим виджет таны түгжээтэй дэлгэцэд зориулагдаагүй байж магадгүй ба энд нэмэхэд аюултай байж болзошгүй."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ойлголоо"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Хэрэглэгчийг сэлгэх"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"эвхмэл цэс"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Энэ харилцан үйлдлийн бүх апп болон дата устах болно."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Харилцан ярианы мэдэгдлийн дээд талд болон түгжигдсэн дэлгэц дээр профайл зураг байдлаар харуулах бөгөөд бөмбөлөг хэлбэрээр харагдана. Бүү саад бол горимыг тасалдуулна"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Чухал"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> нь харилцан ярианы онцлогуудыг дэмждэггүй"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Эдгээр мэдэгдлийг өөрчлөх боломжгүй."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Дуудлагын мэдэгдлийг өөрчлөх боломжгүй."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Энэ бүлэг мэдэгдлийг энд тохируулах боломжгүй байна"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Илүү өндөр нягтрал авах бол утсыг хөнтөрнө үү"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Эвхэгддэг төхөөрөмжийг дэлгэж байна"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Эвхэгддэг төхөөрөмжийг хөнтөрч байна"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Нүүрэн талын дэлгэцийг асаасан"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"эвхсэн"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"дэлгэсэн"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Хандалт"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Товчлуурын шууд холбоос"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Товчлуурын шууд холбоосыг өөрчлөх"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Товчлол оноохын тулд товч дарна уу"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Товчлолууд хайх"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ямар ч хайлтын илэрц байхгүй"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Хураах дүрс тэмдэг"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Чирэх бариул"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Гарын тохиргоо"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Товчлол тохируулах"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Цуцлах"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Товч дарна уу"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Товчийн хослолыг аль хэдийн ашиглаж байна. Өөр товч туршиж үзнэ үү."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Гараа ашиглан шилжих"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Товчлуурын шууд холбоосыг мэдэж аваарай"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Мэдрэгч самбараа ашиглан шилжээрэй"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index cd9062252425..280a757d1661 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"लॉक स्‍क्रीन विजेट"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"विजेट वापरून अ‍ॅप उघडण्यासाठी, तुम्हाला हे तुम्हीच असल्याची पडताळणी करावी लागेल. तसेच, लक्षात ठेवा, तुमचा टॅबलेट लॉक असतानादेखील कोणीही ती पाहू शकते. काही विजेट कदाचित तुमच्या लॉक स्‍क्रीनसाठी नाहीत आणि ती इथे जोडणे असुरक्षित असू शकते."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"समजले"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"वापरकर्ता स्विच करा"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"पुलडाउन मेनू"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"या सत्रातील सर्व अ‍ॅप्स आणि डेटा हटवला जाईल."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"संभाषण सूचनांच्या वरती आणि लॉक स्क्रीनवरील प्रोफाइल फोटो म्हणून दिसते, बबल म्हणून दिसते, व्यत्यय आणू नका यामध्ये अडथळा आणते"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"प्राधान्य"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> हे संभाषण वैशिष्ट्यांना सपोर्ट करत नाही"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"या सूचनांमध्ये सुधारणा केली जाऊ शकत नाही."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"कॉलशी संबंधित सूचनांमध्ये फेरबदल केला जाऊ शकत नाही."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"या सूचनांचा संच येथे कॉन्फिगर केला जाऊ शकत नाही"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"उच्च रेझोल्यूशनसाठी, फोन फ्लिप करा"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फोल्ड करता येण्यासारखे डिव्हाइस अनफोल्ड केले जात आहे"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फोल्ड करता येण्यासारखे डिव्हाइस आजूबाजूला फ्लिप केले जात आहे"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"पुढील स्क्रीन सुरू केलेली आहे"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"फोल्ड केलेले"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"फोल्ड न केलेले"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"अ‍ॅक्सेसिबिलिटी"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"कीबोर्ड शॉर्टकट"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"कीबोर्ड शॉर्टकट कस्टमाइझ करा"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"शॉर्टकट असाइन करण्यासाठी की प्रेस करा"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"शोधण्यासाठी शॉर्टकट"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"कोणतेही शोध परिणाम नाहीत"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"कोलॅप्स करा आयकन"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ड्रॅग हॅंडल"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"कीबोर्ड सेटिंग्ज"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"शॉर्टकट सेट करा"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"रद्द करा"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"की प्रेस करा"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"की कॉम्बिनेशन आधीपासून वापरले जात आहे. दुसरी की वापरून पहा."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"तुमचा कीबोर्ड वापरून नेव्हिगेट करा"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"कीबोर्ड शॉर्टकट जाणून घ्या"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"तुमचा टचपॅड वापरून नेव्हिगेट करा"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index c108fc476da0..d20262ace5d2 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widget skrin kunci"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Untuk membuka apl menggunakan widget, anda perlu mengesahkan identiti anda. Selain itu, perlu diingat bahawa sesiapa sahaja boleh melihat widget tersebut, walaupun semasa tablet anda dikunci. Sesetengah widget mungkin tidak sesuai untuk skrin kunci anda dan mungkin tidak selamat untuk ditambahkan di sini."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Tukar pengguna"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu tarik turun"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua apl dan data dalam sesi ini akan dipadam."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Ditunjukkan di bahagian atas pemberitahuan perbualan dan sebagai gambar profil pada skrin kunci, muncul sebagai gelembung, mengganggu Jangan Ganggu"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Keutamaan"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak menyokong ciri perbualan"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Pemberitahuan ini tidak boleh diubah suai."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Pemberitahuan panggilan tidak boleh diubah suai."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Kumpulan pemberitahuan ini tidak boleh dikonfigurasikan di sini"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Untuk peleraian lebih tinggi, balikkan telefon"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Peranti boleh lipat dibuka"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Peranti boleh lipat diterbalikkan"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Skrin hadapan dihidupkan"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"terlipat"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"tidak terlipat"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Kebolehaksesan"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Pintasan papan kekunci"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sesuaikan pintasan papan kekunci"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Tekan kekunci untuk menetapkan pintasan"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pintasan carian"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Tiada hasil carian"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Kuncupkan ikon"</string>
@@ -1431,14 +1441,21 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Pemegang seret"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Tetapan Papan Kekunci"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Tetapkan pintasan"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Batal"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Tekan kekunci"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Gabungan kekunci sudah digunakan. Cuba kekunci lain."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigasi menggunakan papan kekunci"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Ketahui pintasan papan kekunci"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigasi menggunakan pad sentuh anda"</string>
<string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Ketahui gerak isyarat pad sentuh"</string>
- <string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Navigasi menggunakan papan kekunci dan pad sentuh anda"</string>
+ <string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Navigasi menggunakan papan kekunci dan pad sentuh"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Ketahui gerak isyarat pad sentuh, pintasan papan kekunci dan pelbagai lagi"</string>
<string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"Kembali"</string>
<string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Akses laman utama"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index ce52f4e4e024..b77f0374e065 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"လော့ခ်မျက်နှာပြင် ဝိဂျက်များ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ဝိဂျက်သုံး၍ အက်ပ်ဖွင့်ရန်အတွက် သင်ဖြစ်ကြောင်း အတည်ပြုရန်လိုသည်။ ထို့ပြင် သင့်တက်ဘလက် လော့ခ်ချထားချိန်၌ပင် မည်သူမဆို ၎င်းတို့ကို ကြည့်နိုင်ကြောင်း သတိပြုပါ။ ဝိဂျက်အချို့ကို လော့ခ်မျက်နှာပြင်အတွက် ရည်ရွယ်ထားခြင်း မရှိသဖြင့် ဤနေရာတွင် ထည့်ပါက မလုံခြုံနိုင်ပါ။"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"နားလည်ပြီ"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"အသုံးပြုသူကို ပြောင်းလဲရန်"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ဆွဲချမီနူး"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ဒီချိတ်ဆက်မှု ထဲက အက်ပ်များ အားလုံး နှင့် ဒေတာကို ဖျက်ပစ်မည်။"</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"စကားဝိုင်း အကြောင်းကြားချက်များ၏ ထိပ်ပိုင်းနှင့် ပရိုဖိုင်ပုံအဖြစ် လော့ခ်မျက်နှာပြင်တွင် ပြသည်။ ပူဖောင်းကွက်အဖြစ် မြင်ရပြီး ‘မနှောင့်ယှက်ရ’ ကို ကြားဖြတ်သည်"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"ဦးစားပေး"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> က စကားဝိုင်းဝန်ဆောင်မှုများကို မပံ့ပိုးပါ"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ဤအကြောင်းကြားချက်များကို ပြုပြင်၍ မရပါ။"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"ခေါ်ဆိုမှုအကြောင်းကြားချက်များကို ပြင်၍မရပါ။"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"ဤအကြောင်းကြားချက်အုပ်စုကို ဤနေရာတွင် စီစဉ်သတ်မှတ်၍ မရပါ"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ပုံရိပ် ပိုမိုပြတ်သားစေရန် ဖုန်းကို တစ်ဖက်သို့ လှန်လိုက်ပါ"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ခေါက်နိုင်သောစက်ကို ဖြန့်လိုက်သည်"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ခေါက်နိုင်သောစက်ကို တစ်ဘက်သို့ လှန်လိုက်သည်"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"ရှေ့စခရင် ဖွင့်ထားသည်"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ခေါက်ထားသည်"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ဖြန့်ထားသည်"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"အများသုံးနိုင်မှု"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"လက်ကွက်ဖြတ်လမ်းများ"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"လက်ကွက်ဖြတ်လမ်းများကို စိတ်ကြိုက်လုပ်ခြင်း"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ဖြတ်လမ်းသတ်မှတ်ရန် ကီးကို နှိပ်ပါ"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ဖြတ်လမ်းများ ရှာရန်"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ရှာဖွေမှုရလဒ် မရှိပါ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"လျှော့ပြရန် သင်္ကေတ"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ဖိဆွဲအထိန်း"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"ကီးဘုတ်ဆက်တင်များ"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ဖြတ်လမ်း သတ်မှတ်ရန်"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"မလုပ်တော့"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ကီးကို နှိပ်ပါ"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"ကီးပေါင်းစပ်ခြင်းကို သုံးနေပြီးဖြစ်သည်။ အခြားကီးကို စမ်းကြည့်ပါ။"</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"သင့်ကီးဘုတ်ကိုသုံး၍ လမ်းညွှန်ခြင်း"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"လက်ကွက်ဖြတ်လမ်းများကို လေ့လာပါ"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"သင့်တာ့ချ်ပက်ကိုသုံး၍ လမ်းညွှန်ခြင်း"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index db352a5fc4b0..fa4886b93dcc 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Låseskjermmoduler"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"For å åpne en app ved hjelp av en modul må du bekrefte at det er deg. Husk også at hvem som helst kan se dem, selv om nettbrettet er låst. Noen moduler er kanskje ikke laget for å være på låseskjermen og kan være utrygge å legge til der."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Greit"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Bytt bruker"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rullegardinmeny"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apper og data i denne økten blir slettet."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Vises øverst på samtalevarsler og som et profilbilde på låseskjermen, vises som en boble, avbryter «Ikke forstyrr»"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> støtter ikke samtalefunksjoner"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Disse varslene kan ikke endres."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Anropsvarsler kan ikke endres."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Denne varselgruppen kan ikke konfigureres her"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Brett ut telefonen for å få høyere oppløsning"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"En foldbar enhet blir brettet ut"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"En foldbar enhet blir snudd"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Frontskjermen er slått på"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"lagt sammen"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"åpen"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Tilgjengelighet"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Hurtigtaster"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tilpass hurtigtastene"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Trykk på tasten for å tilordne hurtigtasten"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Snarveier til søk"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ingen søkeresultater"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Skjul-ikon"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Håndtak"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Tastaturinnstillinger"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Angi hurtigtast"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Avbryt"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Trykk på tasten"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Tastekombinasjonen brukes allerede. Prøv en annen tast."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naviger med tastaturet"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Lær deg hurtigtaster"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naviger med styreflaten"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 2c1d7271ac19..babc0d19b781 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"लक स्क्रिन विजेटहरू"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"विजेट प्रयोग गरी एप खोल्न तपाईंले आफ्नो पहिचान पुष्टि गर्नु पर्ने हुन्छ। साथै, तपाईंको ट्याब्लेट लक भएका बेला पनि सबै जनाले तिनलाई देख्न सक्छन् भन्ने कुरा ख्याल गर्नुहोस्। केही विजेटहरू लक स्क्रिनमा प्रयोग गर्ने उद्देश्यले नबनाइएका हुन सक्छन् र तिनलाई यहाँ हाल्नु सुरक्षित नहुन सक्छ।"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"बुझेँ"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"प्रयोगकर्ता फेर्नुहोस्"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"पुलडाउन मेनु"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"यो सत्रमा भएका सबै एपहरू र डेटा मेटाइने छ।"</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"यो वार्तालापका सूचनाहरूको सिरानमा, बबलका रूपमा र लक स्क्रिनमा प्रोफाइल फोटोका रूपमा देखिन्छ। साथै, यसले गर्दा \'बाधा नपुऱ्याउनुहोस्\' नामक सुविधामा अवरोध आउँछ"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"प्राथमिकता"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> मा वार्तालापसम्बन्धी सुविधा प्रयोग गर्न मिल्दैन"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"यी सूचनाहरू परिमार्जन गर्न मिल्दैन।"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"कलसम्बन्धी सूचनाहरू परिमार्जन गर्न मिल्दैन।"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"यहाँबाट सूचनाहरूको यो समूह कन्फिगर गर्न सकिँदैन"</string>
@@ -1355,10 +1361,9 @@
<string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"स्क्रिनहरू बदल्ने हो?"</string>
<string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"उच्च रिजोल्युसनको सेल्फी खिच्न पछाडिको क्यामेरा प्रयोग गर्नुहोस्"</string>
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"उच्च रिजोल्युसनको सेल्फी खिच्न फोन फ्लिप गर्नुहोस्"</string>
- <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फोल्ड गर्न मिल्ने डिभाइस अनफोल्ड गरेको देखाइएको एनिमेसन"</string>
- <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फोल्ड गर्न मिल्ने डिभाइस यताउता पल्टाएर देखाइएको एनिमेसन"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फोल्डेबल डिभाइस अनफोल्ड गरेको देखाइएको एनिमेसन"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फोल्डेबल डिभाइस यताउता पल्टाएर देखाइएको एनिमेसन"</string>
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"अगाडिको स्क्रिन अन गरिएको छ"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"फोल्ड गरिएको"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"अनफोल्ड गरिएको"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"सर्वसुलभता"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"किबोर्डका सर्टकटहरू"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"किबोर्डका सर्टकटहरू कस्टमाइज गर्नुहोस्"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"सर्टकट असाइन गर्न की थिच्नुहोस्"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"खोजका सर्टकटहरू"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"कुनै पनि खोज परिणाम भेटिएन"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"\"कोल्याप्स गर्नुहोस्\" आइकन"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ड्र्याग ह्यान्डल"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"किबोर्डसम्बन्धी सेटिङ"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"सर्टकट सेट गर्नुहोस्"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"रद्द गर्नुहोस्"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"की थिच्नुहोस्"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"यो की कम्बिनेसन प्रयोग गरिसकिएको छ। अर्कै की प्रयोग गरी हेर्नुहोस्।"</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"किबोर्ड प्रयोग गरी नेभिगेट गर्नुहोस्"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"किबोर्डका सर्टकटहरू प्रयोग गर्न सिक्नुहोस्"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"टचप्याड प्रयोग गरी नेभिगेट गर्नुहोस्"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 0d195a3b40d7..61c4bd545cb1 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets op het vergrendelscherm"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Als je een app wilt openen met een widget, moet je verifiëren dat jij het bent. Houd er ook rekening mee dat iedereen ze kan bekijken, ook als je tablet vergrendeld is. Bepaalde widgets zijn misschien niet bedoeld voor je vergrendelscherm en kunnen hier niet veilig worden toegevoegd."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Gebruiker wijzigen"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pull-downmenu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps en gegevens in deze sessie worden verwijderd."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Wordt getoond bovenaan gespreksmeldingen en als profielfoto op het vergrendelscherm, verschijnt als bubbel, onderbreekt Niet storen"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioriteit"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ondersteunt geen gespreksfuncties"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Deze meldingen kunnen niet worden aangepast."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Gespreksmeldingen kunnen niet worden aangepast."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Deze groep meldingen kan hier niet worden ingesteld"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Gebruik minder dan <xliff:g id="LENGTH">%1$d</xliff:g> tekens"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildnummer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Buildnummer naar klembord gekopieerd."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"kopiëren naar klembord."</string>
<string name="basic_status" msgid="2315371112182658176">"Gesprek openen"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Gesprekswidgets"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Tik op een gesprek om het toe te voegen aan je startscherm"</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Draai de telefoon om voor een hogere resolutie"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Opvouwbaar apparaat wordt uitgevouwen"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Opvouwbaar apparaat wordt gedraaid"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Scherm aan voorzijde aangezet"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"dichtgevouwen"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"opengevouwen"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Toegankelijkheid"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Sneltoetsen"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sneltoetsen aanpassen"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Druk op de toets om de sneltoets toe te wijzen"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Sneltoetsen zoeken"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Geen zoekresultaten"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icoon voor samenvouwen"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Handgreep voor slepen"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Toetsenbordinstellingen"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Sneltoets instellen"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Annuleren"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Druk op een toets"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Toetsencombinatie is al in gebruik. Probeer een andere toets."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigeren met je toetsenbord"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Leer sneltoetsen die je kunt gebruiken"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigeren met je touchpad"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 181315ba045c..e932e74cad0e 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ଲକ ସ୍କ୍ରିନ ୱିଜେଟ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ଏକ ୱିଜେଟ ବ୍ୟବହାର କରି ଗୋଟିଏ ଆପ ଖୋଲିବା ପାଇଁ ଏହା ଆପଣ ଅଟନ୍ତି ବୋଲି ଆପଣଙ୍କୁ ଯାଞ୍ଚ କରିବାକୁ ହେବ। ଆହୁରି ମଧ୍ୟ, ଆପଣଙ୍କ ଟାବଲେଟ ଲକ ଥିଲେ ମଧ୍ୟ ଯେ କୌଣସି ବ୍ୟକ୍ତି ଏହାକୁ ଭ୍ୟୁ କରିପାରିବେ ବୋଲି ମନେ ରଖନ୍ତୁ। କିଛି ୱିଜେଟ ଆପଣଙ୍କ ଲକ ସ୍କ୍ରିନ ପାଇଁ ଉଦ୍ଦିଷ୍ଟ ହୋଇନଥାଇପାରେ ଏବଂ ଏଠାରେ ଯୋଗ କରିବା ଅସୁରକ୍ଷିତ ହୋଇପାରେ।"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ବୁଝିଗଲି"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ୟୁଜର୍‍ ବଦଳାନ୍ତୁ"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ପୁଲଡାଉନ ମେନୁ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ଏହି ସେସନର ସମସ୍ତ ଆପ୍‌ ଓ ଡାଟା ଡିଲିଟ୍‌ ହୋଇଯିବ।"</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"ବାର୍ତ୍ତାଳାପ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ଶୀର୍ଷରେ ଏବଂ ଲକ୍ ସ୍କ୍ରିନରେ ଏକ ପ୍ରୋଫାଇଲ୍ ଛବି ଭାବେ ଦେଖାଏ, ଏକ ବବଲ୍ ଭାବେ ଦେଖାଯାଏ, \'ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\'କୁ ବାଧା ଦିଏ"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"ପ୍ରାଥମିକତା"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବାର୍ତ୍ତାଳାପ ଫିଚରଗୁଡ଼ିକୁ ସମର୍ଥନ କରେ ନାହିଁ"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ପରିବର୍ତ୍ତନ କରିହେବ ନାହିଁ।"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"କଲ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ପରିବର୍ତ୍ତନ କରାଯାଇପାରିବ ନାହିଁ।"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"ଏଠାରେ ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ଗ୍ରୁପ୍ କନଫ୍ୟୁଗର୍ କରାଯାଇପାରିବ ନାହିଁ"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ଉଚ୍ଚ ରିଜୋଲ୍ୟୁସନ ପାଇଁ ଫୋନକୁ ଫ୍ଲିପ କରନ୍ତୁ"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ଫୋଲ୍ଡ କରାଯାଇପାରୁଥିବା ଡିଭାଇସକୁ ଅନଫୋଲ୍ଡ କରାଯାଉଛି"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ଫୋଲ୍ଡ କରାଯାଇପାରୁଥିବା ଡିଭାଇସକୁ ଫ୍ଲିପ କରାଯାଉଛି"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"ସାମ୍ନା ସ୍କ୍ରିନ ଚାଲୁ ଅଛି"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ଫୋଲ୍ଡେଡ"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ଅନଫୋଲ୍ଡେଡ"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ଆକ୍ସେସିବିଲିଟୀ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"କୀବୋର୍ଡ ସର୍ଟକଟ"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"କୀବୋର୍ଡ ସର୍ଟକଟଗୁଡ଼ିକୁ କଷ୍ଟମାଇଜ କରନ୍ତୁ"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ସର୍ଟକଟ ଆସାଇନ କରିବା ପାଇଁ କୀ\'କୁ ଦବାନ୍ତୁ"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ସର୍ଚ୍ଚ ସର୍ଟକଟ"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"କୌଣସି ସର୍ଚ୍ଚ ଫଳାଫଳ ନାହିଁ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ଆଇକନକୁ ସଙ୍କୁଚିତ କରନ୍ତୁ"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ଡ୍ରାଗ ହେଣ୍ଡେଲ"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"କୀବୋର୍ଡ ସେଟିଂ"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ସର୍ଟକଟ ସେଟ କରନ୍ତୁ"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ବାତିଲ କରନ୍ତୁ"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"କୀ ଦବାନ୍ତୁ"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"କୀ କମ୍ବିନେସନ ପୂର୍ବରୁ ବ୍ୟବହାର କରାଯାଉଛି। ଅନ୍ୟ ଏକ କୀ ବ୍ୟବହାର କରି ଦେଖନ୍ତୁ।"</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ଆପଣଙ୍କ କୀବୋର୍ଡ ବ୍ୟବହାର କରି ନାଭିଗେଟ କରନ୍ତୁ"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"କୀବୋର୍ଡ ସର୍ଟକଟଗୁଡ଼ିକ ବିଷୟରେ ଜାଣନ୍ତୁ"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ଆପଣଙ୍କ ଟଚପେଡ ବ୍ୟବହାର କରି ନାଭିଗେଟ କରନ୍ତୁ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 5b9919ef97b6..80798b714d12 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ਲਾਕ ਸਕ੍ਰੀਨ ਵਿਜੇਟ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ਵਿਜੇਟ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਐਪ ਖੋਲ੍ਹਣ ਲਈ, ਤੁਹਾਨੂੰ ਇਹ ਪੁਸ਼ਟੀ ਕਰਨ ਦੀ ਲੋੜ ਪਵੇਗੀ ਕਿ ਇਹ ਤੁਸੀਂ ਹੀ ਹੋ। ਨਾਲ ਹੀ, ਇਹ ਵੀ ਧਿਆਨ ਵਿੱਚ ਰੱਖੋ ਕਿ ਕੋਈ ਵੀ ਉਨ੍ਹਾਂ ਨੂੰ ਦੇਖ ਸਕਦਾ ਹੈ, ਭਾਵੇਂ ਤੁਹਾਡਾ ਟੈਬਲੈੱਟ ਲਾਕ ਹੋਵੇ। ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਕੁਝ ਵਿਜੇਟ ਤੁਹਾਡੀ ਲਾਕ ਸਕ੍ਰੀਨ ਲਈ ਨਾ ਬਣੇ ਹੋਣ ਅਤੇ ਉਨ੍ਹਾਂ ਨੂੰ ਇੱਥੇ ਸ਼ਾਮਲ ਕਰਨਾ ਅਸੁਰੱਖਿਅਤ ਹੋਵੇ।"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ਸਮਝ ਲਿਆ"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ਵਰਤੋਂਕਾਰ ਸਵਿੱਚ ਕਰੋ"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ਪੁੱਲਡਾਊਨ ਮੀਨੂ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ਇਸ ਸੈਸ਼ਨ ਵਿਚਲੀਆਂ ਸਾਰੀਆਂ ਐਪਾਂ ਅਤੇ ਡਾਟੇ ਨੂੰ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"ਗੱਲਬਾਤ ਸੂਚਨਾਵਾਂ ਦੇ ਸਿਖਰ \'ਤੇ ਅਤੇ ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰੋਫਾਈਲ ਤਸਵੀਰ ਵਜੋਂ ਦਿਖਾਈਆਂ ਜਾਂਦੀਆਂ ਹਨ, ਜੋ ਕਿ ਬਬਲ ਵਜੋਂ ਦਿਸਦੀਆਂ ਹਨ ਅਤੇ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਸੁਵਿਧਾ ਵਿੱਚ ਵਿਘਨ ਵੀ ਪਾ ਸਕਦੀਆਂ ਹਨ"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"ਤਰਜੀਹ"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਐਪ ਗੱਲਬਾਤ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ਇਹਨਾਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਸੋਧਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ।"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"ਕਾਲ ਸੰਬੰਧੀ ਸੂਚਨਾਵਾਂ ਨੂੰ ਸੋਧਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ।"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"ਇਹ ਸੂਚਨਾਵਾਂ ਦਾ ਗਰੁੱਪ ਇੱਥੇ ਸੰਰੂਪਿਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ਉੱਚ ਰੈਜ਼ੋਲਿਊਸ਼ਨ ਲਈ, ਫ਼ੋਨ ਨੂੰ ਫਲਿੱਪ ਕਰੋ"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ਮੋੜਨਯੋਗ ਡੀਵਾਈਸ ਨੂੰ ਖੋਲ੍ਹਿਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ਮੋੜਨਯੋਗ ਡੀਵਾਈਸ ਨੂੰ ਆਲੇ-ਦੁਆਲੇ ਫਲਿੱਪ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"ਅਗਲੀ ਸਕ੍ਰੀਨ ਚਾਲੂ ਕੀਤੀ ਗਈ"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ਫੋਲਡਯੋਗ ਡੀਵਾਈਸ"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ਅਣਫੋਲਡਯੋਗ ਡੀਵਾਈਸ"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ਪਹੁੰਚਯੋਗਤਾ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ ਵਿਉਂਤਬੱਧ ਕਰੋ"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ਸ਼ਾਰਟਕੱਟ ਨਿਰਧਾਰਿਤ ਕਰਨ ਲਈ ਕੁੰਜੀ ਦਬਾਓ"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ਸ਼ਾਰਟਕੱਟ ਖੋਜੋ"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ਕੋਈ ਖੋਜ ਨਤੀਜਾ ਨਹੀਂ ਮਿਲਿਆ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ਪ੍ਰਤੀਕ ਨੂੰ ਸਮੇਟੋ"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ਘਸੀਟਣ ਵਾਲਾ ਹੈਂਡਲ"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"ਕੀ-ਬੋਰਡ ਸੈਟਿੰਗਾਂ"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ਸ਼ਾਰਟਕੱਟ ਸੈੱਟ ਕਰੋ"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ਰੱਦ ਕਰੋ"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ਕੁੰਜੀ ਦਬਾਓ"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"ਕੁੰਜੀ ਸੁਮੇਲ ਪਹਿਲਾਂ ਹੀ ਵਰਤੋਂ ਵਿੱਚ ਹੈ। ਕੋਈ ਹੋਰ ਕੁੰਜੀ ਨੂੰ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ਆਪਣੇ ਕੀ-ਬੋਰਡ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਨੈਵੀਗੇਟ ਕਰੋ"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ਕੀ-ਬੋਰਡ ਦੇ ਸ਼ਾਰਟਕੱਟਾਂ ਬਾਰੇ ਜਾਣੋ"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ਆਪਣੇ ਟੱਚਪੈਡ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਨੈਵੀਗੇਟ ਕਰੋ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index e41d16f82785..67fdf8c2c383 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widżety na ekranie blokady"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Aby otworzyć aplikację za pomocą widżetu, musisz potwierdzić swoją tożsamość. Pamiętaj też, że każdy będzie mógł wyświetlić widżety nawet wtedy, gdy tablet będzie zablokowany. Niektóre widżety mogą nie być przeznaczone do umieszczenia na ekranie blokady i ich dodanie w tym miejscu może być niebezpieczne."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Przełącz użytkownika"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Wszystkie aplikacje i dane w tej sesji zostaną usunięte."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekranie blokady, jako dymek, przerywa działanie trybu Nie przeszkadzać"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Priorytetowe"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> nie obsługuje funkcji rozmów"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Tych powiadomień nie można zmodyfikować."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Powiadomień o połączeniach nie można modyfikować."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Tej grupy powiadomień nie można tu skonfigurować"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Wpisz mniej znaków niż <xliff:g id="LENGTH">%1$d</xliff:g>"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numer kompilacji"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Numer kompilacji został skopiowany do schowka."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"Kopiuj do schowka"</string>
<string name="basic_status" msgid="2315371112182658176">"Otwarta rozmowa"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widżety rozmów"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Kliknij rozmowę, aby dodać ją do ekranu głównego"</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Odwróć telefon, aby uzyskać wyższą rozdzielczość"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Składane urządzenie jest rozkładane"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Składane urządzenie jest obracane"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Ekran przedni jest włączony"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"po zamknięciu"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"po otwarciu"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ułatwienia dostępu"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Skróty klawiszowe"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Dostosuj skróty klawiszowe"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Naciśnij klawisz, aby przypisać skrót"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Skróty do wyszukiwania"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Brak wyników wyszukiwania"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona zwijania"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Uchwyt do przeciągania"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Ustawienia klawiatury"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ustaw skrót"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Anuluj"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Naciśnij klawisz"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinacja klawiszy jest już używana. Użyj innego klawisza."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Nawiguj za pomocą klawiatury"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Dowiedz się więcej o skrótach klawiszowych"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Nawiguj za pomocą touchpada"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 72e593c06718..7db8d8dd5fcb 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets da tela de bloqueio"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir um app usando um widget, você precisa confirmar sua identidade. E não se esqueça que qualquer pessoa pode ver os widgets, mesmo com o tablet bloqueado. Além disso, alguns apps não foram criados para a tela de bloqueio, é melhor manter a segurança."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendi"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Trocar usuário"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu suspenso"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Aparecem na parte superior das notificações de conversa, como uma foto do perfil na tela de bloqueio e como um balão. Interrompem o Não perturbe."</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritárias"</string>
<string name="no_shortcut" msgid="8257177117568230126">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não é compatível com recursos de conversa"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Não é possível modificar essas notificações."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Não é possível modificar as notificações de chamada."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Não é possível configurar esse grupo de notificações aqui"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para uma resolução maior, vire o smartphone"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo dobrável sendo aberto"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo dobrável sendo virado"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Tela frontal ativada"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"fechado"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"aberto"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos do teclado"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizar atalhos de teclado"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pressione a tecla para atribuir o atalho"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pesquisar atalhos"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nenhum resultado de pesquisa"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícone \"Fechar\""</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Alça de arrastar"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Configurações do teclado"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Definir atalho"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancelar"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pressione a tecla"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Essa combinação de teclas já está em uso. Tente outra tecla."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navegue usando o teclado"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprenda atalhos do teclado"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navegue usando o touchpad"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 460d55304e1e..d9d82bffd294 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -528,6 +528,8 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets do ecrã de bloqueio"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir uma app através de um widget, vai ter de validar a sua identidade. Além disso, tenha em atenção que qualquer pessoa pode ver os widgets, mesmo quando o tablet estiver bloqueado. Alguns widgets podem não se destinar ao ecrã de bloqueio e pode ser inseguro adicioná-los aqui."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
+ <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Widgets"</string>
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="511359420883794513">"Para adicionar widgets ao ecrã de bloqueio como um atalho, certifique-se de que estão ativados nas definições."</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Mudar utilizador"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu pendente"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todas as apps e dados desta sessão serão eliminados."</string>
@@ -780,6 +782,7 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Aparece na parte superior das notificações de conversas e como uma imagem do perfil no ecrã de bloqueio, surge como um balão, interrompe o modo Não incomodar"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioridade"</string>
<string name="no_shortcut" msgid="8257177117568230126">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> não suporta funcionalidades de conversa."</string>
+ <string name="notification_guts_bundle_feedback" msgid="5393570876655201459">"Enviar feedback sobre o pacote"</string>
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Não é possível modificar estas notificações."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Não é possível modificar as notificações de chamadas."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Não é possível configurar este grupo de notificações aqui."</string>
@@ -1220,8 +1223,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Use menos de <xliff:g id="LENGTH">%1$d</xliff:g> carateres"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da compilação"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Número da compilação copiado para a área de transferência."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"copiar para a área de transferência."</string>
<string name="basic_status" msgid="2315371112182658176">"Abrir conversa"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Toque numa conversa para a adicionar ao ecrã principal"</string>
@@ -1357,8 +1359,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para uma resolução superior, inverta o telemóvel"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo dobrável a ser desdobrado"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo dobrável a ser virado ao contrário"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Ecrã frontal ativado"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"fechado"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"aberto"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1419,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos de teclado"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalize os atalhos de teclado"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Prima a tecla para atribuir o atalho"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pesquisar atalhos"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nenhum resultado da pesquisa"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícone de reduzir"</string>
@@ -1431,9 +1437,13 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Indicador para arrastar"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Definições do teclado"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Configurar atalho"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancelar"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Prima a tecla"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"A combinação de teclas já está a ser usada. Experimente outra tecla."</string>
+ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"A combinação de teclas já está a ser usada. Experimente outra tecla."</string>
+ <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Não é possível definir o atalho."</string>
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navegue com o teclado"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprenda atalhos de teclado"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navegue com o touchpad"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 72e593c06718..7db8d8dd5fcb 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets da tela de bloqueio"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir um app usando um widget, você precisa confirmar sua identidade. E não se esqueça que qualquer pessoa pode ver os widgets, mesmo com o tablet bloqueado. Além disso, alguns apps não foram criados para a tela de bloqueio, é melhor manter a segurança."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendi"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Trocar usuário"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu suspenso"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Aparecem na parte superior das notificações de conversa, como uma foto do perfil na tela de bloqueio e como um balão. Interrompem o Não perturbe."</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritárias"</string>
<string name="no_shortcut" msgid="8257177117568230126">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não é compatível com recursos de conversa"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Não é possível modificar essas notificações."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Não é possível modificar as notificações de chamada."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Não é possível configurar esse grupo de notificações aqui"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para uma resolução maior, vire o smartphone"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo dobrável sendo aberto"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo dobrável sendo virado"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Tela frontal ativada"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"fechado"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"aberto"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos do teclado"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizar atalhos de teclado"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pressione a tecla para atribuir o atalho"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pesquisar atalhos"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nenhum resultado de pesquisa"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícone \"Fechar\""</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Alça de arrastar"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Configurações do teclado"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Definir atalho"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancelar"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pressione a tecla"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Essa combinação de teclas já está em uso. Tente outra tecla."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navegue usando o teclado"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprenda atalhos do teclado"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navegue usando o touchpad"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 42fd14b1b9c2..60e5b8a4e163 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgeturi pe ecranul de blocare"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Pentru a deschide o aplicație folosind un widget, va trebui să-ți confirmi identitatea. În plus, reține că oricine poate să vadă widgeturile, chiar dacă tableta este blocată. Este posibil ca unele widgeturi să nu fi fost create pentru ecranul de blocare și poate fi nesigur să le adaugi aici."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Schimbă utilizatorul"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"meniu vertical"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toate aplicațiile și datele din această sesiune vor fi șterse."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Se afișează în partea de sus a notificărilor pentru conversații și ca fotografie de profil pe ecranul de blocare, apare ca un balon, întrerupe funcția Nu deranja"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritate"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> nu acceptă funcții pentru conversații"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Aceste notificări nu pot fi modificate."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Notificările pentru apeluri nu pot fi modificate."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Acest grup de notificări nu poate fi configurat aici"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Pentru o rezoluție mai mare, deschide telefonul"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispozitiv pliabil care este desfăcut"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispozitiv pliabil care este întors"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Ecranul frontal este activat"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"închis"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"deschis"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilitate"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Comenzi rapide de la tastatură"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizează comenzile rapide de la tastatură"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Apasă tasta pentru a atribui comanda rapidă"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Comenzi directe de căutare"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Niciun rezultat al căutării"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Pictograma de restrângere"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ghidaj de tragere"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Setările tastaturii"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Setează o comandă rapidă"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Anulează"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Apasă tasta"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Combinația de taste este deja folosită. Încearcă altă tastă."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navighează folosind tastatura"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Învață comenzile rapide de la tastatură"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navighează folosind touchpadul"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 866cb5e8f602..2707e4b4873d 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Виджеты на заблокированном экране"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Чтобы открыть приложение, используя виджет, вам нужно будет подтвердить свою личность. Обратите внимание, что виджеты видны всем, даже если планшет заблокирован. Некоторые виджеты не предназначены для использования на заблокированном экране. Добавлять их туда может быть небезопасно."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ОК"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Сменить пользователя."</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"раскрывающееся меню"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Все приложения и данные этого профиля будут удалены."</string>
@@ -698,8 +702,8 @@
<string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Контроль шума"</string>
<string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Пространственное звучание"</string>
<string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Отключено"</string>
- <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Без отсле­живания"</string>
- <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"С отсле­живанием"</string>
+ <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Статичное"</string>
+ <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Динамичное"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Нажмите, чтобы изменить режим звонка."</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"режим звонка"</string>
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"отключить звук"</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Появляется в верхней части уведомлений о сообщениях, в виде всплывающего чата, а также в качестве фото профиля на заблокированном экране, прерывает режим \"Не беспокоить\"."</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Приоритет"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" не поддерживает функции разговоров."</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Эти уведомления нельзя изменить."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Уведомления о звонках нельзя изменить."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Эту группу уведомлений нельзя настроить здесь."</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Переверните телефон и используйте основную камеру, чтобы делать снимки с более высоким разрешением."</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Складное устройство в разложенном виде"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Перевернутое складное устройство"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Передний экран включен"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"устройство сложено"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"устройство разложено"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Специальные возможности"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Быстрые клавиши"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Как настроить быстрые клавиши"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Нажмите клавишу, чтобы назначить быструю команду."</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Найти быстрые клавиши"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ничего не найдено"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Значок \"Свернуть\""</string>
@@ -1431,15 +1441,22 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Маркер перемещения"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Настройки клавиатуры"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Задать сочетание клавиш"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Отмена"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Нажмите клавишу"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Это сочетание клавиш уже используется. Попробуйте другое."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Навигация с помощью клавиатуры"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Узнайте о сочетаниях клавиш."</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Навигация с помощью сенсорной панели"</string>
<string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Узнайте о жестах на сенсорной панели."</string>
<string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Навигация с помощью клавиатуры и сенсорной панели"</string>
- <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Узнайте о жестах на сенсорной панели, сочетаниях клавиш и многом другом."</string>
+ <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Выучите жесты на сенсорной панели, сочетания клавиш и другие варианты навигации."</string>
<string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"Назад"</string>
<string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"На главный экран"</string>
<string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Просмотр недавних приложений"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 0ccd61c41905..761d8febff9b 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"අගුළු තිර විජට්"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"විජට් එකක් භාවිතයෙන් යෙදුමක් විවෘත කිරීමට, ඔබට ඒ ඔබ බව සත්‍යාපනය කිරීමට අවශ්‍ය වනු ඇත. එසේම, ඔබේ ටැබ්ලටය අගුළු දමා ඇති විට පවා ඕනෑම කෙනෙකුට ඒවා බැලිය හැකි බව මතක තබා ගන්න. සමහර විජට් ඔබේ අගුළු තිරය සඳහා අදහස් කර නොතිබිය හැකි අතර මෙහි එක් කිරීමට අනාරක්ෂිත විය හැක."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"තේරුණා"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"පරිශීලක මාරුව"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"නිපතන මෙනුව"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"මෙම සැසියේ සියළුම යෙදුම් සහ දත්ත මකාවී."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"සංවාද දැනුම්දීම්වල ඉහළින්ම සහ අගුලු තිරයේ ඇති පැතිකඩ පින්තූරයක් ලෙස පෙන්වයි, බුබුළක් ලෙස දිස් වේ, බාධා නොකරන්න සඳහා බාධා කරයි"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"ප්‍රමුඛතාව"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> සංවාද විශේෂාංගවලට සහාය නොදක්වයි"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"මෙම දැනුම්දීම් වෙනස් කළ නොහැක."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"ඇමතුම් දැනුම්දීම් වෙනස් කළ නොහැකිය."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"මෙම දැනුම්දීම් සමූහය මෙහි වින්‍යාස කළ නොහැක"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ඉහළ විභේදනය සඳහා, දුරකථනය හරවන්න"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"දිග හැරෙමින් පවතින නැමිය හැකි උපාංගය"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"වටා පෙරළෙමින් තිබෙන නැමිය හැකි උපාංගය"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"ඉදිරිපස තිරය ක්‍රියාත්මකයි"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"නැවූ"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"නොනැවූ"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ප්‍රවේශ්‍යතාව"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"යතුරු පුවරු කෙටි මං"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"යතුරුපුවරු කෙටිමං අභිරුචිකරණය කරන්න"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"කෙටි මග පැවරීමට යතුර ඔබන්න"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"කෙටි මං සොයන්න"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"සෙවීම් ප්‍රතිඵල නැත"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"හැකුළුම් නිරූපකය"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ඇදීම් හැඬලය"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"යතුරු පුවරු සැකසීම්"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"කෙටිමඟ සකසන්න"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"අවලංගු කරන්න"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"යතුර ඔබන්න"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"යතුරු සංයෝජනය දැනටමත් භාවිත වේ. වෙනත් යතුරක් උත්සාහ කරන්න."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ඔබේ යතුරු පුවරුව භාවිතයෙන් සංචාලනය කරන්න"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"යතුරුපුවරු කෙටිමං ඉගෙන ගන්න"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ඔබේ ස්පර්ශ පෑඩ් භාවිතයෙන් සංචාලනය කරන්න"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index cc59beafe025..88aa12d275e2 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Miniaplikácie na uzamknutej obrazovke"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Ak chcete otvoriť aplikáciu pomocou miniaplikácie, budete musieť overiť svoju totožnosť. Pamätajte, že si miniaplikáciu môže pozrieť ktokoľvek, aj keď máte tablet uzamknutý. Niektoré miniaplikácie možno nie sú určené pre uzamknutú obrazovku a ich pridanie tu môže byť nebezpečné."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Dobre"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Prepnutie používateľa"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rozbaľovacia ponuka"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Všetky aplikácie a údaje v tejto relácii budú odstránené."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Zobrazuje sa ako bublina v hornej časti upozornení konverzácie a profilová fotka na uzamknutej obrazovke, preruší režim bez vyrušení"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritné"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> nepodporuje funkcie konverzácie"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Tieto upozornenia sa nedajú upraviť."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Upozornenia na hovory sa nedajú upraviť."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Túto skupinu upozornení nejde na tomto mieste konfigurovať"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Ak chcete vyššie rozlíšenie, prevráťte telefón"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rozloženie skladacieho zariadenia"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Prevrátenie skladacieho zariadenia"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Predná obrazovka je zapnutá"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"zložené"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"rozložené"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Dostupnosť"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klávesové skratky"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prispôsobenie klávesových skratiek"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Stlačením klávesa priraďte skratku"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prehľadávať skratky"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Žiadne výsledky vyhľadávania"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona zbalenia"</string>
@@ -1431,14 +1441,21 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Presúvadlo"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Nastavenia klávesnice"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Nastaviť skratku"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Zrušiť"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Stlačte kláves"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinácia klávesov sa už používa. Skúste iný kláves."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Pohybujte sa v systéme pomocou klávesnice"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Naučte sa klávesové skratky"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Pohybujte sa v systéme pomocou touchpadu"</string>
<string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Naučte sa gestá touchpadu"</string>
- <string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Prechádzajte pomocou klávesnice a touchpadu"</string>
+ <string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Pohybujte sa v systéme pomocou klávesnice a touchpadu"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Naučte sa gestá touchpadu, klávesové skratky a ďalšie funkcie"</string>
<string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"Prechod späť"</string>
<string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Prejsť na plochu"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 38f1e5a1fb6d..4704e980cf72 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Pripomočki na zaklenjenem zaslonu"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Če želite aplikacijo odpreti s pripomočkom, morate potrditi, da ste to vi. Upoštevajte tudi, da si jih lahko ogledajo vsi, tudi ko je tablični računalnik zaklenjen. Nekateri pripomočki morda niso predvideni za uporabo na zaklenjenem zaslonu, zato jih tukaj morda ni varno dodati."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Razumem"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Preklop med uporabniki"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"spustni meni"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Vse aplikacije in podatki v tej seji bodo izbrisani."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Prikaz v obliki oblačka na vrhu razdelka z obvestili za pogovor in kot profilna slika na zaklenjenem zaslonu, preglasitev načina Ne moti."</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prednostno"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> ne podpira pogovornih funkcij."</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Za ta obvestila ni mogoče spremeniti nastavitev."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Obvestil o klicih ni mogoče spreminjati."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Te skupine obvestil ni mogoče konfigurirati tukaj"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Uporabite manj kot <xliff:g id="LENGTH">%1$d</xliff:g> znakov."</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Delovna različica"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Delovna različica je bila kopirana v odložišče."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"kopiranje v odložišče."</string>
<string name="basic_status" msgid="2315371112182658176">"Odprt pogovor"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Pripomočki za pogovore"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Dotaknite se pogovora, da ga dodate na začetni zaslon."</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Za višjo ločljivost obrnite telefon"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Razpiranje zložljive naprave"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Obračanje zložljive naprave"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Sprednji zaslon je vklopljen"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"zaprto"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"razprto"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Dostopnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Bližnjične tipke"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagajanje bližnjičnih tipk"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pritisnite tipko za dodelitev bližnjice"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Iskanje po bližnjicah"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ni rezultatov iskanja"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za strnitev"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ročica za vlečenje"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Nastavitve tipkovnice"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Nastavite bližnjico"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Prekliči"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pritisnite tipko"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinacija tipk je že v uporabi. Poskusite z drugo tipko."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Krmarjenje s tipkovnico"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Učenje bližnjičnih tipk"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Krmarjenje s sledilno ploščico"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 9ed8bf29d630..d082bfdc1e56 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Miniaplikacionet në ekranin e kyçjes"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Për të hapur një aplikacion duke përdorur një miniaplikacion, do të duhet të verifikosh që je ti. Ki parasysh gjithashtu që çdo person mund t\'i shikojë, edhe kur tableti yt është i kyçur. Disa miniaplikacione mund të mos jenë planifikuar për ekranin tënd të kyçjes dhe mund të mos jetë e sigurt t\'i shtosh këtu."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"E kuptova"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Ndërro përdorues"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menyja me tërheqje poshtë"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Të gjitha aplikacionet dhe të dhënat në këtë sesion do të fshihen."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Shfaqet në krye të njoftimeve të bisedës dhe si fotografia e profilit në ekranin e kyçjes, shfaqet si flluskë dhe ndërpret modalitetin \"Mos shqetëso\""</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Me përparësi"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk mbështet veçoritë e bisedës"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Këto njoftime nuk mund të modifikohen."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Njoftimet e telefonatave nuk mund të modifikohen."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Ky grup njoftimesh nuk mund të konfigurohet këtu"</string>
@@ -1418,7 +1424,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Qasshmëria"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Shkurtoret e tastierës"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizo shkurtoret e tastierës"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Shtyp tastin për të caktuar shkurtoren"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Kërko për shkurtoret"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Asnjë rezultat kërkimi"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona e palosjes"</string>
@@ -1431,9 +1442,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Doreza e zvarritjes"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Cilësimet e tastierës"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Cakto shkurtoren"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Anulo"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Shtyp tastin"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinimi i tasteve është tashmë në përdorim. Provo një tast tjetër."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigo duke përdorur tastierën tënde"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Mëso shkurtoret e tastierës"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigo duke përdorur bllokun me prekje"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 102c452fc54a..71fd8879edcf 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Виџети за закључани екран"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Да бисте отворили апликацију која користи виџет, треба да потврдите да сте то ви. Имајте у виду да свако може да га види, чак и када је таблет закључан. Неки виџети можда нису намењени за закључани екран и можда није безбедно да их тамо додате."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Важи"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Замени корисника"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"падајући мени"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Све апликације и подаци у овој сесији ће бити избрисани."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Приказује се у врху обавештења о конверзацијама и као слика профила на закључаном екрану, појављује се као облачић, прекида режим Не узнемиравај"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Приоритетно"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не подржава функције конверзације"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Ова обавештења не могу да се мењају."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Обавештења о позивима не могу да се мењају."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Ова група обавештења не може да се конфигурише овде"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Користите мањи број знакова од <xliff:g id="LENGTH">%1$d</xliff:g>"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Број верзије"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Број верзије је копиран у привремену меморију."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"копирајте у привремену меморију."</string>
<string name="basic_status" msgid="2315371112182658176">"Отворите конверзацију"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Виџети за конверзацију"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Додирните конверзацију да бисте је додали на почетни екран"</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"За већу резолуцију обрните телефон"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Уређај на преклоп се отвара"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Уређај на преклоп се обрће"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Предњи екран је укључен"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"затворено"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"отворено"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Приступачност"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Тастерске пречице"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Прилагодите тастерске пречице"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Притисните тастер да бисте доделили пречицу"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Претражите пречице"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Нема резултата претраге"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Икона за скупљање"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Маркер за превлачење"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Подешавања тастатуре"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Подеси пречицу"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Откажи"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Притисните тастер"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Комбинација тастера се већ користи. Пробајте са другим тастером."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Крећите се помоћу тастатуре"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Сазнајте више о тастерским пречицама"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Крећите се помоћу тачпеда"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index c2ac21691aa1..175b1d0783ff 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgetar för låsskärm"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Du måste verifiera din identitet innan du öppnar en app med en widget. Tänk också på att alla kan se dem, även när surfplattan är låst. Vissa widgetar kanske inte är avsedda för låsskärmen och det kan vara osäkert att lägga till dem här."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Byt användare"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rullgardinsmeny"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alla appar och data i denna session kommer att raderas."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Visas högst upp i konversationsaviseringarna och som profilbild på låsskärmen, visas som bubbla, åsidosätter Stör ej"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> har inte stöd för konversationsfunktioner"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Det går inte att ändra de här aviseringarna."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Det går inte att ändra samtalsaviseringarna."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Den här aviseringsgruppen kan inte konfigureras här"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Använd färre än <xliff:g id="LENGTH">%1$d</xliff:g> tecken"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Versionsnummer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Versionsnumret har kopierats till urklipp."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"kopiera till urklipp."</string>
<string name="basic_status" msgid="2315371112182658176">"Öppen konversation"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Konversationswidgetar"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Tryck på en konversation för att lägga till den på startskärmen"</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Vänd telefonen för högre upplösning"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"En vikbar enhet viks upp"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"En vikbar enhet vänds"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Den främre skärmen har aktiverats"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"hopvikt"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"uppvikt"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Tillgänglighet"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Kortkommandon"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Anpassa kortkommandon"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Tryck på tangenten för att ange kortkommando"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Sökgenvägar"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Inga sökresultat"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikonen Komprimera"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Handtag"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Tangentbordsinställningar"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ange kortkommando"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Avbryt"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Tryck på tangenten"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Tangentkombinationen används redan. Testa en annan tangent."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigera med tangentbordet"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Lär dig kortkommandon"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigera med styrplattan"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 3418907ea44c..fe431b7cfecc 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Wijeti zinazoonekana kwenye skrini iliyofungwa"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Utahitaji kuthibitisha kuwa ni wewe ili ufungue programu ukitumia wijeti. Pia, kumbuka kuwa mtu yeyote anaweza kuziona, hata kishikwambi chako kikiwa kimefungwa. Huenda baadhi ya wijeti hazikukusudiwa kutumika kwenye skrini yako iliyofungwa na huenda si salama kuziweka hapa."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Nimeelewa"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Badili mtumiaji"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menyu ya kuvuta chini"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Data na programu zote katika kipindi hiki zitafutwa."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Huonyeshwa kwenye sehemu ya juu ya arifa za mazungumzo na kama picha ya wasifu kwenye skrini iliyofungwa. Huonekana kama kiputo na hukatiza kipengele cha Usinisumbue"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Kipaumbele"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> haitumii vipengele vya mazungumzo"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Arifa hizi haziwezi kubadilishwa."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Arifa za simu haziwezi kubadilishwa."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Kikundi hiki cha arifa hakiwezi kuwekewa mipangilio hapa"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Kwa ubora wa juu, geuza simu"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Kifaa kinachokunjwa kikikunjuliwa"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Kifaa kinachokunjwa kikigeuzwa"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Umewasha skrini ya mbele"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"kimekunjwa"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"kimefunguliwa"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ufikivu"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Mikato ya kibodi"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Weka mapendeleo ya mikato ya kibodi"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Bonyeza kitufe ukabidhi njia ya mkato"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Njia mkato za kutafutia"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Hamna matokeo ya utafutaji"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Kunja aikoni"</string>
@@ -1431,15 +1441,22 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Aikoni ya buruta"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Mipangilio ya Kibodi"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Weka njia ya mkato"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Acha"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Bonyeza kitufe"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Tayari unatumia mchanganyiko huu wa vitufe. Jatibu kitufe kingine."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Kusogeza kwa kutumia kibodi yako"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Fahamu kuhusu mikato ya kibodi"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Kusogeza kwa kutumia padi yako ya kugusa"</string>
<string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Fahamu miguso ya padi ya kugusa"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Kusogeza kwa kutumia kibodi na padi yako ya kugusa"</string>
- <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Jifunze kuhusu miguso ya padi ya kugusa, mikato ya kibodi na mengineyo"</string>
+ <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Fahamu kuhusu miguso ya padi ya kugusa, mikato ya kibodi na mengineyo"</string>
<string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"Rudi nyuma"</string>
<string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Nenda kwenye ukurasa wa mwanzo"</string>
<string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Angalia programu za hivi majuzi"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 99c912ca072a..6d03b79dfebf 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"பூட்டுத் திரை விட்ஜெட்கள்"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"விட்ஜெட்டைப் பயன்படுத்தி ஆப்ஸைத் திறக்க, அது நீங்கள்தான் என்பதை உறுதிசெய்ய வேண்டும். அத்துடன், உங்கள் டேப்லெட் பூட்டப்பட்டிருந்தாலும்கூட அவற்றை யார் வேண்டுமானாலும் பார்க்கலாம் என்பதை நினைவில்கொள்ளுங்கள். சில விட்ஜெட்கள் உங்கள் பூட்டுத் திரைக்காக உருவாக்கப்பட்டவை அல்ல என்பதையும் அவற்றை இங்கே சேர்ப்பது பாதுகாப்பற்றதாக இருக்கக்கூடும் என்பதையும் நினைவில்கொள்ளுங்கள்."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"சரி"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"பயனரை மாற்று"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"கீழ் இழுக்கும் மெனு"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"இந்த அமர்வின் எல்லா ஆப்ஸும் தரவும் நீக்கப்படும்."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"உரையாடல் அறிவிப்புகளின் மேற்பகுதியில் காட்டப்படும், திரை பூட்டப்பட்டிருக்கும்போது சுயவிவரப் படமாகக் காட்டப்படும், குமிழாகத் தோன்றும், தொந்தரவு செய்ய வேண்டாம் அம்சம் இயக்கப்பட்டிருக்கும்போதும் காட்டப்படும்"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"முன்னுரிமை"</string>
<string name="no_shortcut" msgid="8257177117568230126">"உரையாடல் அம்சங்களை <xliff:g id="APP_NAME">%1$s</xliff:g> ஆதரிக்காது"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"இந்த அறிவிப்புகளை மாற்ற இயலாது."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"அழைப்பு அறிவிப்புகளை மாற்ற முடியாது."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"இந்த அறிவுப்புக் குழுக்களை இங்கே உள்ளமைக்க இயலாது"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"உயர் தெளிவுத்திறனுக்கு, மொபைலை ஃபிளிப் செய்யுங்கள்"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"மடக்கத்தக்க சாதனம் திறக்கப்படுகிறது"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"மடக்கத்தக்க சாதனம் ஃபிளிப் செய்யப்பட்டு திருப்பப்படுகிறது"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"முன்பக்கத் திரை இயக்கப்பட்டுள்ளது"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"மடக்கப்பட்டது"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"விரிக்கப்பட்டது"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"மாற்றுத்திறன் வசதி"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"கீபோர்டு ஷார்ட்கட்கள்"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"கீபோர்டு ஷார்ட்கட்களைப் பிரத்தியேகப்படுத்துதல்"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ஷார்ட்கட்டை அமைக்க பட்டனை அழுத்துங்கள்"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ஷார்ட்கட்களைத் தேடுக"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"தேடல் முடிவுகள் இல்லை"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"சுருக்குவதற்கான ஐகான்"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"இழுப்பதற்கான ஹேண்டில்"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"கீபோர்டு அமைப்புகள்"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ஷார்ட்கட்டை அமையுங்கள்"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ரத்துசெய்"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"பட்டனை அழுத்துங்கள்"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"பட்டன் சேர்க்கை ஏற்கெனவே பயன்பாட்டில் உள்ளது. வேறொரு பட்டனைப் பயன்படுத்திப் பார்க்கவும்."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"கீபோர்டைப் பயன்படுத்திச் செல்லுதல்"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"கீபோர்டு ஷார்ட்கட்கள் குறித்துத் தெரிந்துகொள்ளுங்கள்"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"டச்பேடைப் பயன்படுத்திச் செல்லுதல்"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 5a088231c945..cfe5101572c0 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"లాక్ స్క్రీన్ విడ్జెట్‌లు"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"విడ్జెట్‌ను ఉపయోగించి యాప్‌ను తెరవడానికి, ఇది మీరేనని వెరిఫై చేయాల్సి ఉంటుంది. అలాగే, మీ టాబ్లెట్ లాక్ చేసి ఉన్నప్పటికీ, ఎవరైనా వాటిని చూడగలరని గుర్తుంచుకోండి. కొన్ని విడ్జెట్‌లు మీ లాక్ స్క్రీన్‌కు తగినవి కాకపోవచ్చు, వాటిని ఇక్కడ జోడించడం సురక్షితం కాకపోవచ్చు."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"అర్థమైంది"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"వినియోగదారుని మార్చు"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"పుల్‌డౌన్ మెనూ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ఈ సెషన్‌లోని అన్ని యాప్‌లు మరియు డేటా తొలగించబడతాయి."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"సంభాషణ నోటిఫికేషన్‌ల ఎగువున, లాక్ స్క్రీన్‌లో ప్రొఫైల్ ఫోటో‌గా చూపిస్తుంది, బబుల్‌గా కనిపిస్తుంది, \'అంతరాయం కలిగించవద్దు\'ను అంతరాయం కలిగిస్తుంది"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"ప్రాధాన్యత"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> సంభాషణ ఫీచర్‌లను సపోర్ట్ చేయదు"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ఈ నోటిఫికేషన్‌లను ఎడిట్ చేయడం వీలుపడదు."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"కాల్ నోటిఫికేషన్‌లను ఎడిట్ చేయడం సాధ్యం కాదు."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"ఈ నోటిఫికేషన్‌ల గ్రూప్‌ను ఇక్కడ కాన్ఫిగర్ చేయలేము"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"అధిక రిజల్యూషన్ కోసం, ఫోన్‌ను తిప్పండి"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"మడవగల పరికరం విప్పబడుతోంది"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"మడవగల పరికరం చుట్టూ తిప్పబడుతోంది"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"ముందు వైపు స్క్రీన్ ఆన్ అయింది"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"మడిచే సదుపాయం గల పరికరం"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"మడిచే సదుపాయం లేని పరికరం"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"యాక్సెసిబిలిటీ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"కీబోర్డ్ షార్ట్‌కట్‌లు"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"కీబోర్డ్ షార్ట్‌కట్‌లను అనుకూలంగా మార్చండి"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"షార్ట్‌కట్‌ను కేటాయించడానికి కీని నొక్కండి"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"షార్ట్‌కట్‌లను వెతకండి"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"సెర్చ్ ఫలితాలు ఏవీ లేవు"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"కుదించండి చిహ్నం"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"లాగే హ్యాండిల్"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"కీబోర్డ్ సెట్టింగ్‌లు"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"షార్ట్‌కట్‌ను సెట్ చేయండి"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"రద్దు చేయండి"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"కీని నొక్కండి"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"కీ కాంబినేషన్ ఇప్పటికే వినియోగంలో ఉంది. వేరొక కీని ట్రై చేయండి."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"మీ కీబోర్డ్ ఉపయోగించి నావిగేట్ చేయండి"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"కీబోర్డ్ షార్ట్‌కట్‌ల గురించి తెలుసుకోండి"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"మీ టచ్‌ప్యాడ్‌ను ఉపయోగించి నావిగేట్ చేయండి"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 816514a9797f..d2b7012985cf 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"วิดเจ็ตในหน้าจอล็อก"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"หากต้องการเปิดแอปโดยใช้วิดเจ็ต คุณจะต้องยืนยันตัวตนของคุณ นอกจากนี้ โปรดทราบว่าผู้อื่นจะดูวิดเจ็ตเหล่านี้ได้แม้ว่าแท็บเล็ตจะล็อกอยู่ก็ตาม วิดเจ็ตบางอย่างอาจไม่ได้มีไว้สำหรับหน้าจอล็อกของคุณ และอาจไม่ปลอดภัยที่จะเพิ่มที่นี่"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"รับทราบ"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"สลับผู้ใช้"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"เมนูแบบเลื่อนลง"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ระบบจะลบแอปและข้อมูลทั้งหมดในเซสชันนี้"</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"แสดงที่ด้านบนของการแจ้งเตือนการสนทนาและเป็นรูปโปรไฟล์บนหน้าจอล็อก ปรากฏเป็นบับเบิล แสดงในโหมดห้ามรบกวน"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"สำคัญ"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ไม่รองรับฟีเจอร์การสนทนา"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"แก้ไขการแจ้งเตือนเหล่านี้ไม่ได้"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"แก้ไขการแจ้งเตือนสายเรียกเข้าไม่ได้"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"การแจ้งเตือนกลุ่มนี้กำหนดค่าที่นี่ไม่ได้"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"ใช้อักขระไม่เกิน <xliff:g id="LENGTH">%1$d</xliff:g> ตัว"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"หมายเลขบิลด์"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"คัดลอกหมายเลขบิลด์ไปยังคลิปบอร์ดแล้ว"</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"คัดลอกไปยังคลิปบอร์ด"</string>
<string name="basic_status" msgid="2315371112182658176">"เปิดการสนทนา"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"วิดเจ็ตการสนทนา"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"แตะการสนทนาเพื่อเพิ่มไปยังหน้าจอหลัก"</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"พลิกด้านโทรศัพท์เพื่อให้ได้ภาพที่มีความละเอียดมากขึ้น"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"อุปกรณ์ที่พับได้กำลังกางออก"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"อุปกรณ์ที่พับได้กำลังพลิกไปมา"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"เปิดหน้าจอด้านหน้าแล้ว"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"พับ"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"กางออก"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"การช่วยเหลือพิเศษ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"แป้นพิมพ์ลัด"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ปรับแต่งแป้นพิมพ์ลัด"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"กดแป้นเพื่อกำหนดแป้นพิมพ์ลัด"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ค้นหาแป้นพิมพ์ลัด"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ไม่พบผลการค้นหา"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ไอคอนยุบ"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"แฮนเดิลการลาก"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"การตั้งค่าแป้นพิมพ์"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ตั้งค่าแป้นพิมพ์ลัด"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ยกเลิก"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"กดแป้น"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"มีการใช้แป้นที่กดร่วมกันนี้แล้ว โปรดลองใช้แป้นอื่น"</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ไปยังส่วนต่างๆ โดยใช้แป้นพิมพ์"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ดูข้อมูลเกี่ยวกับแป้นพิมพ์ลัด"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ไปยังส่วนต่างๆ โดยใช้ทัชแพด"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 3845fcd314a4..132bb62199a6 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Mga widget ng lock screen"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para magbukas ng app gamit ang isang widget, kakailanganin mong i-verify na ikaw iyan. Bukod pa rito, tandaang puwedeng tingnan ng kahit na sino ang mga ito, kahit na naka-lock ang iyong tablet. Posibleng hindi para sa iyong lock screen ang ilang widget at posibleng hindi ligtas ang mga ito na idagdag dito."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Magpalit ng user"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ide-delete ang lahat ng app at data sa session na ito."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Makikita sa itaas ng mga notification ng pag-uusap at bilang larawan sa profile sa lock screen, lumalabas bilang bubble, naaabala ang Huwag Istorbohin"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Priyoridad"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Hindi sinusuportahan ng <xliff:g id="APP_NAME">%1$s</xliff:g> ang mga feature ng pag-uusap"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Hindi puwedeng baguhin ang mga notification na ito."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Hindi mabago ang mga notification ng tawag."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Hindi mako-configure dito ang pangkat na ito ng mga notification"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Gumamit ng mas kaunti sa <xliff:g id="LENGTH">%1$d</xliff:g> (na) character"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero ng build"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Nakopya sa clipboard ang numero ng build."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"kopyahin sa clipboard."</string>
<string name="basic_status" msgid="2315371112182658176">"Buksan ang pag-uusap"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Mga widget ng pag-uusap"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Mag-tap sa isang pag-uusap para idagdag ito sa iyong Home screen"</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para sa mas mataas na resolution, i-flip ang telepono"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ina-unfold na foldable na device"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Fini-flip na foldable na device"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Na-on ang screen sa harap"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"naka-fold"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"hindi naka-fold"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Mga keyboard shortcut"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"I-customize ang mga keyboard shortcut"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pindutin ang key para magtalaga ng shortcut"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Mga shortcut ng paghahanap"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Walang resulta ng paghahanap"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"I-collapse ang icon"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Handle sa pag-drag"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Mga Setting ng Keyboard"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Magtakda ng shortcut"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Kanselahin"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pindutin ang key"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Ginagamit na ang kumbinasyon ng key. Sumubok ng ibang key."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Mag-navigate gamit ang iyong keyboard"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Matuto ng mga keyboard shortcut"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Mag-navigate gamit ang iyong touchpad"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 45d8b4605c29..afdc9a0a6fa8 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -113,7 +113,7 @@
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Bir uygulamayı kaydet"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Tüm ekranı kaydet"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Tüm ekranı kaydet: %s"</string>
- <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Tüm ekranınızı kaydettiğinizde ekranınızda gösterilen her şey kaydedilir. Bu nedenle şifre, ödeme ayrıntıları, mesaj, fotoğraf, ses ve video gibi öğeler konusunda dikkatli olun."</string>
+ <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Ekranın tamamını kaydederken ekranınızda gösterilen her şey kaydedilir. Bu nedenle şifre, ödeme ayrıntıları, mesaj, fotoğraf, ses ve video gibi öğeler konusunda dikkatli olun."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Bir uygulamayı kaydettiğinizde o uygulamada gösterilen veya oynatılan her şey kaydedilir. Bu nedenle şifre, ödeme ayrıntıları, mesaj, fotoğraf, ses ve video gibi öğeler konusunda dikkatli olun."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ekranı kaydet"</string>
<string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Kaydedilecek uygulamayı seçin"</string>
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Kilit ekranı widget\'ları"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Widget kullanarak bir uygulamayı açmak için kimliğinizi doğrulamanız gerekir. Ayrıca, tabletiniz kilitliyken bile widget\'ların herkes tarafından görüntülenebileceğini unutmayın. Bazı widget\'lar kilit ekranınız için tasarlanmamış olabileceğinden buraya eklenmeleri güvenli olmayabilir."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Anladım"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Kullanıcı değiştirme"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"açılır menü"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bu oturumdaki tüm uygulamalar ve veriler silinecek."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Görüşme bildirimlerinin üstünde ve kilit ekranında profil resmi olarak gösterilir, baloncuk olarak görünür, Rahatsız Etmeyin\'i kesintiye uğratır"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Öncelikli"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>, sohbet özelliklerini desteklemiyor"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Bu bildirimler değiştirilemez."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Arama bildirimleri değiştirilemez."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Bu bildirim grubu burada yapılandırılamaz"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Daha yüksek çözünürlük için telefonu çevirin"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Katlanabilir cihaz açılıyor"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Katlanabilir cihaz döndürülüyor"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Ön ekran açıldı"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"katlanmış"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"katlanmamış"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Erişilebilirlik"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klavye kısayolları"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Klavye kısayollarını özelleştirin"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Kısayol atamak için tuşa basın"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Arama kısayolları"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Arama sonucu yok"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Daralt simgesi"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Sürükleme tutamacı"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Klavye Ayarları"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Kısayol ayarla"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"İptal"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Tuşa basın"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Tuş kombinasyonu zaten kullanılıyor. Başka bir tuş deneyin."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Klavyenizi kullanarak gezinin"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Klavye kısayollarını öğrenin"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Dokunmatik alanınızı kullanarak gezinin"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 4c4c80ea31a3..17d2081bc6f2 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Віджети для заблокованого екрана"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Щоб відкрити додаток за допомогою віджета, вам потрібно буде підтвердити особу. Пам’ятайте також, що бачити віджети можуть усі, навіть коли планшет заблоковано. Можливо, деякі віджети не призначені для заблокованого екрана, і додавати їх на нього може бути небезпечно."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Змінити користувача"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"спадне меню"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Усі додатки й дані з цього сеансу буде видалено."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"З’являється вгорі сповіщень про розмови і як зображення профілю на заблокованому екрані, відображається як спливаючий чат, перериває режим \"Не турбувати\""</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Пріоритет"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не підтримує функції розмов"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Ці сповіщення не можна змінити."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Сповіщення про виклик не можна змінити."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Цю групу сповіщень не можна налаштувати тут"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Для вищої роздільної здатності переверніть телефон"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Розкладний пристрій у розкладеному стані"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Розкладний пристрій обертається"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Передній екран увімкнено"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"складений"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"розкладений"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Доступність"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Комбінації клавіш"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Налаштуйте комбінації клавіш"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Натисніть клавішу, щоб призначити комбінацію клавіш"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Комбінації клавіш для пошуку"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Нічого не знайдено"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Значок згортання"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Маркер переміщення"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Налаштування клавіатури"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Налаштувати комбінацію клавіш"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Скасувати"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Натисніть клавішу"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Комбінація клавіш уже використовується. Спробуйте іншу клавішу."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Навігація за допомогою клавіатури"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Дізнайтеся більше про комбінації клавіш"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Навігація за допомогою сенсорної панелі"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 109f43eb5632..f9d41416acc6 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"مقفل اسکرین کے ویجیٹس"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ویجیٹ کے ذریعے ایپ کھولنے کے لیے آپ کو تصدیق کرنی ہوگی کہ یہ آپ ہی ہیں۔ نیز، ذہن میں رکھیں کہ کوئی بھی انہیں دیکھ سکتا ہے، یہاں تک کہ جب آپ کا ٹیبلیٹ مقفل ہو۔ ہو سکتا ہے کچھ ویجٹس آپ کی لاک اسکرین کے لیے نہ بنائے گئے ہوں اور یہاں شامل کرنا غیر محفوظ ہو سکتا ہے۔"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"سمجھ آ گئی"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"صارف سوئچ کریں"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"پل ڈاؤن مینیو"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"اس سیشن میں موجود سبھی ایپس اور ڈیٹا کو حذف کر دیا جائے گا۔"</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"یہ گفتگو کی اطلاعات کے اوپری حصّے پر اور مقفل اسکرین پر پروفائل کی تصویر کے بطور دکھائی دیتا ہے، بلبلے کے بطور ظاہر ہوتا ہے، \'ڈسٹرب نہ کریں\' میں مداخلت کرتا ہے"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"ترجیح"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ایپ گفتگو کی خصوصیات کو سپورٹ نہیں کرتی ہے"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"ان اطلاعات کی ترمیم نہیں کی جا سکتی۔"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"کال کی اطلاعات میں ترمیم نہیں کی جا سکتی۔"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"اطلاعات کے اس گروپ کو یہاں کنفیگر نہیں کیا جا سکتا"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"زیادہ ریزولوشن کے لیے، فون پلٹائیں"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"فولڈ ہونے والے آلے کو کھولا جا رہا ہے"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"فولڈ ہونے والے آلے کو گھمایا جا رہا ہے"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"فرنٹ اسکرین آن ہے"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"فولڈ کردہ"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"اَن فولڈ کردہ"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ایکسیسبیلٹی"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"کی بورڈ شارٹ کٹس"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"کی بورڈ شارٹ کٹس کو حسب ضرورت بنائیں"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"شارٹ کٹ تفویض کرنے کے لیے کلید کو دبائیں"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"تلاش کے شارٹ کٹس"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"تلاش کا کوئی نتیجہ نہیں ہے"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"آئیکن سکیڑیں"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"گھسیٹنے کا ہینڈل"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"کی بورڈ کی ترتیبات"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"شارٹ کٹ سیٹ کریں"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"منسوخ کریں"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"کلید کو دبائیں"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"کلیدی مجموعہ پہلے سے استعمال میں ہے۔ دوسری کلید آزمائیں۔"</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"اپنے کی بورڈ کا استعمال کر کے نیویگیٹ کریں"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"کی بورڈ شارٹ کٹس جانیں"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"اپنے ٹچ پیڈ کا استعمال کر کے نیویگیٹ کریں"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 1c27a0055cce..4f97000b7b1c 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Ekran qulfi vidjetlari"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Ilovani vidjet orqali ochish uchun shaxsingizni tasdiqlashingiz kerak. Shuningdek, planshet qulflanganda ham bu axborotlar hammaga koʻrinishini unutmang. Ayrim vidjetlar ekran qulfiga moslanmagan va ularni bu yerda chiqarish xavfli boʻlishi mumkin."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Foydalanuvchini almashtirish"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"tortib tushiriladigan menyu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ushbu seansdagi barcha ilovalar va ma’lumotlar o‘chirib tashlanadi."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Suhbat bildirishnomalari tepasida va ekran qulfida profil rasmi sifatida chiqariladi, bulutcha sifatida chiqadi, Bezovta qilinmasin rejimini bekor qiladi"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Muhim"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasida suhbat funksiyalari ishlamaydi"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Bu bildirishnomalarni tahrirlash imkonsiz."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Chaqiruv bildirishnomalarini tahrirlash imkonsiz."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Ushbu bildirishnomalar guruhi bu yerda sozlanmaydi"</string>
@@ -1220,8 +1226,7 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Kiritiladigan belgilar <xliff:g id="LENGTH">%1$d</xliff:g> tadan oshmasin"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Nashr raqami"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Nashr raqami vaqtinchalik xotiraga nusxalandi."</string>
- <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
- <skip />
+ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"vaqtincha xotiraga nusxalash"</string>
<string name="basic_status" msgid="2315371112182658176">"Suhbatni ochish"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Suhbat vidjetlari"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Bosh ekranga chiqariladigan suhbat ustiga bosing"</string>
@@ -1357,8 +1362,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Yuqori aniqlik uchun telefonni aylantiring"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Buklanadigan qurilma ochilmoqda"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Buklanadigan qurilma aylantirilmoqda"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Old ekran yoqildi"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"buklangan"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"buklanmagan"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1422,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Qulayliklar"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tezkor tugmalar"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tezkor tugmalarni moslash"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Tezkor tugma sozlash uchun tugmani bosing"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Tezkor tugmalar qidiruvi"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Hech narsa topilmadi"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Yigʻish belgisi"</string>
@@ -1431,9 +1440,15 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Surish dastagi"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Klaviatura sozlamalari"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Tezkor tugma sozlash"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Bekor qilish"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Tugmani bosing"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Bu tugmalar birikmasi band. Boshqasini ishlating."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Klaviatura yordamida kezing"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Tezkor tugmalar haqida"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Sensorli panel yordamida kezing"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index d8e3bc0c1ffd..417f49415b9c 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Tiện ích trên màn hình khoá"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Để dùng tiện ích mở một ứng dụng, bạn cần xác minh danh tính của mình. Ngoài ra, hãy lưu ý rằng bất kỳ ai cũng có thể xem các tiện ích này, ngay cả khi máy tính bảng của bạn được khoá. Một số tiện ích có thể không dành cho màn hình khoá và không an toàn khi thêm vào đây."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Tôi hiểu"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Chuyển đổi người dùng"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"trình đơn kéo xuống"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tất cả ứng dụng và dữ liệu trong phiên này sẽ bị xóa."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Hiện ở đầu phần thông báo cuộc trò chuyện và ở dạng ảnh hồ sơ trên màn hình khóa, xuất hiện ở dạng bong bóng, làm gián đoạn chế độ Không làm phiền"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Mức độ ưu tiên"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> không hỗ trợ các tính năng trò chuyện"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Không thể sửa đổi các thông báo này."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Không thể sửa đổi các thông báo cuộc gọi."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Không thể định cấu hình nhóm thông báo này tại đây"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Để có độ phân giải cao hơn, hãy lật điện thoại"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Thiết bị có thể gập lại đang được mở ra"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Thiết bị có thể gập lại đang được lật ngược"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Đã bật màn hình trước"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"gập"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"mở"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Hỗ trợ tiếp cận"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Phím tắt"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tuỳ chỉnh phím tắt"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Nhấn phím để chỉ định phím tắt"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Tìm lối tắt"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Không có kết quả tìm kiếm nào"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Biểu tượng Thu gọn"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Nút kéo"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Cài đặt bàn phím"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Đặt phím tắt"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Huỷ"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Nhấn phím"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Tổ hợp phím đã được sử dụng. Hãy thử một phím khác."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Di chuyển bằng bàn phím"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Tìm hiểu về phím tắt"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Di chuyển bằng bàn di chuột"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index d9a974aad94a..3b72bd50f867 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -113,7 +113,7 @@
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"录制单个应用"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"录制整个屏幕"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"全屏录制:%s"</string>
- <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"录制整个屏幕时,屏幕上显示的所有内容均会被录制。因此,请务必小心操作,谨防泄露密码、付款信息、消息、照片、音频、视频等。"</string>
+ <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"录制整个屏幕时,屏幕上显示的所有内容均会被录制。因此,请务必小心操作,谨防泄露密码、付款详情、消息、照片、音频、视频等敏感信息。"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"录制单个应用时,该应用中显示或播放的所有内容均会被录制。因此,请务必小心操作,谨防泄露密码、付款信息、消息、照片、音频、视频等。"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"录制屏幕"</string>
<string name="screenrecord_app_selector_title" msgid="3854492366333954736">"选择要录制的应用"</string>
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"锁屏微件"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"若要使用微件打开应用,您需要验证是您本人在操作。另外请注意,任何人都可以查看此类微件,即使您的平板电脑已锁定。有些微件可能不适合显示在锁定的屏幕中,因此添加到这里可能不安全。"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"知道了"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切换用户"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"下拉菜单"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"此会话中的所有应用和数据都将被删除。"</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"以气泡形式显示在对话通知顶部(屏幕锁定时显示为个人资料照片),并且会中断勿扰模式"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"优先"</string>
<string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>不支持对话功能"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"无法修改这些通知。"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"无法修改来电通知。"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"您无法在此处配置这组通知"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"若要获得更高的分辨率,请翻转手机"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展开可折叠设备"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻转可折叠设备"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"前屏已开启"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"折叠状态"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"展开状态"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"无障碍功能"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"键盘快捷键"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"自定义键盘快捷键"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"按下按键即可指定快捷键"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"搜索快捷键"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"无搜索结果"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"收起图标"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"拖动手柄"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"键盘设置"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"设置快捷键"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"取消"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"按下按键"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"按键组合已被使用,请尝试使用其他按键。"</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"使用键盘导航"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"了解键盘快捷键"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"使用触控板导航"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 443b8556fe18..aca9e685847e 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"上鎖畫面小工具"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"如要使用小工具開啟應用程式,系統會要求你驗證身分。請注意,所有人都能查看小工具,即使平板電腦已鎖定亦然。部分小工具可能不適用於上鎖畫面,新增至這裡可能會有安全疑慮。"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"知道了"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切換使用者"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"下拉式選單"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會被刪除。"</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"以對話氣泡形式顯示在對話通知頂部 (在上鎖畫面會顯示為個人檔案相片),並會中斷「請勿打擾」模式"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"優先"</string>
<string name="no_shortcut" msgid="8257177117568230126">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」不支援對話功能"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"無法修改這些通知。"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"無法修改通話通知。"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"無法在此設定這組通知"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"如要提高解像度,請切換至手機後置鏡頭"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展開折疊式裝置"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻轉折疊式裝置"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"正面螢幕已開啟"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"已摺疊"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"已打開"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"無障礙功能"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"鍵盤快速鍵"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"自訂鍵盤快速鍵"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"按鍵即可指派快速鍵"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"搜尋快速鍵"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"沒有相符的搜尋結果"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"收合圖示"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"拖曳控點"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"鍵盤設定"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"設定快速鍵"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"取消"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"按鍵"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"此按鍵組合已在使用,請改用其他按鍵。"</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"使用鍵盤導覽"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"瞭解鍵盤快速鍵"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"使用觸控板導覽"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 4b84f25fca1b..506ed573949b 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"螢幕鎖定小工具"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"如要使用小工具開啟應用程式,需先驗證身分。請留意,即使平板電腦已鎖定,所有人都還是能查看小工具。某些小工具可能不適用於螢幕鎖定畫面,新增到此可能會有安全疑慮。"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"我知道了"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切換使用者"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"下拉式選單"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會刪除。"</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"以對話框的形式顯示在對話通知頂端 (螢幕鎖定時會顯示為個人資料相片),並會中斷「零打擾」模式"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"優先"</string>
<string name="no_shortcut" msgid="8257177117568230126">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」不支援對話功能"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"無法修改這些通知。"</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"無法修改來電通知。"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"無法在這裡設定這個通知群組"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"如要提高解析度,請切換至手機後置鏡頭"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展開的折疊式裝置"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻轉折疊式裝置"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"正面螢幕已開啟"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"已摺疊"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"已展開"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"無障礙"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"鍵盤快速鍵"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"自訂鍵盤快速鍵"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"按下按鍵即可指派快速鍵"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"搜尋快速鍵"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"找不到相符的搜尋結果"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"收合圖示"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"拖曳控點"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"鍵盤設定"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"設定快速鍵"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"取消"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"按下按鍵"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"這個按鍵組合已在使用中,請改用其他按鍵。"</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"使用鍵盤操作"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"學習鍵盤快速鍵"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"使用觸控板操作"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 4afb67d2af8f..1a17fcc4a35d 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -528,6 +528,10 @@
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Amawijethi wesikrini esikhiyiwe"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Ukuze uvule i-app usebenzisa iwijethi, uzodinga ukuqinisekisa ukuthi nguwe. Futhi, khumbula ukuthi noma ubani angakwazi ukuzibuka, nanoma ithebhulethi yakho ikhiyiwe. Amanye amawijethi kungenzeka abengahloselwe ukukhiya isikrini sakho futhi kungenzeka awaphephile ukuthi angafakwa lapha."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ngiyezwa"</string>
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_label (1461611028615752141) -->
+ <skip />
+ <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (511359420883794513) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Shintsha umsebenzisi"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"imenyu yokudonsela phansi"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Wonke ama-app nedatha kulesi sikhathi azosuswa."</string>
@@ -780,6 +784,8 @@
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Ivela phezu kwezaziso zengxoxo futhi njengesithombe sephrofayela esikrinini sokukhiya, ivela njengebhamuza, ukuphazamisa okuthi Ungaphazamisi"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Okubalulekile"</string>
<string name="no_shortcut" msgid="8257177117568230126">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayisekeli izici zengxoxo"</string>
+ <!-- no translation found for notification_guts_bundle_feedback (5393570876655201459) -->
+ <skip />
<string name="notification_unblockable_desc" msgid="2073030886006190804">"Lezi zaziso azikwazi ukushintshwa."</string>
<string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Izaziso zekholi azikwazi ukushintshwa."</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"Leli qembu lezaziso alikwazi ukulungiselelwa lapha"</string>
@@ -1357,8 +1363,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Ukuze uthole ukulungiswa okuphezulu, phendula ifoni"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Idivayisi egoqekayo iyembulwa"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Idivayisi egoqekayo iphendulwa nxazonke"</string>
- <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
- <skip />
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Isikrini sangaphambili sivuliwe"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"kugoqiwe"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"kuvuliwe"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1418,7 +1423,12 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ukufinyeleleka"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Izinqamuleli zekhibhodi"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Hlela izinqamuleli zekhibhodi ngendlela oyifisayo"</string>
- <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Cindezela ukhiye ukuze unikeze isinqamuleli"</string>
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_dialog_title (7106420484940737208) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_add_shortcut_description (6866025005347407696) -->
+ <skip />
+ <!-- no translation found for shortcut_customize_mode_remove_shortcut_description (6851287900585057128) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Sesha izinqamuleli"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ayikho imiphumela yosesho"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Goqa isithonjana"</string>
@@ -1431,9 +1441,16 @@
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Hudula isibambi"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Amasethingi Ekhibhodi"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Setha isinqamuleli"</string>
+ <!-- no translation found for shortcut_helper_customize_dialog_remove_button_label (6546386970440176552) -->
+ <skip />
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Khansela"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Cindezela ukhiye"</string>
- <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Inhlanganisela yokhiye isiyasetshenziswa kakade. Zama omunye ukhiye."</string>
+ <!-- no translation found for shortcut_customizer_key_combination_in_use_error_message (7693234470526626327) -->
+ <skip />
+ <!-- no translation found for shortcut_customizer_generic_error_message (3128454624049722741) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_plus_symbol (4534843157353732011) -->
+ <skip />
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Funa usebenzisa ikhibhodi yakho"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Funda izinqamuleli zamakhibhodi"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Funa usebenzisa iphedi yokuthinta"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 411f36b73802..478050b0ed85 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -236,6 +236,9 @@
<!-- The size of a bluetooth indicator icon that displays next to the RSSI status icon. -->
<dimen name="status_bar_connected_device_bt_indicator_size">17dp</dimen>
+ <!-- Height of a small notification in the status bar (2025 redesign version) -->
+ <dimen name="notification_2025_min_height">@*android:dimen/notification_2025_min_height</dimen>
+
<!-- Height of a small notification in the status bar-->
<dimen name="notification_min_height">@*android:dimen/notification_min_height</dimen>
@@ -1995,12 +1998,16 @@
<dimen name="backlight_indicator_step_large_radius">28dp</dimen>
<!-- Touchpad gestures tutorial-->
- <!-- This value is in unit of dp/ms
+ <!-- This value is in dp/ms.
TriggerSwipeUpTouchTracker (which is base for gesture tutorial implementation) uses value
of 0.5dp but from manual testing it's too high and doesn't really feel like it's forcing
slowing down. Also for tutorial it should be fine to lean to the side of being more strict
rather than not strict enough and not teaching user the proper gesture as a result.-->
<dimen name="touchpad_recent_apps_gesture_velocity_threshold">0.05dp</dimen>
+ <!-- This value is in dp/ms.
+ As above, it's not tied to system-wide value (defined in launcher's
+ quickstep_fling_threshold_speed) because for tutorial it's fine to be more strict. -->
+ <dimen name="touchpad_home_gesture_velocity_threshold">0.5dp</dimen>
<!-- Normal gesture threshold is system_gestures_distance_threshold but for tutorial we can
exaggerate gesture, which also works much better with live tracking -->
<dimen name="touchpad_tutorial_gestures_distance_threshold">48dp</dimen>
@@ -2086,7 +2093,7 @@
<dimen name="volume_dialog_floating_sliders_vertical_padding">10dp</dimen>
<dimen name="volume_dialog_floating_sliders_vertical_padding_negative">-10dp</dimen>
<dimen name="volume_dialog_floating_sliders_horizontal_padding">4dp</dimen>
- <dimen name="volume_dialog_button_size">48dp</dimen>
+ <dimen name="volume_dialog_button_size">40dp</dimen>
<dimen name="volume_dialog_slider_width">52dp</dimen>
<dimen name="volume_dialog_slider_height">254dp</dimen>
@@ -2094,7 +2101,7 @@
<dimen name="volume_dialog_background_square_corner_radius">12dp</dimen>
- <dimen name="volume_dialog_ringer_drawer_button_size">40dp</dimen>
+ <dimen name="volume_dialog_ringer_drawer_button_size">@dimen/volume_dialog_button_size</dimen>
<dimen name="volume_dialog_ringer_drawer_button_icon_radius">10dp</dimen>
<dimen name="volume_dialog_ringer_selected_button_background_radius">20dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 731c4ef463fd..4bf67a12963a 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2287,6 +2287,14 @@
<string name="system_multitasking_replace">During split screen: replace an app from one to another</string>
<!-- User visible title for the keyboard shortcut that moves a focused task to a next display [CHAR LIMIT=70] -->
<string name="system_multitasking_move_to_next_display">Move active window between displays</string>
+ <!-- User visible title for the keyboard shortcut that snaps a task to the left in desktop mode [CHAR LIMIT=70] -->
+ <string name="system_desktop_mode_snap_left_window">Move window to the left</string>
+ <!-- User visible title for the keyboard shortcut that snaps a task to the right in desktop mode [CHAR LIMIT=70] -->
+ <string name="system_desktop_mode_snap_right_window">Move window to the right</string>
+ <!-- User visible title for the keyboard shortcut that toggles between maximizing and restoring a task's previous bounds in desktop mode [CHAR LIMIT=70] -->
+ <string name="system_desktop_mode_toggle_maximize_window">Maximize window</string>
+ <!-- User visible title for the keyboard shortcut that minimizes a task in desktop mode [CHAR LIMIT=70] -->
+ <string name="system_desktop_mode_minimize_window">Minimize window</string>
<!-- User visible title for the input keyboard shortcuts list. [CHAR LIMIT=70] -->
<string name="keyboard_shortcut_group_input">Input</string>
@@ -3816,6 +3824,14 @@
[CHAR LIMIT=NONE]
-->
<string name="shortcut_helper_key_combinations_or_separator">or</string>
+ <!-- Word that combines different possible key combinations of a shortcut. For example the
+ "Go to home screen" shortcut could be triggered using "ctrl" plus "h".
+ This is only used for accessibility content descriptions of the key combinations.
+ [CHAR LIMIT=NONE] -->
+ <string name="shortcut_helper_key_combinations_and_conjunction">plus</string>
+ <!-- Word that represents the forward slash character "/". To be used only in accessibility
+ content descriptions. [CHAR LIMIT=NONE] -->
+ <string name="shortcut_helper_key_combinations_forward_slash">forward slash</string>
<!-- Content description of the drag handle that allows to swipe to dismiss the shortcut helper.
The helper is a component that shows the user which keyboard shortcuts they can
use. The helper shows shortcuts in categories, which can be collapsed or expanded.
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 0381811e29ed..9aa71374fb8e 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -1084,11 +1084,6 @@
<!-- Setting a placeholder will avoid using the SystemUI icon on the splash screen -->
<item name="android:windowSplashScreenAnimatedIcon">@drawable/ic_blank</item>
<item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item>
-
- <!--
- TODO(b/309578419): Make the activity handle insets properly and then remove this.
- -->
- <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
</style>
<style name="Widget.SliceView.VolumePanel">
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java
index 9513c8e4d8be..5a9cbce73e4b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java
@@ -174,9 +174,20 @@ public interface KeyguardViewController {
/**
* Stop showing the alternate bouncer, if showing.
+ *
+ * <p>Should be like calling {@link #hideAlternateBouncer(boolean, boolean)} with a {@code true}
+ * {@code clearDismissAction} parameter.
*/
void hideAlternateBouncer(boolean updateScrim);
+ /**
+ * Stop showing the alternate bouncer, if showing.
+ *
+ * @param updateScrim Whether to update the scrim
+ * @param clearDismissAction Whether the pending dismiss action should be cleared
+ */
+ void hideAlternateBouncer(boolean updateScrim, boolean clearDismissAction);
+
// TODO: Deprecate registerStatusBar in KeyguardViewController interface. It is currently
// only used for testing purposes in StatusBarKeyguardViewManager, and it prevents us from
// achieving complete abstraction away from where the Keyguard View is mounted.
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index 3794e7bf6b55..08d3e17c03d7 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -833,9 +833,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
}
// Set the surface of the SurfaceView to black to avoid users seeing the contents below the
// magnifier when the mirrored surface has an alpha less than 1.
- if (Flags.addBlackBackgroundForWindowMagnifier()) {
- mTransaction.setColor(mMirrorSurfaceView.getSurfaceControl(), COLOR_BLACK_ARRAY);
- }
+ mTransaction.setColor(mMirrorSurfaceView.getSurfaceControl(), COLOR_BLACK_ARRAY);
mTransaction.show(mMirrorSurface)
.reparent(mMirrorSurface, mMirrorSurfaceView.getSurfaceControl());
modifyWindowMagnification(false);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index b491c94db151..f6b6655dca4d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -64,6 +64,7 @@ import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.biometrics.AuthController.ScaleFactorProvider;
import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor;
+import com.android.systemui.biometrics.plugins.AuthContextPlugins;
import com.android.systemui.biometrics.shared.model.BiometricModalities;
import com.android.systemui.biometrics.shared.model.PromptKind;
import com.android.systemui.biometrics.ui.CredentialView;
@@ -132,6 +133,7 @@ public class AuthContainerView extends LinearLayout
private final int mEffectiveUserId;
private final IBinder mWindowToken = new Binder();
private final ViewCaptureAwareWindowManager mWindowManager;
+ @Nullable private final AuthContextPlugins mAuthContextPlugins;
private final Interpolator mLinearOutSlowIn;
private final LockPatternUtils mLockPatternUtils;
private final WakefulnessLifecycle mWakefulnessLifecycle;
@@ -289,6 +291,7 @@ public class AuthContainerView extends LinearLayout
@Nullable List<FaceSensorPropertiesInternal> faceProps,
@NonNull WakefulnessLifecycle wakefulnessLifecycle,
@NonNull UserManager userManager,
+ @Nullable AuthContextPlugins authContextPlugins,
@NonNull LockPatternUtils lockPatternUtils,
@NonNull InteractionJankMonitor jankMonitor,
@NonNull Provider<PromptSelectorInteractor> promptSelectorInteractorProvider,
@@ -306,6 +309,7 @@ public class AuthContainerView extends LinearLayout
WindowManager wm = getContext().getSystemService(WindowManager.class);
mWindowManager = new ViewCaptureAwareWindowManager(wm, lazyViewCapture,
enableViewCaptureTracing());
+ mAuthContextPlugins = authContextPlugins;
mWakefulnessLifecycle = wakefulnessLifecycle;
mApplicationCoroutineScope = applicationCoroutineScope;
@@ -446,7 +450,7 @@ public class AuthContainerView extends LinearLayout
final CredentialViewModel vm = mCredentialViewModelProvider.get();
vm.setAnimateContents(animateContents);
((CredentialView) mCredentialView).init(vm, this, mPanelController, animatePanel,
- mBiometricCallback);
+ mBiometricCallback, mAuthContextPlugins);
mLayout.addView(mCredentialView);
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index a5bd559dcbf2..4faf6ff9f596 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -21,6 +21,7 @@ import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRIN
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_REAR;
import static android.view.Display.INVALID_DISPLAY;
+import static com.android.systemui.Flags.contAuthPlugin;
import static com.android.systemui.util.ConvenienceExtensionsKt.toKotlinLazy;
import android.annotation.NonNull;
@@ -74,6 +75,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.CoreStartable;
import com.android.systemui.biometrics.domain.interactor.LogContextInteractor;
import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor;
+import com.android.systemui.biometrics.plugins.AuthContextPlugins;
import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams;
import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel;
import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel;
@@ -108,6 +110,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.Set;
import javax.inject.Inject;
@@ -139,6 +142,7 @@ public class AuthController implements
private final ActivityTaskManager mActivityTaskManager;
@Nullable private final FingerprintManager mFingerprintManager;
@Nullable private final FaceManager mFaceManager;
+ @Nullable private final AuthContextPlugins mContextPlugins;
private final Provider<UdfpsController> mUdfpsControllerFactory;
private final CoroutineScope mApplicationCoroutineScope;
private Job mBiometricContextListenerJob = null;
@@ -717,6 +721,7 @@ public class AuthController implements
@NonNull WindowManager windowManager,
@Nullable FingerprintManager fingerprintManager,
@Nullable FaceManager faceManager,
+ Optional<AuthContextPlugins> contextPlugins,
Provider<UdfpsController> udfpsControllerFactory,
@NonNull DisplayManager displayManager,
@NonNull WakefulnessLifecycle wakefulnessLifecycle,
@@ -744,6 +749,7 @@ public class AuthController implements
mActivityTaskManager = activityTaskManager;
mFingerprintManager = fingerprintManager;
mFaceManager = faceManager;
+ mContextPlugins = contAuthPlugin() ? contextPlugins.orElse(null) : null;
mUdfpsControllerFactory = udfpsControllerFactory;
mUdfpsLogger = udfpsLogger;
mDisplayManager = displayManager;
@@ -858,6 +864,10 @@ public class AuthController implements
mActivityTaskManager.registerTaskStackListener(mTaskStackListener);
mOrientationListener.enable();
updateSensorLocations();
+
+ if (mContextPlugins != null) {
+ mContextPlugins.activate();
+ }
}
@Override
@@ -1350,7 +1360,7 @@ public class AuthController implements
config.mSensorIds = sensorIds;
config.mScaleProvider = this::getScaleFactor;
return new AuthContainerView(config, mApplicationCoroutineScope, mFpProps, mFaceProps,
- wakefulnessLifecycle, userManager, lockPatternUtils,
+ wakefulnessLifecycle, userManager, mContextPlugins, lockPatternUtils,
mInteractionJankMonitor, mPromptSelectorInteractor, viewModel,
mCredentialViewModelProvider, bgExecutor, mVibratorHelper,
mLazyViewCapture, mMSDLPlayer);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 2863e29c9a34..a9133e45e93f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -814,6 +814,11 @@ public class UdfpsController implements DozeReceiver, Dumpable {
private void showUdfpsOverlay(@NonNull UdfpsControllerOverlay overlay) {
mExecution.assertIsMainThread();
+ if (mOverlay != null) {
+ Log.d(TAG, "showUdfpsOverlay | the overlay is already showing");
+ return;
+ }
+
mOverlay = overlay;
final int requestReason = overlay.getRequestReason();
if (requestReason == REASON_AUTH_KEYGUARD
@@ -823,7 +828,7 @@ public class UdfpsController implements DozeReceiver, Dumpable {
return;
}
if (overlay.show(this, mOverlayParams)) {
- Log.v(TAG, "showUdfpsOverlay | adding window reason=" + requestReason);
+ Log.d(TAG, "showUdfpsOverlay | adding window reason=" + requestReason);
mOnFingerDown = false;
mAttemptedToDismissKeyguard = false;
mOrientationListener.enable();
@@ -832,7 +837,7 @@ public class UdfpsController implements DozeReceiver, Dumpable {
overlay.getRequestId(), mSensorProps.sensorId);
}
} else {
- Log.v(TAG, "showUdfpsOverlay | the overlay is already showing");
+ Log.d(TAG, "showUdfpsOverlay | the overlay is already showing");
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
index 2593cebb14d0..51eb13947d40 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
@@ -41,6 +41,7 @@ import android.view.WindowManager
import android.view.accessibility.AccessibilityManager
import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener
import androidx.annotation.VisibleForTesting
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.app.viewcapture.ViewCaptureAwareWindowManager
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.animation.ActivityTransitionAnimator
@@ -73,7 +74,6 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
-import com.android.app.tracing.coroutines.launchTraced as launch
private const val TAG = "UdfpsControllerOverlay"
@@ -245,7 +245,7 @@ constructor(
return true
}
- Log.v(TAG, "showUdfpsOverlay | the overlay is already showing")
+ Log.d(TAG, "showUdfpsOverlay | the overlay is already showing")
return false
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt b/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt
index e2a8a691b1fd..60ce17721b42 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt
@@ -36,6 +36,7 @@ import com.android.systemui.biometrics.data.repository.FingerprintPropertyReposi
import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepositoryImpl
import com.android.systemui.biometrics.data.repository.PromptRepository
import com.android.systemui.biometrics.data.repository.PromptRepositoryImpl
+import com.android.systemui.biometrics.plugins.AuthContextPlugins
import com.android.systemui.biometrics.udfps.BoundingBoxOverlapDetector
import com.android.systemui.biometrics.udfps.EllipseOverlapDetector
import com.android.systemui.biometrics.udfps.OverlapDetector
@@ -58,7 +59,7 @@ import javax.inject.Qualifier
/** Dagger module for all things biometric. */
@Module
interface BiometricsModule {
- /** Starts AuthController. */
+ /** Starts AuthController. */
@Binds
@IntoMap
@ClassKey(AuthController::class)
@@ -103,8 +104,9 @@ interface BiometricsModule {
@SysUISingleton
fun displayStateRepository(impl: DisplayStateRepositoryImpl): DisplayStateRepository
- @BindsOptionalOf
- fun deviceEntryUnlockTrackerViewBinder(): DeviceEntryUnlockTrackerViewBinder
+ @BindsOptionalOf fun authContextPlugins(): AuthContextPlugins
+
+ @BindsOptionalOf fun deviceEntryUnlockTrackerViewBinder(): DeviceEntryUnlockTrackerViewBinder
companion object {
/** Background [Executor] for HAL related operations. */
@@ -117,8 +119,7 @@ interface BiometricsModule {
@Provides fun providesUdfpsUtils(): UdfpsUtils = UdfpsUtils()
- @Provides
- fun provideIconProvider(context: Context): IconProvider = IconProvider(context)
+ @Provides fun provideIconProvider(context: Context): IconProvider = IconProvider(context)
@Provides
@SysUISingleton
@@ -136,7 +137,7 @@ interface BiometricsModule {
EllipseOverlapDetectorParams(
minOverlap = values[3],
targetSize = values[2],
- stepSize = values[4].toInt()
+ stepSize = values[4].toInt(),
)
)
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/plugins/AuthContextPlugins.kt b/packages/SystemUI/src/com/android/systemui/biometrics/plugins/AuthContextPlugins.kt
new file mode 100644
index 000000000000..ca38e9869ed1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/plugins/AuthContextPlugins.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.plugins
+
+import com.android.systemui.plugins.AuthContextPlugin
+import com.android.systemui.plugins.PluginManager
+
+/** Wrapper interface for registering & forwarding events to all available [AuthContextPlugin]s. */
+interface AuthContextPlugins {
+ /** Finds and actives all plugins via SysUI's [PluginManager] (should be called at startup). */
+ fun activate()
+
+ /**
+ * Interact with all registered plugins.
+ *
+ * The provided [block] will be repeated for each available plugin.
+ */
+ suspend fun use(block: (AuthContextPlugin) -> Unit)
+
+ /**
+ * Like [use] but when no existing coroutine context is available.
+ *
+ * The [block] will be run on SysUI's general background context and can, optionally, be
+ * confined to [runOnMain] (defaults to a background thread).
+ */
+ fun useInBackground(runOnMain: Boolean = false, block: (AuthContextPlugin) -> Unit)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt
index b28733f5cc55..dad140f00cee 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt
@@ -11,6 +11,7 @@ import android.view.accessibility.AccessibilityManager
import android.widget.LinearLayout
import android.widget.TextView
import com.android.systemui.biometrics.AuthPanelController
+import com.android.systemui.biometrics.plugins.AuthContextPlugins
import com.android.systemui.biometrics.ui.binder.CredentialViewBinder
import com.android.systemui.biometrics.ui.binder.Spaghetti
import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel
@@ -33,6 +34,7 @@ class CredentialPasswordView(context: Context, attrs: AttributeSet?) :
panelViewController: AuthPanelController,
animatePanel: Boolean,
legacyCallback: Spaghetti.Callback,
+ plugins: AuthContextPlugins?,
) {
CredentialViewBinder.bind(
this,
@@ -40,7 +42,8 @@ class CredentialPasswordView(context: Context, attrs: AttributeSet?) :
viewModel,
panelViewController,
animatePanel,
- legacyCallback
+ legacyCallback,
+ plugins,
)
}
@@ -78,7 +81,7 @@ class CredentialPasswordView(context: Context, attrs: AttributeSet?) :
0,
statusBarInsets.top,
0,
- if (keyboardInsets.bottom == 0) navigationInsets.bottom else keyboardInsets.bottom
+ if (keyboardInsets.bottom == 0) navigationInsets.bottom else keyboardInsets.bottom,
)
return WindowInsets.CONSUMED
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPatternView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPatternView.kt
index d9d286fe7035..e80a79ba1641 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPatternView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPatternView.kt
@@ -8,6 +8,7 @@ import android.view.WindowInsets
import android.view.WindowInsets.Type
import android.widget.LinearLayout
import com.android.systemui.biometrics.AuthPanelController
+import com.android.systemui.biometrics.plugins.AuthContextPlugins
import com.android.systemui.biometrics.ui.binder.CredentialViewBinder
import com.android.systemui.biometrics.ui.binder.Spaghetti
import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel
@@ -23,6 +24,7 @@ class CredentialPatternView(context: Context, attrs: AttributeSet?) :
panelViewController: AuthPanelController,
animatePanel: Boolean,
legacyCallback: Spaghetti.Callback,
+ plugins: AuthContextPlugins?,
) {
CredentialViewBinder.bind(
this,
@@ -30,7 +32,8 @@ class CredentialPatternView(context: Context, attrs: AttributeSet?) :
viewModel,
panelViewController,
animatePanel,
- legacyCallback
+ legacyCallback,
+ plugins,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialView.kt
index e2f98958ab55..f3e49175538f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialView.kt
@@ -1,6 +1,7 @@
package com.android.systemui.biometrics.ui
import com.android.systemui.biometrics.AuthPanelController
+import com.android.systemui.biometrics.plugins.AuthContextPlugins
import com.android.systemui.biometrics.ui.binder.Spaghetti
import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel
@@ -29,5 +30,6 @@ sealed interface CredentialView {
panelViewController: AuthPanelController,
animatePanel: Boolean,
legacyCallback: Spaghetti.Callback,
+ plugins: AuthContextPlugins?,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialViewBinder.kt
index 39543e78f784..10b12117a3a9 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialViewBinder.kt
@@ -9,18 +9,21 @@ import android.widget.TextView
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.app.animation.Interpolators
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.biometrics.AuthPanelController
+import com.android.systemui.biometrics.plugins.AuthContextPlugins
import com.android.systemui.biometrics.ui.CredentialPasswordView
import com.android.systemui.biometrics.ui.CredentialPatternView
import com.android.systemui.biometrics.ui.CredentialView
import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.plugins.AuthContextPlugin
import com.android.systemui.res.R
import kotlinx.coroutines.Job
+import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.onEach
-import com.android.app.tracing.coroutines.launchTraced as launch
private const val ANIMATE_CREDENTIAL_INITIAL_DURATION_MS = 150
@@ -42,6 +45,7 @@ object CredentialViewBinder {
panelViewController: AuthPanelController,
animatePanel: Boolean,
legacyCallback: Spaghetti.Callback,
+ plugins: AuthContextPlugins?,
maxErrorDuration: Long = 3_000L,
requestFocusForInput: Boolean = true,
) {
@@ -72,6 +76,10 @@ object CredentialViewBinder {
}
repeatOnLifecycle(Lifecycle.State.STARTED) {
+ if (plugins != null) {
+ launch { plugins.notifyShowingBPCredential(view) }
+ }
+
// show prompt metadata
launch {
viewModel.header.collect { header ->
@@ -136,6 +144,12 @@ object CredentialViewBinder {
host.onCredentialAttemptsRemaining(info.remaining!!, info.message)
}
}
+
+ try {
+ awaitCancellation()
+ } catch (_: Throwable) {
+ plugins?.notifyHidingBPCredential()
+ }
}
}
@@ -172,3 +186,15 @@ private var TextView.textOrHide: String?
text = if (gone) "" else value
}
get() = text?.toString()
+
+private suspend fun AuthContextPlugins.notifyShowingBPCredential(view: View) = use { plugin ->
+ plugin.onShowingSensitiveSurface(
+ AuthContextPlugin.SensitiveSurface.BiometricPrompt(view = view, isCredential = true)
+ )
+}
+
+private fun AuthContextPlugins.notifyHidingBPCredential() = useInBackground { plugin ->
+ plugin.onHidingSensitiveSurface(
+ AuthContextPlugin.SensitiveSurface.BiometricPrompt(isCredential = true)
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt
index 12f06bbd4f5e..8a4cc63f65fb 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt
@@ -3,6 +3,8 @@ package com.android.systemui.bouncer.ui.binder
import android.view.ViewGroup
import com.android.keyguard.KeyguardMessageAreaController
import com.android.keyguard.dagger.KeyguardBouncerComponent
+import com.android.systemui.Flags.contAuthPlugin
+import com.android.systemui.biometrics.plugins.AuthContextPlugins
import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlags
@@ -17,6 +19,7 @@ import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransition
import com.android.systemui.log.BouncerLogger
import com.android.systemui.user.domain.interactor.SelectedUserInteractor
import dagger.Lazy
+import java.util.Optional
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -60,6 +63,7 @@ class BouncerViewBinder
constructor(
private val legacyBouncerDependencies: Lazy<LegacyBouncerDependencies>,
private val composeBouncerDependencies: Lazy<ComposeBouncerDependencies>,
+ private val contextPlugins: Optional<AuthContextPlugins>,
) {
fun bind(view: ViewGroup) {
if (ComposeBouncerFlags.isOnlyComposeBouncerEnabled()) {
@@ -85,6 +89,7 @@ constructor(
deps.bouncerMessageInteractor,
deps.bouncerLogger,
deps.selectedUserInteractor,
+ if (contAuthPlugin()) contextPlugins.orElse(null) else null,
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/KeyguardBouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/KeyguardBouncerViewBinder.kt
index 71eda0c19e6f..434a9ce58c3b 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/KeyguardBouncerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/KeyguardBouncerViewBinder.kt
@@ -22,11 +22,13 @@ import android.view.ViewGroup
import android.window.OnBackAnimationCallback
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.keyguard.KeyguardMessageAreaController
import com.android.keyguard.KeyguardSecurityContainerController
import com.android.keyguard.KeyguardSecurityModel
import com.android.keyguard.KeyguardSecurityView
import com.android.keyguard.dagger.KeyguardBouncerComponent
+import com.android.systemui.biometrics.plugins.AuthContextPlugins
import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor
import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.EXPANSION_VISIBLE
import com.android.systemui.bouncer.ui.BouncerViewDelegate
@@ -35,10 +37,10 @@ import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransition
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.log.BouncerLogger
import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.AuthContextPlugin
import com.android.systemui.user.domain.interactor.SelectedUserInteractor
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.flow.filter
-import com.android.app.tracing.coroutines.launchTraced as launch
/** Binds the bouncer container to its view model. */
object KeyguardBouncerViewBinder {
@@ -52,6 +54,7 @@ object KeyguardBouncerViewBinder {
bouncerMessageInteractor: BouncerMessageInteractor,
bouncerLogger: BouncerLogger,
selectedUserInteractor: SelectedUserInteractor,
+ plugins: AuthContextPlugins?,
) {
// Builds the KeyguardSecurityContainerController from bouncer view group.
val securityContainerController: KeyguardSecurityContainerController =
@@ -94,7 +97,7 @@ object KeyguardBouncerViewBinder {
override fun setDismissAction(
onDismissAction: ActivityStarter.OnDismissAction?,
- cancelAction: Runnable?
+ cancelAction: Runnable?,
) {
securityContainerController.setOnDismissAction(onDismissAction, cancelAction)
}
@@ -138,7 +141,7 @@ object KeyguardBouncerViewBinder {
it.bindMessageView(
bouncerMessageInteractor,
messageAreaControllerFactory,
- bouncerLogger
+ bouncerLogger,
)
}
} else {
@@ -149,6 +152,13 @@ object KeyguardBouncerViewBinder {
securityContainerController.reset()
securityContainerController.onPause()
}
+ plugins?.apply {
+ if (isShowing) {
+ notifyBouncerShowing(view)
+ } else {
+ notifyBouncerGone()
+ }
+ }
}
}
@@ -209,7 +219,7 @@ object KeyguardBouncerViewBinder {
securityContainerController.showMessage(
it.message,
it.colorStateList,
- /* animated= */ true
+ /* animated= */ true,
)
viewModel.onMessageShown()
}
@@ -233,8 +243,19 @@ object KeyguardBouncerViewBinder {
awaitCancellation()
} finally {
viewModel.setBouncerViewDelegate(null)
+ plugins?.notifyBouncerGone()
}
}
}
}
}
+
+private suspend fun AuthContextPlugins.notifyBouncerShowing(view: View) = use { plugin ->
+ plugin.onShowingSensitiveSurface(
+ AuthContextPlugin.SensitiveSurface.LockscreenBouncer(view = view)
+ )
+}
+
+private fun AuthContextPlugins.notifyBouncerGone() = useInBackground { plugin ->
+ plugin.onHidingSensitiveSurface(AuthContextPlugin.SensitiveSurface.LockscreenBouncer())
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModel.kt
index 47d913746ed7..5deb751ced27 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModel.kt
@@ -23,6 +23,7 @@ import android.graphics.Bitmap
import androidx.compose.ui.input.key.KeyEvent
import androidx.compose.ui.input.key.type
import androidx.core.graphics.drawable.toBitmap
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.app.tracing.coroutines.traceCoroutine
import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
@@ -35,6 +36,7 @@ import com.android.systemui.bouncer.ui.helper.BouncerHapticPlayer
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.shared.model.Text
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.keyguard.domain.interactor.KeyguardDismissActionInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardMediaKeyInteractor
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.user.ui.viewmodel.UserSwitcherViewModel
@@ -48,7 +50,6 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
-import com.android.app.tracing.coroutines.launchTraced as launch
/** Models UI state for the content of the bouncer scene. */
class BouncerSceneContentViewModel
@@ -67,6 +68,7 @@ constructor(
private val bouncerHapticPlayer: BouncerHapticPlayer,
private val keyguardMediaKeyInteractor: KeyguardMediaKeyInteractor,
private val bouncerActionButtonInteractor: BouncerActionButtonInteractor,
+ private val keyguardDismissActionInteractor: KeyguardDismissActionInteractor,
) : ExclusiveActivatable() {
private val _selectedUserImage = MutableStateFlow<Bitmap?>(null)
val selectedUserImage: StateFlow<Bitmap?> = _selectedUserImage.asStateFlow()
@@ -421,6 +423,13 @@ constructor(
}
}
+ /**
+ * Notifies that the bouncer UI has been destroyed (e.g. the composable left the composition).
+ */
+ fun onUiDestroyed() {
+ keyguardDismissActionInteractor.clearDismissAction()
+ }
+
data class DialogViewModel(
val text: String,
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 5bad9fc9c5d7..6f2a2c4ccaaa 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
@@ -33,6 +33,7 @@ import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
+import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
@@ -105,11 +106,11 @@ private fun BrightnessSlider(
null
}
- val overriddenByAppState =
+ val overriddenByAppState by
if (Flags.showToastWhenAppControlBrightness()) {
- viewModel.brightnessOverriddenByWindow.collectAsStateWithLifecycle().value
+ viewModel.brightnessOverriddenByWindow.collectAsStateWithLifecycle()
} else {
- false
+ remember { mutableStateOf(false) }
}
PlatformSlider(
diff --git a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.kt b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.kt
index 44dd34a89303..8ddd1ed04f33 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.kt
@@ -34,6 +34,7 @@ import com.android.systemui.communal.shared.log.CommunalStatsLogProxyImpl
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.communal.shared.model.GlanceableHubMultiUserHelper
import com.android.systemui.communal.shared.model.GlanceableHubMultiUserHelperImpl
+import com.android.systemui.communal.ui.compose.sceneTransitions
import com.android.systemui.communal.util.CommunalColors
import com.android.systemui.communal.util.CommunalColorsImpl
import com.android.systemui.communal.widgets.CommunalWidgetModule
@@ -113,6 +114,7 @@ interface CommunalModule {
SceneContainerConfig(
sceneKeys = listOf(CommunalScenes.Blank, CommunalScenes.Communal),
initialSceneKey = CommunalScenes.Blank,
+ transitions = sceneTransitions,
navigationDistances =
mapOf(CommunalScenes.Blank to 0, CommunalScenes.Communal to 1),
)
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt
index 7b54815ab344..26abb48ce7db 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt
@@ -20,9 +20,11 @@ import android.app.admin.DevicePolicyManager
import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL
import android.content.IntentFilter
import android.content.pm.UserInfo
+import android.content.res.Resources
import android.os.UserHandle
import android.provider.Settings
import com.android.systemui.Flags.communalHub
+import com.android.systemui.Flags.glanceableHubV2
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.communal.data.model.CommunalEnabledState
import com.android.systemui.communal.data.model.DisabledReason
@@ -33,6 +35,7 @@ import com.android.systemui.communal.data.model.DisabledReason.DISABLED_REASON_U
import com.android.systemui.communal.shared.model.CommunalBackgroundType
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.flags.FeatureFlagsClassic
import com.android.systemui.flags.Flags
import com.android.systemui.util.kotlin.emitOnStart
@@ -53,13 +56,30 @@ interface CommunalSettingsRepository {
fun getEnabledState(user: UserInfo): Flow<CommunalEnabledState>
/**
- * Returns true if both the communal trunk-stable flag and resource flag are enabled.
+ * Returns true if any glanceable hub functionality should be enabled via configs and flags.
*
- * The trunk-stable flag is controlled by server rollout and is on all devices. The resource
- * flag is enabled via resource overlay only on products we want the hub to be present on.
+ * This should be used for preventing basic glanceable hub functionality from running on devices
+ * that don't need it.
+ *
+ * If the glanceable_hub_v2 flag is enabled, checks the config_glanceableHubEnabled Android
+ * config boolean. Otherwise, checks the old config_communalServiceEnabled config and
+ * communal_hub flag.
*/
fun getFlagEnabled(): Boolean
+ /**
+ * Returns true if the Android config config_glanceableHubEnabled and the glanceable_hub_v2 flag
+ * are enabled.
+ *
+ * This should be used to flag off new glanceable hub or dream behavior that should launch
+ * together with the new hub experience that brings the hub to mobile.
+ *
+ * The trunk-stable flag is controlled by server rollout and is on all devices. The Android
+ * config flag is enabled via resource overlay only on products we want the hub to be present
+ * on.
+ */
+ fun getV2FlagEnabled(): Boolean
+
/** Keyguard widgets enabled state by Device Policy Manager for the specified user. */
fun getAllowedByDevicePolicy(user: UserInfo): Flow<Boolean>
@@ -72,6 +92,7 @@ class CommunalSettingsRepositoryImpl
@Inject
constructor(
@Background private val bgDispatcher: CoroutineDispatcher,
+ @Main private val resources: Resources,
private val featureFlagsClassic: FeatureFlagsClassic,
private val secureSettings: SecureSettings,
private val broadcastDispatcher: BroadcastDispatcher,
@@ -79,7 +100,18 @@ constructor(
) : CommunalSettingsRepository {
override fun getFlagEnabled(): Boolean {
- return featureFlagsClassic.isEnabled(Flags.COMMUNAL_SERVICE_ENABLED) && communalHub()
+ return if (getV2FlagEnabled()) {
+ true
+ } else {
+ // This config (exposed as a classic feature flag) is targeted only to tablet.
+ // TODO(b/379181581): clean up usages of communal_hub flag
+ featureFlagsClassic.isEnabled(Flags.COMMUNAL_SERVICE_ENABLED) && communalHub()
+ }
+ }
+
+ override fun getV2FlagEnabled(): Boolean {
+ return resources.getBoolean(com.android.internal.R.bool.config_glanceableHubEnabled) &&
+ glanceableHubV2()
}
override fun getEnabledState(user: UserInfo): Flow<CommunalEnabledState> {
@@ -128,7 +160,7 @@ constructor(
secureSettings.getIntForUser(
GLANCEABLE_HUB_BACKGROUND_SETTING,
CommunalBackgroundType.ANIMATED.value,
- user.id
+ user.id,
)
CommunalBackgroundType.entries.find { type -> type.value == intType }
?: CommunalBackgroundType.ANIMATED
diff --git a/packages/SystemUI/src/com/android/systemui/communal/util/WidgetViewFactory.kt b/packages/SystemUI/src/com/android/systemui/communal/util/WidgetViewFactory.kt
index cc6007b400f7..50d86a24be96 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/util/WidgetViewFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/util/WidgetViewFactory.kt
@@ -20,6 +20,7 @@ import android.content.Context
import android.os.Bundle
import android.util.SizeF
import com.android.app.tracing.coroutines.withContextTraced as withContext
+import com.android.systemui.Flags
import com.android.systemui.communal.domain.model.CommunalContentModel
import com.android.systemui.communal.shared.model.GlanceableHubMultiUserHelper
import com.android.systemui.communal.widgets.AppWidgetHostListenerDelegate
@@ -30,6 +31,9 @@ import com.android.systemui.communal.widgets.WidgetInteractionHandler
import com.android.systemui.dagger.qualifiers.UiBackground
import dagger.Lazy
import java.util.concurrent.Executor
+import java.util.concurrent.LinkedBlockingQueue
+import java.util.concurrent.ThreadPoolExecutor
+import java.util.concurrent.TimeUnit
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
@@ -53,7 +57,11 @@ constructor(
withContext("$TAG#createWidget", uiBgContext) {
val view =
CommunalAppWidgetHostView(context, interactionHandler).apply {
- setExecutor(uiBgExecutor)
+ if (Flags.communalHubUseThreadPoolForWidgets()) {
+ setExecutor(widgetExecutor)
+ } else {
+ setExecutor(uiBgExecutor)
+ }
setAppWidget(model.appWidgetId, model.providerInfo)
}
@@ -90,5 +98,20 @@ constructor(
private companion object {
const val TAG = "WidgetViewFactory"
+
+ val poolSize = Runtime.getRuntime().availableProcessors().coerceAtLeast(2)
+
+ /**
+ * This executor is used for widget inflation. Parameters match what launcher uses. See
+ * [com.android.launcher3.util.Executors.THREAD_POOL_EXECUTOR].
+ */
+ val widgetExecutor =
+ ThreadPoolExecutor(
+ /*corePoolSize*/ poolSize,
+ /*maxPoolSize*/ poolSize,
+ /*keepAlive*/ 1,
+ /*unit*/ TimeUnit.SECONDS,
+ /*workQueue*/ LinkedBlockingQueue(),
+ )
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
index 41edb4a1ffaf..740e011b3d20 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
@@ -16,6 +16,7 @@
package com.android.systemui.controls.management
+import android.app.Activity
import android.app.ActivityOptions
import android.content.ComponentName
import android.content.Context
@@ -34,25 +35,25 @@ import androidx.activity.ComponentActivity
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
-import com.android.systemui.res.R
import com.android.systemui.controls.CustomIconCache
import com.android.systemui.controls.controller.ControlsControllerImpl
import com.android.systemui.controls.controller.StructureInfo
import com.android.systemui.controls.ui.ControlsActivity
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.res.R
import com.android.systemui.settings.UserTracker
import java.util.concurrent.Executor
import javax.inject.Inject
-/**
- * Activity for rearranging and removing controls for a given structure
- */
-open class ControlsEditingActivity @Inject constructor(
+/** Activity for rearranging and removing controls for a given structure */
+open class ControlsEditingActivity
+@Inject
+constructor(
@Main private val mainExecutor: Executor,
private val controller: ControlsControllerImpl,
private val userTracker: UserTracker,
private val customIconCache: CustomIconCache,
-) : ComponentActivity() {
+) : ComponentActivity(), ControlsManagementActivity {
companion object {
private const val DEBUG = false
@@ -64,6 +65,9 @@ open class ControlsEditingActivity @Inject constructor(
private val EMPTY_TEXT_ID = R.string.controls_favorite_removed
}
+ override val activity: Activity
+ get() = this
+
private lateinit var component: ComponentName
private lateinit var structure: CharSequence
private lateinit var model: FavoritesModel
@@ -73,16 +77,17 @@ open class ControlsEditingActivity @Inject constructor(
private var isFromFavoriting: Boolean = false
- private val userTrackerCallback: UserTracker.Callback = object : UserTracker.Callback {
- private val startingUser = controller.currentUserId
+ private val userTrackerCallback: UserTracker.Callback =
+ object : UserTracker.Callback {
+ private val startingUser = controller.currentUserId
- override fun onUserChanged(newUser: Int, userContext: Context) {
- if (newUser != startingUser) {
- userTracker.removeCallback(this)
- finish()
+ override fun onUserChanged(newUser: Int, userContext: Context) {
+ if (newUser != startingUser) {
+ userTracker.removeCallback(this)
+ finish()
+ }
}
}
- }
private val mOnBackInvokedCallback = OnBackInvokedCallback {
if (DEBUG) {
@@ -98,9 +103,7 @@ open class ControlsEditingActivity @Inject constructor(
component = it
} ?: run(this::finish)
isFromFavoriting = intent.getBooleanExtra(EXTRA_FROM_FAVORITING, false)
- intent.getCharSequenceExtra(EXTRA_STRUCTURE)?.let {
- structure = it
- } ?: run(this::finish)
+ intent.getCharSequenceExtra(EXTRA_STRUCTURE)?.let { structure = it } ?: run(this::finish)
bindViews()
@@ -117,7 +120,9 @@ open class ControlsEditingActivity @Inject constructor(
Log.d(TAG, "Registered onBackInvokedCallback")
}
onBackInvokedDispatcher.registerOnBackInvokedCallback(
- OnBackInvokedDispatcher.PRIORITY_DEFAULT, mOnBackInvokedCallback)
+ OnBackInvokedDispatcher.PRIORITY_DEFAULT,
+ mOnBackInvokedCallback,
+ )
}
override fun onStop() {
@@ -142,18 +147,21 @@ open class ControlsEditingActivity @Inject constructor(
override fun run() {
finish()
}
- }
- ).start()
+ },
+ )
+ .start()
}
private fun bindViews() {
setContentView(R.layout.controls_management)
+ applyInsets(R.id.controls_management_root)
+
lifecycle.addObserver(
ControlsAnimations.observerForAnimations(
requireViewById<ViewGroup>(R.id.controls_management_root),
window,
- intent
+ intent,
)
)
@@ -163,81 +171,86 @@ open class ControlsEditingActivity @Inject constructor(
}
requireViewById<TextView>(R.id.title).text = structure
setTitle(structure)
- subtitle = requireViewById<TextView>(R.id.subtitle).apply {
- setText(SUBTITLE_ID)
- }
+ subtitle = requireViewById<TextView>(R.id.subtitle).apply { setText(SUBTITLE_ID) }
}
private fun bindButtons() {
- addControls = requireViewById<Button>(R.id.addControls).apply {
- isEnabled = true
- visibility = View.VISIBLE
- setOnClickListener {
- if (saveButton.isEnabled) {
- // The user has made changes
- Toast.makeText(
- applicationContext,
- R.string.controls_favorite_toast_no_changes,
- Toast.LENGTH_SHORT
- ).show()
- }
- if (isFromFavoriting) {
- animateExitAndFinish()
- } else {
- startActivity(Intent(context, ControlsFavoritingActivity::class.java).also {
- it.putExtra(ControlsFavoritingActivity.EXTRA_STRUCTURE, structure)
- it.putExtra(Intent.EXTRA_COMPONENT_NAME, component)
- it.putExtra(
- ControlsFavoritingActivity.EXTRA_APP,
- intent.getCharSequenceExtra(EXTRA_APP),
- )
- it.putExtra(
- ControlsFavoritingActivity.EXTRA_SOURCE,
- ControlsFavoritingActivity.EXTRA_SOURCE_VALUE_FROM_EDITING,
+ addControls =
+ requireViewById<Button>(R.id.addControls).apply {
+ isEnabled = true
+ visibility = View.VISIBLE
+ setOnClickListener {
+ if (saveButton.isEnabled) {
+ // The user has made changes
+ Toast.makeText(
+ applicationContext,
+ R.string.controls_favorite_toast_no_changes,
+ Toast.LENGTH_SHORT,
+ )
+ .show()
+ }
+ if (isFromFavoriting) {
+ animateExitAndFinish()
+ } else {
+ startActivity(
+ Intent(context, ControlsFavoritingActivity::class.java).also {
+ it.putExtra(ControlsFavoritingActivity.EXTRA_STRUCTURE, structure)
+ it.putExtra(Intent.EXTRA_COMPONENT_NAME, component)
+ it.putExtra(
+ ControlsFavoritingActivity.EXTRA_APP,
+ intent.getCharSequenceExtra(EXTRA_APP),
+ )
+ it.putExtra(
+ ControlsFavoritingActivity.EXTRA_SOURCE,
+ ControlsFavoritingActivity.EXTRA_SOURCE_VALUE_FROM_EDITING,
+ )
+ },
+ ActivityOptions.makeSceneTransitionAnimation(
+ this@ControlsEditingActivity
+ )
+ .toBundle(),
)
- },
- ActivityOptions.makeSceneTransitionAnimation(
- this@ControlsEditingActivity
- ).toBundle(),
- )
+ }
}
}
- }
- saveButton = requireViewById<Button>(R.id.done).apply {
- isEnabled = isFromFavoriting
- setText(R.string.save)
- setOnClickListener {
- saveFavorites()
- startActivity(
- Intent(applicationContext, ControlsActivity::class.java),
- ActivityOptions
- .makeSceneTransitionAnimation(this@ControlsEditingActivity).toBundle()
- )
- animateExitAndFinish()
+ saveButton =
+ requireViewById<Button>(R.id.done).apply {
+ isEnabled = isFromFavoriting
+ setText(R.string.save)
+ setOnClickListener {
+ saveFavorites()
+ startActivity(
+ Intent(applicationContext, ControlsActivity::class.java),
+ ActivityOptions.makeSceneTransitionAnimation(this@ControlsEditingActivity)
+ .toBundle(),
+ )
+ animateExitAndFinish()
+ }
}
- }
}
private fun saveFavorites() {
controller.replaceFavoritesForStructure(
- StructureInfo(component, structure, model.favorites))
+ StructureInfo(component, structure, model.favorites)
+ )
}
- private val favoritesModelCallback = object : FavoritesModel.FavoritesModelCallback {
- override fun onNoneChanged(showNoFavorites: Boolean) {
- if (showNoFavorites) {
- subtitle.setText(EMPTY_TEXT_ID)
- } else {
- subtitle.setText(SUBTITLE_ID)
+ private val favoritesModelCallback =
+ object : FavoritesModel.FavoritesModelCallback {
+ override fun onNoneChanged(showNoFavorites: Boolean) {
+ if (showNoFavorites) {
+ subtitle.setText(EMPTY_TEXT_ID)
+ } else {
+ subtitle.setText(SUBTITLE_ID)
+ }
}
- }
- override fun onChange() = Unit
+ override fun onChange() = Unit
- override fun onFirstChange() {
- saveButton.isEnabled = true
+ override fun onFirstChange() {
+ saveButton.isEnabled = true
+ }
}
- }
private fun setUpList() {
val controls = controller.getFavoritesForStructure(component, structure)
@@ -245,44 +258,55 @@ open class ControlsEditingActivity @Inject constructor(
val elevation = resources.getFloat(R.dimen.control_card_elevation)
val recyclerView = requireViewById<RecyclerView>(R.id.list)
recyclerView.alpha = 0.0f
- val adapter = ControlAdapter(elevation, userTracker.userId).apply {
- registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
- var hasAnimated = false
- override fun onChanged() {
- if (!hasAnimated) {
- hasAnimated = true
- ControlsAnimations.enterAnimation(recyclerView).start()
+ val adapter =
+ ControlAdapter(elevation, userTracker.userId).apply {
+ registerAdapterDataObserver(
+ object : RecyclerView.AdapterDataObserver() {
+ var hasAnimated = false
+
+ override fun onChanged() {
+ if (!hasAnimated) {
+ hasAnimated = true
+ ControlsAnimations.enterAnimation(recyclerView).start()
+ }
+ }
}
- }
- })
- }
+ )
+ }
- val margin = resources
- .getDimensionPixelSize(R.dimen.controls_card_margin)
+ val margin = resources.getDimensionPixelSize(R.dimen.controls_card_margin)
val itemDecorator = MarginItemDecorator(margin, margin)
val spanCount = ControlAdapter.findMaxColumns(resources)
recyclerView.apply {
this.adapter = adapter
- layoutManager = object : GridLayoutManager(recyclerView.context, spanCount) {
-
- // This will remove from the announcement the row corresponding to the divider,
- // as it's not something that should be announced.
- override fun getRowCountForAccessibility(
- recycler: RecyclerView.Recycler,
- state: RecyclerView.State
- ): Int {
- val initial = super.getRowCountForAccessibility(recycler, state)
- return if (initial > 0) initial - 1 else initial
- }
- }.apply {
- spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
- override fun getSpanSize(position: Int): Int {
- return if (adapter?.getItemViewType(position)
- != ControlAdapter.TYPE_CONTROL) spanCount else 1
+ layoutManager =
+ object : GridLayoutManager(recyclerView.context, spanCount) {
+
+ // This will remove from the announcement the row corresponding to the
+ // divider,
+ // as it's not something that should be announced.
+ override fun getRowCountForAccessibility(
+ recycler: RecyclerView.Recycler,
+ state: RecyclerView.State,
+ ): Int {
+ val initial = super.getRowCountForAccessibility(recycler, state)
+ return if (initial > 0) initial - 1 else initial
+ }
+ }
+ .apply {
+ spanSizeLookup =
+ object : GridLayoutManager.SpanSizeLookup() {
+ override fun getSpanSize(position: Int): Int {
+ return if (
+ adapter?.getItemViewType(position) !=
+ ControlAdapter.TYPE_CONTROL
+ )
+ spanCount
+ else 1
+ }
+ }
}
- }
- }
addItemDecoration(itemDecorator)
}
adapter.changeModel(model)
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
index 2ea4303e2290..ab55c5326b55 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
@@ -18,6 +18,7 @@ package com.android.systemui.controls.management
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
+import android.app.Activity
import android.app.ActivityOptions
import android.content.ComponentName
import android.content.Context
@@ -39,22 +40,24 @@ import androidx.activity.ComponentActivity
import androidx.annotation.VisibleForTesting
import androidx.viewpager2.widget.ViewPager2
import com.android.systemui.Prefs
-import com.android.systemui.res.R
import com.android.systemui.controls.TooltipManager
import com.android.systemui.controls.controller.ControlsControllerImpl
import com.android.systemui.controls.controller.StructureInfo
import com.android.systemui.controls.ui.ControlsActivity
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.res.R
import com.android.systemui.settings.UserTracker
import java.text.Collator
import java.util.concurrent.Executor
import javax.inject.Inject
-open class ControlsFavoritingActivity @Inject constructor(
+open class ControlsFavoritingActivity
+@Inject
+constructor(
@Main private val executor: Executor,
private val controller: ControlsControllerImpl,
private val userTracker: UserTracker,
-) : ComponentActivity() {
+) : ComponentActivity(), ControlsManagementActivity {
companion object {
private const val DEBUG = false
@@ -74,6 +77,9 @@ open class ControlsFavoritingActivity @Inject constructor(
private const val TOOLTIP_MAX_SHOWN = 2
}
+ override val activity: Activity
+ get() = this
+
private var component: ComponentName? = null
private var appName: CharSequence? = null
private var structureExtra: CharSequence? = null
@@ -95,18 +101,21 @@ open class ControlsFavoritingActivity @Inject constructor(
private val fromProviderSelector: Boolean
get() = openSource == EXTRA_SOURCE_VALUE_FROM_PROVIDER_SELECTOR
+
private val fromEditing: Boolean
get() = openSource == EXTRA_SOURCE_VALUE_FROM_EDITING
- private val userTrackerCallback: UserTracker.Callback = object : UserTracker.Callback {
- private val startingUser = controller.currentUserId
- override fun onUserChanged(newUser: Int, userContext: Context) {
- if (newUser != startingUser) {
- userTracker.removeCallback(this)
- finish()
+ private val userTrackerCallback: UserTracker.Callback =
+ object : UserTracker.Callback {
+ private val startingUser = controller.currentUserId
+
+ override fun onUserChanged(newUser: Int, userContext: Context) {
+ if (newUser != startingUser) {
+ userTracker.removeCallback(this)
+ finish()
+ }
}
}
- }
private val mOnBackInvokedCallback = OnBackInvokedCallback {
if (DEBUG) {
@@ -138,81 +147,113 @@ open class ControlsFavoritingActivity @Inject constructor(
bindViews()
}
- private val controlsModelCallback = object : ControlsModel.ControlsModelCallback {
- override fun onFirstChange() {
- doneButton.isEnabled = true
- }
+ private val controlsModelCallback =
+ object : ControlsModel.ControlsModelCallback {
+ override fun onFirstChange() {
+ doneButton.isEnabled = true
+ }
- override fun onChange() {
- val structure: StructureContainer = listOfStructures[structurePager.currentItem]
- rearrangeButton.isEnabled = structure.model.favorites.isNotEmpty()
+ override fun onChange() {
+ val structure: StructureContainer = listOfStructures[structurePager.currentItem]
+ rearrangeButton.isEnabled = structure.model.favorites.isNotEmpty()
+ }
}
- }
private fun loadControls() {
component?.let { componentName ->
statusText.text = resources.getText(com.android.internal.R.string.loading)
- val emptyZoneString = resources.getText(
- R.string.controls_favorite_other_zone_header)
- controller.loadForComponent(componentName, { data ->
- val allControls = data.allControls
- val favoriteKeys = data.favoritesIds
- val error = data.errorOnLoad
- val controlsByStructure = allControls.groupBy { it.control.structure ?: "" }
- listOfStructures = controlsByStructure.map {
- StructureContainer(it.key, AllModel(
- it.value, favoriteKeys, emptyZoneString, controlsModelCallback))
- }.sortedWith(comparator)
-
- val structureIndex = listOfStructures.indexOfFirst {
- sc -> sc.structureName == structureExtra
- }.let { if (it == -1) 0 else it }
-
- // If we were requested to show a single structure, set the list to just that one
- if (intent.getBooleanExtra(EXTRA_SINGLE_STRUCTURE, false)) {
- listOfStructures = listOf(listOfStructures[structureIndex])
- }
+ val emptyZoneString = resources.getText(R.string.controls_favorite_other_zone_header)
+ controller.loadForComponent(
+ componentName,
+ { data ->
+ val allControls = data.allControls
+ val favoriteKeys = data.favoritesIds
+ val error = data.errorOnLoad
+ val controlsByStructure = allControls.groupBy { it.control.structure ?: "" }
+ listOfStructures =
+ controlsByStructure
+ .map {
+ StructureContainer(
+ it.key,
+ AllModel(
+ it.value,
+ favoriteKeys,
+ emptyZoneString,
+ controlsModelCallback,
+ ),
+ )
+ }
+ .sortedWith(comparator)
+
+ val structureIndex =
+ listOfStructures
+ .indexOfFirst { sc -> sc.structureName == structureExtra }
+ .let { if (it == -1) 0 else it }
+
+ // If we were requested to show a single structure, set the list to just that
+ // one
+ if (intent.getBooleanExtra(EXTRA_SINGLE_STRUCTURE, false)) {
+ listOfStructures = listOf(listOfStructures[structureIndex])
+ }
- executor.execute {
- structurePager.adapter = StructureAdapter(listOfStructures, userTracker.userId)
- structurePager.setCurrentItem(structureIndex)
- if (error) {
- statusText.text = resources.getString(R.string.controls_favorite_load_error,
- appName ?: "")
- subtitleView.visibility = View.GONE
- } else if (listOfStructures.isEmpty()) {
- statusText.text = resources.getString(R.string.controls_favorite_load_none)
- subtitleView.visibility = View.GONE
- } else {
- statusText.visibility = View.GONE
-
- pageIndicator.setNumPages(listOfStructures.size)
- pageIndicator.setLocation(0f)
- pageIndicator.visibility =
- if (listOfStructures.size > 1) View.VISIBLE else View.INVISIBLE
-
- ControlsAnimations.enterAnimation(pageIndicator).apply {
- addListener(object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator) {
- // Position the tooltip if necessary after animations are complete
- // so we can get the position on screen. The tooltip is not
- // rooted in the layout root.
- if (pageIndicator.visibility == View.VISIBLE &&
- mTooltipManager != null) {
- val p = IntArray(2)
- pageIndicator.getLocationOnScreen(p)
- val x = p[0] + pageIndicator.width / 2
- val y = p[1] + pageIndicator.height
- mTooltipManager?.show(
- R.string.controls_structure_tooltip, x, y)
- }
+ executor.execute {
+ structurePager.adapter =
+ StructureAdapter(listOfStructures, userTracker.userId)
+ structurePager.setCurrentItem(structureIndex)
+ if (error) {
+ statusText.text =
+ resources.getString(
+ R.string.controls_favorite_load_error,
+ appName ?: "",
+ )
+ subtitleView.visibility = View.GONE
+ } else if (listOfStructures.isEmpty()) {
+ statusText.text =
+ resources.getString(R.string.controls_favorite_load_none)
+ subtitleView.visibility = View.GONE
+ } else {
+ statusText.visibility = View.GONE
+
+ pageIndicator.setNumPages(listOfStructures.size)
+ pageIndicator.setLocation(0f)
+ pageIndicator.visibility =
+ if (listOfStructures.size > 1) View.VISIBLE else View.INVISIBLE
+
+ ControlsAnimations.enterAnimation(pageIndicator)
+ .apply {
+ addListener(
+ object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator) {
+ // Position the tooltip if necessary after
+ // animations are complete
+ // so we can get the position on screen. The tooltip
+ // is not
+ // rooted in the layout root.
+ if (
+ pageIndicator.visibility == View.VISIBLE &&
+ mTooltipManager != null
+ ) {
+ val p = IntArray(2)
+ pageIndicator.getLocationOnScreen(p)
+ val x = p[0] + pageIndicator.width / 2
+ val y = p[1] + pageIndicator.height
+ mTooltipManager?.show(
+ R.string.controls_structure_tooltip,
+ x,
+ y,
+ )
+ }
+ }
+ }
+ )
}
- })
- }.start()
- ControlsAnimations.enterAnimation(structurePager).start()
+ .start()
+ ControlsAnimations.enterAnimation(structurePager).start()
+ }
}
- }
- }, { runnable -> cancelLoadRunnable = runnable })
+ },
+ { runnable -> cancelLoadRunnable = runnable },
+ )
}
}
@@ -221,35 +262,39 @@ open class ControlsFavoritingActivity @Inject constructor(
pageIndicator.alpha = 0.0f
structurePager.apply {
adapter = StructureAdapter(emptyList(), userTracker.userId)
- registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
- override fun onPageSelected(position: Int) {
- super.onPageSelected(position)
- val name = listOfStructures[position].structureName
- val title = if (!TextUtils.isEmpty(name)) name else appName
- titleView.text = title
- titleView.requestFocus()
- }
+ registerOnPageChangeCallback(
+ object : ViewPager2.OnPageChangeCallback() {
+ override fun onPageSelected(position: Int) {
+ super.onPageSelected(position)
+ val name = listOfStructures[position].structureName
+ val title = if (!TextUtils.isEmpty(name)) name else appName
+ titleView.text = title
+ titleView.requestFocus()
+ }
- override fun onPageScrolled(
- position: Int,
- positionOffset: Float,
- positionOffsetPixels: Int
- ) {
- super.onPageScrolled(position, positionOffset, positionOffsetPixels)
- pageIndicator.setLocation(position + positionOffset)
+ override fun onPageScrolled(
+ position: Int,
+ positionOffset: Float,
+ positionOffsetPixels: Int,
+ ) {
+ super.onPageScrolled(position, positionOffset, positionOffsetPixels)
+ pageIndicator.setLocation(position + positionOffset)
+ }
}
- })
+ )
}
}
private fun bindViews() {
setContentView(R.layout.controls_management)
+ applyInsets(R.id.controls_management_root)
+
lifecycle.addObserver(
ControlsAnimations.observerForAnimations(
requireViewById<ViewGroup>(R.id.controls_management_root),
window,
- intent
+ intent,
)
)
@@ -260,41 +305,43 @@ open class ControlsFavoritingActivity @Inject constructor(
statusText = requireViewById(R.id.status_message)
if (shouldShowTooltip()) {
- mTooltipManager = TooltipManager(statusText.context,
- TOOLTIP_PREFS_KEY, TOOLTIP_MAX_SHOWN)
+ mTooltipManager =
+ TooltipManager(statusText.context, TOOLTIP_PREFS_KEY, TOOLTIP_MAX_SHOWN)
addContentView(
mTooltipManager?.layout,
FrameLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
- Gravity.TOP or Gravity.LEFT
- )
+ Gravity.TOP or Gravity.LEFT,
+ ),
)
}
- pageIndicator = requireViewById<ManagementPageIndicator>(
- R.id.structure_page_indicator).apply {
- visibilityListener = {
- if (it != View.VISIBLE) {
- mTooltipManager?.hide(true)
+ pageIndicator =
+ requireViewById<ManagementPageIndicator>(R.id.structure_page_indicator).apply {
+ visibilityListener = {
+ if (it != View.VISIBLE) {
+ mTooltipManager?.hide(true)
+ }
}
}
- }
- val title = structureExtra
- ?: (appName ?: resources.getText(R.string.controls_favorite_default_title))
- titleView = requireViewById<TextView>(R.id.title).apply {
- text = title
- }
- subtitleView = requireViewById<TextView>(R.id.subtitle).apply {
- text = resources.getText(R.string.controls_favorite_subtitle)
- }
+ val title =
+ structureExtra
+ ?: (appName ?: resources.getText(R.string.controls_favorite_default_title))
+ titleView = requireViewById<TextView>(R.id.title).apply { text = title }
+ subtitleView =
+ requireViewById<TextView>(R.id.subtitle).apply {
+ text = resources.getText(R.string.controls_favorite_subtitle)
+ }
structurePager = requireViewById<ViewPager2>(R.id.structure_pager)
- structurePager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
- override fun onPageSelected(position: Int) {
- super.onPageSelected(position)
- mTooltipManager?.hide(true)
+ structurePager.registerOnPageChangeCallback(
+ object : ViewPager2.OnPageChangeCallback() {
+ override fun onPageSelected(position: Int) {
+ super.onPageSelected(position)
+ mTooltipManager?.hide(true)
+ }
}
- })
+ )
bindButtons()
}
@@ -307,47 +354,53 @@ open class ControlsFavoritingActivity @Inject constructor(
override fun run() {
finish()
}
- }
- ).start()
+ },
+ )
+ .start()
}
private fun bindButtons() {
- rearrangeButton = requireViewById<Button>(R.id.rearrange).apply {
- text = if (fromEditing) {
- getString(R.string.controls_favorite_back_to_editing)
- } else {
- getString(R.string.controls_favorite_rearrange_button)
- }
- isEnabled = false
- visibility = View.VISIBLE
- setOnClickListener {
- if (component == null) return@setOnClickListener
- saveFavorites()
- startActivity(
- Intent(context, ControlsEditingActivity::class.java).also {
- it.putExtra(Intent.EXTRA_COMPONENT_NAME, component)
- it.putExtra(ControlsEditingActivity.EXTRA_APP, appName)
- it.putExtra(ControlsEditingActivity.EXTRA_FROM_FAVORITING, true)
- it.putExtra(
- ControlsEditingActivity.EXTRA_STRUCTURE,
- listOfStructures[structurePager.currentItem].structureName,
- )
- },
- ActivityOptions
- .makeSceneTransitionAnimation(this@ControlsFavoritingActivity).toBundle()
- )
+ rearrangeButton =
+ requireViewById<Button>(R.id.rearrange).apply {
+ text =
+ if (fromEditing) {
+ getString(R.string.controls_favorite_back_to_editing)
+ } else {
+ getString(R.string.controls_favorite_rearrange_button)
+ }
+ isEnabled = false
+ visibility = View.VISIBLE
+ setOnClickListener {
+ if (component == null) return@setOnClickListener
+ saveFavorites()
+ startActivity(
+ Intent(context, ControlsEditingActivity::class.java).also {
+ it.putExtra(Intent.EXTRA_COMPONENT_NAME, component)
+ it.putExtra(ControlsEditingActivity.EXTRA_APP, appName)
+ it.putExtra(ControlsEditingActivity.EXTRA_FROM_FAVORITING, true)
+ it.putExtra(
+ ControlsEditingActivity.EXTRA_STRUCTURE,
+ listOfStructures[structurePager.currentItem].structureName,
+ )
+ },
+ ActivityOptions.makeSceneTransitionAnimation(
+ this@ControlsFavoritingActivity
+ )
+ .toBundle(),
+ )
+ }
}
- }
- doneButton = requireViewById<Button>(R.id.done).apply {
- isEnabled = false
- setOnClickListener {
- if (component == null) return@setOnClickListener
- saveFavorites()
- animateExitAndFinish()
- openControlsOrigin()
+ doneButton =
+ requireViewById<Button>(R.id.done).apply {
+ isEnabled = false
+ setOnClickListener {
+ if (component == null) return@setOnClickListener
+ saveFavorites()
+ animateExitAndFinish()
+ openControlsOrigin()
+ }
}
- }
}
private fun saveFavorites() {
@@ -362,14 +415,14 @@ open class ControlsFavoritingActivity @Inject constructor(
private fun openControlsOrigin() {
startActivity(
Intent(applicationContext, ControlsActivity::class.java),
- ActivityOptions.makeSceneTransitionAnimation(this).toBundle()
+ ActivityOptions.makeSceneTransitionAnimation(this).toBundle(),
)
}
override fun onPause() {
super.onPause()
mTooltipManager?.hide(false)
- }
+ }
override fun onStart() {
super.onStart()
@@ -380,7 +433,9 @@ open class ControlsFavoritingActivity @Inject constructor(
Log.d(TAG, "Registered onBackInvokedCallback")
}
onBackInvokedDispatcher.registerOnBackInvokedCallback(
- OnBackInvokedDispatcher.PRIORITY_DEFAULT, mOnBackInvokedCallback)
+ OnBackInvokedDispatcher.PRIORITY_DEFAULT,
+ mOnBackInvokedCallback,
+ )
}
override fun onResume() {
@@ -393,7 +448,7 @@ open class ControlsFavoritingActivity @Inject constructor(
loadControls()
isPagerLoaded = true
}
- }
+ }
override fun onStop() {
super.onStop()
@@ -403,8 +458,7 @@ open class ControlsFavoritingActivity @Inject constructor(
if (DEBUG) {
Log.d(TAG, "Unregistered onBackInvokedCallback")
}
- onBackInvokedDispatcher.unregisterOnBackInvokedCallback(
- mOnBackInvokedCallback)
+ onBackInvokedDispatcher.unregisterOnBackInvokedCallback(mOnBackInvokedCallback)
}
override fun onConfigurationChanged(newConfig: Configuration) {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsManagementActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsManagementActivity.kt
new file mode 100644
index 000000000000..c3b8cff7e4eb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsManagementActivity.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.controls.management
+
+import android.app.Activity
+import android.view.View
+import android.view.ViewGroup
+import android.view.WindowInsets
+import android.view.WindowInsets.Type
+
+interface ControlsManagementActivity {
+ val activity: Activity
+}
+
+fun ControlsManagementActivity.applyInsets(viewId: Int) {
+ activity.requireViewById<ViewGroup>(viewId).apply {
+ setOnApplyWindowInsetsListener { v: View, insets: WindowInsets ->
+ v.apply {
+ val paddings = insets.getInsets(Type.systemBars() or Type.displayCutout())
+ setPadding(paddings.left, paddings.top, paddings.right, paddings.bottom)
+ }
+
+ WindowInsets.CONSUMED
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
index 10a0117f8757..f56cd00baa15 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
@@ -16,6 +16,7 @@
package com.android.systemui.controls.management
+import android.app.Activity
import android.app.ActivityOptions
import android.app.Dialog
import android.content.ComponentName
@@ -35,7 +36,6 @@ import androidx.activity.ComponentActivity
import androidx.annotation.VisibleForTesting
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
-import com.android.systemui.res.R
import com.android.systemui.controls.ControlsServiceInfo
import com.android.systemui.controls.controller.ControlsController
import com.android.systemui.controls.panels.AuthorizedPanelsRepository
@@ -43,40 +43,46 @@ import com.android.systemui.controls.ui.ControlsActivity
import com.android.systemui.controls.ui.SelectedItem
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.res.R
import com.android.systemui.settings.UserTracker
import java.util.concurrent.Executor
import javax.inject.Inject
-/**
- * Activity to select an application to favorite the [Control] provided by them.
- */
-open class ControlsProviderSelectorActivity @Inject constructor(
+/** Activity to select an application to favorite the [Control] provided by them. */
+open class ControlsProviderSelectorActivity
+@Inject
+constructor(
@Main private val executor: Executor,
@Background private val backExecutor: Executor,
private val listingController: ControlsListingController,
private val controlsController: ControlsController,
private val userTracker: UserTracker,
private val authorizedPanelsRepository: AuthorizedPanelsRepository,
- private val panelConfirmationDialogFactory: PanelConfirmationDialogFactory
-) : ComponentActivity() {
+ private val panelConfirmationDialogFactory: PanelConfirmationDialogFactory,
+) : ComponentActivity(), ControlsManagementActivity {
companion object {
private const val DEBUG = false
private const val TAG = "ControlsProviderSelectorActivity"
const val BACK_SHOULD_EXIT = "back_should_exit"
}
+
+ override val activity: Activity
+ get() = this
+
private var backShouldExit = false
private lateinit var recyclerView: RecyclerView
- private val userTrackerCallback: UserTracker.Callback = object : UserTracker.Callback {
- private val startingUser = listingController.currentUserId
+ private val userTrackerCallback: UserTracker.Callback =
+ object : UserTracker.Callback {
+ private val startingUser = listingController.currentUserId
- override fun onUserChanged(newUser: Int, userContext: Context) {
- if (newUser != startingUser) {
- userTracker.removeCallback(this)
- finish()
+ override fun onUserChanged(newUser: Int, userContext: Context) {
+ if (newUser != startingUser) {
+ userTracker.removeCallback(this)
+ finish()
+ }
}
}
- }
private var dialog: Dialog? = null
private val mOnBackInvokedCallback = OnBackInvokedCallback {
@@ -95,10 +101,12 @@ open class ControlsProviderSelectorActivity @Inject constructor(
ControlsAnimations.observerForAnimations(
requireViewById<ViewGroup>(R.id.controls_management_root),
window,
- intent
+ intent,
)
)
+ applyInsets(R.id.controls_management_root)
+
requireViewById<ViewStub>(R.id.stub).apply {
layoutResource = R.layout.controls_management_apps
inflate()
@@ -114,9 +122,7 @@ open class ControlsProviderSelectorActivity @Inject constructor(
requireViewById<Button>(R.id.other_apps).apply {
visibility = View.VISIBLE
setText(com.android.internal.R.string.cancel)
- setOnClickListener {
- onBackPressed()
- }
+ setOnClickListener { onBackPressed() }
}
requireViewById<View>(R.id.done).visibility = View.GONE
@@ -125,9 +131,10 @@ open class ControlsProviderSelectorActivity @Inject constructor(
override fun onBackPressed() {
if (!backShouldExit) {
- val i = Intent().apply {
- component = ComponentName(applicationContext, ControlsActivity::class.java)
- }
+ val i =
+ Intent().apply {
+ component = ComponentName(applicationContext, ControlsActivity::class.java)
+ }
startActivity(i, ActivityOptions.makeSceneTransitionAnimation(this).toBundle())
}
animateExitAndFinish()
@@ -138,33 +145,40 @@ open class ControlsProviderSelectorActivity @Inject constructor(
userTracker.addCallback(userTrackerCallback, executor)
recyclerView.alpha = 0.0f
- recyclerView.adapter = AppAdapter(
- backExecutor,
- executor,
- lifecycle,
- listingController,
- LayoutInflater.from(this),
- ::onAppSelected,
- FavoritesRenderer(resources, controlsController::countFavoritesForComponent),
- resources,
- authorizedPanelsRepository.getAuthorizedPanels()
- ).apply {
- registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
- var hasAnimated = false
- override fun onChanged() {
- if (!hasAnimated) {
- hasAnimated = true
- ControlsAnimations.enterAnimation(recyclerView).start()
- }
+ recyclerView.adapter =
+ AppAdapter(
+ backExecutor,
+ executor,
+ lifecycle,
+ listingController,
+ LayoutInflater.from(this),
+ ::onAppSelected,
+ FavoritesRenderer(resources, controlsController::countFavoritesForComponent),
+ resources,
+ authorizedPanelsRepository.getAuthorizedPanels(),
+ )
+ .apply {
+ registerAdapterDataObserver(
+ object : RecyclerView.AdapterDataObserver() {
+ var hasAnimated = false
+
+ override fun onChanged() {
+ if (!hasAnimated) {
+ hasAnimated = true
+ ControlsAnimations.enterAnimation(recyclerView).start()
+ }
+ }
+ }
+ )
}
- })
- }
if (DEBUG) {
Log.d(TAG, "Registered onBackInvokedCallback")
}
onBackInvokedDispatcher.registerOnBackInvokedCallback(
- OnBackInvokedDispatcher.PRIORITY_DEFAULT, mOnBackInvokedCallback)
+ OnBackInvokedDispatcher.PRIORITY_DEFAULT,
+ mOnBackInvokedCallback,
+ )
}
override fun onStop() {
@@ -184,38 +198,45 @@ open class ControlsProviderSelectorActivity @Inject constructor(
launchFavoritingActivity(serviceInfo.componentName)
} else {
val appName = serviceInfo.loadLabel() ?: ""
- dialog = panelConfirmationDialogFactory.createConfirmationDialog(this, appName) { ok ->
- if (ok) {
- authorizedPanelsRepository.addAuthorizedPanels(
- setOf(serviceInfo.componentName.packageName)
- )
- val selected = SelectedItem.PanelItem(appName, serviceInfo.componentName)
- controlsController.setPreferredSelection(selected)
- animateExitAndFinish()
- openControlsOrigin()
- }
- dialog = null
- }.also { it.show() }
+ dialog =
+ panelConfirmationDialogFactory
+ .createConfirmationDialog(this, appName) { ok ->
+ if (ok) {
+ authorizedPanelsRepository.addAuthorizedPanels(
+ setOf(serviceInfo.componentName.packageName)
+ )
+ val selected =
+ SelectedItem.PanelItem(appName, serviceInfo.componentName)
+ controlsController.setPreferredSelection(selected)
+ animateExitAndFinish()
+ openControlsOrigin()
+ }
+ dialog = null
+ }
+ .also { it.show() }
}
}
/**
* Launch the [ControlsFavoritingActivity] for the specified component.
+ *
* @param component a component name for a [ControlsProviderService]
*/
private fun launchFavoritingActivity(component: ComponentName?) {
executor.execute {
component?.let {
- val intent = Intent(applicationContext, ControlsFavoritingActivity::class.java)
- .apply {
- putExtra(ControlsFavoritingActivity.EXTRA_APP,
- listingController.getAppLabel(it))
- putExtra(Intent.EXTRA_COMPONENT_NAME, it)
- putExtra(
- ControlsFavoritingActivity.EXTRA_SOURCE,
- ControlsFavoritingActivity.EXTRA_SOURCE_VALUE_FROM_PROVIDER_SELECTOR,
- )
- }
+ val intent =
+ Intent(applicationContext, ControlsFavoritingActivity::class.java).apply {
+ putExtra(
+ ControlsFavoritingActivity.EXTRA_APP,
+ listingController.getAppLabel(it),
+ )
+ putExtra(Intent.EXTRA_COMPONENT_NAME, it)
+ putExtra(
+ ControlsFavoritingActivity.EXTRA_SOURCE,
+ ControlsFavoritingActivity.EXTRA_SOURCE_VALUE_FROM_PROVIDER_SELECTOR,
+ )
+ }
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle())
}
}
@@ -228,8 +249,8 @@ open class ControlsProviderSelectorActivity @Inject constructor(
private fun openControlsOrigin() {
startActivity(
- Intent(applicationContext, ControlsActivity::class.java),
- ActivityOptions.makeSceneTransitionAnimation(this).toBundle()
+ Intent(applicationContext, ControlsActivity::class.java),
+ ActivityOptions.makeSceneTransitionAnimation(this).toBundle(),
)
}
@@ -242,7 +263,8 @@ open class ControlsProviderSelectorActivity @Inject constructor(
override fun run() {
finish()
}
- }
- ).start()
+ },
+ )
+ .start()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
index 955a5a35d82f..8296ec2311b6 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
@@ -16,6 +16,7 @@
package com.android.systemui.controls.ui
+import android.app.Activity
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
@@ -25,36 +26,40 @@ import android.content.res.Configuration
import android.os.Bundle
import android.os.RemoteException
import android.service.dreams.IDreamManager
-import android.view.View
import android.view.ViewGroup
-import android.view.WindowInsets
-import android.view.WindowInsets.Type
import android.view.WindowManager
import androidx.activity.ComponentActivity
-import com.android.systemui.res.R
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.controls.management.ControlsAnimations
+import com.android.systemui.controls.management.ControlsManagementActivity
+import com.android.systemui.controls.management.applyInsets
import com.android.systemui.controls.settings.ControlsSettingsDialogManager
import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.res.R
import com.android.systemui.statusbar.policy.KeyguardStateController
import javax.inject.Inject
/**
* Displays Device Controls inside an activity. This activity is available to be displayed over the
* lockscreen if the user has allowed it via
- * [android.provider.Settings.Secure.LOCKSCREEN_SHOW_CONTROLS]. This activity will be
- * destroyed on SCREEN_OFF events, due to issues with occluded activities over lockscreen as well as
- * user expectations for the activity to not continue running.
+ * [android.provider.Settings.Secure.LOCKSCREEN_SHOW_CONTROLS]. This activity will be destroyed on
+ * SCREEN_OFF events, due to issues with occluded activities over lockscreen as well as user
+ * expectations for the activity to not continue running.
*/
// Open for testing
-open class ControlsActivity @Inject constructor(
+open class ControlsActivity
+@Inject
+constructor(
private val uiController: ControlsUiController,
private val broadcastDispatcher: BroadcastDispatcher,
private val dreamManager: IDreamManager,
private val featureFlags: FeatureFlags,
private val controlsSettingsDialogManager: ControlsSettingsDialogManager,
- private val keyguardStateController: KeyguardStateController
-) : ComponentActivity() {
+ private val keyguardStateController: KeyguardStateController,
+) : ComponentActivity(), ControlsManagementActivity {
+
+ override val activity: Activity
+ get() = this
private val lastConfiguration = Configuration()
@@ -69,38 +74,27 @@ open class ControlsActivity @Inject constructor(
setContentView(R.layout.controls_fullscreen)
+ applyInsets(R.id.control_detail_root)
+
lifecycle.addObserver(
ControlsAnimations.observerForAnimations(
requireViewById(R.id.control_detail_root),
window,
intent,
- false
+ false,
)
)
- requireViewById<ViewGroup>(R.id.control_detail_root).apply {
- setOnApplyWindowInsetsListener {
- v: View, insets: WindowInsets ->
- v.apply {
- val l = getPaddingLeft()
- val t = getPaddingTop()
- val r = getPaddingRight()
- setPadding(l, t, r, insets.getInsets(Type.systemBars()).bottom)
- }
-
- WindowInsets.CONSUMED
- }
- }
-
initBroadcastReceiver()
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
- val interestingFlags = ActivityInfo.CONFIG_ORIENTATION or
+ val interestingFlags =
+ ActivityInfo.CONFIG_ORIENTATION or
ActivityInfo.CONFIG_SCREEN_SIZE or
ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
- if (lastConfiguration.diff(newConfig) and interestingFlags != 0 ) {
+ if (lastConfiguration.diff(newConfig) and interestingFlags != 0) {
uiController.onSizeChange()
}
lastConfiguration.setTo(newConfig)
@@ -164,15 +158,18 @@ open class ControlsActivity @Inject constructor(
}
private fun initBroadcastReceiver() {
- broadcastReceiver = object : BroadcastReceiver() {
- override fun onReceive(context: Context, intent: Intent) {
- val action = intent.getAction()
- if (action == Intent.ACTION_SCREEN_OFF ||
- action == Intent.ACTION_DREAMING_STARTED) {
- finish()
+ broadcastReceiver =
+ object : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ val action = intent.getAction()
+ if (
+ action == Intent.ACTION_SCREEN_OFF ||
+ action == Intent.ACTION_DREAMING_STARTED
+ ) {
+ finish()
+ }
}
}
- }
val filter = IntentFilter()
filter.addAction(Intent.ACTION_SCREEN_OFF)
diff --git a/packages/SystemUI/src/com/android/systemui/display/DisplayModule.kt b/packages/SystemUI/src/com/android/systemui/display/DisplayModule.kt
index e862525623fe..9b181be93b61 100644
--- a/packages/SystemUI/src/com/android/systemui/display/DisplayModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/DisplayModule.kt
@@ -30,6 +30,7 @@ import com.android.systemui.display.data.repository.FocusedDisplayRepository
import com.android.systemui.display.data.repository.FocusedDisplayRepositoryImpl
import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor
import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractorImpl
+import com.android.systemui.display.domain.interactor.DisplayWindowPropertiesInteractorModule
import com.android.systemui.display.domain.interactor.RearDisplayStateInteractor
import com.android.systemui.display.domain.interactor.RearDisplayStateInteractorImpl
import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
@@ -41,7 +42,7 @@ import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
/** Module binding display related classes. */
-@Module
+@Module(includes = [DisplayWindowPropertiesInteractorModule::class])
interface DisplayModule {
@Binds
fun bindConnectedDisplayInteractor(
diff --git a/packages/SystemUI/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractor.kt b/packages/SystemUI/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractor.kt
new file mode 100644
index 000000000000..22e467bd5e3c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractor.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.display.domain.interactor
+
+import android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository
+import com.android.systemui.display.shared.model.DisplayWindowProperties
+import dagger.Binds
+import dagger.Module
+import javax.inject.Inject
+
+/** Provides per display instances of [DisplayWindowProperties]. */
+interface DisplayWindowPropertiesInteractor {
+
+ /**
+ * Returns a [DisplayWindowProperties] instance for a given display id, to be used for the
+ * status bar.
+ *
+ * @throws IllegalArgumentException if no display with the given display id exists.
+ */
+ fun getForStatusBar(displayId: Int): DisplayWindowProperties
+}
+
+@SysUISingleton
+class DisplayWindowPropertiesInteractorImpl
+@Inject
+constructor(private val repo: DisplayWindowPropertiesRepository) :
+ DisplayWindowPropertiesInteractor {
+
+ override fun getForStatusBar(displayId: Int): DisplayWindowProperties {
+ return repo.get(displayId, TYPE_STATUS_BAR)
+ }
+}
+
+@Module
+interface DisplayWindowPropertiesInteractorModule {
+
+ @Binds
+ fun interactor(impl: DisplayWindowPropertiesInteractorImpl): DisplayWindowPropertiesInteractor
+}
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialAnimation.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialAnimation.kt
index 2be619bac998..abd39cc8dea8 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialAnimation.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialAnimation.kt
@@ -23,13 +23,16 @@ import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeOut
import androidx.compose.animation.togetherWith
+import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.node.Ref
@@ -93,13 +96,19 @@ private fun EducationAnimation(
animationProperties: LottieDynamicProperties,
) {
val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(educationAnimationId))
+ var isPlaying by remember { mutableStateOf(true) }
val progress by
- animateLottieCompositionAsState(composition, iterations = LottieConstants.IterateForever)
+ animateLottieCompositionAsState(
+ composition,
+ iterations = LottieConstants.IterateForever,
+ isPlaying = isPlaying,
+ restartOnPlay = false,
+ )
LottieAnimation(
composition = composition,
progress = { progress },
dynamicProperties = animationProperties,
- modifier = Modifier.fillMaxSize(),
+ modifier = Modifier.fillMaxSize().clickable { isPlaying = !isPlaying },
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutCategoriesUtils.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutCategoriesUtils.kt
index a0897f293624..27d1a30f4346 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutCategoriesUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutCategoriesUtils.kt
@@ -116,7 +116,10 @@ constructor(
.filter {
// Allow KEYCODE_UNKNOWN (0) because shortcuts can have just modifiers and no
// keycode, or they could have a baseCharacter instead of a keycode.
- it.keycode == KeyEvent.KEYCODE_UNKNOWN || supportedKeyCodes.contains(it.keycode)
+ it.keycode == KeyEvent.KEYCODE_UNKNOWN ||
+ supportedKeyCodes.contains(it.keycode) ||
+ // Support keyboard function row key codes
+ keyGlyphMap?.functionRowKeys?.contains(it.keycode) ?: false
}
.mapNotNull { toShortcut(keyGlyphMap, keyCharacterMap, it, keepIcons) }
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt
index e47b33f8c37c..d91922ddb65e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt
@@ -99,6 +99,7 @@ import android.view.KeyEvent.KEYCODE_PAGE_DOWN
import android.view.KeyEvent.KEYCODE_PAGE_UP
import android.view.KeyEvent.KEYCODE_PERIOD
import android.view.KeyEvent.KEYCODE_RECENT_APPS
+import android.view.KeyEvent.KEYCODE_SCREENSHOT
import android.view.KeyEvent.KEYCODE_SCROLL_LOCK
import android.view.KeyEvent.KEYCODE_SHIFT_LEFT
import android.view.KeyEvent.KEYCODE_SHIFT_RIGHT
@@ -125,6 +126,14 @@ object ShortcutHelperKeys {
KEYCODE_RECENT_APPS to R.drawable.ic_check_box_outline_blank,
)
+ val keyLabelResIds =
+ mapOf(
+ KEYCODE_BACK to R.string.group_system_go_back,
+ KEYCODE_HOME to R.string.group_system_access_home_screen,
+ KEYCODE_RECENT_APPS to R.string.group_system_overview_open_apps,
+ KEYCODE_SCREENSHOT to R.string.group_system_full_screenshot,
+ )
+
val modifierLabels =
mapOf<Int, (Context) -> String>(
// Modifiers
@@ -140,6 +149,7 @@ object ShortcutHelperKeys {
mapOf<Int, (Context) -> String>(
KEYCODE_HOME to { context -> context.getString(R.string.keyboard_key_home) },
KEYCODE_BACK to { context -> context.getString(R.string.keyboard_key_back) },
+ KEYCODE_RECENT_APPS to { context -> context.getString(R.string.accessibility_recent) },
KEYCODE_DPAD_UP to { context -> context.getString(R.string.keyboard_key_dpad_up) },
KEYCODE_DPAD_DOWN to { context -> context.getString(R.string.keyboard_key_dpad_down) },
KEYCODE_DPAD_LEFT to { context -> context.getString(R.string.keyboard_key_dpad_left) },
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/InputShortcutsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/InputShortcutsSource.kt
index 1b2098650278..4787507dac39 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/InputShortcutsSource.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/InputShortcutsSource.kt
@@ -17,12 +17,16 @@
package com.android.systemui.keyboard.shortcut.data.source
import android.content.res.Resources
+import android.hardware.input.InputManager
+import android.view.KeyEvent.KEYCODE_EMOJI_PICKER
import android.view.KeyEvent.KEYCODE_SPACE
import android.view.KeyEvent.META_CTRL_ON
import android.view.KeyEvent.META_SHIFT_ON
import android.view.KeyboardShortcutGroup
+import android.view.KeyboardShortcutInfo
import android.view.WindowManager
import android.view.WindowManager.KeyboardShortcutsReceiver
+import com.android.systemui.Flags.shortcutHelperKeyGlyph
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyboard.shortcut.data.model.shortcutInfo
import com.android.systemui.res.R
@@ -31,16 +35,19 @@ import kotlinx.coroutines.suspendCancellableCoroutine
class InputShortcutsSource
@Inject
-constructor(@Main private val resources: Resources, private val windowManager: WindowManager) :
- KeyboardShortcutGroupsSource {
+constructor(
+ @Main private val resources: Resources,
+ private val windowManager: WindowManager,
+ private val inputManager: InputManager,
+) : KeyboardShortcutGroupsSource {
override suspend fun shortcutGroups(deviceId: Int): List<KeyboardShortcutGroup> =
- getInputLanguageShortcutGroup() + getImeShortcutGroup(deviceId)
+ getInputLanguageShortcutGroup(deviceId) + getImeShortcutGroup(deviceId)
- private fun getInputLanguageShortcutGroup() =
+ private fun getInputLanguageShortcutGroup(deviceId: Int) =
listOf(
KeyboardShortcutGroup(
resources.getString(R.string.shortcut_helper_category_input),
- inputLanguageShortcuts()
+ inputLanguageShortcuts() + hardwareShortcuts(deviceId),
)
)
@@ -53,9 +60,23 @@ constructor(@Main private val resources: Resources, private val windowManager: W
/* Switch previous language (next language): Ctrl + Shift + Space */
shortcutInfo(resources.getString(R.string.input_switch_input_language_previous)) {
command(META_CTRL_ON or META_SHIFT_ON, KEYCODE_SPACE)
- }
+ },
)
+ private fun hardwareShortcuts(deviceId: Int): List<KeyboardShortcutInfo> {
+ if (shortcutHelperKeyGlyph()) {
+ val keyGlyphMap = inputManager.getKeyGlyphMap(deviceId)
+ if (keyGlyphMap != null && keyGlyphMap.functionRowKeys.contains(KEYCODE_EMOJI_PICKER)) {
+ return listOf(
+ shortcutInfo(resources.getString(R.string.input_access_emoji)) {
+ command(modifiers = 0, KEYCODE_EMOJI_PICKER)
+ }
+ )
+ }
+ }
+ return emptyList()
+ }
+
private suspend fun getImeShortcutGroup(deviceId: Int): List<KeyboardShortcutGroup> =
suspendCancellableCoroutine { continuation ->
val shortcutsReceiver = KeyboardShortcutsReceiver {
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
index 0201f402af2a..5ef869e6d848 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
@@ -16,24 +16,34 @@
package com.android.systemui.keyboard.shortcut.data.source
+import android.content.Context
import android.content.res.Resources
import android.view.KeyEvent.KEYCODE_D
import android.view.KeyEvent.KEYCODE_DPAD_LEFT
import android.view.KeyEvent.KEYCODE_DPAD_RIGHT
import android.view.KeyEvent.KEYCODE_DPAD_UP
+import android.view.KeyEvent.KEYCODE_EQUALS
+import android.view.KeyEvent.KEYCODE_LEFT_BRACKET
+import android.view.KeyEvent.KEYCODE_MINUS
+import android.view.KeyEvent.KEYCODE_RIGHT_BRACKET
import android.view.KeyEvent.KEYCODE_TAB
import android.view.KeyEvent.META_ALT_ON
import android.view.KeyEvent.META_CTRL_ON
import android.view.KeyEvent.META_META_ON
import android.view.KeyEvent.META_SHIFT_ON
import android.view.KeyboardShortcutGroup
+import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyboard.shortcut.data.model.shortcutInfo
import com.android.systemui.res.R
import com.android.window.flags.Flags.enableMoveToNextDisplayShortcut
+import com.android.window.flags.Flags.enableTaskResizingKeyboardShortcuts
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
import javax.inject.Inject
-class MultitaskingShortcutsSource @Inject constructor(@Main private val resources: Resources) :
+class MultitaskingShortcutsSource
+@Inject
+constructor(@Main private val resources: Resources, @Application private val context: Context) :
KeyboardShortcutGroupsSource {
override suspend fun shortcutGroups(deviceId: Int) =
@@ -95,6 +105,40 @@ class MultitaskingShortcutsSource @Inject constructor(@Main private val resource
}
)
}
+ if (
+ DesktopModeStatus.canEnterDesktopMode(context) && enableTaskResizingKeyboardShortcuts()
+ ) {
+ // Snap a freeform window to the left
+ // - Meta + Left bracket
+ add(
+ shortcutInfo(resources.getString(R.string.system_desktop_mode_snap_left_window)) {
+ command(META_META_ON, KEYCODE_LEFT_BRACKET)
+ }
+ )
+ // Snap a freeform window to the right
+ // - Meta + Right bracket
+ add(
+ shortcutInfo(resources.getString(R.string.system_desktop_mode_snap_right_window)) {
+ command(META_META_ON, KEYCODE_RIGHT_BRACKET)
+ }
+ )
+ // Toggle maximize a freeform window
+ // - Meta + Equals
+ add(
+ shortcutInfo(
+ resources.getString(R.string.system_desktop_mode_toggle_maximize_window)
+ ) {
+ command(META_META_ON, KEYCODE_EQUALS)
+ }
+ )
+ // Minimize a freeform window
+ // - Meta + Minus
+ add(
+ shortcutInfo(resources.getString(R.string.system_desktop_mode_minimize_window)) {
+ command(META_META_ON, KEYCODE_MINUS)
+ }
+ )
+ }
}
private fun recentsShortcuts() =
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSource.kt
index 7c0c75ef2c4c..a650cd889381 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSource.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSource.kt
@@ -17,6 +17,8 @@
package com.android.systemui.keyboard.shortcut.data.source
import android.content.res.Resources
+import android.hardware.input.InputManager
+import android.hardware.input.KeyGlyphMap
import android.view.KeyEvent.KEYCODE_A
import android.view.KeyEvent.KEYCODE_BACK
import android.view.KeyEvent.KEYCODE_DEL
@@ -35,26 +37,87 @@ import android.view.KeyEvent.KEYCODE_TAB
import android.view.KeyEvent.META_CTRL_ON
import android.view.KeyEvent.META_META_ON
import android.view.KeyboardShortcutGroup
+import android.view.KeyboardShortcutInfo
+import com.android.systemui.Flags.shortcutHelperKeyGlyph
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyboard.shortcut.data.model.shortcutInfo
+import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperKeys
import com.android.systemui.res.R
import javax.inject.Inject
-class SystemShortcutsSource @Inject constructor(@Main private val resources: Resources) :
+class SystemShortcutsSource
+@Inject
+constructor(@Main private val resources: Resources, private val inputManager: InputManager) :
KeyboardShortcutGroupsSource {
override suspend fun shortcutGroups(deviceId: Int) =
listOf(
KeyboardShortcutGroup(
resources.getString(R.string.shortcut_helper_category_system_controls),
- systemControlsShortcuts()
+ hardwareShortcuts(deviceId) + systemControlsShortcuts(),
),
KeyboardShortcutGroup(
resources.getString(R.string.shortcut_helper_category_system_apps),
- systemAppsShortcuts()
- )
+ systemAppsShortcuts(),
+ ),
)
+ private fun hardwareShortcuts(deviceId: Int): List<KeyboardShortcutInfo> =
+ if (shortcutHelperKeyGlyph()) {
+ val keyGlyphMap = inputManager.getKeyGlyphMap(deviceId)
+ if (keyGlyphMap != null) {
+ functionRowKeys(keyGlyphMap) + keyCombinationShortcuts(keyGlyphMap)
+ } else {
+ // Not add function row keys if it is not supported by keyboard
+ emptyList()
+ }
+ } else {
+ defaultFunctionRowKeys()
+ }
+
+ private fun defaultFunctionRowKeys(): List<KeyboardShortcutInfo> =
+ listOf(
+ shortcutInfo(resources.getString(R.string.group_system_access_home_screen)) {
+ command(modifiers = 0, KEYCODE_HOME)
+ },
+ shortcutInfo(resources.getString(R.string.group_system_go_back)) {
+ command(modifiers = 0, KEYCODE_BACK)
+ },
+ shortcutInfo(resources.getString(R.string.group_system_overview_open_apps)) {
+ command(modifiers = 0, KEYCODE_RECENT_APPS)
+ },
+ )
+
+ private fun functionRowKeys(keyGlyphMap: KeyGlyphMap): List<KeyboardShortcutInfo> {
+ val functionRowKeys = mutableListOf<KeyboardShortcutInfo>()
+ keyGlyphMap.functionRowKeys.forEach { keyCode ->
+ val labelResId = ShortcutHelperKeys.keyLabelResIds[keyCode]
+ if (labelResId != null) {
+ functionRowKeys.add(
+ shortcutInfo(resources.getString(labelResId)) {
+ command(modifiers = 0, keyCode)
+ }
+ )
+ }
+ }
+ return functionRowKeys
+ }
+
+ private fun keyCombinationShortcuts(keyGlyphMap: KeyGlyphMap): List<KeyboardShortcutInfo> {
+ val shortcuts = mutableListOf<KeyboardShortcutInfo>()
+ keyGlyphMap.hardwareShortcuts.forEach { (keyCombination, keyCode) ->
+ val labelResId = ShortcutHelperKeys.keyLabelResIds[keyCode]
+ if (labelResId != null) {
+ val info =
+ shortcutInfo(resources.getString(labelResId)) {
+ command(keyCombination.modifierState, keyCombination.keycode)
+ }
+ shortcuts.add(info)
+ }
+ }
+ return shortcuts
+ }
+
private fun systemControlsShortcuts() =
listOf(
// Access list of all apps and search (i.e. Search/Launcher):
@@ -63,36 +126,24 @@ class SystemShortcutsSource @Inject constructor(@Main private val resources: Res
command(META_META_ON)
},
// Access home screen:
- // - Home button
// - Meta + H
// - Meta + Enter
shortcutInfo(resources.getString(R.string.group_system_access_home_screen)) {
- command(modifiers = 0, KEYCODE_HOME)
- },
- shortcutInfo(resources.getString(R.string.group_system_access_home_screen)) {
command(META_META_ON, KEYCODE_H)
},
shortcutInfo(resources.getString(R.string.group_system_access_home_screen)) {
command(META_META_ON, KEYCODE_ENTER)
},
// Overview of open apps:
- // - Recent apps button
// - Meta + Tab
shortcutInfo(resources.getString(R.string.group_system_overview_open_apps)) {
- command(modifiers = 0, KEYCODE_RECENT_APPS)
- },
- shortcutInfo(resources.getString(R.string.group_system_overview_open_apps)) {
command(META_META_ON, KEYCODE_TAB)
},
// Back: go back to previous state (back button)
- // - Back button
// - Meta + Escape OR
// - Meta + Backspace OR
// - Meta + Left arrow
shortcutInfo(resources.getString(R.string.group_system_go_back)) {
- command(modifiers = 0, KEYCODE_BACK)
- },
- shortcutInfo(resources.getString(R.string.group_system_go_back)) {
command(META_META_ON, KEYCODE_ESCAPE)
},
shortcutInfo(resources.getString(R.string.group_system_go_back)) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt
index 0381eaec5026..2385cc6a4c47 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt
@@ -16,14 +16,22 @@
package com.android.systemui.keyboard.shortcut.domain.interactor
+import android.content.Context
+import android.view.KeyEvent.META_META_ON
import com.android.systemui.Flags.keyboardShortcutHelperShortcutCustomizer
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyboard.shortcut.data.repository.ShortcutCategoriesRepository
+import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperKeys
+import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperKeys.metaModifierIconResId
import com.android.systemui.keyboard.shortcut.qualifiers.CustomShortcutCategories
import com.android.systemui.keyboard.shortcut.qualifiers.DefaultShortcutCategories
import com.android.systemui.keyboard.shortcut.shared.model.Shortcut
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
+import com.android.systemui.res.R
import dagger.Lazy
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
@@ -34,6 +42,7 @@ import kotlinx.coroutines.flow.flowOf
class ShortcutHelperCategoriesInteractor
@Inject
constructor(
+ @Application private val context: Context,
@DefaultShortcutCategories defaultCategoriesRepository: ShortcutCategoriesRepository,
@CustomShortcutCategories customCategoriesRepositoryLazy: Lazy<ShortcutCategoriesRepository>,
) {
@@ -87,6 +96,54 @@ constructor(
label = commonLabel,
icon = groupedShortcuts.firstOrNull()?.icon,
commands = groupedShortcuts.flatMap { it.commands },
+ contentDescription =
+ toContentDescription(commonLabel, groupedShortcuts.flatMap { it.commands }),
)
}
+
+ private fun toContentDescription(label: String, commands: List<ShortcutCommand>): String {
+ val pressKey = context.getString(R.string.shortcut_helper_add_shortcut_dialog_placeholder)
+ val andConjunction =
+ context.getString(R.string.shortcut_helper_key_combinations_and_conjunction)
+ val orConjunction =
+ context.getString(R.string.shortcut_helper_key_combinations_or_separator)
+ val forwardSlash =
+ context.getString(R.string.shortcut_helper_key_combinations_forward_slash)
+ return buildString {
+ append("$label, $pressKey")
+ commands.forEachIndexed { i, shortcutCommand ->
+ if (i > 0) {
+ append(", $orConjunction")
+ }
+ shortcutCommand.keys.forEachIndexed { j, shortcutKey ->
+ if (j > 0) {
+ append(" $andConjunction")
+ }
+ if (shortcutKey is ShortcutKey.Text) {
+ // Special handling for "/" as TalkBack will not read punctuation by
+ // default.
+ if (shortcutKey.value.equals("/")) {
+ append(" $forwardSlash")
+ } else {
+ append(" ${shortcutKey.value}")
+ }
+ } else if (shortcutKey is ShortcutKey.Icon.ResIdIcon) {
+ val keyLabel =
+ if (shortcutKey.drawableResId == metaModifierIconResId) {
+ ShortcutHelperKeys.modifierLabels[META_META_ON]
+ } else {
+ val keyCode =
+ ShortcutHelperKeys.keyIcons.entries
+ .firstOrNull { it.value == shortcutKey.drawableResId }
+ ?.key
+ ShortcutHelperKeys.specialKeyLabels[keyCode]
+ }
+ if (keyLabel != null) {
+ append(" ${keyLabel.invoke(context)}")
+ }
+ } // No-Op when shortcutKey is ShortcutKey.Icon.DrawableIcon
+ }
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/Shortcut.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/Shortcut.kt
index bf7df7ef8561..9cc15ce809e9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/Shortcut.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/Shortcut.kt
@@ -20,18 +20,24 @@ data class Shortcut(
val label: String,
val commands: List<ShortcutCommand>,
val icon: ShortcutIcon? = null,
+ val contentDescription: String = "",
) {
val containsCustomShortcutCommands: Boolean = commands.any { it.isCustom }
}
class ShortcutBuilder(private val label: String) {
val commands = mutableListOf<ShortcutCommand>()
+ var contentDescription = ""
fun command(builder: ShortcutCommandBuilder.() -> Unit) {
commands += ShortcutCommandBuilder().apply(builder).build()
}
- fun build() = Shortcut(label, commands)
+ fun contentDescription(string: () -> String) {
+ contentDescription = string.invoke()
+ }
+
+ fun build() = Shortcut(label, commands, contentDescription = contentDescription)
}
fun shortcut(label: String, block: ShortcutBuilder.() -> Unit): Shortcut =
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
index e3675de5d197..1f37c7de1439 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
@@ -96,6 +96,8 @@ import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.semantics.contentDescription
+import androidx.compose.ui.semantics.hideFromAccessibility
import androidx.compose.ui.semantics.isTraversalGroup
import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics
@@ -111,6 +113,7 @@ import androidx.compose.ui.util.fastForEach
import androidx.compose.ui.util.fastForEachIndexed
import com.android.compose.modifiers.thenIf
import com.android.compose.ui.graphics.painter.rememberDrawablePainter
+import com.android.systemui.keyboard.shortcut.shared.model.Shortcut as ShortcutModel
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo
@@ -121,7 +124,6 @@ import com.android.systemui.keyboard.shortcut.ui.model.IconSource
import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCategoryUi
import com.android.systemui.keyboard.shortcut.ui.model.ShortcutsUiState
import com.android.systemui.res.R
-import com.android.systemui.keyboard.shortcut.shared.model.Shortcut as ShortcutModel
import kotlinx.coroutines.delay
@Composable
@@ -465,14 +467,10 @@ private fun EndSidePanel(
onCustomizationRequested = { requestInfo ->
when (requestInfo) {
is ShortcutCustomizationRequestInfo.Add ->
- onCustomizationRequested(
- requestInfo.copy(categoryType = category.type)
- )
+ onCustomizationRequested(requestInfo.copy(categoryType = category.type))
is ShortcutCustomizationRequestInfo.Delete ->
- onCustomizationRequested(
- requestInfo.copy(categoryType = category.type)
- )
+ onCustomizationRequested(requestInfo.copy(categoryType = category.type))
}
},
)
@@ -572,20 +570,31 @@ private fun Shortcut(
}
.focusable(interactionSource = interactionSource)
.padding(8.dp)
+ .semantics { contentDescription = shortcut.contentDescription }
) {
Row(
- modifier = Modifier.width(128.dp).align(Alignment.CenterVertically).weight(0.333f),
+ modifier =
+ Modifier.width(128.dp).align(Alignment.CenterVertically).weight(0.333f).semantics {
+ hideFromAccessibility()
+ },
horizontalArrangement = Arrangement.spacedBy(16.dp),
verticalAlignment = Alignment.CenterVertically,
) {
if (shortcut.icon != null) {
- ShortcutIcon(shortcut.icon, modifier = Modifier.size(24.dp))
+ ShortcutIcon(
+ shortcut.icon,
+ modifier = Modifier.size(24.dp).semantics { hideFromAccessibility() },
+ )
}
- ShortcutDescriptionText(searchQuery = searchQuery, shortcut = shortcut)
+ ShortcutDescriptionText(
+ searchQuery = searchQuery,
+ shortcut = shortcut,
+ modifier = Modifier.semantics { hideFromAccessibility() },
+ )
}
- Spacer(modifier = Modifier.width(24.dp))
+ Spacer(modifier = Modifier.width(24.dp).semantics { hideFromAccessibility() })
ShortcutKeyCombinations(
- modifier = Modifier.weight(.666f),
+ modifier = Modifier.weight(.666f).semantics { hideFromAccessibility() },
shortcut = shortcut,
isCustomizing = isCustomizing,
onAddShortcutRequested = {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt b/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt
index a94df091230d..7a72732ea6bf 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt
@@ -36,6 +36,7 @@ import com.android.systemui.SystemUIAppComponentFactoryBase.ContextAvailableCall
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
import com.android.systemui.keyguard.ui.preview.KeyguardRemotePreviewManager
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
@@ -44,6 +45,7 @@ class CustomizationProvider :
ContentProvider(), SystemUIAppComponentFactoryBase.ContextInitializer {
@Inject lateinit var interactor: KeyguardQuickAffordanceInteractor
+ @Inject lateinit var shadeModeInteractor: ShadeModeInteractor
@Inject lateinit var previewManager: KeyguardRemotePreviewManager
@Inject @Main lateinit var mainDispatcher: CoroutineDispatcher
@@ -73,6 +75,11 @@ class CustomizationProvider :
MATCH_CODE_ALL_SELECTIONS,
)
addURI(Contract.AUTHORITY, Contract.FlagsTable.TABLE_NAME, MATCH_CODE_ALL_FLAGS)
+ addURI(
+ Contract.AUTHORITY,
+ Contract.RuntimeValuesTable.TABLE_NAME,
+ MATCH_CODE_ALL_RUNTIME_VALUES,
+ )
}
override fun onCreate(): Boolean {
@@ -94,7 +101,8 @@ class CustomizationProvider :
MATCH_CODE_ALL_SLOTS,
MATCH_CODE_ALL_AFFORDANCES,
MATCH_CODE_ALL_FLAGS,
- MATCH_CODE_ALL_SELECTIONS -> "vnd.android.cursor.dir/vnd."
+ MATCH_CODE_ALL_SELECTIONS,
+ MATCH_CODE_ALL_RUNTIME_VALUES -> "vnd.android.cursor.dir/vnd."
else -> null
}
@@ -113,6 +121,7 @@ class CustomizationProvider :
Contract.LockScreenQuickAffordances.SelectionTable.TABLE_NAME
)
MATCH_CODE_ALL_FLAGS -> Contract.FlagsTable.TABLE_NAME
+ MATCH_CODE_ALL_RUNTIME_VALUES -> Contract.RuntimeValuesTable.TABLE_NAME
else -> null
}
@@ -146,6 +155,7 @@ class CustomizationProvider :
MATCH_CODE_ALL_SLOTS -> querySlots()
MATCH_CODE_ALL_SELECTIONS -> querySelections()
MATCH_CODE_ALL_FLAGS -> queryFlags()
+ MATCH_CODE_ALL_RUNTIME_VALUES -> queryRuntimeValues()
else -> null
}
}
@@ -334,6 +344,23 @@ class CustomizationProvider :
}
}
+ private fun queryRuntimeValues(): Cursor {
+ return MatrixCursor(
+ arrayOf(
+ Contract.RuntimeValuesTable.Columns.NAME,
+ Contract.RuntimeValuesTable.Columns.VALUE,
+ )
+ )
+ .apply {
+ addRow(
+ arrayOf(
+ Contract.RuntimeValuesTable.KEY_IS_SHADE_LAYOUT_WIDE,
+ if (shadeModeInteractor.isShadeLayoutWide.value) 1 else 0,
+ )
+ )
+ }
+ }
+
private suspend fun deleteSelection(uri: Uri, selectionArgs: Array<out String>?): Int {
if (selectionArgs == null) {
throw IllegalArgumentException(
@@ -370,5 +397,6 @@ class CustomizationProvider :
private const val MATCH_CODE_ALL_AFFORDANCES = 2
private const val MATCH_CODE_ALL_SELECTIONS = 3
private const val MATCH_CODE_ALL_FLAGS = 4
+ private const val MATCH_CODE_ALL_RUNTIME_VALUES = 5
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt
index 21090c12e9fe..cc8652c76181 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt
@@ -18,7 +18,6 @@
package com.android.systemui.keyguard.domain.interactor
import com.android.keyguard.logging.KeyguardLogger
-import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlags
import com.android.systemui.dagger.SysUISingleton
@@ -28,15 +27,12 @@ import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.keyguard.shared.model.DismissAction
import com.android.systemui.keyguard.shared.model.KeyguardDone
import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
-import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.log.core.LogLevel
-import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.domain.interactor.ShadeInteractor
-import com.android.systemui.util.kotlin.Utils.Companion.sampleFilter
import dagger.Lazy
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -66,8 +62,6 @@ constructor(
val dismissInteractor: KeyguardDismissInteractor,
@Application private val applicationScope: CoroutineScope,
deviceUnlockedInteractor: Lazy<DeviceUnlockedInteractor>,
- powerInteractor: PowerInteractor,
- alternateBouncerInteractor: AlternateBouncerInteractor,
shadeInteractor: Lazy<ShadeInteractor>,
keyguardInteractor: Lazy<KeyguardInteractor>,
sceneInteractor: Lazy<SceneInteractor>,
@@ -144,42 +138,6 @@ constructor(
}
}
- /** Flow that emits whenever we need to reset the dismiss action */
- private val resetDismissAction: Flow<Unit> =
- combine(
- if (SceneContainerFlag.isEnabled) {
- // Using currentScene instead of isFinishedIn because of a race condition that
- // forms between isFinishedIn(Gone) and isOnShadeWhileUnlocked where the latter
- // emits false before the former emits true, causing the evaluation of the
- // combine to come up with true, temporarily, before settling on false, which is
- // a valid final state. That causes an incorrect reset of the dismiss action to
- // occur before it gets executed.
- sceneInteractor
- .get()
- .currentScene
- .map { it == Scenes.Gone }
- .distinctUntilChanged()
- } else {
- transitionInteractor.isFinishedIn(
- scene = Scenes.Gone,
- stateWithoutSceneContainer = GONE,
- )
- },
- transitionInteractor.isFinishedIn(
- scene = Scenes.Bouncer,
- stateWithoutSceneContainer = PRIMARY_BOUNCER,
- ),
- alternateBouncerInteractor.isVisible,
- isOnShadeWhileUnlocked,
- powerInteractor.isAsleep,
- ) { isOnGone, isOnBouncer, isOnAltBouncer, isOnShadeWhileUnlocked, isAsleep ->
- (!isOnGone && !isOnBouncer && !isOnAltBouncer && !isOnShadeWhileUnlocked) ||
- isAsleep
- }
- .filter { it }
- .sampleFilter(dismissAction) { it !is DismissAction.None }
- .map {}
-
fun runDismissAnimationOnKeyguard(): Boolean {
return willAnimateDismissActionOnLockscreen.value
}
@@ -220,19 +178,15 @@ constructor(
}
}
- launch {
- resetDismissAction.collect {
- log("resetDismissAction")
- repository.dismissAction.value.onCancelAction.run()
- clearDismissAction()
- }
- }
-
launch { repository.dismissAction.collect { log("updatedDismissAction=$it") } }
awaitCancellation()
}
}
+ fun clearDismissAction() {
+ repository.setDismissAction(DismissAction.None)
+ }
+
/** Run the dismiss action and starts the dismiss keyguard transition. */
private suspend fun runDismissAction() {
val dismissAction = repository.dismissAction.value
@@ -249,10 +203,6 @@ constructor(
}
}
- private fun clearDismissAction() {
- repository.setDismissAction(DismissAction.None)
- }
-
private fun log(message: String) {
keyguardLogger.log(TAG, LogLevel.DEBUG, message)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt
index f0bccacadc57..85ce5cd0f9fd 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt
@@ -23,7 +23,9 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.ALTERNATE_BOUNCE
import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.ui.composable.transitions.TO_BOUNCER_FADE_FRACTION
import javax.inject.Inject
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
@@ -36,9 +38,7 @@ import kotlinx.coroutines.flow.Flow
@SysUISingleton
class AlternateBouncerToPrimaryBouncerTransitionViewModel
@Inject
-constructor(
- animationFlow: KeyguardTransitionAnimationFlow,
-) : DeviceEntryIconTransition {
+constructor(animationFlow: KeyguardTransitionAnimationFlow) : DeviceEntryIconTransition {
private val transitionAnimation =
animationFlow
.setup(
@@ -46,9 +46,23 @@ constructor(
edge = Edge.create(from = ALTERNATE_BOUNCER, to = Scenes.Bouncer),
)
.setupWithoutSceneContainer(
- edge = Edge.create(from = ALTERNATE_BOUNCER, to = PRIMARY_BOUNCER),
+ edge = Edge.create(from = ALTERNATE_BOUNCER, to = PRIMARY_BOUNCER)
)
+ private val alphaForAnimationStep: (Float) -> Float =
+ when {
+ SceneContainerFlag.isEnabled -> { step ->
+ 1f - Math.min((step / TO_BOUNCER_FADE_FRACTION), 1f)
+ }
+ else -> { step -> 1f - step }
+ }
+
+ val lockscreenAlpha: Flow<Float> =
+ transitionAnimation.sharedFlow(
+ duration = FromAlternateBouncerTransitionInteractor.TO_PRIMARY_BOUNCER_DURATION,
+ onStep = alphaForAnimationStep,
+ )
+
override val deviceEntryParentViewAlpha: Flow<Float> =
transitionAnimation.immediatelyTransitionTo(0f)
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSwitchingController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSwitchingController.java
index b69b25dbddf2..8fbbb8bc4872 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSwitchingController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSwitchingController.java
@@ -813,8 +813,15 @@ public class MediaSwitchingController
}
private void attachConnectNewDeviceItemIfNeeded(List<MediaItem> mediaItems) {
+ boolean isSelectedDeviceNotAGroup = getSelectedMediaDevice().size() == 1;
+ if (enableInputRouting()) {
+ // When input routing is enabled, there are expected to be at least 2 total selected
+ // devices: one output device and one input device.
+ isSelectedDeviceNotAGroup = getSelectedMediaDevice().size() <= 2;
+ }
+
// Attach "Connect a device" item only when current output is not remote and not a group
- if (!isCurrentConnectedDeviceRemote() && getSelectedMediaDevice().size() == 1) {
+ if (!isCurrentConnectedDeviceRemote() && isSelectedDeviceNotAGroup) {
mediaItems.add(MediaItem.createPairNewDeviceMediaItem());
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
index a3b7590117c1..d2b1d5449aaf 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
@@ -56,7 +56,7 @@ import com.android.systemui.settings.DisplayTracker;
import com.android.systemui.shared.statusbar.phone.BarTransitions.TransitionMode;
import com.android.systemui.shared.system.TaskStackChangeListeners;
import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.phone.AutoHideController;
+import com.android.systemui.statusbar.phone.AutoHideControllerStore;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.Utils;
@@ -124,7 +124,7 @@ public class NavigationBarControllerImpl implements
TaskbarDelegate taskbarDelegate,
NavigationBarComponent.Factory navigationBarComponentFactory,
DumpManager dumpManager,
- AutoHideController autoHideController,
+ AutoHideControllerStore autoHideControllerStore,
LightBarController lightBarController,
TaskStackChangeListeners taskStackChangeListeners,
Optional<Pip> pipOptional,
@@ -146,8 +146,9 @@ public class NavigationBarControllerImpl implements
mTaskbarDelegate = taskbarDelegate;
mTaskbarDelegate.setDependencies(commandQueue, overviewProxyService,
navBarHelper, navigationModeController, sysUiFlagsContainer,
- dumpManager, autoHideController, lightBarController, pipOptional,
- backAnimation.orElse(null), taskStackChangeListeners);
+ dumpManager, autoHideControllerStore.forDisplay(mContext.getDisplayId()),
+ lightBarController, pipOptional, backAnimation.orElse(null),
+ taskStackChangeListeners);
mIsLargeScreen = isLargeScreen(mContext);
mIsPhone = determineIfPhone(mContext, deviceStateManager);
dumpManager.registerDumpable(this);
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
index 96c0cac53908..c895732f79f6 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
@@ -151,6 +151,7 @@ import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.phone.AutoHideController;
+import com.android.systemui.statusbar.phone.AutoHideControllerStore;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -261,8 +262,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
private final LightBarController mMainLightBarController;
private final LightBarController.Factory mLightBarControllerFactory;
private AutoHideController mAutoHideController;
- private final AutoHideController mMainAutoHideController;
- private final AutoHideController.Factory mAutoHideControllerFactory;
+ private final AutoHideControllerStore mAutoHideControllerStore;
private final Optional<TelecomManager> mTelecomManagerOptional;
private final InputMethodManager mInputMethodManager;
private final TaskStackChangeListeners mTaskStackChangeListeners;
@@ -582,8 +582,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
NavBarHelper navBarHelper,
LightBarController mainLightBarController,
LightBarController.Factory lightBarControllerFactory,
- AutoHideController mainAutoHideController,
- AutoHideController.Factory autoHideControllerFactory,
+ AutoHideControllerStore autoHideControllerStore,
Optional<TelecomManager> telecomManagerOptional,
InputMethodManager inputMethodManager,
DeadZone deadZone,
@@ -630,8 +629,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
mNotificationShadeDepthController = notificationShadeDepthController;
mMainLightBarController = mainLightBarController;
mLightBarControllerFactory = lightBarControllerFactory;
- mMainAutoHideController = mainAutoHideController;
- mAutoHideControllerFactory = autoHideControllerFactory;
+ mAutoHideControllerStore = autoHideControllerStore;
mTelecomManagerOptional = telecomManagerOptional;
mInputMethodManager = inputMethodManager;
mUserContextProvider = userContextProvider;
@@ -846,13 +844,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
? mMainLightBarController : mLightBarControllerFactory.create(mContext);
setLightBarController(lightBarController);
- // TODO(b/118592525): to support multi-display, we start to add something which is
- // per-display, while others may be global. I think it's time to
- // add a new class maybe named DisplayDependency to solve
- // per-display Dependency problem.
- // Alternative: this is a good case for a Dagger subcomponent. Same with LightBarController.
- AutoHideController autoHideController = mIsOnDefaultDisplay
- ? mMainAutoHideController : mAutoHideControllerFactory.create(mContext);
+ AutoHideController autoHideController = mAutoHideControllerStore.forDisplay(mDisplayId);
setAutoHideController(autoHideController);
restoreAppearanceAndTransientState();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
index 5167d173647e..9dc21fb89b16 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
@@ -629,11 +629,7 @@ constructor(
id = R.string.accessibility_quick_settings_expand
)
)
- .padding(
- horizontal = {
- QuickSettingsShade.Dimensions.Padding.roundToPx()
- }
- )
+ .padding(horizontal = qsHorizontalMargin())
) {
QuickQuickSettingsLayout(
tiles = Tiles,
@@ -737,8 +733,8 @@ constructor(
.sysuiResTag(ResIdTags.quickSettingsPanel)
.padding(
top = QuickSettingsShade.Dimensions.Padding,
- start = QuickSettingsShade.Dimensions.Padding,
- end = QuickSettingsShade.Dimensions.Padding,
+ start = qsHorizontalMargin(),
+ end = qsHorizontalMargin(),
)
) {
QuickSettingsLayout(
@@ -1127,6 +1123,8 @@ private object ResIdTags {
const val qsFooterActions = "qs_footer_actions"
}
+@Composable private fun qsHorizontalMargin() = dimensionResource(id = R.dimen.qs_horizontal_margin)
+
@Composable
private fun interactionsConfig() =
InteractionsConfig(
diff --git a/packages/SystemUI/src/com/android/systemui/qs/flags/QsInCompose.kt b/packages/SystemUI/src/com/android/systemui/qs/flags/QsInCompose.kt
new file mode 100644
index 000000000000..3067ccbb7cea
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/flags/QsInCompose.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.flags
+
+import com.android.systemui.flags.RefactorFlagUtils
+import com.android.systemui.shade.shared.flag.DualShade
+
+/**
+ * Object to help check if the new QS ui should be used. This is true if either [QSComposeFragment]
+ * or [DualShade] are enabled.
+ */
+object QsInCompose {
+
+ /**
+ * This is not a real flag name, but a representation of the allowed flag names. Should not be
+ * used with test annotations.
+ */
+ private val flagName = "${QSComposeFragment.FLAG_NAME}|${DualShade.FLAG_NAME}"
+
+ @JvmStatic
+ inline val isEnabled: Boolean
+ get() = QSComposeFragment.isEnabled || DualShade.isEnabled
+
+ @JvmStatic
+ fun isUnexpectedlyInLegacyMode() =
+ RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, flagName)
+
+ @JvmStatic fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, flagName)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractor.kt
index 4806c3f83224..8f870d468997 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractor.kt
@@ -18,7 +18,7 @@ package com.android.systemui.qs.tiles.impl.custom.domain.interactor
import android.os.UserHandle
import android.service.quicksettings.Tile
-import com.android.app.tracing.coroutines.launchTraced as launch
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
@@ -28,7 +28,6 @@ import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTilePacka
import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel
import com.android.systemui.qs.tiles.impl.di.QSTileScope
import com.android.systemui.user.data.repository.UserRepository
-import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -45,6 +44,7 @@ import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.shareIn
+import com.android.app.tracing.coroutines.launchTraced as launch
@QSTileScope
@OptIn(ExperimentalCoroutinesApi::class)
@@ -64,7 +64,7 @@ constructor(
private val bindingFlow =
mutableUserFlow
.flatMapLatest { user ->
- conflatedCallbackFlow {
+ ConflatedCallbackFlow.conflatedCallbackFlow {
serviceInteractor.setUser(user)
// Wait for the CustomTileInteractor to become initialized first, because
@@ -79,7 +79,7 @@ constructor(
defaultsRepository.requestNewDefaults(
user,
tileSpec.componentName,
- true,
+ true
)
}
.launchIn(this)
@@ -99,7 +99,7 @@ constructor(
override fun tileData(
user: UserHandle,
- triggers: Flow<DataUpdateTrigger>,
+ triggers: Flow<DataUpdateTrigger>
): Flow<CustomTileDataModel> {
tileScope.launch { mutableUserFlow.emit(user) }
return bindingFlow.combine(triggers) { _, _ -> }.flatMapLatest { dataFlow(user) }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
index f9a1ad5d8424..ab3862b75ee8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
@@ -25,7 +25,6 @@ import com.android.systemui.Dumpable
import com.android.systemui.animation.Expandable
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.dagger.qualifiers.UiBackground
import com.android.systemui.plugins.qs.QSTile
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.tileimpl.QSTileImpl.DrawableIcon
@@ -36,17 +35,14 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import java.io.PrintWriter
import java.util.concurrent.CopyOnWriteArraySet
-import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collectIndexed
import kotlinx.coroutines.flow.filterNotNull
-import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.takeWhile
-import kotlinx.coroutines.launch
// TODO(b/http://b/299909989): Use QSTileViewModel directly after the rollout
class QSTileViewModelAdapter
@@ -55,7 +51,6 @@ constructor(
@Application private val applicationScope: CoroutineScope,
private val qsHost: QSHost,
@Assisted private val qsTileViewModel: QSTileViewModel,
- @UiBackground private val uiBgDispatcher: CoroutineDispatcher,
) : QSTile, Dumpable {
private val context
@@ -167,25 +162,19 @@ constructor(
override fun setListening(client: Any?, listening: Boolean) {
client ?: return
if (listening) {
- applicationScope.launch(uiBgDispatcher) {
- val shouldStartMappingJob =
- listeningClients.add(client) // new client
- && listeningClients.size == 1 // first client
-
- if (shouldStartMappingJob) {
- stateJob =
- qsTileViewModel.state
- .filterNotNull()
- .map { mapState(context, it, qsTileViewModel.config) }
- .onEach { legacyState ->
- val changed = legacyState.copyTo(cachedState)
- if (changed) {
- callbacks.forEach { it.onStateChanged(legacyState) }
- }
+ val clientWasNotAlreadyListening = listeningClients.add(client)
+ if (clientWasNotAlreadyListening && listeningClients.size == 1) {
+ stateJob =
+ qsTileViewModel.state
+ .filterNotNull()
+ .map { mapState(context, it, qsTileViewModel.config) }
+ .onEach { legacyState ->
+ val changed = legacyState.copyTo(cachedState)
+ if (changed) {
+ callbacks.forEach { it.onStateChanged(legacyState) }
}
- .flowOn(uiBgDispatcher)
- .launchIn(applicationScope)
- }
+ }
+ .launchIn(applicationScope)
}
} else {
listeningClients.remove(client)
diff --git a/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt
index e441a23d3725..e36e40d312b5 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt
@@ -29,6 +29,7 @@ import com.android.systemui.scene.domain.startable.StatusBarStartable
import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.SceneContainerConfig
import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.ui.composable.SceneContainerTransitions
import com.android.systemui.scene.ui.viewmodel.SplitEdgeDetector
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shade.shared.flag.DualShade
@@ -98,6 +99,7 @@ interface KeyguardlessSceneContainerFrameworkModule {
Scenes.Shade.takeUnless { DualShade.isEnabled },
),
initialSceneKey = Scenes.Gone,
+ transitions = SceneContainerTransitions,
overlayKeys =
listOfNotNull(
Overlays.NotificationsShade.takeIf { DualShade.isEnabled },
diff --git a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
index 4beec1041a03..fe014524e3da 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
@@ -29,6 +29,7 @@ import com.android.systemui.scene.domain.startable.StatusBarStartable
import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.SceneContainerConfig
import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.ui.composable.SceneContainerTransitions
import com.android.systemui.scene.ui.viewmodel.SplitEdgeDetector
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shade.shared.flag.DualShade
@@ -106,6 +107,7 @@ interface SceneContainerFrameworkModule {
Scenes.Shade.takeUnless { DualShade.isEnabled },
),
initialSceneKey = Scenes.Lockscreen,
+ transitions = SceneContainerTransitions,
overlayKeys =
listOfNotNull(
Overlays.NotificationsShade.takeIf { DualShade.isEnabled },
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt
index 16ed59f4e6f2..c1646b8f2060 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt
@@ -20,6 +20,7 @@ import com.android.systemui.scene.domain.SceneDomainModule
import com.android.systemui.scene.domain.resolver.HomeSceneFamilyResolverModule
import com.android.systemui.scene.shared.model.SceneContainerConfig
import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.ui.composable.SceneContainerTransitions
import dagger.Module
import dagger.Provides
@@ -35,7 +36,7 @@ import dagger.Provides
// List SceneResolver modules for supported SceneFamilies
HomeSceneFamilyResolverModule::class,
- ],
+ ]
)
object ShadelessSceneContainerFrameworkModule {
@@ -46,20 +47,12 @@ object ShadelessSceneContainerFrameworkModule {
return SceneContainerConfig(
// Note that this list is in z-order. The first one is the bottom-most and the
// last one is top-most.
- sceneKeys =
- listOf(
- Scenes.Gone,
- Scenes.Lockscreen,
- Scenes.Bouncer,
- ),
+ sceneKeys = listOf(Scenes.Gone, Scenes.Lockscreen, Scenes.Bouncer),
initialSceneKey = Scenes.Lockscreen,
+ transitions = SceneContainerTransitions,
overlayKeys = emptyList(),
navigationDistances =
- mapOf(
- Scenes.Gone to 0,
- Scenes.Lockscreen to 0,
- Scenes.Bouncer to 1,
- )
+ mapOf(Scenes.Gone to 0, Scenes.Lockscreen to 0, Scenes.Bouncer to 1),
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfig.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfig.kt
index 2311e47abfae..ce7be8311c68 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfig.kt
@@ -18,6 +18,7 @@ package com.android.systemui.scene.shared.model
import com.android.compose.animation.scene.OverlayKey
import com.android.compose.animation.scene.SceneKey
+import com.android.compose.animation.scene.SceneTransitions
/** Models the configuration of the scene container. */
data class SceneContainerConfig(
@@ -38,6 +39,9 @@ data class SceneContainerConfig(
*/
val initialSceneKey: SceneKey,
+ /** Transition definitions to be used when animating between scene transitions. */
+ val transitions: SceneTransitions,
+
/**
* The keys to all overlays in the container, sorted by z-order such that the last one renders
* on top of all previous ones. Overlay keys within the same container must not repeat but it's
@@ -61,7 +65,7 @@ data class SceneContainerConfig(
* Note that this is not the z-order of rendering; that's determined by the order of declaration
* of scenes in the [sceneKeys] list.
*/
- val navigationDistances: Map<SceneKey, Int>
+ val navigationDistances: Map<SceneKey, Int>,
) {
init {
check(sceneKeys.isNotEmpty()) { "A container must have at least one scene key." }
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
index 1e3a233bfc7e..1c15c74d5631 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
@@ -196,6 +196,7 @@ object SceneWindowRootViewBinder {
sceneByKey = sceneByKey,
overlayByKey = overlayByKey,
initialSceneKey = containerConfig.initialSceneKey,
+ sceneTransitions = containerConfig.transitions,
dataSourceDelegator = dataSourceDelegator,
qsSceneAdapter = qsSceneAdapter,
)
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotShelfView.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotShelfView.kt
index b8ea8f9052ca..c5c705c97b8d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotShelfView.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotShelfView.kt
@@ -29,6 +29,7 @@ import android.view.View
import android.view.ViewGroup
import android.view.WindowInsets
import android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL
+import android.view.accessibility.AccessibilityEvent
import android.widget.FrameLayout
import android.widget.ImageView
import com.android.systemui.res.R
@@ -83,6 +84,20 @@ class ScreenshotShelfView(context: Context, attrs: AttributeSet? = null) :
})
gestureDetector.setIsLongpressEnabled(false)
+
+ // Extend the timeout on any accessibility event (e.g. voice access or explore-by-touch).
+ setAccessibilityDelegate(
+ object : AccessibilityDelegate() {
+ override fun onRequestSendAccessibilityEvent(
+ host: ViewGroup,
+ child: View,
+ event: AccessibilityEvent,
+ ): Boolean {
+ userInteractionCallback?.invoke()
+ return super.onRequestSendAccessibilityEvent(host, child, event)
+ }
+ }
+ )
}
override fun onFinishInflate() {
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
index 8c004c4d3adf..6844f053cd21 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
@@ -48,7 +48,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.brightness.ui.viewmodel.BrightnessSliderViewModel;
import com.android.systemui.compose.ComposeInitializer;
import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.qs.flags.QSComposeFragment;
+import com.android.systemui.qs.flags.QsInCompose;
import com.android.systemui.res.R;
import com.android.systemui.shade.domain.interactor.ShadeInteractor;
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
@@ -96,7 +96,7 @@ public class BrightnessDialog extends Activity {
super.onCreate(savedInstanceState);
setWindowAttributes();
View view;
- if (!QSComposeFragment.isEnabled()) {
+ if (!QsInCompose.isEnabled()) {
setContentView(R.layout.brightness_mirror_container);
view = findViewById(R.id.brightness_mirror_container);
setDialogContent((FrameLayout) view);
@@ -140,7 +140,7 @@ public class BrightnessDialog extends Activity {
window.getDecorView();
window.setLayout(WRAP_CONTENT, WRAP_CONTENT);
getTheme().applyStyle(R.style.Theme_SystemUI_QuickSettings, false);
- if (QSComposeFragment.isEnabled()) {
+ if (QsInCompose.isEnabled()) {
window.getDecorView().addOnAttachStateChangeListener(
new View.OnAttachStateChangeListener() {
@Override
@@ -217,7 +217,7 @@ public class BrightnessDialog extends Activity {
@Override
protected void onStart() {
super.onStart();
- if (!QSComposeFragment.isEnabled()) {
+ if (!QsInCompose.isEnabled()) {
mBrightnessController.registerCallbacks();
}
MetricsLogger.visible(this, MetricsEvent.BRIGHTNESS_DIALOG);
@@ -241,7 +241,7 @@ public class BrightnessDialog extends Activity {
protected void onStop() {
super.onStop();
MetricsLogger.hidden(this, MetricsEvent.BRIGHTNESS_DIALOG);
- if (!QSComposeFragment.isEnabled()) {
+ if (!QsInCompose.isEnabled()) {
mBrightnessController.unregisterCallbacks();
}
}
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 84c7ab200fad..9e9a38e87924 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt
@@ -26,6 +26,7 @@ import com.android.systemui.display.data.repository.DisplayScopeRepository
import com.android.systemui.statusbar.data.repository.LightBarControllerStore
import com.android.systemui.statusbar.data.repository.PrivacyDotWindowControllerStore
import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryStore
+import com.android.systemui.statusbar.phone.AutoHideControllerStore
import com.android.systemui.statusbar.window.StatusBarWindowControllerStore
import com.android.systemui.statusbar.window.data.repository.StatusBarWindowStateRepositoryStore
import com.android.systemui.util.kotlin.pairwiseBy
@@ -50,6 +51,7 @@ constructor(
private val initializerStore: StatusBarInitializerStore,
private val statusBarWindowControllerStore: StatusBarWindowControllerStore,
private val statusBarInitializerStore: StatusBarInitializerStore,
+ private val autoHideControllerStore: AutoHideControllerStore,
private val privacyDotWindowControllerStore: PrivacyDotWindowControllerStore,
private val lightBarControllerStore: LightBarControllerStore,
) : CoreStartable {
@@ -95,6 +97,7 @@ constructor(
statusBarModeRepositoryStore.forDisplay(displayId),
initializerStore.forDisplay(displayId),
statusBarWindowControllerStore.forDisplay(displayId),
+ autoHideControllerStore.forDisplay(displayId),
)
.start()
}
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 ff4760fd2837..9f5a3116948f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarOrchestrator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarOrchestrator.kt
@@ -71,9 +71,9 @@ constructor(
@Assisted private val statusBarInitializer: StatusBarInitializer,
@Assisted private val statusBarWindowController: StatusBarWindowController,
@Main private val mainContext: CoroutineContext,
+ @Assisted private val autoHideController: AutoHideController,
private val demoModeController: DemoModeController,
private val pluginDependencyProvider: PluginDependencyProvider,
- private val autoHideController: AutoHideController,
private val remoteInputManager: NotificationRemoteInputManager,
private val notificationShadeWindowViewControllerLazy:
Lazy<NotificationShadeWindowViewController>,
@@ -210,10 +210,6 @@ constructor(
}
private fun setUpAutoHide() {
- if (displayId != Display.DEFAULT_DISPLAY) {
- return
- }
- // TODO(b/373309973): per display implementation of auto hide controller
autoHideController.setStatusBar(
object : AutoHideUiElement {
override fun synchronizeState() {}
@@ -241,10 +237,7 @@ constructor(
if (!demoModeController.isInDemoMode) {
barTransitions.transitionTo(barMode.toTransitionModeInt(), animate)
}
- if (displayId == Display.DEFAULT_DISPLAY) {
- // TODO(b/373309973): per display implementation of auto hide controller
- autoHideController.touchAutoHide()
- }
+ autoHideController.touchAutoHide()
}
private fun updateBubblesVisibility(statusBarVisible: Boolean) {
@@ -288,6 +281,7 @@ constructor(
statusBarModeRepository: StatusBarModePerDisplayRepository,
statusBarInitializer: StatusBarInitializer,
statusBarWindowController: StatusBarWindowController,
+ autoHideController: AutoHideController,
): StatusBarOrchestrator
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt
index b67092ca9348..0569074c88b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt
@@ -17,98 +17,16 @@
package com.android.systemui.statusbar.notification
import android.content.Context
-import android.provider.DeviceConfig
-import com.android.internal.annotations.VisibleForTesting
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.NOTIFICATIONS_USE_PEOPLE_FILTERING
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.statusbar.notification.collection.NotificationClassificationFlag
-import com.android.systemui.statusbar.notification.shared.NotificationMinimalism
-import com.android.systemui.statusbar.notification.shared.PriorityPeopleSection
-import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING
-import com.android.systemui.statusbar.notification.stack.BUCKET_FOREGROUND_SERVICE
-import com.android.systemui.statusbar.notification.stack.BUCKET_HEADS_UP
-import com.android.systemui.statusbar.notification.stack.BUCKET_MEDIA_CONTROLS
-import com.android.systemui.statusbar.notification.stack.BUCKET_PEOPLE
-import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT
-import com.android.systemui.statusbar.notification.stack.PriorityBucket
-import com.android.systemui.util.DeviceConfigProxy
import com.android.systemui.util.Utils
import javax.inject.Inject
-private var sUsePeopleFiltering: Boolean? = null
-
-/** Feature controller for the NOTIFICATIONS_USE_PEOPLE_FILTERING config. */
@SysUISingleton
class NotificationSectionsFeatureManager
@Inject
-constructor(val proxy: DeviceConfigProxy, val context: Context) {
-
- fun isFilteringEnabled(): Boolean {
- return usePeopleFiltering(proxy)
- }
+constructor(val context: Context) {
fun isMediaControlsEnabled(): Boolean {
return Utils.useQsMediaPlayer(context)
}
-
- fun getNotificationBuckets(): IntArray {
- if (
- PriorityPeopleSection.isEnabled ||
- NotificationMinimalism.isEnabled ||
- NotificationClassificationFlag.isEnabled
- ) {
- // We don't need this list to be adaptive, it can be the superset of all features.
- return PriorityBucket.getAllInOrder()
- }
- return when {
- isFilteringEnabled() && isMediaControlsEnabled() ->
- intArrayOf(
- BUCKET_HEADS_UP,
- BUCKET_FOREGROUND_SERVICE,
- BUCKET_MEDIA_CONTROLS,
- BUCKET_PEOPLE,
- BUCKET_ALERTING,
- BUCKET_SILENT
- )
- !isFilteringEnabled() && isMediaControlsEnabled() ->
- intArrayOf(
- BUCKET_HEADS_UP,
- BUCKET_FOREGROUND_SERVICE,
- BUCKET_MEDIA_CONTROLS,
- BUCKET_ALERTING,
- BUCKET_SILENT
- )
- isFilteringEnabled() && !isMediaControlsEnabled() ->
- intArrayOf(
- BUCKET_HEADS_UP,
- BUCKET_FOREGROUND_SERVICE,
- BUCKET_PEOPLE,
- BUCKET_ALERTING,
- BUCKET_SILENT
- )
- else -> intArrayOf(BUCKET_ALERTING, BUCKET_SILENT)
- }
- }
-
- fun getNumberOfBuckets(): Int {
- return getNotificationBuckets().size
- }
-
- @VisibleForTesting
- fun clearCache() {
- sUsePeopleFiltering = null
- }
-}
-
-private fun usePeopleFiltering(proxy: DeviceConfigProxy): Boolean {
- if (sUsePeopleFiltering == null) {
- sUsePeopleFiltering =
- proxy.getBoolean(
- DeviceConfig.NAMESPACE_SYSTEMUI,
- NOTIFICATIONS_USE_PEOPLE_FILTERING,
- true
- )
- }
-
- return sUsePeopleFiltering!!
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
index 81335658679b..64e78e4fbe48 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
@@ -98,22 +98,17 @@ constructor(
}
/** Are there any pinned heads up rows to display? */
- val hasPinnedRows: Flow<Boolean> by lazy {
- if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) {
- flowOf(false)
- } else {
- headsUpRepository.activeHeadsUpRows.flatMapLatest { rows ->
- if (rows.isNotEmpty()) {
- combine(rows.map { it.pinnedStatus }) { pinnedStatus ->
- pinnedStatus.any { it.isPinned }
- }
- } else {
- // if the set is empty, there are no flows to combine
- flowOf(false)
+ val hasPinnedRows: Flow<Boolean> =
+ headsUpRepository.activeHeadsUpRows.flatMapLatest { rows ->
+ if (rows.isNotEmpty()) {
+ combine(rows.map { it.pinnedStatus }) { pinnedStatus ->
+ pinnedStatus.any { it.isPinned }
}
+ } else {
+ // if the set is empty, there are no flows to combine
+ flowOf(false)
}
}
- }
val isHeadsUpOrAnimatingAway: Flow<Boolean> by lazy {
if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) {
@@ -143,15 +138,10 @@ constructor(
}
}
- val showHeadsUpStatusBar: Flow<Boolean> by lazy {
- if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) {
- flowOf(false)
- } else {
- combine(hasPinnedRows, canShowHeadsUp) { hasPinnedRows, canShowHeadsUp ->
- hasPinnedRows && canShowHeadsUp
- }
+ val showHeadsUpStatusBar =
+ combine(hasPinnedRows, canShowHeadsUp) { hasPinnedRows, canShowHeadsUp ->
+ hasPinnedRows && canShowHeadsUp
}
- }
fun headsUpRow(key: HeadsUpRowKey): HeadsUpRowInteractor =
HeadsUpRowInteractor(key as HeadsUpRowRepository)
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 b7ab996a608c..7ad65fc64735 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
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.notification.row;
+import static android.app.Flags.notificationsRedesignTemplates;
import static android.app.Notification.Action.SEMANTIC_ACTION_MARK_CONVERSATION_AS_PRIORITY;
import static android.service.notification.NotificationListenerService.REASON_CANCEL;
@@ -102,6 +103,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
import com.android.systemui.statusbar.notification.headsup.PinnedStatus;
import com.android.systemui.statusbar.notification.logging.NotificationCounters;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
@@ -121,7 +123,6 @@ import com.android.systemui.statusbar.notification.stack.NotificationChildrenCon
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.SwipeableView;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
import com.android.systemui.statusbar.policy.InflatedSmartReplyState;
import com.android.systemui.statusbar.policy.RemoteInputView;
import com.android.systemui.statusbar.policy.SmartReplyConstants;
@@ -2083,8 +2084,13 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
R.dimen.notification_min_height_before_p);
mMaxSmallHeightBeforeS = NotificationUtils.getFontScaledHeight(mContext,
R.dimen.notification_min_height_before_s);
- mMaxSmallHeight = NotificationUtils.getFontScaledHeight(mContext,
- R.dimen.notification_min_height);
+ if (notificationsRedesignTemplates()) {
+ mMaxSmallHeight = NotificationUtils.getFontScaledHeight(mContext,
+ R.dimen.notification_2025_min_height);
+ } else {
+ mMaxSmallHeight = NotificationUtils.getFontScaledHeight(mContext,
+ R.dimen.notification_min_height);
+ }
mMaxSmallHeightLarge = NotificationUtils.getFontScaledHeight(mContext,
R.dimen.notification_min_height_increased);
mMaxExpandedHeight = NotificationUtils.getFontScaledHeight(mContext,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
index 31e4d2cac50c..043d64e46039 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
@@ -21,7 +21,6 @@ import android.view.View
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.media.controls.ui.controller.KeyguardMediaController
import com.android.systemui.shade.ShadeDisplayAware
-import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
import com.android.systemui.statusbar.notification.SourceType
import com.android.systemui.statusbar.notification.collection.NotificationClassificationFlag
import com.android.systemui.statusbar.notification.collection.render.MediaContainerController
@@ -36,6 +35,7 @@ import com.android.systemui.statusbar.notification.dagger.SilentHeader
import com.android.systemui.statusbar.notification.dagger.SocialHeader
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
+import com.android.systemui.statusbar.notification.stack.PriorityBucket
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.foldToSparseArray
@@ -51,7 +51,6 @@ class NotificationSectionsManager
internal constructor(
@ShadeDisplayAware private val configurationController: ConfigurationController,
private val keyguardMediaController: KeyguardMediaController,
- private val sectionsFeatureManager: NotificationSectionsFeatureManager,
private val mediaContainerController: MediaContainerController,
private val notificationRoundnessManager: NotificationRoundnessManager,
@IncomingHeader private val incomingHeaderController: SectionHeaderController,
@@ -120,8 +119,8 @@ internal constructor(
}
fun createSectionsForBuckets(): Array<NotificationSection> =
- sectionsFeatureManager
- .getNotificationBuckets()
+ PriorityBucket
+ .getAllInOrder()
.map { NotificationSection(it) }
.toTypedArray()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
index a55a165d9b66..01efd5de93ed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
@@ -43,6 +43,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
import com.android.systemui.keyguard.shared.model.StatusBarState.SHADE
import com.android.systemui.keyguard.shared.model.StatusBarState.SHADE_LOCKED
import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerToGoneTransitionViewModel
+import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerToPrimaryBouncerTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel
import com.android.systemui.keyguard.ui.viewmodel.AodToGoneTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.AodToLockscreenTransitionViewModel
@@ -124,6 +125,8 @@ constructor(
private val notificationStackAppearanceInteractor: NotificationStackAppearanceInteractor,
private val alternateBouncerToGoneTransitionViewModel:
AlternateBouncerToGoneTransitionViewModel,
+ private val alternateBouncerToPrimaryBouncerTransitionViewModel:
+ AlternateBouncerToPrimaryBouncerTransitionViewModel,
private val aodToGoneTransitionViewModel: AodToGoneTransitionViewModel,
private val aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel,
private val aodToOccludedTransitionViewModel: AodToOccludedTransitionViewModel,
@@ -560,6 +563,7 @@ constructor(
lockscreenToGoneTransitionViewModel.notificationAlpha(viewState),
lockscreenToOccludedTransitionViewModel.lockscreenAlpha,
lockscreenToPrimaryBouncerTransitionViewModel.lockscreenAlpha,
+ alternateBouncerToPrimaryBouncerTransitionViewModel.lockscreenAlpha,
occludedToAodTransitionViewModel.lockscreenAlpha,
occludedToGoneTransitionViewModel.notificationAlpha(viewState),
occludedToLockscreenTransitionViewModel.lockscreenAlpha,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
index b9639a7a90f2..677ed9f1ccdc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
@@ -37,19 +37,20 @@ import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.CrossFadeHelper;
import com.android.systemui.statusbar.HeadsUpStatusBarView;
import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.core.StatusBarRootModernization;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.SourceType;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationIconInteractor;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation;
import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.phone.fragment.dagger.HomeStatusBarScope;
import com.android.systemui.statusbar.policy.Clock;
-import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.statusbar.notification.headsup.OnHeadsUpChangedListener;
import com.android.systemui.util.ViewController;
import java.util.ArrayList;
@@ -249,10 +250,14 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar
updateParentClipping(false /* shouldClip */);
mView.setVisibility(View.VISIBLE);
show(mView);
- hide(mClockView, View.INVISIBLE);
+ if (!StatusBarRootModernization.isEnabled()) {
+ hide(mClockView, View.INVISIBLE);
+ }
mOperatorNameViewOptional.ifPresent(view -> hide(view, View.INVISIBLE));
} else {
- show(mClockView);
+ if (!StatusBarRootModernization.isEnabled()) {
+ show(mClockView);
+ }
mOperatorNameViewOptional.ifPresent(this::show);
hide(mView, View.GONE, () -> {
updateParentClipping(true /* shouldClip */);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarControllerImpl.java
index 1a4f3ca5b07f..ea67f1cdb60a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarControllerImpl.java
@@ -527,12 +527,16 @@ public class LightBarControllerImpl implements
@Override
public LightBarController create(@NonNull Context context) {
// TODO: b/380394368 - Make sure correct per display instances are used.
- return mFactory.create(
+ LightBarControllerImpl lightBarController = mFactory.create(
context.getDisplayId(),
mApplicationScope,
mDarkIconDispatcherStore.getDefaultDisplay(),
mStatusBarModeRepositoryStore.getDefaultDisplay()
);
+ // Calling start() manually to keep the legacy behavior. Before, LightBarControllerImpl
+ // was doing work in the constructor, which moved to start().
+ lightBarController.start();
+ return lightBarController;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index aef26dea3c0d..bd1360f6e939 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -818,7 +818,10 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
* dragging it and translation should be deferred {@see KeyguardBouncer#show(boolean, boolean)}
*/
public void showPrimaryBouncer(boolean scrimmed) {
- hideAlternateBouncer(false);
+ hideAlternateBouncer(
+ /* updateScrim= */ false,
+ // When the scene framework is on, don't ever clear the pending dismiss action from
+ /* clearDismissAction= */ !SceneContainerFlag.isEnabled());
if (mKeyguardStateController.isShowing() && !isBouncerShowing()) {
if (SceneContainerFlag.isEnabled()) {
mSceneInteractorLazy.get().changeScene(
@@ -1005,6 +1008,15 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
@Override
public void hideAlternateBouncer(boolean updateScrim) {
+ hideAlternateBouncer(updateScrim, /* clearDismissAction= */ true);
+ }
+
+ @Override
+ public void hideAlternateBouncer(boolean updateScrim, boolean clearDismissAction) {
+ if (clearDismissAction) {
+ mKeyguardDismissActionInteractor.get().clearDismissAction();
+ }
+
updateAlternateBouncerShowing(mAlternateBouncerInteractor.hide() && updateScrim);
}
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 42b9d5b12afc..4f32aaa2654e 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
@@ -35,8 +35,6 @@ import com.android.systemui.statusbar.data.repository.PrivacyDotViewControllerSt
import com.android.systemui.statusbar.data.repository.PrivacyDotWindowControllerStoreModule
import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryStore
import com.android.systemui.statusbar.events.PrivacyDotViewControllerModule
-import com.android.systemui.statusbar.phone.AutoHideController
-import com.android.systemui.statusbar.phone.AutoHideControllerImpl
import com.android.systemui.statusbar.phone.AutoHideControllerStore
import com.android.systemui.statusbar.phone.CentralSurfacesCommandQueueCallbacks
import com.android.systemui.statusbar.phone.MultiDisplayAutoHideControllerStore
@@ -80,9 +78,6 @@ interface StatusBarPhoneModule {
@Binds fun statusBarInitializer(@Default impl: StatusBarInitializerImpl): StatusBarInitializer
- @Binds
- fun autoHideControllerFactory(impl: AutoHideControllerImpl.Factory): AutoHideController.Factory
-
companion object {
/** Binds {@link StatusBarInitializer} as a {@link CoreStartable}. */
@Provides
@@ -128,6 +123,7 @@ interface StatusBarPhoneModule {
statusBarModeRepositoryStore: StatusBarModeRepositoryStore,
initializerStore: StatusBarInitializerStore,
statusBarWindowControllerStore: StatusBarWindowControllerStore,
+ autoHideControllerStore: AutoHideControllerStore,
statusBarOrchestratorFactory: StatusBarOrchestrator.Factory,
): StatusBarOrchestrator {
return statusBarOrchestratorFactory.create(
@@ -137,6 +133,7 @@ interface StatusBarPhoneModule {
statusBarModeRepositoryStore.defaultDisplay,
initializerStore.defaultDisplay,
statusBarWindowControllerStore.defaultDisplay,
+ autoHideControllerStore.defaultDisplay,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/domain/interactor/CollapsedStatusBarInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/domain/interactor/CollapsedStatusBarInteractor.kt
index b2a0272c06d1..a0cb8298bdb2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/domain/interactor/CollapsedStatusBarInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/domain/interactor/CollapsedStatusBarInteractor.kt
@@ -30,13 +30,13 @@ import kotlinx.coroutines.flow.map
@SysUISingleton
class CollapsedStatusBarInteractor
@Inject
-constructor(DisableFlagsInteractor: DisableFlagsInteractor) {
+constructor(disableFlagsInteractor: DisableFlagsInteractor) {
/**
* The visibilities of various status bar child views, based only on the information we received
* from disable flags.
*/
val visibilityViaDisableFlags: Flow<StatusBarDisableFlagsVisibilityModel> =
- DisableFlagsInteractor.disableFlags.map {
+ disableFlagsInteractor.disableFlags.map {
StatusBarDisableFlagsVisibilityModel(
isClockAllowed = it.isClockEnabled,
areNotificationIconsAllowed = it.areNotificationIconsEnabled,
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 6a9b43c995e4..c52275a9eaa4 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
@@ -32,6 +32,7 @@ import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
import com.android.systemui.statusbar.chips.ui.model.MultipleOngoingActivityChipsModel
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModel
@@ -39,6 +40,7 @@ import com.android.systemui.statusbar.events.domain.interactor.SystemStatusEvent
import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState
import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.Idle
import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
+import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor
import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor
import com.android.systemui.statusbar.phone.domain.interactor.LightsOutInteractor
import com.android.systemui.statusbar.pipeline.shared.domain.interactor.CollapsedStatusBarInteractor
@@ -137,6 +139,7 @@ constructor(
collapsedStatusBarInteractor: CollapsedStatusBarInteractor,
private val lightsOutInteractor: LightsOutInteractor,
private val notificationsInteractor: ActiveNotificationsInteractor,
+ headsUpNotificationInteractor: HeadsUpNotificationInteractor,
keyguardTransitionInteractor: KeyguardTransitionInteractor,
keyguardInteractor: KeyguardInteractor,
sceneInteractor: SceneInteractor,
@@ -222,27 +225,43 @@ constructor(
isHomeStatusBarAllowed && !isSecureCameraActive
}
+ private val isAnyChipVisible =
+ if (StatusBarNotifChips.isEnabled) {
+ ongoingActivityChips.map { it.primary is OngoingActivityChipModel.Shown }
+ } else {
+ primaryOngoingActivityChip.map { it is OngoingActivityChipModel.Shown }
+ }
+
override val isClockVisible: Flow<VisibilityModel> =
combine(
shouldHomeStatusBarBeVisible,
+ headsUpNotificationInteractor.showHeadsUpStatusBar,
collapsedStatusBarInteractor.visibilityViaDisableFlags,
- ) { shouldStatusBarBeVisible, visibilityViaDisableFlags ->
- val showClock = shouldStatusBarBeVisible && visibilityViaDisableFlags.isClockAllowed
- // TODO(b/364360986): Take CollapsedStatusBarFragment.clockHiddenMode into account.
- VisibilityModel(showClock.toVisibilityInt(), visibilityViaDisableFlags.animate)
+ ) { shouldStatusBarBeVisible, showHeadsUp, visibilityViaDisableFlags ->
+ val showClock =
+ shouldStatusBarBeVisible && visibilityViaDisableFlags.isClockAllowed && !showHeadsUp
+ // Always use View.INVISIBLE here, so that animations work
+ VisibilityModel(showClock.toVisibleOrInvisible(), visibilityViaDisableFlags.animate)
}
override val isNotificationIconContainerVisible: Flow<VisibilityModel> =
combine(
shouldHomeStatusBarBeVisible,
+ isAnyChipVisible,
collapsedStatusBarInteractor.visibilityViaDisableFlags,
- ) { shouldStatusBarBeVisible, visibilityViaDisableFlags ->
+ ) { shouldStatusBarBeVisible, anyChipVisible, visibilityViaDisableFlags ->
val showNotificationIconContainer =
- shouldStatusBarBeVisible && visibilityViaDisableFlags.areNotificationIconsAllowed
+ if (anyChipVisible) {
+ false
+ } else {
+ shouldStatusBarBeVisible &&
+ visibilityViaDisableFlags.areNotificationIconsAllowed
+ }
VisibilityModel(
- showNotificationIconContainer.toVisibilityInt(),
+ showNotificationIconContainer.toVisibleOrGone(),
visibilityViaDisableFlags.animate,
)
}
+
private val isSystemInfoVisible =
combine(
shouldHomeStatusBarBeVisible,
@@ -250,7 +269,7 @@ constructor(
) { shouldStatusBarBeVisible, visibilityViaDisableFlags ->
val showSystemInfo =
shouldStatusBarBeVisible && visibilityViaDisableFlags.isSystemInfoAllowed
- VisibilityModel(showSystemInfo.toVisibilityInt(), visibilityViaDisableFlags.animate)
+ VisibilityModel(showSystemInfo.toVisibleOrGone(), visibilityViaDisableFlags.animate)
}
override val systemInfoCombinedVis =
@@ -270,7 +289,11 @@ constructor(
)
@View.Visibility
- private fun Boolean.toVisibilityInt(): Int {
+ private fun Boolean.toVisibleOrGone(): Int {
return if (this) View.VISIBLE else View.GONE
}
+
+ // Similar to the above, but uses INVISIBLE in place of GONE
+ @View.Visibility
+ private fun Boolean.toVisibleOrInvisible(): Int = if (this) View.VISIBLE else View.INVISIBLE
}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt
index bcf4bad9991d..45fdd21e795e 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt
@@ -63,7 +63,8 @@ fun HomeGestureTutorialScreen(onDoneButtonClicked: () -> Unit, onBack: () -> Uni
private fun rememberHomeGestureRecognizer(resources: Resources): GestureRecognizer {
val distance =
resources.getDimensionPixelSize(R.dimen.touchpad_tutorial_gestures_distance_threshold)
- return remember(distance) { HomeGestureRecognizer(distance) }
+ val velocity = resources.getDimension(R.dimen.touchpad_home_gesture_velocity_threshold)
+ return remember(distance) { HomeGestureRecognizer(distance, velocity) }
}
@Composable
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizer.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizer.kt
index e10b8253ebad..9801626dac8f 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizer.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizer.kt
@@ -19,9 +19,14 @@ package com.android.systemui.touchpad.tutorial.ui.gesture
import android.util.MathUtils
import android.view.MotionEvent
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.InProgress
+import kotlin.math.abs
/** Recognizes touchpad home gesture, that is - using three fingers on touchpad - swiping up. */
-class HomeGestureRecognizer(private val gestureDistanceThresholdPx: Int) : GestureRecognizer {
+class HomeGestureRecognizer(
+ private val gestureDistanceThresholdPx: Int,
+ private val velocityThresholdPxPerMs: Float,
+ private val velocityTracker: VelocityTracker = VerticalVelocityTracker(),
+) : GestureRecognizer {
private val distanceTracker = DistanceTracker()
private var gestureStateChangedCallback: (GestureState) -> Unit = {}
@@ -37,10 +42,14 @@ class HomeGestureRecognizer(private val gestureDistanceThresholdPx: Int) : Gestu
override fun accept(event: MotionEvent) {
if (!isThreeFingerTouchpadSwipe(event)) return
val gestureState = distanceTracker.processEvent(event)
+ velocityTracker.accept(event)
updateGestureState(
gestureStateChangedCallback,
gestureState,
- isFinished = { -it.deltaY >= gestureDistanceThresholdPx },
+ isFinished = {
+ -it.deltaY >= gestureDistanceThresholdPx &&
+ abs(velocityTracker.calculateVelocity().value) >= velocityThresholdPxPerMs
+ },
progress = { InProgress(MathUtils.saturate(-it.deltaY / gestureDistanceThresholdPx)) },
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizer.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizer.kt
index c47888609a61..5ff583a19ee9 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizer.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizer.kt
@@ -28,10 +28,10 @@ import kotlin.math.abs
class RecentAppsGestureRecognizer(
private val gestureDistanceThresholdPx: Int,
private val velocityThresholdPxPerMs: Float,
- private val distanceTracker: DistanceTracker = DistanceTracker(),
- private val velocityTracker: VerticalVelocityTracker = VerticalVelocityTracker(),
+ private val velocityTracker: VelocityTracker = VerticalVelocityTracker(),
) : GestureRecognizer {
+ private val distanceTracker = DistanceTracker()
private var gestureStateChangedCallback: (GestureState) -> Unit = {}
override fun addGestureStateCallback(callback: (GestureState) -> Unit) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialog.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialog.kt
index 5c0cc8150d70..39b434ad65f1 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialog.kt
@@ -21,20 +21,24 @@ import android.content.Context
import android.graphics.PixelFormat
import android.os.Bundle
import android.view.MotionEvent
+import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
+import com.android.app.tracing.coroutines.coroutineScopeTraced
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.res.R
import com.android.systemui.volume.Events
+import com.android.systemui.volume.dialog.dagger.VolumeDialogComponent
import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogVisibilityInteractor
-import com.android.systemui.volume.dialog.ui.binder.VolumeDialogViewBinder
import javax.inject.Inject
+import kotlinx.coroutines.awaitCancellation
class VolumeDialog
@Inject
constructor(
@Application context: Context,
- private val viewBinder: VolumeDialogViewBinder,
+ private val componentFactory: VolumeDialogComponent.Factory,
private val visibilityInteractor: VolumeDialogVisibilityInteractor,
) : Dialog(context, R.style.Theme_SystemUI_Dialog_Volume) {
@@ -64,7 +68,14 @@ constructor(
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.volume_dialog)
- viewBinder.bind(this)
+ requireViewById<View>(R.id.volume_dialog_root).repeatWhenAttached {
+ coroutineScopeTraced("[Volume]dialog") {
+ val component = componentFactory.create(this)
+ with(component.volumeDialogViewBinder()) { bind(this@VolumeDialog) }
+
+ awaitCancellation()
+ }
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialogPlugin.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialogPlugin.kt
index b912361ae059..094ec39c1c98 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialogPlugin.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialogPlugin.kt
@@ -16,6 +16,7 @@
package com.android.systemui.volume.dialog
+import com.android.app.tracing.coroutines.coroutineScopeTraced
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.plugins.VolumeDialog
@@ -23,7 +24,6 @@ import com.android.systemui.volume.dialog.dagger.VolumeDialogPluginComponent
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
-import kotlinx.coroutines.coroutineScope
class VolumeDialogPlugin
@Inject
@@ -38,7 +38,7 @@ constructor(
override fun init(windowType: Int, callback: VolumeDialog.Callback?) {
job =
applicationCoroutineScope.launch {
- coroutineScope {
+ coroutineScopeTraced("[Volume]plugin") {
pluginComponent =
volumeDialogPluginComponentFactory.create(this).also {
it.viewModel().launchVolumeDialog()
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogComponent.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogComponent.kt
index fb157958a630..434f6b567048 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogComponent.kt
@@ -20,6 +20,7 @@ import com.android.systemui.volume.dialog.dagger.module.VolumeDialogModule
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialog
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderComponent
+import com.android.systemui.volume.dialog.ui.binder.VolumeDialogViewBinder
import dagger.BindsInstance
import dagger.Subcomponent
import kotlinx.coroutines.CoroutineScope
@@ -32,21 +33,21 @@ import kotlinx.coroutines.CoroutineScope
@Subcomponent(modules = [VolumeDialogModule::class])
interface VolumeDialogComponent {
- /**
- * Provides a coroutine scope to use inside [VolumeDialogScope].
- * [com.android.systemui.volume.dialog.VolumeDialogPlugin] manages the lifecycle of this scope.
- * It's cancelled when the dialog is disposed. This helps to free occupied resources when volume
- * dialog is not shown.
- */
- @VolumeDialog fun coroutineScope(): CoroutineScope
-
- @VolumeDialogScope fun volumeDialog(): com.android.systemui.volume.dialog.VolumeDialog
+ fun volumeDialogViewBinder(): VolumeDialogViewBinder
fun sliderComponentFactory(): VolumeDialogSliderComponent.Factory
@Subcomponent.Factory
interface Factory {
- fun create(@BindsInstance @VolumeDialog scope: CoroutineScope): VolumeDialogComponent
+ fun create(
+ /**
+ * Provides a coroutine scope to use inside [VolumeDialogScope].
+ * [com.android.systemui.volume.dialog.VolumeDialogPlugin] manages the lifecycle of this
+ * scope. It's cancelled when the dialog is disposed. This helps to free occupied
+ * resources when volume dialog is not shown.
+ */
+ @BindsInstance @VolumeDialog scope: CoroutineScope
+ ): VolumeDialogComponent
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderTouchesViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderTouchesViewBinder.kt
index 7fd177d55d76..e0336243b327 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderTouchesViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderTouchesViewBinder.kt
@@ -18,9 +18,6 @@ package com.android.systemui.volume.dialog.sliders.ui
import android.annotation.SuppressLint
import android.view.View
-import com.android.systemui.lifecycle.WindowLifecycleState
-import com.android.systemui.lifecycle.repeatWhenAttached
-import com.android.systemui.lifecycle.viewModel
import com.android.systemui.res.R
import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderScope
import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogSliderTouchesViewModel
@@ -30,22 +27,14 @@ import javax.inject.Inject
@VolumeDialogSliderScope
class VolumeDialogSliderTouchesViewBinder
@Inject
-constructor(private val viewModelFactory: VolumeDialogSliderTouchesViewModel.Factory) {
+constructor(private val viewModel: VolumeDialogSliderTouchesViewModel) {
@SuppressLint("ClickableViewAccessibility")
fun bind(view: View) {
with(view.requireViewById<Slider>(R.id.volume_dialog_slider)) {
- repeatWhenAttached {
- viewModel(
- traceName = "VolumeDialogSliderTouchesViewBinder",
- minWindowLifecycleState = WindowLifecycleState.ATTACHED,
- factory = { viewModelFactory.create() },
- ) { viewModel ->
- setOnTouchListener { _, event ->
- viewModel.onTouchEvent(event)
- false
- }
- }
+ setOnTouchListener { _, event ->
+ viewModel.onTouchEvent(event)
+ false
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt
index 1c231b521bae..f9334dfc7ba2 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt
@@ -20,9 +20,6 @@ import android.animation.Animator
import android.animation.ObjectAnimator
import android.view.View
import android.view.animation.DecelerateInterpolator
-import com.android.systemui.lifecycle.WindowLifecycleState
-import com.android.systemui.lifecycle.repeatWhenAttached
-import com.android.systemui.lifecycle.viewModel
import com.android.systemui.res.R
import com.android.systemui.volume.dialog.shared.model.VolumeDialogStreamModel
import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderScope
@@ -33,7 +30,7 @@ import com.google.android.material.slider.LabelFormatter
import com.google.android.material.slider.Slider
import javax.inject.Inject
import kotlin.math.roundToInt
-import kotlinx.coroutines.awaitCancellation
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@@ -43,32 +40,20 @@ private const val PROGRESS_CHANGE_ANIMATION_DURATION_MS = 80L
class VolumeDialogSliderViewBinder
@Inject
constructor(
- private val viewModelFactory: VolumeDialogSliderViewModel.Factory,
+ private val viewModel: VolumeDialogSliderViewModel,
private val jankListenerFactory: JankListenerFactory,
) {
- fun bind(view: View) {
- with(view) {
- val sliderView: Slider =
- requireViewById<Slider>(R.id.volume_dialog_slider).apply {
- labelBehavior = LabelFormatter.LABEL_GONE
- }
- repeatWhenAttached {
- viewModel(
- traceName = "VolumeDialogSliderViewBinder",
- minWindowLifecycleState = WindowLifecycleState.ATTACHED,
- factory = { viewModelFactory.create() },
- ) { viewModel ->
- sliderView.addOnChangeListener { _, value, fromUser ->
- viewModel.setStreamVolume(value.roundToInt(), fromUser)
- }
-
- viewModel.model.onEach { it.bindToSlider(sliderView) }.launchIn(this)
-
- awaitCancellation()
- }
+ fun CoroutineScope.bind(view: View) {
+ val sliderView: Slider =
+ view.requireViewById<Slider>(R.id.volume_dialog_slider).apply {
+ labelBehavior = LabelFormatter.LABEL_GONE
}
+ sliderView.addOnChangeListener { _, value, fromUser ->
+ viewModel.setStreamVolume(value.roundToInt(), fromUser)
}
+
+ viewModel.model.onEach { it.bindToSlider(sliderView) }.launchIn(this)
}
private suspend fun VolumeDialogStreamModel.bindToSlider(slider: Slider) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSlidersViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSlidersViewBinder.kt
index 1b2b4fff5b8e..242845a47f29 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSlidersViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSlidersViewBinder.kt
@@ -21,58 +21,47 @@ import android.view.View
import android.view.ViewGroup
import androidx.annotation.LayoutRes
import androidx.compose.ui.util.fastForEachIndexed
-import com.android.systemui.lifecycle.WindowLifecycleState
-import com.android.systemui.lifecycle.repeatWhenAttached
-import com.android.systemui.lifecycle.viewModel
import com.android.systemui.res.R
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderComponent
import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogSlidersViewModel
import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@VolumeDialogScope
class VolumeDialogSlidersViewBinder
@Inject
-constructor(private val viewModelFactory: VolumeDialogSlidersViewModel.Factory) {
+constructor(private val viewModel: VolumeDialogSlidersViewModel) {
- fun bind(view: View) {
- with(view) {
- val floatingSlidersContainer: ViewGroup =
- requireViewById(R.id.volume_dialog_floating_sliders_container)
- val mainSliderContainer: View =
- requireViewById(R.id.volume_dialog_main_slider_container)
- repeatWhenAttached {
- viewModel(
- traceName = "VolumeDialogSlidersViewBinder",
- minWindowLifecycleState = WindowLifecycleState.ATTACHED,
- factory = { viewModelFactory.create() },
- ) { viewModel ->
- viewModel.sliders
- .onEach { uiModel ->
- uiModel.sliderComponent.bindSlider(mainSliderContainer)
+ fun CoroutineScope.bind(view: View) {
+ val floatingSlidersContainer: ViewGroup =
+ view.requireViewById(R.id.volume_dialog_floating_sliders_container)
+ val mainSliderContainer: View =
+ view.requireViewById(R.id.volume_dialog_main_slider_container)
+ viewModel.sliders
+ .onEach { uiModel ->
+ bindSlider(uiModel.sliderComponent, mainSliderContainer)
- val floatingSliderViewBinders = uiModel.floatingSliderComponent
- floatingSlidersContainer.ensureChildCount(
- viewLayoutId = R.layout.volume_dialog_slider_floating,
- count = floatingSliderViewBinders.size,
- )
- floatingSliderViewBinders.fastForEachIndexed { index, sliderComponent ->
- sliderComponent.bindSlider(
- floatingSlidersContainer.getChildAt(index)
- )
- }
- }
- .launchIn(this)
+ val floatingSliderViewBinders = uiModel.floatingSliderComponent
+ floatingSlidersContainer.ensureChildCount(
+ viewLayoutId = R.layout.volume_dialog_slider_floating,
+ count = floatingSliderViewBinders.size,
+ )
+ floatingSliderViewBinders.fastForEachIndexed { index, sliderComponent ->
+ bindSlider(sliderComponent, floatingSlidersContainer.getChildAt(index))
}
}
- }
+ .launchIn(this)
}
- private fun VolumeDialogSliderComponent.bindSlider(sliderContainer: View) {
- sliderViewBinder().bind(sliderContainer)
- sliderTouchesViewBinder().bind(sliderContainer)
+ private fun CoroutineScope.bindSlider(
+ component: VolumeDialogSliderComponent,
+ sliderContainer: View,
+ ) {
+ with(component.sliderViewBinder()) { bind(sliderContainer) }
+ with(component.sliderTouchesViewBinder()) { bind(sliderContainer) }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderTouchesViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderTouchesViewModel.kt
index 144c75da2b2b..9126f45fe32a 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderTouchesViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderTouchesViewModel.kt
@@ -17,20 +17,16 @@
package com.android.systemui.volume.dialog.sliders.ui.viewmodel
import android.view.MotionEvent
+import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderScope
import com.android.systemui.volume.dialog.sliders.domain.interactor.VolumeDialogSliderInputEventsInteractor
-import dagger.assisted.AssistedFactory
-import dagger.assisted.AssistedInject
+import javax.inject.Inject
+@VolumeDialogSliderScope
class VolumeDialogSliderTouchesViewModel
-@AssistedInject
+@Inject
constructor(private val interactor: VolumeDialogSliderInputEventsInteractor) {
fun onTouchEvent(event: MotionEvent) {
interactor.onTouchEvent(event)
}
-
- @AssistedFactory
- interface Factory {
- fun create(): VolumeDialogSliderTouchesViewModel
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt
index cf04d45d54ff..6dd5b638a3bc 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt
@@ -21,9 +21,9 @@ import com.android.systemui.volume.Events
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialog
import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogVisibilityInteractor
import com.android.systemui.volume.dialog.shared.model.VolumeDialogStreamModel
+import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderScope
import com.android.systemui.volume.dialog.sliders.domain.interactor.VolumeDialogSliderInteractor
-import dagger.assisted.AssistedFactory
-import dagger.assisted.AssistedInject
+import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
@@ -49,8 +49,9 @@ import kotlinx.coroutines.flow.stateIn
private const val VOLUME_UPDATE_GRACE_PERIOD = 1000
@OptIn(ExperimentalCoroutinesApi::class)
+@VolumeDialogSliderScope
class VolumeDialogSliderViewModel
-@AssistedInject
+@Inject
constructor(
private val interactor: VolumeDialogSliderInteractor,
private val visibilityInteractor: VolumeDialogVisibilityInteractor,
@@ -90,10 +91,4 @@ constructor(
private fun getTimestampMillis(): Long = systemClock.uptimeMillis()
private data class VolumeUpdate(val newVolumeLevel: Int, val timestampMillis: Long)
-
- @AssistedFactory
- interface Factory {
-
- fun create(): VolumeDialogSliderViewModel
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSlidersViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSlidersViewModel.kt
index d1972231d373..d8e6aec026c6 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSlidersViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSlidersViewModel.kt
@@ -17,10 +17,10 @@
package com.android.systemui.volume.dialog.sliders.ui.viewmodel
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialog
+import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderComponent
import com.android.systemui.volume.dialog.sliders.domain.interactor.VolumeDialogSlidersInteractor
-import dagger.assisted.AssistedFactory
-import dagger.assisted.AssistedInject
+import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
@@ -28,8 +28,9 @@ import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
+@VolumeDialogScope
class VolumeDialogSlidersViewModel
-@AssistedInject
+@Inject
constructor(
@VolumeDialog coroutineScope: CoroutineScope,
private val slidersInteractor: VolumeDialogSlidersInteractor,
@@ -47,12 +48,6 @@ constructor(
}
.stateIn(coroutineScope, SharingStarted.Eagerly, null)
.filterNotNull()
-
- @AssistedFactory
- interface Factory {
-
- fun create(): VolumeDialogSlidersViewModel
- }
}
/** Models slider ui */
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinder.kt
index f6c1743a4bea..a3166a9978f4 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinder.kt
@@ -25,9 +25,6 @@ import android.view.ViewTreeObserver
import android.view.ViewTreeObserver.InternalInsetsInfo
import androidx.constraintlayout.motion.widget.MotionLayout
import com.android.internal.view.RotationPolicy
-import com.android.systemui.lifecycle.WindowLifecycleState
-import com.android.systemui.lifecycle.repeatWhenAttached
-import com.android.systemui.lifecycle.viewModel
import com.android.systemui.res.R
import com.android.systemui.util.children
import com.android.systemui.volume.SystemUIInterpolators
@@ -44,7 +41,6 @@ import com.android.systemui.volume.dialog.utils.VolumeTracer
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.launchIn
@@ -61,7 +57,7 @@ class VolumeDialogViewBinder
@Inject
constructor(
private val volumeResources: VolumeDialogResources,
- private val dialogViewModelFactory: VolumeDialogViewModel.Factory,
+ private val viewModel: VolumeDialogViewModel,
private val jankListenerFactory: JankListenerFactory,
private val tracer: VolumeTracer,
private val volumeDialogRingerViewBinder: VolumeDialogRingerViewBinder,
@@ -69,35 +65,27 @@ constructor(
private val settingsButtonViewBinder: VolumeDialogSettingsButtonViewBinder,
) {
- fun bind(dialog: Dialog) {
+ fun CoroutineScope.bind(dialog: Dialog) {
// Root view of the Volume Dialog.
val root: MotionLayout = dialog.requireViewById(R.id.volume_dialog_root)
root.alpha = 0f
- root.repeatWhenAttached {
- root.viewModel(
- traceName = "VolumeDialogViewBinder",
- minWindowLifecycleState = WindowLifecycleState.ATTACHED,
- factory = { dialogViewModelFactory.create() },
- ) { viewModel ->
- animateVisibility(root, dialog, viewModel.dialogVisibilityModel)
-
- viewModel.dialogTitle.onEach { dialog.window?.setTitle(it) }.launchIn(this)
- viewModel.motionState
- .scan(0) { acc, motionState ->
- // don't animate the initial state
- root.transitionToState(motionState, animate = acc != 0)
- acc + 1
- }
- .launchIn(this)
- launch { root.viewTreeObserver.computeInternalInsetsListener(root) }
+ animateVisibility(root, dialog, viewModel.dialogVisibilityModel)
- awaitCancellation()
+ viewModel.dialogTitle.onEach { dialog.window?.setTitle(it) }.launchIn(this)
+ viewModel.motionState
+ .scan(0) { acc, motionState ->
+ // don't animate the initial state
+ root.transitionToState(motionState, animate = acc != 0)
+ acc + 1
}
- }
- volumeDialogRingerViewBinder.bind(root)
- slidersViewBinder.bind(root)
- settingsButtonViewBinder.bind(root)
+ .launchIn(this)
+
+ launch { root.viewTreeObserver.computeInternalInsetsListener(root) }
+
+ with(volumeDialogRingerViewBinder) { bind(root) }
+ with(slidersViewBinder) { bind(root) }
+ with(settingsButtonViewBinder) { bind(root) }
}
private fun CoroutineScope.animateVisibility(
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogPluginViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogPluginViewModel.kt
index e858cfef67ea..ff525f46a7ed 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogPluginViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogPluginViewModel.kt
@@ -17,14 +17,14 @@
package com.android.systemui.volume.dialog.ui.viewmodel
import com.android.systemui.volume.Events
-import com.android.systemui.volume.dialog.dagger.VolumeDialogComponent
+import com.android.systemui.volume.dialog.VolumeDialog
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogPluginScope
import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogVisibilityInteractor
import com.android.systemui.volume.dialog.shared.VolumeDialogLogger
import com.android.systemui.volume.dialog.shared.model.VolumeDialogVisibilityModel
import javax.inject.Inject
+import javax.inject.Provider
import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.cancel
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapLatest
@@ -34,8 +34,8 @@ import kotlinx.coroutines.flow.mapLatest
class VolumeDialogPluginViewModel
@Inject
constructor(
- private val componentFactory: VolumeDialogComponent.Factory,
private val dialogVisibilityInteractor: VolumeDialogVisibilityInteractor,
+ private val volumeDialogProvider: Provider<VolumeDialog>,
private val logger: VolumeDialogLogger,
) {
@@ -45,7 +45,7 @@ constructor(
.mapLatest { visibilityModel ->
with(visibilityModel) {
if (this is VolumeDialogVisibilityModel.Visible) {
- showDialog(componentFactory)
+ showDialog()
Events.writeEvent(Events.EVENT_SHOW_DIALOG, reason, keyguardLocked)
logger.onShow(reason)
}
@@ -59,16 +59,14 @@ constructor(
}
}
- private suspend fun showDialog(componentFactory: VolumeDialogComponent.Factory): Unit =
- coroutineScope {
- val volumeDialogComponent: VolumeDialogComponent = componentFactory.create(this)
- val dialog =
- volumeDialogComponent.volumeDialog().apply {
- setOnDismissListener {
- volumeDialogComponent.coroutineScope().cancel()
- dialogVisibilityInteractor.dismissDialog(Events.DISMISS_REASON_UNKNOWN)
- }
+ private fun showDialog() {
+ volumeDialogProvider
+ .get()
+ .apply {
+ setOnDismissListener {
+ dialogVisibilityInteractor.dismissDialog(Events.DISMISS_REASON_UNKNOWN)
}
- dialog.show()
- }
+ }
+ .show()
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogViewModel.kt
index 0352799916bc..7a6ede4c8b9c 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogViewModel.kt
@@ -23,6 +23,7 @@ import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.DevicePostureController
import com.android.systemui.statusbar.policy.devicePosture
import com.android.systemui.statusbar.policy.onConfigChanged
+import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogStateInteractor
import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogVisibilityInteractor
import com.android.systemui.volume.dialog.shared.model.VolumeDialogStateModel
@@ -30,9 +31,7 @@ import com.android.systemui.volume.dialog.shared.model.VolumeDialogVisibilityMod
import com.android.systemui.volume.dialog.shared.model.streamLabel
import com.android.systemui.volume.dialog.sliders.domain.interactor.VolumeDialogSlidersInteractor
import com.android.systemui.volume.dialog.sliders.domain.model.VolumeDialogSliderType
-import dagger.assisted.AssistedFactory
-import dagger.assisted.AssistedInject
-import kotlinx.coroutines.ExperimentalCoroutinesApi
+import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filterNotNull
@@ -40,9 +39,9 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
/** Provides a state for the Volume Dialog. */
-@OptIn(ExperimentalCoroutinesApi::class)
+@VolumeDialogScope
class VolumeDialogViewModel
-@AssistedInject
+@Inject
constructor(
private val context: Context,
dialogVisibilityInteractor: VolumeDialogVisibilityInteractor,
@@ -84,9 +83,4 @@ constructor(
val isHalfOpen = devicePosture == DevicePostureController.DEVICE_POSTURE_HALF_OPENED
return isLandscape && isHalfOpen
}
-
- @AssistedFactory
- interface Factory {
- fun create(): VolumeDialogViewModel
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt
index feae901114e5..3bd249689da9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt
@@ -413,6 +413,7 @@ class ShortcutHelperViewModelTest : SysuiTestCase() {
key("Ctrl")
key("A")
}
+ contentDescription { "$label, Press key Ctrl plus A" }
}
companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
index 929b0aad3299..67e03e4bdb22 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
@@ -273,6 +273,12 @@ class CustomizationProviderTest : SysuiTestCase() {
"${Contract.AUTHORITY}." +
Contract.FlagsTable.TABLE_NAME
)
+ assertThat(underTest.getType(Contract.RuntimeValuesTable.URI))
+ .isEqualTo(
+ "vnd.android.cursor.dir/vnd." +
+ "${Contract.AUTHORITY}." +
+ Contract.RuntimeValuesTable.TABLE_NAME
+ )
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaSwitchingControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaSwitchingControllerTest.java
index eb1b44b75247..7ba797c03a0d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaSwitchingControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaSwitchingControllerTest.java
@@ -1467,4 +1467,66 @@ public class MediaSwitchingControllerTest extends SysuiTestCase {
verify(mInputRouteManager, never()).selectDevice(outputMediaDevice);
verify(mLocalMediaManager, atLeastOnce()).connectDevice(outputMediaDevice);
}
+
+ @DisableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
+ @Test
+ public void connectDeviceButton_presentAtAllTimesForNonGroupOutputs() {
+ mMediaSwitchingController.start(mCb);
+ reset(mCb);
+
+ // Mock the selected output device.
+ doReturn(Collections.singletonList(mMediaDevice1))
+ .when(mLocalMediaManager)
+ .getSelectedMediaDevice();
+
+ // Verify that there is initially one "Connect a device" button present.
+ assertThat(getNumberOfConnectDeviceButtons()).isEqualTo(1);
+
+ // Change the selected device, and verify that there is still one "Connect a device" button
+ // present.
+ doReturn(Collections.singletonList(mMediaDevice2))
+ .when(mLocalMediaManager)
+ .getSelectedMediaDevice();
+ mMediaSwitchingController.onDeviceListUpdate(mMediaDevices);
+
+ assertThat(getNumberOfConnectDeviceButtons()).isEqualTo(1);
+ }
+
+ @EnableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
+ @Test
+ public void connectDeviceButton_presentAtAllTimesForNonGroupOutputs_inputRoutingEnabled() {
+ mMediaSwitchingController.start(mCb);
+ reset(mCb);
+
+ // Mock the selected output device.
+ doReturn(Collections.singletonList(mMediaDevice1))
+ .when(mLocalMediaManager)
+ .getSelectedMediaDevice();
+
+ // Mock the selected input media device.
+ final MediaDevice selectedInputMediaDevice = mock(MediaDevice.class);
+ doReturn(selectedInputMediaDevice).when(mInputRouteManager).getSelectedInputDevice();
+
+ // Verify that there is initially one "Connect a device" button present.
+ assertThat(getNumberOfConnectDeviceButtons()).isEqualTo(1);
+
+ // Change the selected device, and verify that there is still one "Connect a device" button
+ // present.
+ doReturn(Collections.singletonList(mMediaDevice2))
+ .when(mLocalMediaManager)
+ .getSelectedMediaDevice();
+ mMediaSwitchingController.onDeviceListUpdate(mMediaDevices);
+
+ assertThat(getNumberOfConnectDeviceButtons()).isEqualTo(1);
+ }
+
+ private int getNumberOfConnectDeviceButtons() {
+ int numberOfConnectDeviceButtons = 0;
+ for (MediaItem item : mMediaSwitchingController.getMediaItemList()) {
+ if (item.getMediaItemType() == MediaItem.MediaItemType.TYPE_PAIR_NEW_DEVICE) {
+ numberOfConnectDeviceButtons++;
+ }
+ }
+ return numberOfConnectDeviceButtons;
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java
index bc3c0d96fa22..d59a404b15bb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java
@@ -49,6 +49,7 @@ import androidx.test.filters.SmallTest;
import com.android.dx.mockito.inline.extended.StaticMockitoSession;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.kosmos.KosmosJavaAdapter;
import com.android.systemui.model.SysUiState;
import com.android.systemui.navigationbar.views.NavigationBar;
import com.android.systemui.recents.OverviewProxyService;
@@ -56,7 +57,7 @@ import com.android.systemui.settings.FakeDisplayTracker;
import com.android.systemui.shared.recents.utilities.Utilities;
import com.android.systemui.shared.system.TaskStackChangeListeners;
import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.phone.AutoHideController;
+import com.android.systemui.statusbar.phone.AutoHideControllerStore;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.concurrency.FakeExecutor;
@@ -89,6 +90,11 @@ public class NavigationBarControllerImplTest extends SysuiTestCase {
private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
+ private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
+
+ private final AutoHideControllerStore mAutoHideControllerStore =
+ mKosmos.getAutoHideControllerStore();
+
@Mock
private CommandQueue mCommandQueue;
@Mock
@@ -113,7 +119,7 @@ public class NavigationBarControllerImplTest extends SysuiTestCase {
mTaskbarDelegate,
mNavigationBarFactory,
mock(DumpManager.class),
- mock(AutoHideController.class),
+ mAutoHideControllerStore,
mock(LightBarController.class),
TaskStackChangeListeners.getTestInstance(),
Optional.of(mock(Pip.class)),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt
index f7059e244084..a64ff321cd4d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt
@@ -31,6 +31,7 @@ import com.android.systemui.activity.SingleActivityFactory
import com.android.systemui.brightness.ui.viewmodel.BrightnessSliderViewModel
import com.android.systemui.brightness.ui.viewmodel.brightnessSliderViewModelFactory
import com.android.systemui.qs.flags.QSComposeFragment
+import com.android.systemui.qs.flags.QsInCompose
import com.android.systemui.res.R
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
@@ -70,8 +71,8 @@ class BrightnessDialogTest(val flags: FlagsParameterization) : SysuiTestCase() {
mSetFlagsRule.setFlagsParameterization(flags)
}
- val viewId by lazy {
- if (QSComposeFragment.isEnabled) {
+ private val viewId by lazy {
+ if (QsInCompose.isEnabled) {
R.id.brightness_dialog_slider
} else {
R.id.brightness_mirror_container
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 af14edd10f5f..a1c9022e18bd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -141,6 +141,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntryB
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
import com.android.systemui.statusbar.notification.interruption.AvalancheProvider;
import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptLogger;
@@ -154,7 +155,6 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController;
import com.android.systemui.statusbar.policy.ZenModeController;
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt
index e0d1d16bcf55..72541540226c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt
@@ -28,6 +28,7 @@ import com.android.systemui.bouncer.domain.interactor.simBouncerInteractor
import com.android.systemui.bouncer.ui.helper.BouncerHapticPlayer
import com.android.systemui.haptics.msdl.bouncerHapticPlayer
import com.android.systemui.inputmethod.domain.interactor.inputMethodInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardDismissActionInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardMediaKeyInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
@@ -63,6 +64,7 @@ val Kosmos.bouncerSceneContentViewModel by Fixture {
bouncerHapticPlayer = bouncerHapticPlayer,
keyguardMediaKeyInteractor = keyguardMediaKeyInteractor,
bouncerActionButtonInteractor = bouncerActionButtonInteractor,
+ keyguardDismissActionInteractor = keyguardDismissActionInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryKosmos.kt
index 5485f79629e8..5da6c7b1f2a8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryKosmos.kt
@@ -17,6 +17,7 @@
package com.android.systemui.communal.data.repository
import android.app.admin.devicePolicyManager
+import android.content.res.mainResources
import com.android.systemui.broadcast.broadcastDispatcher
import com.android.systemui.flags.featureFlagsClassic
import com.android.systemui.kosmos.Kosmos
@@ -27,6 +28,7 @@ val Kosmos.communalSettingsRepository: CommunalSettingsRepository by
Kosmos.Fixture {
CommunalSettingsRepositoryImpl(
bgDispatcher = testDispatcher,
+ resources = mainResources,
featureFlagsClassic = featureFlagsClassic,
secureSettings = fakeSettings,
broadcastDispatcher = broadcastDispatcher,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractorKosmos.kt
new file mode 100644
index 000000000000..c2466bb4c14d
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractorKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.display.domain.interactor
+
+import com.android.systemui.display.data.repository.displayWindowPropertiesRepository
+import com.android.systemui.kosmos.Kosmos
+
+val Kosmos.displayWindowPropertiesInteractor by
+ Kosmos.Fixture { DisplayWindowPropertiesInteractorImpl(displayWindowPropertiesRepository) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
index 2c8581608739..e7672ffabc79 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
@@ -55,10 +55,10 @@ var Kosmos.shortcutHelperAppCategoriesShortcutsSource: KeyboardShortcutGroupsSou
Kosmos.Fixture { AppCategoriesShortcutsSource(windowManager, testDispatcher) }
var Kosmos.shortcutHelperSystemShortcutsSource: KeyboardShortcutGroupsSource by
- Kosmos.Fixture { SystemShortcutsSource(mainResources) }
+ Kosmos.Fixture { SystemShortcutsSource(mainResources, fakeInputManager.inputManager) }
var Kosmos.shortcutHelperMultiTaskingShortcutsSource: KeyboardShortcutGroupsSource by
- Kosmos.Fixture { MultitaskingShortcutsSource(mainResources) }
+ Kosmos.Fixture { MultitaskingShortcutsSource(mainResources, applicationContext) }
val Kosmos.shortcutHelperStateRepository by
Kosmos.Fixture {
@@ -72,7 +72,9 @@ val Kosmos.shortcutHelperStateRepository by
}
var Kosmos.shortcutHelperInputShortcutsSource: KeyboardShortcutGroupsSource by
- Kosmos.Fixture { InputShortcutsSource(mainResources, windowManager) }
+ Kosmos.Fixture {
+ InputShortcutsSource(mainResources, windowManager, fakeInputManager.inputManager)
+ }
var Kosmos.shortcutHelperCurrentAppShortcutsSource: KeyboardShortcutGroupsSource by
Kosmos.Fixture { CurrentAppShortcutsSource(windowManager) }
@@ -141,7 +143,10 @@ val Kosmos.shortcutHelperStateInteractor by
val Kosmos.shortcutHelperCategoriesInteractor by
Kosmos.Fixture {
- ShortcutHelperCategoriesInteractor(defaultShortcutCategoriesRepository) {
+ ShortcutHelperCategoriesInteractor(
+ context = applicationContext,
+ defaultShortcutCategoriesRepository,
+ ) {
customShortcutCategoriesRepository
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt
index bd841ab2e801..09f5fd79eeca 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt
@@ -17,14 +17,12 @@
package com.android.systemui.keyguard.domain.interactor
import com.android.keyguard.logging.KeyguardLogger
-import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor
import com.android.systemui.bouncer.domain.interactor.primaryBouncerInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
import com.android.systemui.keyguard.data.repository.keyguardRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.log.logcatLogBuffer
-import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.shade.domain.interactor.shadeInteractor
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -38,8 +36,6 @@ val Kosmos.keyguardDismissActionInteractor by
dismissInteractor = keyguardDismissInteractor,
applicationScope = testScope.backgroundScope,
deviceUnlockedInteractor = { deviceUnlockedInteractor },
- powerInteractor = powerInteractor,
- alternateBouncerInteractor = alternateBouncerInteractor,
shadeInteractor = { shadeInteractor },
keyguardInteractor = { keyguardInteractor },
sceneInteractor = { sceneInteractor },
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 3d60abf59d62..5b2c8dda2475 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
@@ -78,6 +78,7 @@ import com.android.systemui.statusbar.notification.domain.interactor.activeNotif
import com.android.systemui.statusbar.notification.domain.interactor.seenNotificationsInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
+import com.android.systemui.statusbar.phone.fakeAutoHideControllerStore
import com.android.systemui.statusbar.phone.keyguardBypassController
import com.android.systemui.statusbar.phone.scrimController
import com.android.systemui.statusbar.pipeline.mobile.data.repository.mobileConnectionsRepository
@@ -132,6 +133,7 @@ class KosmosJavaAdapter() {
val simBouncerInteractor by lazy { kosmos.simBouncerInteractor }
val statusBarStateController by lazy { kosmos.statusBarStateController }
val statusBarModePerDisplayRepository by lazy { kosmos.fakeStatusBarModePerDisplayRepository }
+ val autoHideControllerStore by lazy { kosmos.fakeAutoHideControllerStore }
val interactionJankMonitor by lazy { kosmos.interactionJankMonitor }
val fakeSceneContainerConfig by lazy { kosmos.sceneContainerConfig }
val sceneInteractor by lazy { kosmos.sceneInteractor }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapterKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapterKosmos.kt
index de9f629ef787..a90876551d20 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapterKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapterKosmos.kt
@@ -18,7 +18,6 @@ package com.android.systemui.qs.tiles.viewmodel
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
-import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.util.mockito.mock
val Kosmos.qsTileViewModelAdaperFactory by
@@ -29,7 +28,6 @@ val Kosmos.qsTileViewModelAdaperFactory by
applicationCoroutineScope,
mock(),
qsTileViewModel,
- testDispatcher,
)
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneKosmos.kt
index 3300c96b87fd..0eca818e9aac 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneKosmos.kt
@@ -13,6 +13,7 @@ import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.SceneContainerConfig
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.ui.FakeOverlay
+import com.android.systemui.scene.ui.composable.SceneContainerTransitions
import com.android.systemui.scene.ui.viewmodel.SceneContainerHapticsViewModel
import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
import com.android.systemui.scene.ui.viewmodel.splitEdgeDetector
@@ -60,6 +61,7 @@ var Kosmos.sceneContainerConfig by Fixture {
SceneContainerConfig(
sceneKeys = sceneKeys,
initialSceneKey = initialSceneKey,
+ transitions = SceneContainerTransitions,
overlayKeys = overlayKeys,
navigationDistances = navigationDistances,
)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/FakeStatusBarOrchestratorFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/FakeStatusBarOrchestratorFactory.kt
index 9197dcdc3f68..2d88ae8e926a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/FakeStatusBarOrchestratorFactory.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/FakeStatusBarOrchestratorFactory.kt
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.core
import com.android.systemui.statusbar.data.repository.StatusBarModePerDisplayRepository
+import com.android.systemui.statusbar.phone.AutoHideController
import com.android.systemui.statusbar.window.StatusBarWindowController
import com.android.systemui.statusbar.window.data.repository.StatusBarWindowStatePerDisplayRepository
import kotlinx.coroutines.CoroutineScope
@@ -36,6 +37,7 @@ class FakeStatusBarOrchestratorFactory : StatusBarOrchestrator.Factory {
statusBarModeRepository: StatusBarModePerDisplayRepository,
statusBarInitializer: StatusBarInitializer,
statusBarWindowController: StatusBarWindowController,
+ autoHideController: AutoHideController,
): StatusBarOrchestrator =
mock<StatusBarOrchestrator>().also { createdOrchestrators[displayId] = it }
}
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 28edae7c3689..8c37bd739bc5 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
@@ -34,6 +34,7 @@ import com.android.systemui.statusbar.data.repository.privacyDotWindowController
import com.android.systemui.statusbar.data.repository.statusBarModeRepository
import com.android.systemui.statusbar.mockNotificationRemoteInputManager
import com.android.systemui.statusbar.phone.mockAutoHideController
+import com.android.systemui.statusbar.phone.multiDisplayAutoHideControllerStore
import com.android.systemui.statusbar.window.data.repository.fakeStatusBarWindowStatePerDisplayRepository
import com.android.systemui.statusbar.window.data.repository.statusBarWindowStateRepositoryStore
import com.android.systemui.statusbar.window.fakeStatusBarWindowController
@@ -50,9 +51,9 @@ val Kosmos.statusBarOrchestrator by
fakeStatusBarInitializer,
fakeStatusBarWindowController,
applicationCoroutineScope.coroutineContext,
+ mockAutoHideController,
mockDemoModeController,
mockPluginDependencyProvider,
- mockAutoHideController,
mockNotificationRemoteInputManager,
{ mockNotificationShadeWindowViewController },
mockShadeSurface,
@@ -80,6 +81,7 @@ val Kosmos.multiDisplayStatusBarStarter by
statusBarInitializerStore,
statusBarWindowControllerStore,
statusBarInitializerStore,
+ multiDisplayAutoHideControllerStore,
privacyDotWindowControllerStore,
lightBarControllerStore,
)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
index 7fbf4e495feb..d1619b7959f2 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
@@ -23,6 +23,7 @@ import com.android.systemui.dump.dumpManager
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.keyguard.ui.viewmodel.alternateBouncerToGoneTransitionViewModel
+import com.android.systemui.keyguard.ui.viewmodel.alternateBouncerToPrimaryBouncerTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.aodBurnInViewModel
import com.android.systemui.keyguard.ui.viewmodel.aodToGoneTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.aodToLockscreenTransitionViewModel
@@ -71,6 +72,8 @@ val Kosmos.sharedNotificationContainerViewModel by Fixture {
shadeInteractor = shadeInteractor,
notificationStackAppearanceInteractor = notificationStackAppearanceInteractor,
alternateBouncerToGoneTransitionViewModel = alternateBouncerToGoneTransitionViewModel,
+ alternateBouncerToPrimaryBouncerTransitionViewModel =
+ alternateBouncerToPrimaryBouncerTransitionViewModel,
aodToGoneTransitionViewModel = aodToGoneTransitionViewModel,
aodToLockscreenTransitionViewModel = aodToLockscreenTransitionViewModel,
aodToOccludedTransitionViewModel = aodToOccludedTransitionViewModel,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/AutoHideKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/AutoHideKosmos.kt
index 951ae59ebcf1..b99e93abfa30 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/AutoHideKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/AutoHideKosmos.kt
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.phone
import android.content.Context
import android.os.Handler
+import android.view.Display
import android.view.IWindowManager
import com.android.systemui.display.data.repository.displayRepository
import com.android.systemui.display.data.repository.fakeDisplayWindowPropertiesRepository
@@ -28,8 +29,6 @@ import org.mockito.Mockito.mock
val Kosmos.mockAutoHideController: AutoHideController by
Kosmos.Fixture { mock(AutoHideController::class.java) }
-var Kosmos.autoHideController by Kosmos.Fixture { mockAutoHideController }
-
val Kosmos.fakeAutoHideControllerFactory by Kosmos.Fixture { FakeAutoHideControllerFactory() }
val Kosmos.multiDisplayAutoHideControllerStore by
@@ -42,6 +41,8 @@ val Kosmos.multiDisplayAutoHideControllerStore by
)
}
+val Kosmos.fakeAutoHideControllerStore by Kosmos.Fixture { FakeAutoHideControllerStore() }
+
class FakeAutoHideControllerFactory :
AutoHideControllerImpl.Factory(mock(Handler::class.java), mock(IWindowManager::class.java)) {
@@ -49,3 +50,15 @@ class FakeAutoHideControllerFactory :
return mock(AutoHideControllerImpl::class.java)
}
}
+
+class FakeAutoHideControllerStore : AutoHideControllerStore {
+
+ private val perDisplayMocks = mutableMapOf<Int, AutoHideController>()
+
+ override val defaultDisplay: AutoHideController
+ get() = forDisplay(Display.DEFAULT_DISPLAY)
+
+ override fun forDisplay(displayId: Int): AutoHideController {
+ return perDisplayMocks.computeIfAbsent(displayId) { mock(AutoHideController::class.java) }
+ }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt
index 03e4c894c2f2..eb17237afbb5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt
@@ -26,6 +26,7 @@ import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.statusbar.chips.ui.viewmodel.ongoingActivityChipsViewModel
import com.android.systemui.statusbar.events.domain.interactor.systemStatusEventAnimationInteractor
import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
+import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
import com.android.systemui.statusbar.phone.domain.interactor.lightsOutInteractor
import com.android.systemui.statusbar.pipeline.shared.domain.interactor.collapsedStatusBarInteractor
@@ -35,6 +36,7 @@ val Kosmos.homeStatusBarViewModel: HomeStatusBarViewModel by
collapsedStatusBarInteractor,
lightsOutInteractor,
activeNotificationsInteractor,
+ headsUpNotificationInteractor,
keyguardTransitionInteractor,
keyguardInteractor,
sceneInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/touchpad/ui/gesture/FakeVelocityTracker.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/touchpad/ui/gesture/FakeVelocityTracker.kt
new file mode 100644
index 000000000000..f12089a08488
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/touchpad/ui/gesture/FakeVelocityTracker.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.touchpad.ui.gesture
+
+import android.view.MotionEvent
+import com.android.systemui.touchpad.tutorial.ui.gesture.Velocity
+import com.android.systemui.touchpad.tutorial.ui.gesture.VelocityTracker
+
+class FakeVelocityTracker : VelocityTracker {
+
+ private var fakeVelocity = Velocity(0f)
+
+ override fun calculateVelocity(): Velocity {
+ return fakeVelocity
+ }
+
+ override fun accept(event: MotionEvent) {}
+
+ fun setVelocity(velocity: Velocity) {
+ fakeVelocity = velocity
+ }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/touchpad/ui/gesture/VelocityTrackerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/touchpad/ui/gesture/VelocityTrackerKosmos.kt
new file mode 100644
index 000000000000..3b61e2191d8c
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/touchpad/ui/gesture/VelocityTrackerKosmos.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.touchpad.ui.gesture
+
+import com.android.systemui.kosmos.Kosmos
+
+var Kosmos.fakeVelocityTracker: FakeVelocityTracker by Kosmos.Fixture { FakeVelocityTracker() }
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 7ef6aace1538..e1b6c9c5aa42 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -409,10 +409,6 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
final int eventSource = event.getSource();
final int displayId = event.getDisplayId();
if ((policyFlags & WindowManagerPolicy.FLAG_PASS_TO_USER) == 0) {
- if (!Flags.doNotResetKeyEventState()) {
- state.reset();
- clearEventStreamHandler(displayId, eventSource);
- }
if (DEBUG) {
Slog.d(TAG, "Not processing event " + event);
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 71a0fc453a95..ab556b39f516 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -2269,8 +2269,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
mContext, shortcutType, userState.mUserId))
: userState.getShortcutTargetsLocked(shortcutType);
- if (Flags.clearDefaultFromA11yShortcutTargetServiceRestore()
- && shortcutType == HARDWARE) {
+ if (shortcutType == HARDWARE) {
final String defaultService =
mContext.getString(R.string.config_defaultAccessibilityService);
final ComponentName defaultServiceComponent = TextUtils.isEmpty(defaultService)
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
index 0ed239e442e7..0cbbf6da022b 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
@@ -240,10 +240,7 @@ public class TouchExplorer extends BaseEventStreamTransformation
}
private void clear(MotionEvent event, int policyFlags) {
- if (mState.isTouchExploring() || Flags.sendHoverEventsBasedOnEventStream()) {
- // If a touch exploration gesture is in progress send events for its end.
- sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
- }
+ sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
mDraggingPointerId = INVALID_POINTER_ID;
// Send exit to any pointers that we have delivered as part of delegating or dragging.
mDispatcher.sendUpForInjectedDownPointers(event, policyFlags);
@@ -562,10 +559,7 @@ public class TouchExplorer extends BaseEventStreamTransformation
// clear any hover events that might have been queued and never sent.
mSendHoverEnterAndMoveDelayed.clear();
mSendHoverExitDelayed.cancel();
- // If a touch exploration gesture is in progress send events for its end.
- if (mState.isTouchExploring() || Flags.sendHoverEventsBasedOnEventStream()) {
- sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
- }
+ sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
if (mState.isClear()) {
if (!mSendHoverEnterAndMoveDelayed.isPending()) {
// Queue a delayed transition to STATE_TOUCH_EXPLORING.
@@ -1599,9 +1593,7 @@ public class TouchExplorer extends BaseEventStreamTransformation
if (mEvents.size() == 0) {
return;
}
- if (Flags.sendHoverEventsBasedOnEventStream()) {
- sendHoverExitAndTouchExplorationGestureEndIfNeeded(mPolicyFlags);
- }
+ sendHoverExitAndTouchExplorationGestureEndIfNeeded(mPolicyFlags);
// Send an accessibility event to announce the touch exploration start.
mDispatcher.sendAccessibilityEvent(TYPE_TOUCH_EXPLORATION_GESTURE_START);
if (isSendMotionEventsEnabled()) {
diff --git a/services/autofill/features.aconfig b/services/autofill/features.aconfig
index b3fe5f234bc2..57036335bb75 100644
--- a/services/autofill/features.aconfig
+++ b/services/autofill/features.aconfig
@@ -31,9 +31,24 @@ flag {
}
flag {
+ name: "fill_dialog_improvements_impl"
+ is_exported: true
+ namespace: "autofill"
+ description: "Improvements for Fill Dialog for non-api changes"
+ bug: "336223371"
+}
+
+flag {
name: "fill_dialog_improvements"
is_exported: true
namespace: "autofill"
description: "Improvements for Fill Dialog, including deprecation of pre-trigger API's"
bug: "336223371"
}
+
+flag {
+ name: "add_last_focused_id_to_fill_event_history"
+ namespace: "autofill"
+ description: "Adds focused id to each event that's part of the fill event history"
+ bug: "334141398"
+}
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index b52c65054e51..cd4ace2e3835 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -900,13 +900,13 @@ final class AutofillManagerServiceImpl
* Updates the last fill selection when an authentication was selected.
*/
void setAuthenticationSelected(int sessionId, @Nullable Bundle clientState,
- int uiType) {
+ int uiType, @Nullable AutofillId focusedId) {
synchronized (mLock) {
if (isValidEventLocked("setAuthenticationSelected()", sessionId)) {
mEventHistory.addEvent(
new Event(Event.TYPE_AUTHENTICATION_SELECTED, null, clientState, null, null,
null, null, null, null, null, null,
- NO_SAVE_UI_REASON_NONE, uiType));
+ NO_SAVE_UI_REASON_NONE, uiType, focusedId));
}
}
}
@@ -915,13 +915,13 @@ final class AutofillManagerServiceImpl
* Updates the last fill selection when an dataset authentication was selected.
*/
void logDatasetAuthenticationSelected(@Nullable String selectedDataset, int sessionId,
- @Nullable Bundle clientState, int uiType) {
+ @Nullable Bundle clientState, int uiType, @Nullable AutofillId focusedId) {
synchronized (mLock) {
if (isValidEventLocked("logDatasetAuthenticationSelected()", sessionId)) {
mEventHistory.addEvent(
new Event(Event.TYPE_DATASET_AUTHENTICATION_SELECTED, selectedDataset,
clientState, null, null, null, null, null, null, null, null,
- NO_SAVE_UI_REASON_NONE, uiType));
+ NO_SAVE_UI_REASON_NONE, uiType, focusedId));
}
}
}
@@ -933,7 +933,7 @@ final class AutofillManagerServiceImpl
synchronized (mLock) {
if (isValidEventLocked("logSaveShown()", sessionId)) {
mEventHistory.addEvent(new Event(Event.TYPE_SAVE_SHOWN, null, clientState, null,
- null, null, null, null, null, null, null));
+ null, null, null, null, null, null, null, /* focusedId= */ null));
}
}
}
@@ -942,13 +942,13 @@ final class AutofillManagerServiceImpl
* Updates the last fill response when a dataset was selected.
*/
void logDatasetSelected(@Nullable String selectedDataset, int sessionId,
- @Nullable Bundle clientState, int uiType) {
+ @Nullable Bundle clientState, int uiType, @Nullable AutofillId focusedId) {
synchronized (mLock) {
if (isValidEventLocked("logDatasetSelected()", sessionId)) {
mEventHistory.addEvent(
new Event(Event.TYPE_DATASET_SELECTED, selectedDataset, clientState, null,
null, null, null, null, null, null, null, NO_SAVE_UI_REASON_NONE,
- uiType));
+ uiType, focusedId));
}
}
}
@@ -956,13 +956,14 @@ final class AutofillManagerServiceImpl
/**
* Updates the last fill response when a dataset is shown.
*/
- void logDatasetShown(int sessionId, @Nullable Bundle clientState, int uiType) {
+ void logDatasetShown(int sessionId, @Nullable Bundle clientState, int uiType,
+ @Nullable AutofillId focusedId) {
synchronized (mLock) {
if (isValidEventLocked("logDatasetShown", sessionId)) {
mEventHistory.addEvent(
new Event(Event.TYPE_DATASETS_SHOWN, null, clientState, null, null, null,
null, null, null, null, null, NO_SAVE_UI_REASON_NONE,
- uiType));
+ uiType, focusedId));
}
}
}
@@ -970,7 +971,8 @@ final class AutofillManagerServiceImpl
/**
* Updates the last fill response when a view was entered.
*/
- void logViewEntered(int sessionId, @Nullable Bundle clientState) {
+ void logViewEntered(int sessionId, @Nullable Bundle clientState,
+ @Nullable AutofillId focusedId) {
synchronized (mLock) {
if (!isValidEventLocked("logViewEntered", sessionId)) {
return;
@@ -988,7 +990,7 @@ final class AutofillManagerServiceImpl
mEventHistory.addEvent(
new Event(Event.TYPE_VIEW_REQUESTED_AUTOFILL, null, clientState, null,
- null, null, null, null, null, null, null));
+ null, null, null, null, null, null, null, focusedId));
}
}
@@ -1001,7 +1003,8 @@ final class AutofillManagerServiceImpl
}
mAugmentedAutofillEventHistory.addEvent(
new Event(Event.TYPE_DATASET_AUTHENTICATION_SELECTED, selectedDataset,
- clientState, null, null, null, null, null, null, null, null));
+ clientState, null, null, null, null, null, null, null, null,
+ /* focusedId= */ null));
}
}
@@ -1014,7 +1017,7 @@ final class AutofillManagerServiceImpl
}
mAugmentedAutofillEventHistory.addEvent(
new Event(Event.TYPE_DATASET_SELECTED, suggestionId, clientState, null, null,
- null, null, null, null, null, null));
+ null, null, null, null, null, null, /* focusedId= */ null));
}
}
@@ -1029,7 +1032,7 @@ final class AutofillManagerServiceImpl
mAugmentedAutofillEventHistory.addEvent(
new Event(Event.TYPE_DATASETS_SHOWN, null, clientState, null, null, null,
null, null, null, null, null, NO_SAVE_UI_REASON_NONE,
- UI_TYPE_INLINE));
+ UI_TYPE_INLINE, /* focusedId= */ null));
}
}
@@ -1113,7 +1116,8 @@ final class AutofillManagerServiceImpl
clientState, selectedDatasets, ignoredDatasets,
changedFieldIds, changedDatasetIds,
manuallyFilledFieldIds, manuallyFilledDatasetIds,
- detectedFieldsIds, detectedFieldClassifications, saveDialogNotShowReason));
+ detectedFieldsIds, detectedFieldClassifications, saveDialogNotShowReason,
+ /* focusedId= */ null));
}
}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 8f12b1db8f29..6b227d7a876e 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -1871,7 +1871,7 @@ final class Session
if (mLogViewEntered) {
mLogViewEntered = false;
- mService.logViewEntered(id, null);
+ mService.logViewEntered(id, null, mCurrentViewId);
}
}
@@ -2775,9 +2775,9 @@ final class Session
forceRemoveFromServiceLocked();
return;
}
+ mService.setAuthenticationSelected(id, mClientState, uiType, mCurrentViewId);
}
- mService.setAuthenticationSelected(id, mClientState, uiType);
final int authenticationId = AutofillManager.makeAuthenticationId(requestId, datasetIndex);
mHandler.sendMessage(
@@ -2850,7 +2850,7 @@ final class Session
if (!mLoggedInlineDatasetShown) {
// Chip inflation already logged, do not log again.
// This is needed because every chip inflation will call this.
- mService.logDatasetShown(this.id, mClientState, uiType);
+ mService.logDatasetShown(this.id, mClientState, uiType, mCurrentViewId);
Slog.d(TAG, "onShown(): " + uiType + ", " + numDatasetsShown);
}
mLoggedInlineDatasetShown = true;
@@ -2858,7 +2858,7 @@ final class Session
mPresentationStatsEventLogger.logWhenDatasetShown(numDatasetsShown);
// Explicitly sets maybeSetSuggestionPresentedTimestampMs
mPresentationStatsEventLogger.maybeSetSuggestionPresentedTimestampMs();
- mService.logDatasetShown(this.id, mClientState, uiType);
+ mService.logDatasetShown(this.id, mClientState, uiType, mCurrentViewId);
Slog.d(TAG, "onShown(): " + uiType + ", " + numDatasetsShown);
}
}
@@ -5139,7 +5139,7 @@ final class Session
// so this calling logViewEntered will be a nop.
// Calling logViewEntered() twice will only log it once
// TODO(271181979): this is broken for multiple partitions
- mService.logViewEntered(this.id, null);
+ mService.logViewEntered(this.id, null, mCurrentViewId);
}
// If this is the first time view is entered for inline, the last
@@ -6657,7 +6657,8 @@ final class Session
// Autofill it directly...
if (dataset.getAuthentication() == null) {
if (generateEvent) {
- mService.logDatasetSelected(dataset.getId(), id, mClientState, uiType);
+ mService.logDatasetSelected(dataset.getId(), id, mClientState, uiType,
+ mCurrentViewId);
}
if (mCurrentViewId != null) {
mInlineSessionController.hideInlineSuggestionsUiLocked(mCurrentViewId);
@@ -6667,7 +6668,8 @@ final class Session
}
// ...or handle authentication.
- mService.logDatasetAuthenticationSelected(dataset.getId(), id, mClientState, uiType);
+ mService.logDatasetAuthenticationSelected(dataset.getId(), id, mClientState, uiType,
+ mCurrentViewId);
mPresentationStatsEventLogger.maybeSetAuthenticationType(
AUTHENTICATION_TYPE_DATASET_AUTHENTICATION);
// does not matter the value of isPrimary because null response won't be overridden.
diff --git a/services/backup/flags.aconfig b/services/backup/flags.aconfig
index fcb7934f7ca0..28d3caeab45a 100644
--- a/services/backup/flags.aconfig
+++ b/services/backup/flags.aconfig
@@ -69,3 +69,11 @@ flag {
bug: "376661510"
is_fixed_read_only: true
}
+
+flag {
+ name: "enable_read_all_external_storage_files"
+ is_exported: true
+ namespace: "onboarding"
+ description: "Enables read all external storage files"
+ bug: "376598575"
+} \ No newline at end of file
diff --git a/services/core/Android.bp b/services/core/Android.bp
index aea16b08df49..6d60164e3d0e 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -188,7 +188,7 @@ java_library_static {
"android.hardware.health-V1.0-java", // HIDL
"android.hardware.health-V2.0-java", // HIDL
"android.hardware.health-V2.1-java", // HIDL
- "android.hardware.health-V3-java", // AIDL
+ "android.hardware.health-V4-java", // AIDL
"android.hardware.health-translate-java",
"android.hardware.light-V1-java",
"android.hardware.security.authgraph-V1-java",
@@ -238,7 +238,6 @@ java_library_static {
"connectivity_flags_lib",
"device_config_service_flags_java",
"dreams_flags_lib",
- "aconfig_flags_java",
"aconfig_new_storage_flags_lib",
"powerstats_flags_lib",
"locksettings_flags_lib",
diff --git a/services/core/java/com/android/server/BinaryTransparencyService.java b/services/core/java/com/android/server/BinaryTransparencyService.java
index 0286f7b0b73d..36dff89d9d61 100644
--- a/services/core/java/com/android/server/BinaryTransparencyService.java
+++ b/services/core/java/com/android/server/BinaryTransparencyService.java
@@ -101,6 +101,9 @@ import java.util.Map;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
+import com.android.server.pm.BackgroundInstallControlService;
+import com.android.server.pm.BackgroundInstallControlCallbackHelper;
+
/**
* @hide
*/
@@ -138,6 +141,10 @@ public class BinaryTransparencyService extends SystemService {
static final int MBA_STATUS_NEW_INSTALL = 3;
// used for indicating newly installed MBAs that are updated (but unused currently)
static final int MBA_STATUS_UPDATED_NEW_INSTALL = 4;
+ // used for indicating preloaded MBAs that are downgraded
+ static final int MBA_STATUS_DOWNGRADED_PRELOADED = 5;
+ // used for indicating MBAs that are uninstalled
+ static final int MBA_STATUS_UNINSTALLED = 6;
@VisibleForTesting
static final String KEY_ENABLE_BIOMETRIC_PROPERTY_VERIFICATION =
@@ -202,7 +209,9 @@ public class BinaryTransparencyService extends SystemService {
* @param mbaStatus Assign this value of MBA status to the returned elements.
* @return a @{@code List<IBinaryTransparencyService.AppInfo>}
*/
- private @NonNull List<IBinaryTransparencyService.AppInfo> collectAppInfo(
+ @VisibleForTesting
+ @NonNull
+ List<IBinaryTransparencyService.AppInfo> collectAppInfo(
PackageState packageState, int mbaStatus) {
// compute content digest
if (DEBUG) {
@@ -336,27 +345,28 @@ public class BinaryTransparencyService extends SystemService {
+ " packages after considering APEXs.");
}
- // proceed with all preloaded apps
- List<IBinaryTransparencyService.AppInfo> allUpdatedPreloadInfo =
- collectAllUpdatedPreloadInfo(packagesMeasured);
- for (IBinaryTransparencyService.AppInfo appInfo : allUpdatedPreloadInfo) {
- packagesMeasured.putBoolean(appInfo.packageName, true);
- writeAppInfoToLog(appInfo);
- }
- if (DEBUG) {
- Slog.d(TAG, "Measured " + packagesMeasured.size()
- + " packages after considering preloads");
- }
-
- if (!android.app.Flags.backgroundInstallControlCallbackApi()
- && CompatChanges.isChangeEnabled(LOG_MBA_INFO)) {
- // lastly measure all newly installed MBAs
- List<IBinaryTransparencyService.AppInfo> allMbaInfo =
- collectAllSilentInstalledMbaInfo(packagesMeasured);
- for (IBinaryTransparencyService.AppInfo appInfo : allMbaInfo) {
+ if (!android.app.Flags.backgroundInstallControlCallbackApi()) {
+ // proceed with all preloaded apps
+ List<IBinaryTransparencyService.AppInfo> allUpdatedPreloadInfo =
+ collectAllUpdatedPreloadInfo(packagesMeasured);
+ for (IBinaryTransparencyService.AppInfo appInfo : allUpdatedPreloadInfo) {
packagesMeasured.putBoolean(appInfo.packageName, true);
writeAppInfoToLog(appInfo);
}
+ if (DEBUG) {
+ Slog.d(TAG, "Measured " + packagesMeasured.size()
+ + " packages after considering preloads");
+ }
+
+ if (CompatChanges.isChangeEnabled(LOG_MBA_INFO)) {
+ // lastly measure all newly installed MBAs
+ List<IBinaryTransparencyService.AppInfo> allMbaInfo =
+ collectAllSilentInstalledMbaInfo(packagesMeasured);
+ for (IBinaryTransparencyService.AppInfo appInfo : allMbaInfo) {
+ packagesMeasured.putBoolean(appInfo.packageName, true);
+ writeAppInfoToLog(appInfo);
+ }
+ }
}
long timeSpentMeasuring = System.currentTimeMillis() - currentTimeMs;
digestAllPackagesLatency.logSample(timeSpentMeasuring);
@@ -466,7 +476,8 @@ public class BinaryTransparencyService extends SystemService {
apexInfo.signerDigests);
}
- private void writeAppInfoToLog(IBinaryTransparencyService.AppInfo appInfo) {
+ @VisibleForTesting
+ void writeAppInfoToLog(IBinaryTransparencyService.AppInfo appInfo) {
// Must order by the proto's field number.
FrameworkStatsLog.write(FrameworkStatsLog.MOBILE_BUNDLED_APP_INFO_GATHERED,
appInfo.packageName,
@@ -1165,41 +1176,86 @@ public class BinaryTransparencyService extends SystemService {
* TODO: Add a host test for testing registration and callback of BicCallbackHandler
* b/380002484
*/
+ @VisibleForTesting
static class BicCallbackHandler extends IRemoteCallback.Stub {
- private static final String BIC_CALLBACK_HANDLER_TAG =
- "BTS.BicCallbackHandler";
- private final BinaryTransparencyServiceImpl mServiceImpl;
- static final String FLAGGED_PACKAGE_NAME_KEY = "packageName";
+ private static final String BIC_CALLBACK_HANDLER_TAG = TAG + ".BicCallbackHandler";
+
+ private static final int INSTALL_EVENT_TYPE_UNSET = -1;
+
+ private final IBicAppInfoHelper mBicAppInfoHelper;
- BicCallbackHandler(BinaryTransparencyServiceImpl impl) {
- mServiceImpl = impl;
+ @VisibleForTesting
+ BicCallbackHandler(IBicAppInfoHelper bicAppInfoHelper) {
+ mBicAppInfoHelper = bicAppInfoHelper;
}
@Override
public void sendResult(Bundle data) {
- String packageName = data.getString(FLAGGED_PACKAGE_NAME_KEY);
- if (packageName == null) return;
- if (DEBUG) {
- Slog.d(BIC_CALLBACK_HANDLER_TAG, "background install event detected for "
- + packageName);
- }
-
- PackageState packageState = LocalServices.getService(PackageManagerInternal.class)
- .getPackageStateInternal(packageName);
- if (packageState == null) {
- Slog.w(TAG, "Package state is unavailable, ignoring the package "
- + packageName);
- return;
- }
- if (packageState.isUpdatedSystemApp()) {
+ String packageName = data.getString(
+ BackgroundInstallControlCallbackHelper.FLAGGED_PACKAGE_NAME_KEY);
+ int installType = data.getInt(
+ BackgroundInstallControlCallbackHelper.INSTALL_EVENT_TYPE_KEY,
+ INSTALL_EVENT_TYPE_UNSET);
+ if (packageName == null || installType == INSTALL_EVENT_TYPE_UNSET) {
+ Slog.w(BIC_CALLBACK_HANDLER_TAG, "Package name or install type is "
+ + "unavailable, ignoring event");
return;
}
- List<IBinaryTransparencyService.AppInfo> mbaInfo = mServiceImpl.collectAppInfo(
- packageState, MBA_STATUS_NEW_INSTALL);
- for (IBinaryTransparencyService.AppInfo appInfo : mbaInfo) {
- mServiceImpl.writeAppInfoToLog(appInfo);
+ Slog.d(BIC_CALLBACK_HANDLER_TAG, "Detected new bic event for: " + packageName);
+ if (installType == BackgroundInstallControlService.INSTALL_EVENT_TYPE_INSTALL) {
+ PackageState packageState = LocalServices.getService(PackageManagerInternal.class)
+ .getPackageStateInternal(packageName);
+ if (packageState == null) {
+ Slog.w(TAG, "Package state is unavailable, ignoring the package "
+ + packageName);
+ return;
+ }
+ int mbaStatus = MBA_STATUS_NEW_INSTALL;
+ if (packageState.isUpdatedSystemApp()) {
+ mbaStatus = MBA_STATUS_UPDATED_PRELOAD;
+ }
+ List<IBinaryTransparencyService.AppInfo> mbaInfo = mBicAppInfoHelper.collectAppInfo(
+ packageState, mbaStatus);
+ for (IBinaryTransparencyService.AppInfo appInfo : mbaInfo) {
+ mBicAppInfoHelper.writeAppInfoToLog(appInfo);
+ }
+ } else if (installType
+ == BackgroundInstallControlService.INSTALL_EVENT_TYPE_UNINSTALL) {
+ IBinaryTransparencyService.AppInfo appInfo
+ = new IBinaryTransparencyService.AppInfo();
+ // since app is already uninstalled we won't be able to retrieve additional
+ // info on it.
+ appInfo.packageName = packageName;
+ appInfo.mbaStatus = MBA_STATUS_UNINSTALLED;
+ mBicAppInfoHelper.writeAppInfoToLog(appInfo);
+ } else {
+ Slog.w(BIC_CALLBACK_HANDLER_TAG, "Unsupported BIC event: " + installType);
}
}
+
+ /**
+ * A wrapper of interface for{@link FrameworkStatsLog and ApkDigests}
+ * for easier testing
+ */
+ @VisibleForTesting
+ public interface IBicAppInfoHelper {
+
+ /**
+ * A wrapper of {@link FrameworkStatsLog}
+ *
+ * @param appInfo The app info of the changed MBA to be logged
+ */
+ public void writeAppInfoToLog(IBinaryTransparencyService.AppInfo appInfo);
+
+ /**
+ * A wrapper of {@link BinaryTransparencyServiceImpl}
+ *
+ * @param packageState The packageState provided retrieved from PackageManagerInternal
+ * @param mbaStatus The MBA status of the package
+ */
+ public List<IBinaryTransparencyService.AppInfo> collectAppInfo(
+ PackageState packageState, int mbaStatus);
+ }
};
/**
@@ -1596,7 +1652,21 @@ public class BinaryTransparencyService extends SystemService {
}
try {
iBics.registerBackgroundInstallCallback(
- new BicCallbackHandler(mServiceImpl));
+ new BicCallbackHandler(
+ new BicCallbackHandler.IBicAppInfoHelper() {
+ @Override
+ public void writeAppInfoToLog(
+ IBinaryTransparencyService.AppInfo appInfo) {
+ mServiceImpl.writeAppInfoToLog(appInfo);
+ }
+
+ @Override
+ public List<IBinaryTransparencyService.AppInfo> collectAppInfo(
+ PackageState packageState, int mbaStatus) {
+ return mServiceImpl.collectAppInfo(packageState, mbaStatus);
+ }
+ }
+ ));
} catch (RemoteException e) {
Slog.e(TAG, "Failed to register BackgroundInstallControl callback.");
}
@@ -1643,8 +1713,12 @@ public class BinaryTransparencyService extends SystemService {
}
String packageName = data.getSchemeSpecificPart();
- // now we've got to check what package is this
- if (isPackagePreloaded(packageName) || isPackageAnApex(packageName)) {
+
+ boolean shouldMeasureMba =
+ !android.app.Flags.backgroundInstallControlCallbackApi()
+ && isPackagePreloaded(packageName);
+
+ if (shouldMeasureMba || isPackageAnApex(packageName)) {
Slog.d(TAG, packageName + " was updated. Scheduling measurement...");
UpdateMeasurementsJobService.scheduleBinaryMeasurements(mContext,
BinaryTransparencyService.this);
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 71cbc10074d6..a58d850e042f 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -5845,7 +5845,7 @@ public final class ActiveServices {
if (r.inSharedIsolatedProcess) {
app = mAm.mProcessList.getSharedIsolatedProcess(procName, r.appInfo.uid,
r.appInfo.packageName);
- if (app != null) {
+ if (app != null && !app.isKilled()) {
final IApplicationThread thread = app.getThread();
final int pid = app.getPid();
final UidRecord uidRecord = app.getUidRecord();
@@ -5870,6 +5870,8 @@ public final class ActiveServices {
// If a dead object exception was thrown -- fall through to
// restart the application.
}
+ } else {
+ app = null;
}
} else {
// If this service runs in an isolated process, then each time
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 053ec824e1a7..78dee3169161 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -132,7 +132,7 @@ import static android.provider.Settings.Global.DEBUG_APP;
import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
import static android.security.Flags.preventIntentRedirect;
import static android.security.Flags.preventIntentRedirectCollectNestedKeysOnServerIfNotCollected;
-import static android.security.Flags.preventIntentRedirectShowToast;
+import static android.security.Flags.preventIntentRedirectShowToastIfNestedKeysNotCollected;
import static android.security.Flags.preventIntentRedirectThrowExceptionIfNestedKeysNotCollected;
import static android.util.FeatureFlagUtils.SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS;
import static android.view.Display.INVALID_DISPLAY;
@@ -192,6 +192,7 @@ import static com.android.systemui.shared.Flags.enableHomeDelay;
import android.Manifest;
import android.Manifest.permission;
+import android.annotation.EnforcePermission;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.PermissionMethod;
@@ -19228,6 +19229,11 @@ public class ActivityManagerService extends IActivityManager.Stub
return mKeyFields.mCreatorPackage;
}
+ @VisibleForTesting
+ public @NonNull Key getKeyFields() {
+ return mKeyFields;
+ }
+
public static boolean isValid(@NonNull Intent intent) {
IBinder binder = intent.getCreatorToken();
IntentCreatorToken token = null;
@@ -19271,9 +19277,13 @@ public class ActivityManagerService extends IActivityManager.Stub
this.mFlags = intent.getFlags() & Intent.IMMUTABLE_FLAGS;
ClipData clipData = intent.getClipData();
if (clipData != null) {
- this.mClipDataUris = new ArrayList<>(clipData.getItemCount());
- for (int i = 0; i < clipData.getItemCount(); i++) {
- this.mClipDataUris.add(clipData.getItemAt(i).getUri());
+ clipData = clipData.cloneOnlyUriItems();
+ if (clipData != null) {
+ List<Uri> clipDataUris = new ArrayList<>();
+ clipData.collectUris(clipDataUris);
+ if (!clipDataUris.isEmpty()) {
+ this.mClipDataUris = clipDataUris;
+ }
}
}
}
@@ -19326,7 +19336,7 @@ public class ActivityManagerService extends IActivityManager.Stub
"[IntentRedirect] The intent does not have its nested keys collected as a "
+ "preparation for creating intent creator tokens. Intent: "
+ intent + "; creatorPackage: " + creatorPackage);
- if (preventIntentRedirectShowToast()) {
+ if (preventIntentRedirectShowToastIfNestedKeysNotCollected()) {
UiThread.getHandler().post(
() -> Toast.makeText(mContext,
"Nested keys not collected. go/report-bug-intentRedir to report a"
@@ -19375,11 +19385,34 @@ public class ActivityManagerService extends IActivityManager.Stub
String creatorPackage) {
if (IntentCreatorToken.isValid(intent)) return null;
IntentCreatorToken.Key key = new IntentCreatorToken.Key(creatorUid, creatorPackage, intent);
+ return createOrGetIntentCreatorToken(intent, key);
+ }
+
+ /**
+ * @hide
+ */
+ @EnforcePermission("android.permission.INTERACT_ACROSS_USERS_FULL")
+ public IBinder refreshIntentCreatorToken(Intent intent) {
+ refreshIntentCreatorToken_enforcePermission();
+ IBinder binder = intent.getCreatorToken();
+ if (binder instanceof IntentCreatorToken) {
+ IntentCreatorToken token = (IntentCreatorToken) binder;
+ IntentCreatorToken.Key key = new IntentCreatorToken.Key(token.getCreatorUid(),
+ token.getCreatorPackage(), intent);
+ return createOrGetIntentCreatorToken(intent, key);
+
+ } else {
+ throw new IllegalArgumentException("intent does not contain a creator token.");
+ }
+ }
+
+ private static IntentCreatorToken createOrGetIntentCreatorToken(Intent intent,
+ IntentCreatorToken.Key key) {
IntentCreatorToken token;
synchronized (sIntentCreatorTokenCache) {
WeakReference<IntentCreatorToken> ref = sIntentCreatorTokenCache.get(key);
if (ref == null || ref.get() == null) {
- token = new IntentCreatorToken(creatorUid, creatorPackage, intent);
+ token = new IntentCreatorToken(key.mCreatorUid, key.mCreatorPackage, intent);
sIntentCreatorTokenCache.put(key, token.mRef);
} else {
token = ref.get();
diff --git a/services/core/java/com/android/server/am/BroadcastController.java b/services/core/java/com/android/server/am/BroadcastController.java
index c6cb67f4efa8..354f281551b2 100644
--- a/services/core/java/com/android/server/am/BroadcastController.java
+++ b/services/core/java/com/android/server/am/BroadcastController.java
@@ -57,6 +57,7 @@ import android.app.ApplicationExitInfo;
import android.app.ApplicationThreadConstants;
import android.app.BackgroundStartPrivileges;
import android.app.BroadcastOptions;
+import android.app.BroadcastStickyCache;
import android.app.IApplicationThread;
import android.app.compat.CompatChanges;
import android.appwidget.AppWidgetManager;
@@ -183,6 +184,13 @@ class BroadcastController {
final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
/**
+ * If {@code false} invalidate the list of {@link android.os.IpcDataCache} present inside the
+ * {@link BroadcastStickyCache} class.
+ * The invalidation is required to start caching of the sticky broadcast in the client side.
+ */
+ private volatile boolean mAreStickyCachesInvalidated = false;
+
+ /**
* Resolver for broadcast intents to registered receivers.
* Holds BroadcastFilter (subclass of IntentFilter).
*/
@@ -288,6 +296,11 @@ class BroadcastController {
IIntentReceiver receiver, IntentFilter filter, String permission,
int userId, int flags) {
mService.enforceNotIsolatedCaller("registerReceiver");
+
+ if (!mAreStickyCachesInvalidated) {
+ BroadcastStickyCache.invalidateAllCaches();
+ mAreStickyCachesInvalidated = true;
+ }
ArrayList<StickyBroadcast> stickyBroadcasts = null;
ProcessRecord callerApp = null;
final boolean visibleToInstantApps =
@@ -700,6 +713,7 @@ class BroadcastController {
String[] excludedPackages, int appOp, Bundle bOptions,
boolean serialized, boolean sticky, int userId) {
mService.enforceNotIsolatedCaller("broadcastIntent");
+ final int result;
synchronized (mService) {
intent = verifyBroadcastLocked(intent);
@@ -722,7 +736,7 @@ class BroadcastController {
final long origId = Binder.clearCallingIdentity();
try {
- return broadcastIntentLocked(callerApp,
+ result = broadcastIntentLocked(callerApp,
callerApp != null ? callerApp.info.packageName : null, callingFeatureId,
intent, resolvedType, resultToApp, resultTo, resultCode, resultData,
resultExtras, requiredPermissions, excludedPermissions, excludedPackages,
@@ -733,6 +747,11 @@ class BroadcastController {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
+
+ if (sticky && result == ActivityManager.BROADCAST_SUCCESS) {
+ BroadcastStickyCache.invalidateCache(intent.getAction());
+ }
+ return result;
}
// Not the binder call surface
@@ -743,6 +762,7 @@ class BroadcastController {
boolean serialized, boolean sticky, int userId,
BackgroundStartPrivileges backgroundStartPrivileges,
@Nullable int[] broadcastAllowList) {
+ final int result;
synchronized (mService) {
intent = verifyBroadcastLocked(intent);
@@ -750,7 +770,7 @@ class BroadcastController {
String[] requiredPermissions = requiredPermission == null ? null
: new String[] {requiredPermission};
try {
- return broadcastIntentLocked(null, packageName, featureId, intent, resolvedType,
+ result = broadcastIntentLocked(null, packageName, featureId, intent, resolvedType,
resultToApp, resultTo, resultCode, resultData, resultExtras,
requiredPermissions, null, null, OP_NONE, bOptions, serialized, sticky, -1,
uid, realCallingUid, realCallingPid, userId,
@@ -760,6 +780,11 @@ class BroadcastController {
Binder.restoreCallingIdentity(origId);
}
}
+
+ if (sticky && result == ActivityManager.BROADCAST_SUCCESS) {
+ BroadcastStickyCache.invalidateCache(intent.getAction());
+ }
+ return result;
}
@GuardedBy("mService")
@@ -1458,6 +1483,7 @@ class BroadcastController {
list.add(StickyBroadcast.create(new Intent(intent), deferUntilActive,
callingUid, callerAppProcessState, resolvedType));
}
+ BroadcastStickyCache.invalidateCache(intent.getAction());
}
}
@@ -1724,6 +1750,7 @@ class BroadcastController {
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
+ final ArrayList<String> changedStickyBroadcasts = new ArrayList<>();
synchronized (mStickyBroadcasts) {
ArrayMap<String, ArrayList<StickyBroadcast>> stickies = mStickyBroadcasts.get(userId);
if (stickies != null) {
@@ -1740,12 +1767,16 @@ class BroadcastController {
if (list.size() <= 0) {
stickies.remove(intent.getAction());
}
+ changedStickyBroadcasts.add(intent.getAction());
}
if (stickies.size() <= 0) {
mStickyBroadcasts.remove(userId);
}
}
}
+ for (int i = changedStickyBroadcasts.size() - 1; i >= 0; --i) {
+ BroadcastStickyCache.invalidateCache(changedStickyBroadcasts.get(i));
+ }
}
void finishReceiver(IBinder caller, int resultCode, String resultData,
@@ -2124,9 +2155,18 @@ class BroadcastController {
}
void removeStickyBroadcasts(int userId) {
+ final ArrayList<String> changedStickyBroadcasts = new ArrayList<>();
synchronized (mStickyBroadcasts) {
+ final ArrayMap<String, ArrayList<StickyBroadcast>> stickies =
+ mStickyBroadcasts.get(userId);
+ if (stickies != null) {
+ changedStickyBroadcasts.addAll(stickies.keySet());
+ }
mStickyBroadcasts.remove(userId);
}
+ for (int i = changedStickyBroadcasts.size() - 1; i >= 0; --i) {
+ BroadcastStickyCache.invalidateCache(changedStickyBroadcasts.get(i));
+ }
}
@NeverCompile
diff --git a/services/core/java/com/android/server/am/BroadcastFilter.java b/services/core/java/com/android/server/am/BroadcastFilter.java
index a32d3cb86c24..05aeb42dbc9f 100644
--- a/services/core/java/com/android/server/am/BroadcastFilter.java
+++ b/services/core/java/com/android/server/am/BroadcastFilter.java
@@ -57,7 +57,6 @@ public final class BroadcastFilter extends IntentFilter {
final boolean visibleToInstantApp;
public final boolean exported;
final int initialPriority;
- final ApplicationInfo applicationInfo;
BroadcastFilter(IntentFilter _filter, ReceiverList _receiverList,
String _packageName, String _featureId, String _receiverId, String _requiredPermission,
@@ -74,10 +73,9 @@ public final class BroadcastFilter extends IntentFilter {
instantApp = _instantApp;
visibleToInstantApp = _visibleToInstantApp;
exported = _exported;
- applicationInfo = _applicationInfo;
initialPriority = getPriority();
setPriority(calculateAdjustedPriority(owningUid, initialPriority,
- applicationInfo, platformCompat));
+ _applicationInfo, platformCompat));
}
public @Nullable String getReceiverClassName() {
@@ -91,7 +89,7 @@ public final class BroadcastFilter extends IntentFilter {
}
public @NonNull ApplicationInfo getApplicationInfo() {
- return applicationInfo;
+ return receiverList.app.info;
}
@NeverCompile
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 7660c154efd5..e838a8dc7e7f 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -42,7 +42,6 @@ import android.aconfigd.Aconfigd.StorageReturnMessages;
import static com.android.aconfig_new_storage.Flags.enableAconfigStorageDaemon;
import static com.android.aconfig_new_storage.Flags.supportImmediateLocalOverrides;
import static com.android.aconfig_new_storage.Flags.supportClearLocalOverridesImmediately;
-import static com.android.aconfig.flags.Flags.enableSystemAconfigdRust;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@@ -461,9 +460,8 @@ public class SettingsToPropertiesMapper {
static ProtoInputStream sendAconfigdRequests(ProtoOutputStream requests) {
// connect to aconfigd socket
LocalSocket client = new LocalSocket();
- String socketName = enableSystemAconfigdRust()
- ? "aconfigd_system" : "aconfigd";
- try{
+ String socketName = "aconfigd_system";
+ try {
client.connect(new LocalSocketAddress(
socketName, LocalSocketAddress.Namespace.RESERVED));
Slog.d(TAG, "connected to aconfigd socket");
diff --git a/services/core/java/com/android/server/biometrics/biometrics.aconfig b/services/core/java/com/android/server/biometrics/biometrics.aconfig
index d3da8dd2cfda..95ba69580bba 100644
--- a/services/core/java/com/android/server/biometrics/biometrics.aconfig
+++ b/services/core/java/com/android/server/biometrics/biometrics.aconfig
@@ -34,3 +34,10 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "frr_dialog_improvement"
+ namespace: "biometrics_framework"
+ description: "This flag controls FRR dialog improvement"
+ bug: "380800403"
+}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecAtomWriter.java b/services/core/java/com/android/server/hdmi/HdmiCecAtomWriter.java
index 53c02176f11d..2e66fbc16496 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecAtomWriter.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecAtomWriter.java
@@ -16,6 +16,8 @@
package com.android.server.hdmi;
+import static android.media.tv.flags.Flags.hdmiControlCollectPhysicalAddress;
+
import static com.android.server.hdmi.Constants.HDMI_EARC_STATUS_ARC_PENDING;
import static com.android.server.hdmi.Constants.HDMI_EARC_STATUS_EARC_CONNECTED;
import static com.android.server.hdmi.Constants.HDMI_EARC_STATUS_EARC_PENDING;
@@ -35,6 +37,8 @@ public class HdmiCecAtomWriter {
@VisibleForTesting
protected static final int FEATURE_ABORT_OPCODE_UNKNOWN = 0x100;
private static final int ERROR_CODE_UNKNOWN = -1;
+ @VisibleForTesting
+ protected static final int PHYSICAL_ADDRESS_INVALID = 0xFFFF;
/**
* Writes a HdmiCecMessageReported atom representing an HDMI CEC message.
@@ -95,6 +99,11 @@ public class HdmiCecAtomWriter {
return createUserControlPressedSpecialArgs(message);
case Constants.MESSAGE_FEATURE_ABORT:
return createFeatureAbortSpecialArgs(message);
+ case Constants.MESSAGE_REPORT_PHYSICAL_ADDRESS:
+ if (hdmiControlCollectPhysicalAddress()) {
+ return createReportPhysicalAddressSpecialArgs(message);
+ }
+ return new MessageReportedSpecialArgs();
default:
return new MessageReportedSpecialArgs();
}
@@ -140,6 +149,23 @@ public class HdmiCecAtomWriter {
}
/**
+ * Constructs the special arguments for a <Report Physical Address> message.
+ *
+ * @param message The HDMI CEC message to log
+ */
+ private MessageReportedSpecialArgs createReportPhysicalAddressSpecialArgs(
+ HdmiCecMessage message) {
+ MessageReportedSpecialArgs specialArgs = new MessageReportedSpecialArgs();
+
+ if (message.getParams().length > 1) {
+ int physicalAddress = (message.getParams()[0] << 8) | message.getParams()[1];
+ specialArgs.mPhysicalAddress = physicalAddress;
+ }
+
+ return specialArgs;
+ }
+
+ /**
* Writes a HdmiCecMessageReported atom.
*
* @param genericArgs Generic arguments; shared by all HdmiCecMessageReported atoms
@@ -156,7 +182,8 @@ public class HdmiCecAtomWriter {
genericArgs.mSendMessageResult,
specialArgs.mUserControlPressedCommand,
specialArgs.mFeatureAbortOpcode,
- specialArgs.mFeatureAbortReason);
+ specialArgs.mFeatureAbortReason,
+ specialArgs.mPhysicalAddress);
}
/**
@@ -166,7 +193,7 @@ public class HdmiCecAtomWriter {
protected void writeHdmiCecMessageReportedAtom(int uid, int direction,
int initiatorLogicalAddress, int destinationLogicalAddress, int opcode,
int sendMessageResult, int userControlPressedCommand, int featureAbortOpcode,
- int featureAbortReason) {
+ int featureAbortReason, int physicalAddress) {
FrameworkStatsLog.write(
FrameworkStatsLog.HDMI_CEC_MESSAGE_REPORTED,
uid,
@@ -177,7 +204,8 @@ public class HdmiCecAtomWriter {
sendMessageResult,
userControlPressedCommand,
featureAbortOpcode,
- featureAbortReason);
+ featureAbortReason,
+ physicalAddress);
}
/**
@@ -284,5 +312,6 @@ public class HdmiCecAtomWriter {
int mUserControlPressedCommand = HdmiStatsEnums.USER_CONTROL_PRESSED_COMMAND_UNKNOWN;
int mFeatureAbortOpcode = FEATURE_ABORT_OPCODE_UNKNOWN;
int mFeatureAbortReason = HdmiStatsEnums.FEATURE_ABORT_REASON_UNKNOWN;
+ int mPhysicalAddress = PHYSICAL_ADDRESS_INVALID;
}
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 6e98bff8dda5..f049ef316cb1 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -725,6 +725,13 @@ public class HdmiControlService extends SystemService {
}
mPowerStatusController.setPowerStatus(getInitialPowerStatus());
setProhibitMode(false);
+ if (isTvDevice() && getWasCecDisabledOnStandbyByLowEnergyMode()) {
+ Slog.w(TAG, "Re-enable CEC on boot-up since it was disabled due to low energy "
+ + " mode.");
+ mHdmiCecConfig.setIntValue(HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
+ HDMI_CEC_CONTROL_ENABLED);
+ setWasCecDisabledOnStandbyByLowEnergyMode(false);
+ }
mHdmiControlEnabled = mHdmiCecConfig.getIntValue(
HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED);
@@ -771,14 +778,6 @@ public class HdmiControlService extends SystemService {
Slog.i(TAG, "Device does not support eARC.");
}
mHdmiCecNetwork = new HdmiCecNetwork(this, mCecController, mMhlController);
- if (isTvDevice() && getWasCecDisabledOnStandbyByLowEnergyMode()) {
- Slog.w(TAG, "Re-enable CEC on boot-up since it was disabled due to low energy "
- + " mode.");
- getHdmiCecConfig().setIntValue(HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
- HDMI_CEC_CONTROL_ENABLED);
- setWasCecDisabledOnStandbyByLowEnergyMode(false);
- setCecEnabled(HDMI_CEC_CONTROL_ENABLED);
- }
if (isCecControlEnabled()) {
initializeCec(INITIATED_BY_BOOT_UP);
} else {
diff --git a/services/core/java/com/android/server/incident/PendingReports.java b/services/core/java/com/android/server/incident/PendingReports.java
index 35b3673fdf77..9a6c87e525e0 100644
--- a/services/core/java/com/android/server/incident/PendingReports.java
+++ b/services/core/java/com/android/server/incident/PendingReports.java
@@ -324,16 +324,12 @@ class PendingReports {
// Allow system apps to skip the consent dialog and use their in-built consent mechanism
// instead.
- boolean captureConsentlessBugreportDelegatedConsentGranted = false;
- if ((flags & IncidentManager.FLAG_ALLOW_CONSENTLESS_BUGREPORT) != 0) {
- captureConsentlessBugreportDelegatedConsentGranted =
- mPermissionManager.checkPermissionForDataDelivery(
- Manifest.permission
- .CAPTURE_CONSENTLESS_BUGREPORT_DELEGATED_CONSENT,
- attributionSource,
- /* message= */ null)
- == PERMISSION_GRANTED;
- }
+ boolean captureConsentlessBugreportDelegatedConsentGranted =
+ mPermissionManager.checkPermissionForDataDelivery(
+ Manifest.permission.CAPTURE_CONSENTLESS_BUGREPORT_DELEGATED_CONSENT,
+ attributionSource,
+ /* message= */ null)
+ == PERMISSION_GRANTED;
if (captureConsentlessBugreportOnUserdebugBuildGranted
|| captureConsentlessBugreportDelegatedConsentGranted) {
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java b/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java
index da31bf29a8e8..ccfa61b400b6 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java
@@ -492,14 +492,21 @@ import java.util.concurrent.atomic.AtomicInteger;
/* package */
void onTransactionResponse(int transactionId, boolean success) {
TransactionAcceptConditions conditions =
- transaction -> transaction.getTransactionId() == transactionId;
+ transaction -> {
+ if (transaction.getTransactionId() != transactionId) {
+ Log.w(
+ TAG,
+ "Unexpected transaction: expected "
+ + transactionId
+ + ", received "
+ + transaction.getTransactionId());
+ return false;
+ }
+ return true;
+ };
ContextHubServiceTransaction transaction = getTransactionAndHandleNext(conditions);
if (transaction == null) {
- Log.w(TAG, "Received unexpected transaction response (expected ID = "
- + transactionId
- + ", received ID = "
- + transaction.getTransactionId()
- + ")");
+ Log.w(TAG, "Received unexpected transaction response");
return;
}
@@ -581,7 +588,7 @@ import java.util.concurrent.atomic.AtomicInteger;
transaction.getTransactionType() == ContextHubTransaction.TYPE_QUERY_NANOAPPS;
ContextHubServiceTransaction transaction = getTransactionAndHandleNext(conditions);
if (transaction == null) {
- Log.w(TAG, "Received unexpected query response (expected " + transaction + ")");
+ Log.w(TAG, "Received unexpected query response");
return;
}
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index e886f3b9f54e..2d2d2584edfd 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -221,6 +221,11 @@ class MediaRouter2ServiceImpl {
}
}
+ @NonNull
+ private SystemMediaRoute2Provider getSystemProviderForUser(@NonNull UserHandler userHandler) {
+ return userHandler.mSystemProvider;
+ }
+
// Start of methods that implement MediaRouter2 operations.
@NonNull
@@ -246,7 +251,7 @@ class MediaRouter2ServiceImpl {
UserRecord userRecord = getOrCreateUserRecordLocked(userId);
if (hasSystemRoutingPermissions) {
MediaRoute2ProviderInfo providerInfo =
- userRecord.mHandler.mSystemProvider.getProviderInfo();
+ getSystemProviderForUser(userRecord.mHandler).getProviderInfo();
if (providerInfo != null) {
systemRoutes = providerInfo.getRoutes();
} else {
@@ -258,7 +263,8 @@ class MediaRouter2ServiceImpl {
}
} else {
systemRoutes = new ArrayList<>();
- systemRoutes.add(userRecord.mHandler.mSystemProvider.getDefaultRoute());
+ systemRoutes.add(
+ getSystemProviderForUser(userRecord.mHandler).getDefaultRoute());
}
}
return new ArrayList<>(systemRoutes);
@@ -850,10 +856,11 @@ class MediaRouter2ServiceImpl {
if (setDeviceRouteSelected) {
// Return a fake system session that shows the device route as selected and
// available bluetooth routes as transferable.
- return userRecord.mHandler.mSystemProvider
+ return getSystemProviderForUser(userRecord.mHandler)
.generateDeviceRouteSelectedSessionInfo(targetPackageName);
} else {
- sessionInfos = userRecord.mHandler.mSystemProvider.getSessionInfos();
+ sessionInfos = getSystemProviderForUser(userRecord.mHandler)
+ .getSessionInfos();
if (!sessionInfos.isEmpty()) {
// Return a copy of the current system session with no modification,
// except setting the client package name.
@@ -866,7 +873,8 @@ class MediaRouter2ServiceImpl {
}
} else {
return new RoutingSessionInfo.Builder(
- userRecord.mHandler.mSystemProvider.getDefaultSessionInfo())
+ getSystemProviderForUser(userRecord.mHandler)
+ .getDefaultSessionInfo())
.setClientPackageName(targetPackageName)
.build();
}
@@ -1374,7 +1382,7 @@ class MediaRouter2ServiceImpl {
}
manager.mLastSessionCreationRequest = null;
} else {
- String defaultRouteId = userHandler.mSystemProvider.getDefaultRoute().getId();
+ String defaultRouteId = getSystemProviderForUser(userHandler).getDefaultRoute().getId();
if (route.isSystemRoute()
&& !routerRecord.hasSystemRoutingPermission()
&& !TextUtils.equals(route.getId(), defaultRouteId)) {
@@ -1462,7 +1470,7 @@ class MediaRouter2ServiceImpl {
routerRecord.mPackageName, routerRecord.mRouterId, route.getId()));
UserHandler userHandler = routerRecord.mUserRecord.mHandler;
- String defaultRouteId = userHandler.mSystemProvider.getDefaultRoute().getId();
+ String defaultRouteId = getSystemProviderForUser(userHandler).getDefaultRoute().getId();
if (route.isSystemRoute()
&& !routerRecord.hasSystemRoutingPermission()
&& !TextUtils.equals(route.getId(), defaultRouteId)) {
@@ -2125,11 +2133,12 @@ class MediaRouter2ServiceImpl {
notifyRoutesUpdated(routesToReport.values().stream().toList());
List<RoutingSessionInfo> sessionInfos =
- mUserRecord.mHandler.mSystemProvider.getSessionInfos();
+ getSystemProviderForUser(mUserRecord.mHandler).getSessionInfos();
RoutingSessionInfo systemSessionToReport =
newSystemRoutingPermissionValue && !sessionInfos.isEmpty()
? sessionInfos.get(0)
- : mUserRecord.mHandler.mSystemProvider.getDefaultSessionInfo();
+ : getSystemProviderForUser(mUserRecord.mHandler)
+ .getDefaultSessionInfo();
notifySessionInfoChanged(systemSessionToReport);
}
}
@@ -2279,7 +2288,7 @@ class MediaRouter2ServiceImpl {
if (route.isSystemRoute() && !hasSystemRoutingPermission()) {
// The router lacks permission to modify system routing, so we hide system
// route info from them.
- route = mUserRecord.mHandler.mSystemProvider.getDefaultRoute();
+ route = getSystemProviderForUser(mUserRecord.mHandler).getDefaultRoute();
}
mRouter.requestCreateSessionByManager(uniqueRequestId, oldSession, route);
} catch (RemoteException ex) {
@@ -2535,6 +2544,10 @@ class MediaRouter2ServiceImpl {
private boolean mRunning;
+ private SystemMediaRoute2Provider getSystemProvider() {
+ return mSystemProvider;
+ }
+
// TODO: (In Android S+) Pull out SystemMediaRoute2Provider out of UserHandler.
UserHandler(
@NonNull MediaRouter2ServiceImpl service,
@@ -2549,19 +2562,19 @@ class MediaRouter2ServiceImpl {
service.mContext, UserHandle.of(userRecord.mUserId), looper)
: new SystemMediaRoute2Provider(
service.mContext, UserHandle.of(userRecord.mUserId), looper);
- mRouteProviders.add(mSystemProvider);
+ mRouteProviders.add(getSystemProvider());
mWatcher = new MediaRoute2ProviderWatcher(service.mContext, this,
this, mUserRecord.mUserId);
}
void init() {
- mSystemProvider.setCallback(this);
+ getSystemProvider().setCallback(this);
}
private void start() {
if (!mRunning) {
mRunning = true;
- mSystemProvider.start();
+ getSystemProvider().start();
mWatcher.start();
}
}
@@ -2570,7 +2583,7 @@ class MediaRouter2ServiceImpl {
if (mRunning) {
mRunning = false;
mWatcher.stop(); // also stops all providers
- mSystemProvider.stop();
+ getSystemProvider().stop();
}
}
@@ -2662,7 +2675,7 @@ class MediaRouter2ServiceImpl {
String indent = prefix + " ";
pw.println(indent + "mRunning=" + mRunning);
- mSystemProvider.dump(pw, prefix);
+ getSystemProvider().dump(pw, prefix);
mWatcher.dump(pw, prefix);
}
@@ -2755,7 +2768,7 @@ class MediaRouter2ServiceImpl {
hasAddedOrModifiedRoutes,
hasRemovedRoutes,
provider.mIsSystemRouteProvider,
- mSystemProvider.getDefaultRoute());
+ getSystemProvider().getDefaultRoute());
}
private static String getPackageNameFromNullableRecord(
@@ -2969,7 +2982,8 @@ class MediaRouter2ServiceImpl {
}
// Bypass checking router if it's the system session (routerRecord should be null)
- if (TextUtils.equals(getProviderId(uniqueSessionId), mSystemProvider.getUniqueId())) {
+ if (TextUtils.equals(
+ getProviderId(uniqueSessionId), getSystemProvider().getUniqueId())) {
return true;
}
@@ -3100,7 +3114,7 @@ class MediaRouter2ServiceImpl {
&& !matchingRequest.mRouterRecord.hasSystemRoutingPermission()) {
// The router lacks permission to modify system routing, so we hide system routing
// session info from them.
- sessionInfo = mSystemProvider.getDefaultSessionInfo();
+ sessionInfo = getSystemProvider().getDefaultSessionInfo();
}
matchingRequest.mRouterRecord.notifySessionCreated(
toOriginalRequestId(uniqueRequestId), sessionInfo);
@@ -3114,13 +3128,13 @@ class MediaRouter2ServiceImpl {
}
// For system provider, notify all routers.
- if (provider == mSystemProvider) {
+ if (provider == getSystemProvider()) {
if (mServiceRef.get() == null) {
return;
}
notifySessionInfoChangedToRouters(getRouterRecords(true), sessionInfo);
notifySessionInfoChangedToRouters(
- getRouterRecords(false), mSystemProvider.getDefaultSessionInfo());
+ getRouterRecords(false), getSystemProvider().getDefaultSessionInfo());
return;
}
@@ -3256,7 +3270,8 @@ class MediaRouter2ServiceImpl {
MediaRoute2ProviderInfo systemProviderInfo = null;
for (MediaRoute2ProviderInfo providerInfo : mLastProviderInfos) {
// TODO: Create MediaRoute2ProviderInfo#isSystemProvider()
- if (TextUtils.equals(providerInfo.getUniqueId(), mSystemProvider.getUniqueId())) {
+ if (TextUtils.equals(
+ providerInfo.getUniqueId(), getSystemProvider().getUniqueId())) {
// Adding routes from system provider will be handled below, so skip it here.
systemProviderInfo = providerInfo;
continue;
@@ -3272,10 +3287,10 @@ class MediaRouter2ServiceImpl {
// This shouldn't happen.
Slog.wtf(TAG, "System route provider not found.");
}
- currentSystemSessionInfo = mSystemProvider.getSessionInfos().get(0);
+ currentSystemSessionInfo = getSystemProvider().getSessionInfos().get(0);
} else {
- currentRoutes.add(mSystemProvider.getDefaultRoute());
- currentSystemSessionInfo = mSystemProvider.getDefaultSessionInfo();
+ currentRoutes.add(getSystemProvider().getDefaultRoute());
+ currentSystemSessionInfo = getSystemProvider().getDefaultSessionInfo();
}
if (!currentRoutes.isEmpty()) {
diff --git a/services/core/java/com/android/server/media/quality/MediaQualityService.java b/services/core/java/com/android/server/media/quality/MediaQualityService.java
index c7e00d3cbb24..65d0ab337400 100644
--- a/services/core/java/com/android/server/media/quality/MediaQualityService.java
+++ b/services/core/java/com/android/server/media/quality/MediaQualityService.java
@@ -25,7 +25,7 @@ import android.media.quality.IAmbientBacklightCallback;
import android.media.quality.IMediaQualityManager;
import android.media.quality.IPictureProfileCallback;
import android.media.quality.ISoundProfileCallback;
-import android.media.quality.MediaQualityContract;
+import android.media.quality.MediaQualityContract.BaseParameters;
import android.media.quality.ParamCapability;
import android.media.quality.PictureProfile;
import android.media.quality.PictureProfileHandle;
@@ -42,6 +42,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
+import java.util.stream.Collectors;
/**
* This service manage picture profile and sound profile for TV setting. Also communicates with the
@@ -71,14 +72,14 @@ public class MediaQualityService extends SystemService {
private final class BinderService extends IMediaQualityManager.Stub {
@Override
- public PictureProfile createPictureProfile(PictureProfile pp) {
+ public PictureProfile createPictureProfile(PictureProfile pp, int userId) {
SQLiteDatabase db = mMediaQualityDbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
- values.put(MediaQualityContract.BaseParameters.PARAMETER_TYPE, pp.getProfileType());
- values.put(MediaQualityContract.BaseParameters.PARAMETER_NAME, pp.getName());
- values.put(MediaQualityContract.BaseParameters.PARAMETER_PACKAGE, pp.getPackageName());
- values.put(MediaQualityContract.BaseParameters.PARAMETER_INPUT_ID, pp.getInputId());
+ values.put(BaseParameters.PARAMETER_TYPE, pp.getProfileType());
+ values.put(BaseParameters.PARAMETER_NAME, pp.getName());
+ values.put(BaseParameters.PARAMETER_PACKAGE, pp.getPackageName());
+ values.put(BaseParameters.PARAMETER_INPUT_ID, pp.getInputId());
values.put(mMediaQualityDbHelper.SETTINGS, bundleToJson(pp.getParameters()));
// id is auto-generated by SQLite upon successful insertion of row
@@ -87,20 +88,21 @@ public class MediaQualityService extends SystemService {
}
@Override
- public void updatePictureProfile(String id, PictureProfile pp) {
+ public void updatePictureProfile(String id, PictureProfile pp, int userId) {
// TODO: implement
}
+
@Override
- public void removePictureProfile(String id) {
+ public void removePictureProfile(String id, int userId) {
// TODO: implement
}
@Override
- public PictureProfile getPictureProfile(int type, String name) {
+ public PictureProfile getPictureProfile(int type, String name, int userId) {
SQLiteDatabase db = mMediaQualityDbHelper.getReadableDatabase();
- String selection = MediaQualityContract.BaseParameters.PARAMETER_TYPE + " = ? AND "
- + MediaQualityContract.BaseParameters.PARAMETER_NAME + " = ?";
+ String selection = BaseParameters.PARAMETER_TYPE + " = ? AND "
+ + BaseParameters.PARAMETER_NAME + " = ?";
String[] selectionArguments = {Integer.toString(type), name};
try (
@@ -176,26 +178,26 @@ public class MediaQualityService extends SystemService {
private String[] getAllPictureProfileColumns() {
return new String[]{
- MediaQualityContract.BaseParameters.PARAMETER_ID,
- MediaQualityContract.BaseParameters.PARAMETER_TYPE,
- MediaQualityContract.BaseParameters.PARAMETER_NAME,
- MediaQualityContract.BaseParameters.PARAMETER_INPUT_ID,
- MediaQualityContract.BaseParameters.PARAMETER_PACKAGE,
+ BaseParameters.PARAMETER_ID,
+ BaseParameters.PARAMETER_TYPE,
+ BaseParameters.PARAMETER_NAME,
+ BaseParameters.PARAMETER_INPUT_ID,
+ BaseParameters.PARAMETER_PACKAGE,
mMediaQualityDbHelper.SETTINGS
};
}
private PictureProfile getPictureProfileFromCursor(Cursor cursor) {
String returnId = cursor.getString(cursor.getColumnIndexOrThrow(
- MediaQualityContract.BaseParameters.PARAMETER_ID));
+ BaseParameters.PARAMETER_ID));
int type = cursor.getInt(cursor.getColumnIndexOrThrow(
- MediaQualityContract.BaseParameters.PARAMETER_TYPE));
+ BaseParameters.PARAMETER_TYPE));
String name = cursor.getString(cursor.getColumnIndexOrThrow(
- MediaQualityContract.BaseParameters.PARAMETER_NAME));
+ BaseParameters.PARAMETER_NAME));
String inputId = cursor.getString(cursor.getColumnIndexOrThrow(
- MediaQualityContract.BaseParameters.PARAMETER_INPUT_ID));
+ BaseParameters.PARAMETER_INPUT_ID));
String packageName = cursor.getString(cursor.getColumnIndexOrThrow(
- MediaQualityContract.BaseParameters.PARAMETER_PACKAGE));
+ BaseParameters.PARAMETER_PACKAGE));
String settings = cursor.getString(
cursor.getColumnIndexOrThrow(mMediaQualityDbHelper.SETTINGS));
return new PictureProfile(returnId, type, name, inputId,
@@ -203,28 +205,26 @@ public class MediaQualityService extends SystemService {
}
@Override
- public List<PictureProfile> getPictureProfilesByPackage(String packageName) {
- String selection = MediaQualityContract.BaseParameters.PARAMETER_PACKAGE + " = ?";
+ public List<PictureProfile> getPictureProfilesByPackage(String packageName, int userId) {
+ String selection = BaseParameters.PARAMETER_PACKAGE + " = ?";
String[] selectionArguments = {packageName};
return getPictureProfilesBasedOnConditions(getAllPictureProfileColumns(), selection,
selectionArguments);
}
@Override
- public List<PictureProfile> getAvailablePictureProfiles() {
+ public List<PictureProfile> getAvailablePictureProfiles(int userId) {
return new ArrayList<>();
}
@Override
- public List<String> getPictureProfilePackageNames() {
- String [] column = {MediaQualityContract.BaseParameters.PARAMETER_NAME};
+ public List<String> getPictureProfilePackageNames(int userId) {
+ String [] column = {BaseParameters.PARAMETER_NAME};
List<PictureProfile> pictureProfiles = getPictureProfilesBasedOnConditions(column,
null, null);
- List<String> packageNames = new ArrayList<>();
- for (PictureProfile pictureProfile: pictureProfiles) {
- packageNames.add(pictureProfile.getName());
- }
- return packageNames;
+ return pictureProfiles.stream()
+ .map(PictureProfile::getName)
+ .collect(Collectors.toList());
}
private List<PictureProfile> getPictureProfilesBasedOnConditions(String[] columns,
@@ -250,40 +250,140 @@ public class MediaQualityService extends SystemService {
}
@Override
- public PictureProfileHandle getPictureProfileHandle(String id) {
+ public PictureProfileHandle getPictureProfileHandle(String id, int userId) {
return null;
}
@Override
- public SoundProfile createSoundProfile(SoundProfile pp) {
- // TODO: implement
- return pp;
+ public SoundProfile createSoundProfile(SoundProfile sp, int userId) {
+ SQLiteDatabase db = mMediaQualityDbHelper.getWritableDatabase();
+
+ ContentValues values = new ContentValues();
+ values.put(BaseParameters.PARAMETER_NAME, sp.getName());
+ values.put(BaseParameters.PARAMETER_PACKAGE, sp.getPackageName());
+ values.put(BaseParameters.PARAMETER_INPUT_ID, sp.getInputId());
+ values.put(mMediaQualityDbHelper.SETTINGS, bundleToJson(sp.getParameters()));
+
+ long id = db.insert(mMediaQualityDbHelper.SOUND_QUALITY_TABLE_NAME, null, values);
+ return new SoundProfile.Builder(sp).setProfileId(Long.toString(id)).build();
}
+
@Override
- public void updateSoundProfile(String id, SoundProfile pp) {
+ public void updateSoundProfile(String id, SoundProfile pp, int userId) {
// TODO: implement
}
+
@Override
- public void removeSoundProfile(String id) {
- // TODO: implement
+ public void removeSoundProfile(String id, int userId) {
+ SQLiteDatabase db = mMediaQualityDbHelper.getWritableDatabase();
+ String selection = BaseParameters.PARAMETER_ID + " = ?";
+ String[] selectionArgs = {id};
+ db.delete(mMediaQualityDbHelper.SOUND_QUALITY_TABLE_NAME, selection, selectionArgs);
}
+
@Override
- public SoundProfile getSoundProfile(int type, String id) {
- return null;
+ public SoundProfile getSoundProfile(int type, String id, int userId) {
+ SQLiteDatabase db = mMediaQualityDbHelper.getReadableDatabase();
+
+ String selection = BaseParameters.PARAMETER_ID + " = ?";
+ String[] selectionArguments = {id};
+
+ try (
+ Cursor cursor = db.query(
+ mMediaQualityDbHelper.SOUND_QUALITY_TABLE_NAME,
+ getAllSoundProfileColumns(),
+ selection,
+ selectionArguments,
+ /*groupBy=*/ null,
+ /*having=*/ null,
+ /*orderBy=*/ null)
+ ) {
+ int count = cursor.getCount();
+ if (count == 0) {
+ return null;
+ }
+ if (count > 1) {
+ Log.wtf(TAG, String.format(Locale.US, "%d entries found for id=%s"
+ + " in %s. Should only ever be 0 or 1.", count, id,
+ mMediaQualityDbHelper.SOUND_QUALITY_TABLE_NAME));
+ return null;
+ }
+ cursor.moveToFirst();
+ return getSoundProfileFromCursor(cursor);
+ }
}
+
@Override
- public List<SoundProfile> getSoundProfilesByPackage(String packageName) {
- return new ArrayList<>();
+ public List<SoundProfile> getSoundProfilesByPackage(String packageName, int userId) {
+ String selection = BaseParameters.PARAMETER_PACKAGE + " = ?";
+ String[] selectionArguments = {packageName};
+ return getSoundProfilesBasedOnConditions(getAllSoundProfileColumns(), selection,
+ selectionArguments);
}
+
@Override
- public List<SoundProfile> getAvailableSoundProfiles() {
+ public List<SoundProfile> getAvailableSoundProfiles(int userId) {
return new ArrayList<>();
}
+
@Override
- public List<String> getSoundProfilePackageNames() {
- return new ArrayList<>();
+ public List<String> getSoundProfilePackageNames(int userId) {
+ String [] column = {BaseParameters.PARAMETER_NAME};
+ List<SoundProfile> soundProfiles = getSoundProfilesBasedOnConditions(column,
+ null, null);
+ return soundProfiles.stream()
+ .map(SoundProfile::getName)
+ .collect(Collectors.toList());
+ }
+
+ private String[] getAllSoundProfileColumns() {
+ return new String[]{
+ BaseParameters.PARAMETER_ID,
+ BaseParameters.PARAMETER_NAME,
+ BaseParameters.PARAMETER_INPUT_ID,
+ BaseParameters.PARAMETER_PACKAGE,
+ mMediaQualityDbHelper.SETTINGS
+ };
+ }
+
+ private SoundProfile getSoundProfileFromCursor(Cursor cursor) {
+ String returnId = cursor.getString(
+ cursor.getColumnIndexOrThrow(BaseParameters.PARAMETER_ID));
+ int type = cursor.getInt(
+ cursor.getColumnIndexOrThrow(BaseParameters.PARAMETER_TYPE));
+ String name = cursor.getString(
+ cursor.getColumnIndexOrThrow(BaseParameters.PARAMETER_NAME));
+ String inputId = cursor.getString(
+ cursor.getColumnIndexOrThrow(BaseParameters.PARAMETER_INPUT_ID));
+ String packageName = cursor.getString(
+ cursor.getColumnIndexOrThrow(BaseParameters.PARAMETER_PACKAGE));
+ String settings = cursor.getString(
+ cursor.getColumnIndexOrThrow(mMediaQualityDbHelper.SETTINGS));
+ return new SoundProfile(returnId, type, name, inputId, packageName,
+ jsonToBundle(settings));
}
+ private List<SoundProfile> getSoundProfilesBasedOnConditions(String[] columns,
+ String selection, String[] selectionArguments) {
+ SQLiteDatabase db = mMediaQualityDbHelper.getReadableDatabase();
+
+ try (
+ Cursor cursor = db.query(
+ mMediaQualityDbHelper.SOUND_QUALITY_TABLE_NAME,
+ columns,
+ selection,
+ selectionArguments,
+ /*groupBy=*/ null,
+ /*having=*/ null,
+ /*orderBy=*/ null)
+ ) {
+ List<SoundProfile> soundProfiles = new ArrayList<>();
+ while (cursor.moveToNext()) {
+ soundProfiles.add(getSoundProfileFromCursor(cursor));
+ }
+ return soundProfiles;
+ }
+ }
@Override
public void registerPictureProfileCallback(final IPictureProfileCallback callback) {
@@ -297,70 +397,70 @@ public class MediaQualityService extends SystemService {
}
@Override
- public void setAmbientBacklightSettings(AmbientBacklightSettings settings) {
+ public void setAmbientBacklightSettings(AmbientBacklightSettings settings, int userId) {
}
@Override
- public void setAmbientBacklightEnabled(boolean enabled) {
+ public void setAmbientBacklightEnabled(boolean enabled, int userId) {
}
@Override
- public List<ParamCapability> getParamCapabilities(List<String> names) {
+ public List<ParamCapability> getParamCapabilities(List<String> names, int userId) {
return new ArrayList<>();
}
@Override
- public List<String> getPictureProfileAllowList() {
+ public List<String> getPictureProfileAllowList(int userId) {
return new ArrayList<>();
}
@Override
- public void setPictureProfileAllowList(List<String> packages) {
+ public void setPictureProfileAllowList(List<String> packages, int userId) {
}
@Override
- public List<String> getSoundProfileAllowList() {
+ public List<String> getSoundProfileAllowList(int userId) {
return new ArrayList<>();
}
@Override
- public void setSoundProfileAllowList(List<String> packages) {
+ public void setSoundProfileAllowList(List<String> packages, int userId) {
}
@Override
- public boolean isSupported() {
+ public boolean isSupported(int userId) {
return false;
}
@Override
- public void setAutoPictureQualityEnabled(boolean enabled) {
+ public void setAutoPictureQualityEnabled(boolean enabled, int userId) {
}
@Override
- public boolean isAutoPictureQualityEnabled() {
+ public boolean isAutoPictureQualityEnabled(int userId) {
return false;
}
@Override
- public void setSuperResolutionEnabled(boolean enabled) {
+ public void setSuperResolutionEnabled(boolean enabled, int userId) {
}
@Override
- public boolean isSuperResolutionEnabled() {
+ public boolean isSuperResolutionEnabled(int userId) {
return false;
}
@Override
- public void setAutoSoundQualityEnabled(boolean enabled) {
+ public void setAutoSoundQualityEnabled(boolean enabled, int userId) {
}
@Override
- public boolean isAutoSoundQualityEnabled() {
+ public boolean isAutoSoundQualityEnabled(int userId) {
return false;
}
@Override
- public boolean isAmbientBacklightEnabled() {
+ public boolean isAmbientBacklightEnabled(int userId) {
return false;
}
}
diff --git a/services/core/java/com/android/server/pm/BackgroundInstallControlCallbackHelper.java b/services/core/java/com/android/server/pm/BackgroundInstallControlCallbackHelper.java
index 27c4e9dca586..bc0fc2b0b7d9 100644
--- a/services/core/java/com/android/server/pm/BackgroundInstallControlCallbackHelper.java
+++ b/services/core/java/com/android/server/pm/BackgroundInstallControlCallbackHelper.java
@@ -33,9 +33,10 @@ import com.android.server.ServiceThread;
public class BackgroundInstallControlCallbackHelper {
- @VisibleForTesting static final String FLAGGED_PACKAGE_NAME_KEY = "packageName";
- @VisibleForTesting static final String FLAGGED_USER_ID_KEY = "userId";
- @VisibleForTesting static final String INSTALL_EVENT_TYPE_KEY = "installEventType";
+ public static final String FLAGGED_PACKAGE_NAME_KEY = "packageName";
+ public static final String FLAGGED_USER_ID_KEY = "userId";
+ public static final String INSTALL_EVENT_TYPE_KEY = "installEventType";
+
private static final String TAG = "BackgroundInstallControlCallbackHelper";
private final Handler mHandler;
diff --git a/services/core/java/com/android/server/pm/InstallDependencyHelper.java b/services/core/java/com/android/server/pm/InstallDependencyHelper.java
index 42b8dd71c6e2..13aab11595d2 100644
--- a/services/core/java/com/android/server/pm/InstallDependencyHelper.java
+++ b/services/core/java/com/android/server/pm/InstallDependencyHelper.java
@@ -97,7 +97,7 @@ public class InstallDependencyHelper {
if (missing.isEmpty()) {
if (DEBUG) {
- Slog.i(TAG, "No missing dependency for " + pkg);
+ Slog.d(TAG, "No missing dependency for " + pkg);
}
// No need for dependency resolution. Move to installation directly.
callback.onResult(null);
@@ -110,7 +110,7 @@ public class InstallDependencyHelper {
}
IDependencyInstallerCallback serviceCallback =
- new DependencyInstallerCallbackCallOnce(handler, callback);
+ new DependencyInstallerCallbackCallOnce(handler, callback, userId);
boolean scheduleSuccess;
synchronized (mRemoteServiceLock) {
scheduleSuccess = mRemoteService.run(service -> {
@@ -125,7 +125,7 @@ public class InstallDependencyHelper {
void notifySessionComplete(int sessionId, boolean success) {
if (DEBUG) {
- Slog.i(TAG, "Session complete for " + sessionId + " result: " + success);
+ Slog.d(TAG, "Session complete for " + sessionId + " result: " + success);
}
synchronized (mTrackers) {
List<DependencyInstallTracker> completedTrackers = new ArrayList<>();
@@ -292,79 +292,130 @@ public class InstallDependencyHelper {
private final Handler mHandler;
private final CallOnceProxy mCallback;
+ private final int mUserId;
@GuardedBy("this")
- private boolean mCalled = false;
+ private boolean mDependencyInstallerCallbackInvoked = false;
- DependencyInstallerCallbackCallOnce(Handler handler, CallOnceProxy callback) {
+ DependencyInstallerCallbackCallOnce(Handler handler, CallOnceProxy callback, int userId) {
mHandler = handler;
mCallback = callback;
+ mUserId = userId;
}
- // TODO(b/372862145): Consider turning the binder call to two-way so that we can
- // throw IllegalArgumentException
@Override
public void onAllDependenciesResolved(int[] sessionIds) throws RemoteException {
synchronized (this) {
- if (mCalled) {
- return;
+ if (mDependencyInstallerCallbackInvoked) {
+ throw new IllegalStateException(
+ "Callback is being or has been already processed");
}
- mCalled = true;
+ mDependencyInstallerCallbackInvoked = true;
}
- ArraySet<Integer> set = new ArraySet<>();
- for (int i = 0; i < sessionIds.length; i++) {
- if (DEBUG) {
- Slog.i(TAG, "onAllDependenciesResolved called with " + sessionIds[i]);
- }
- set.add(sessionIds[i]);
+
+ if (DEBUG) {
+ Slog.d(TAG, "onAllDependenciesResolved started");
}
- DependencyInstallTracker tracker = new DependencyInstallTracker(mCallback, set);
+ // Before creating any tracker, validate the arguments
+ ArraySet<Integer> validSessionIds = validateSessionIds(sessionIds);
+
+ if (validSessionIds.isEmpty()) {
+ mCallback.onResult(null);
+ return;
+ }
+
+ // Create a tracker now if there are any pending sessions remaining.
+ DependencyInstallTracker tracker = new DependencyInstallTracker(
+ mCallback, validSessionIds);
synchronized (mTrackers) {
mTrackers.add(tracker);
}
- // In case any of the session ids have already been installed, check if they
- // are valid.
- mHandler.post(() -> {
- if (DEBUG) {
- Slog.i(TAG, "onAllDependenciesResolved cleaning up invalid sessions");
+ // By the time the tracker was created, some of the sessions in validSessionIds
+ // could have finished. Avoid waiting for them indefinitely.
+ for (int sessionId : validSessionIds) {
+ SessionInfo sessionInfo = mPackageInstallerService.getSessionInfo(sessionId);
+
+ // Don't wait for sessions that finished already
+ if (sessionInfo == null) {
+ notifySessionComplete(sessionId, /*success=*/ true);
+ }
+ }
+ }
+
+ @Override
+ public void onFailureToResolveAllDependencies() throws RemoteException {
+ synchronized (this) {
+ if (mDependencyInstallerCallbackInvoked) {
+ throw new IllegalStateException(
+ "Callback is being or has been already processed");
}
+ mDependencyInstallerCallbackInvoked = true;
+ }
+ onError(mCallback, "Failed to resolve all dependencies automatically");
+ }
- for (int i = 0; i < sessionIds.length; i++) {
- int sessionId = sessionIds[i];
- SessionInfo sessionInfo = mPackageInstallerService.getSessionInfo(sessionId);
+ private ArraySet<Integer> validateSessionIds(int[] sessionIds) {
+ // Before creating any tracker, validate the arguments
+ ArraySet<Integer> validSessionIds = new ArraySet<>();
- // Continue waiting if session exists and hasn't passed or failed yet.
- if (sessionInfo != null && !sessionInfo.isSessionApplied
- && !sessionInfo.isSessionFailed) {
- continue;
+ List<SessionInfo> historicalSessions = null;
+ for (int i = 0; i < sessionIds.length; i++) {
+ int sessionId = sessionIds[i];
+ SessionInfo sessionInfo = mPackageInstallerService.getSessionInfo(sessionId);
+
+ // Continue waiting if session exists and hasn't passed or failed yet.
+ if (sessionInfo != null) {
+ if (sessionInfo.isSessionFailed) {
+ throwValidationError("Session already finished: " + sessionId);
}
- if (DEBUG) {
- Slog.i(TAG, "onAllDependenciesResolved cleaning up finished"
- + " session: " + sessionId);
+ // Wait for session to finish install if it's not already successful.
+ if (!sessionInfo.isSessionApplied) {
+ if (DEBUG) {
+ Slog.d(TAG, "onAllDependenciesResolved pending session: " + sessionId);
+ }
+ validSessionIds.add(sessionId);
}
- // If session info is null, we assume it to be success.
- // TODO(b/372862145): Check historical sessions to be more precise.
- boolean success = sessionInfo == null || sessionInfo.isSessionApplied;
+ // An applied session found. No need to check historical session anymore.
+ continue;
+ }
+
+ if (DEBUG) {
+ Slog.d(TAG, "onAllDependenciesResolved cleaning up finished"
+ + " session: " + sessionId);
+ }
- notifySessionComplete(sessionId, /*success=*/success);
+ if (historicalSessions == null) {
+ historicalSessions = mPackageInstallerService.getHistoricalSessions(
+ mUserId).getList();
}
- });
+
+ sessionInfo = historicalSessions.stream().filter(
+ s -> s.sessionId == sessionId).findFirst().orElse(null);
+
+ if (sessionInfo == null) {
+ throwValidationError("Failed to find session: " + sessionId);
+ }
+
+ // Historical session must have been successful, otherwise throw IAE.
+ if (!sessionInfo.isSessionApplied) {
+ throwValidationError("Session already finished: " + sessionId);
+ }
+ }
+
+ return validSessionIds;
}
- @Override
- public void onFailureToResolveAllDependencies() throws RemoteException {
+ private void throwValidationError(String msg) {
+ // Allow client to invoke callback again.
synchronized (this) {
- if (mCalled) {
- return;
- }
- onError(mCallback, "Failed to resolve all dependencies automatically");
- mCalled = true;
+ mDependencyInstallerCallbackInvoked = false;
}
+ throw new IllegalArgumentException(msg);
}
}
@@ -377,6 +428,7 @@ public class InstallDependencyHelper {
// TODO(b/372862145): Determine and add support for rebooting while dependency is being resolved
private static class DependencyInstallTracker {
private final CallOnceProxy mCallback;
+ @GuardedBy("this")
private final ArraySet<Integer> mPendingSessionIds;
DependencyInstallTracker(CallOnceProxy callback, ArraySet<Integer> pendingSessionIds) {
@@ -399,7 +451,6 @@ public class InstallDependencyHelper {
if (!success) {
// If one of the dependency fails, the orig session would fail too.
onError(mCallback, "Failed to install all dependencies");
- // TODO(b/372862145): Abandon the rest of the pending sessions.
return false; // No point in tracking anymore
}
@@ -411,6 +462,5 @@ public class InstallDependencyHelper {
return true; // Keep on tracking
}
}
-
}
}
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index e5e274450655..8168c5493304 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -229,7 +229,6 @@ final class InstallPackageHelper {
private final SharedLibrariesImpl mSharedLibraries;
private final PackageManagerServiceInjector mInjector;
private final UpdateOwnershipHelper mUpdateOwnershipHelper;
- private final InstallDependencyHelper mInstallDependencyHelper;
private final Object mInternalLock = new Object();
@GuardedBy("mInternalLock")
@@ -240,8 +239,7 @@ final class InstallPackageHelper {
AppDataHelper appDataHelper,
RemovePackageHelper removePackageHelper,
DeletePackageHelper deletePackageHelper,
- BroadcastHelper broadcastHelper,
- InstallDependencyHelper installDependencyHelper) {
+ BroadcastHelper broadcastHelper) {
mPm = pm;
mInjector = pm.mInjector;
mAppDataHelper = appDataHelper;
@@ -255,7 +253,6 @@ final class InstallPackageHelper {
mPackageAbiHelper = pm.mInjector.getAbiHelper();
mSharedLibraries = pm.mInjector.getSharedLibrariesImpl();
mUpdateOwnershipHelper = pm.mInjector.getUpdateOwnershipHelper();
- mInstallDependencyHelper = installDependencyHelper;
}
/**
@@ -1367,10 +1364,6 @@ final class InstallPackageHelper {
}
}
}
-
- for (InstallRequest request : requests) {
- mInstallDependencyHelper.notifySessionComplete(request.getSessionId(), success);
- }
}
@GuardedBy("mPm.mInstallLock")
diff --git a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
index 0f245b6c2201..7229f070acf0 100644
--- a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
+++ b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
@@ -29,6 +29,7 @@ import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.pm.ApplicationInfo;
import android.content.pm.Flags;
import android.content.pm.PackageManager;
import android.os.Build;
@@ -638,7 +639,9 @@ final class PackageAbiHelperImpl implements PackageAbiHelper {
return NativeLibraryHelper.checkAlignmentForCompatMode(
handle, libraryRoot, nativeLibraryRootRequiresIsa, abiOverride);
} catch (IOException e) {
- throw new RuntimeException(e);
+ Slog.e(PackageManagerService.TAG, "Failed to check alignment of package : "
+ + pkg.getPackageName());
+ return ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_ERROR;
}
}
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 47b785040d44..ceb931400d48 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -2329,6 +2329,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
}
}
+ mInstallDependencyHelper.notifySessionComplete(session.sessionId, success);
+
final File appIconFile = buildAppIconFile(session.sessionId);
if (appIconFile.exists()) {
appIconFile.delete();
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 040b1943b23d..ab26f024a18a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2118,8 +2118,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
mDeletePackageHelper = new DeletePackageHelper(this, mRemovePackageHelper,
mBroadcastHelper);
mInstallPackageHelper = new InstallPackageHelper(this, mAppDataHelper, mRemovePackageHelper,
- mDeletePackageHelper, mBroadcastHelper,
- injector.getPackageInstallerService().getInstallDependencyHelper());
+ mDeletePackageHelper, mBroadcastHelper);
mInstantAppRegistry = new InstantAppRegistry(mContext, mPermissionManager,
mInjector.getUserManagerInternal(), mDeletePackageHelper);
diff --git a/services/core/java/com/android/server/pm/ScanPackageUtils.java b/services/core/java/com/android/server/pm/ScanPackageUtils.java
index 2665196bf3be..a317e1628f97 100644
--- a/services/core/java/com/android/server/pm/ScanPackageUtils.java
+++ b/services/core/java/com/android/server/pm/ScanPackageUtils.java
@@ -445,7 +445,12 @@ final class ScanPackageUtils {
pkgSetting.getLegacyNativeLibraryPath(),
parsedPackage.isNativeLibraryRootRequiresIsa(),
pkgSetting.getCpuAbiOverride());
- pkgSetting.setPageSizeAppCompatFlags(mode);
+ if (mode >= ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_UNDEFINED) {
+ pkgSetting.setPageSizeAppCompatFlags(mode);
+ } else {
+ Slog.e(TAG, "Error occurred while checking alignment of package : "
+ + parsedPackage.getPackageName());
+ }
}
}
}
diff --git a/services/core/java/com/android/server/power/hint/adpf_flags.aconfig b/services/core/java/com/android/server/power/hint/adpf_flags.aconfig
index 147d76bda477..97d34836c70c 100644
--- a/services/core/java/com/android/server/power/hint/adpf_flags.aconfig
+++ b/services/core/java/com/android/server/power/hint/adpf_flags.aconfig
@@ -5,3 +5,11 @@
package: "android.adpf"
container: "system"
+flag {
+ name: "adpf_viewrootimpl_action_down_boost"
+ is_exported: true
+ namespace: "game"
+ description: "Guards boosting on touch in ViewRootImpl."
+ is_fixed_read_only: true
+ bug: "360345939"
+}
diff --git a/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java b/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java
index 2cc08c327b71..a15360760e32 100644
--- a/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java
+++ b/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java
@@ -199,7 +199,7 @@ public class AdvancedProtectionService extends IAdvancedProtectionService.Stub
}
void sendCallbackAdded(boolean enabled, IAdvancedProtectionCallback callback) {
- Message.obtain(mHandler, MODE_CHANGED, /*enabled*/ enabled ? 1 : 0, /*unused*/ -1,
+ Message.obtain(mHandler, CALLBACK_ADDED, /*enabled*/ enabled ? 1 : 0, /*unused*/ -1,
/*callback*/ callback)
.sendToTarget();
}
diff --git a/services/core/java/com/android/server/security/advancedprotection/features/DisallowInstallUnknownSourcesAdvancedProtectionHook.java b/services/core/java/com/android/server/security/advancedprotection/features/DisallowInstallUnknownSourcesAdvancedProtectionHook.java
index 21752e524619..a2933d96e4a8 100644
--- a/services/core/java/com/android/server/security/advancedprotection/features/DisallowInstallUnknownSourcesAdvancedProtectionHook.java
+++ b/services/core/java/com/android/server/security/advancedprotection/features/DisallowInstallUnknownSourcesAdvancedProtectionHook.java
@@ -19,13 +19,24 @@ package com.android.server.security.advancedprotection.features;
import static android.security.advancedprotection.AdvancedProtectionManager.ADVANCED_PROTECTION_SYSTEM_ENTITY;
import static android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES;
+import android.Manifest;
import android.annotation.NonNull;
+import android.app.ActivityManagerInternal;
+import android.app.AppGlobals;
+import android.app.AppOpsManager;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.os.Process;
+import android.os.RemoteException;
import android.os.UserManager;
import android.security.advancedprotection.AdvancedProtectionFeature;
import android.util.Slog;
+import com.android.server.LocalServices;
+
/** @hide */
public final class DisallowInstallUnknownSourcesAdvancedProtectionHook
extends AdvancedProtectionHook {
@@ -33,13 +44,25 @@ public final class DisallowInstallUnknownSourcesAdvancedProtectionHook
private final AdvancedProtectionFeature mFeature = new AdvancedProtectionFeature(
FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES);
+
+ private final ActivityManagerInternal mActivityManagerInternal;
+ private final AppOpsManager mAppOpsManager;
private final DevicePolicyManager mDevicePolicyManager;
+ private final IPackageManager mIPackageManager;
+ private final PackageManager mPackageManager;
+ private final UserManager mUserManager;
public DisallowInstallUnknownSourcesAdvancedProtectionHook(@NonNull Context context,
boolean enabled) {
super(context, enabled);
+ mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
+ mAppOpsManager = context.getSystemService(AppOpsManager.class);
mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
- onAdvancedProtectionChanged(enabled);
+ mIPackageManager = AppGlobals.getPackageManager();
+ mUserManager = context.getSystemService(UserManager.class);
+ mPackageManager = context.getPackageManager();
+
+ setRestriction(enabled);
}
@NonNull
@@ -53,21 +76,48 @@ public final class DisallowInstallUnknownSourcesAdvancedProtectionHook
return true;
}
- @Override
- public void onAdvancedProtectionChanged(boolean enabled) {
+ private void setRestriction(boolean enabled) {
if (enabled) {
Slog.d(TAG, "Setting DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY restriction");
mDevicePolicyManager.addUserRestrictionGlobally(ADVANCED_PROTECTION_SYSTEM_ENTITY,
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY);
- return;
+ } else {
+ Slog.d(TAG, "Clearing DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY restriction");
+ mDevicePolicyManager.clearUserRestrictionGlobally(ADVANCED_PROTECTION_SYSTEM_ENTITY,
+ UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY);
}
- Slog.d(TAG, "Clearing DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY restriction");
- mDevicePolicyManager.clearUserRestrictionGlobally(ADVANCED_PROTECTION_SYSTEM_ENTITY,
- UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY);
+ }
- // TODO(b/369361373):
- // 1. After clearing the restriction, set AppOpsManager.OP_REQUEST_INSTALL_PACKAGES to
- // disabled.
- // 2. Update dialog strings.
+ @Override
+ public void onAdvancedProtectionChanged(boolean enabled) {
+ setRestriction(enabled);
+ if (enabled) return;
+
+ // Leave OP_REQUEST_INSTALL_PACKAGES disabled when APM is disabled.
+ Slog.d(TAG, "Setting all OP_REQUEST_INSTALL_PACKAGES to MODE_ERRORED");
+ for (UserInfo userInfo : mUserManager.getAliveUsers()) {
+ try {
+ final String[] packagesWithRequestInstallPermission = mIPackageManager
+ .getAppOpPermissionPackages(
+ Manifest.permission.REQUEST_INSTALL_PACKAGES, userInfo.id);
+ for (String packageName : packagesWithRequestInstallPermission) {
+ try {
+ int uid = mPackageManager.getPackageUidAsUser(packageName, userInfo.id);
+ boolean isCallerInstrumented = mActivityManagerInternal
+ .getInstrumentationSourceUid(uid) != Process.INVALID_UID;
+ if (!isCallerInstrumented) {
+ mAppOpsManager.setMode(AppOpsManager.OP_REQUEST_INSTALL_PACKAGES, uid,
+ packageName, AppOpsManager.MODE_ERRORED);
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.e(TAG, "Couldn't retrieve uid for a package: " + e);
+ }
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Couldn't retrieve packages with REQUEST_INSTALL_PACKAGES."
+ + " getAppOpPermissionPackages() threw the following exception: " + e);
+ }
+ }
+ // TODO(b/369361373): Update dialog strings.
}
}
diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java b/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java
index 38bc026c473a..e191ff20a518 100644
--- a/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java
@@ -119,14 +119,14 @@ public final class ClientProfile {
* If resource holder retains ownership of the resource in a challenge scenario then value is
* true.
*/
- private boolean mResourceHolderRetain;
+ private boolean mResourceOwnershipRetention;
private ClientProfile(Builder builder) {
this.mId = builder.mId;
this.mTvInputSessionId = builder.mTvInputSessionId;
this.mUseCase = builder.mUseCase;
this.mProcessId = builder.mProcessId;
- this.mResourceHolderRetain = builder.mResourceHolderRetain;
+ this.mResourceOwnershipRetention = builder.mResourceOwnershipRetention;
}
public int getId() {
@@ -149,8 +149,8 @@ public final class ClientProfile {
* Returns true when the resource holder retains ownership of the resource in a challenge
* scenario.
*/
- public boolean shouldResourceHolderRetain() {
- return mResourceHolderRetain;
+ public boolean resourceOwnershipRetentionEnabled() {
+ return mResourceOwnershipRetention;
}
/**
@@ -199,12 +199,12 @@ public final class ClientProfile {
* scenario, when both resource holder and resource challenger have same processId and same
* priority.
*
- * @param resourceHolderRetain Set to true to allow the resource holder to retain ownership, or
- * false (or resourceHolderRetain not set at all) to allow the resource challenger to
- * acquire the resource. If not explicitly set, resourceHolderRetain is set to false.
+ * @param enabled Set to {@code true} to allow the resource holder to retain ownership,
+ * or false to allow the resource challenger to acquire the resource.
+ * If not explicitly set, enabled is set to {@code false}.
*/
- public void setResourceHolderRetain(boolean resourceHolderRetain) {
- mResourceHolderRetain = resourceHolderRetain;
+ public void setResourceOwnershipRetention(boolean enabled) {
+ mResourceOwnershipRetention = enabled;
}
/**
@@ -389,7 +389,7 @@ public final class ClientProfile {
private String mTvInputSessionId;
private int mUseCase;
private int mProcessId;
- private boolean mResourceHolderRetain = false;
+ private boolean mResourceOwnershipRetention = false;
Builder(int id) {
this.mId = id;
@@ -428,12 +428,12 @@ public final class ClientProfile {
/**
* Builder for {@link ClientProfile}.
*
- * @param resourceHolderRetain the determining factor for resource ownership during
- * challenger scenario. The default behavior favors the resource challenger and grants
- * them ownership of the resource if resourceHolderRetain is not explicitly set to true.
+ * @param enabled the determining factor for resource ownership during challenger scenario.
+ * The default behavior favors the resource challenger and grants them ownership of
+ * the resource if resourceOwnershipRetention is not explicitly set to true.
*/
- public Builder resourceHolderRetain(boolean resourceHolderRetain) {
- this.mResourceHolderRetain = resourceHolderRetain;
+ public Builder resourceOwnershipRetention(boolean enabled) {
+ this.mResourceOwnershipRetention = enabled;
return this;
}
diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
index 5ae8c11f1d8f..bb192c0b4603 100644
--- a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
@@ -231,10 +231,10 @@ public class TunerResourceManagerService extends SystemService implements IBinde
}
@Override
- public void setResourceHolderRetain(int clientId, boolean resourceHolderRetain) {
- enforceTrmAccessPermission("setResourceHolderRetain");
+ public void setResourceOwnershipRetention(int clientId, boolean enabled) {
+ enforceTrmAccessPermission("setResourceOwnershipRetention");
synchronized (mLock) {
- getClientProfile(clientId).setResourceHolderRetain(resourceHolderRetain);
+ getClientProfile(clientId).setResourceOwnershipRetention(enabled);
}
}
@@ -1079,7 +1079,8 @@ public class TunerResourceManagerService extends SystemService implements IBinde
|| ((requestClient.getPriority() == currentLowestPriority)
&& isRequestFromSameProcess
&& !(setResourceHolderRetain()
- && requestClient.shouldResourceHolderRetain())))) {
+ && requestClient
+ .resourceOwnershipRetentionEnabled())))) {
frontendHandle[0] = inUseLowestPriorityFrontend.getHandle();
reclaimOwnerId[0] = inUseLowestPriorityFrontend.getOwnerClientId();
return true;
@@ -1265,7 +1266,8 @@ public class TunerResourceManagerService extends SystemService implements IBinde
|| ((requestClient.getPriority() == currentLowestPriority)
&& isRequestFromSameProcess
&& !(setResourceHolderRetain()
- && requestClient.shouldResourceHolderRetain())))) {
+ && requestClient
+ .resourceOwnershipRetentionEnabled())))) {
lnbHandle[0] = inUseLowestPriorityLnb.getHandle();
reclaimOwnerId[0] = inUseLowestPriorityLnb.getOwnerClientId();
return true;
@@ -1352,7 +1354,8 @@ public class TunerResourceManagerService extends SystemService implements IBinde
|| ((requestClient.getPriority() == currentLowestPriority)
&& isRequestFromSameProcess
&& !(setResourceHolderRetain()
- && requestClient.shouldResourceHolderRetain())))) {
+ && requestClient
+ .resourceOwnershipRetentionEnabled())))) {
casSessionHandle[0] = cas.getHandle();
reclaimOwnerId[0] = lowestPriorityOwnerId;
return true;
@@ -1439,7 +1442,8 @@ public class TunerResourceManagerService extends SystemService implements IBinde
|| ((requestClient.getPriority() == currentLowestPriority)
&& isRequestFromSameProcess
&& !(setResourceHolderRetain()
- && requestClient.shouldResourceHolderRetain())))) {
+ && requestClient
+ .resourceOwnershipRetentionEnabled())))) {
ciCamHandle[0] = ciCam.getHandle();
reclaimOwnerId[0] = lowestPriorityOwnerId;
return true;
@@ -1677,7 +1681,8 @@ public class TunerResourceManagerService extends SystemService implements IBinde
|| ((requestClient.getPriority() == currentLowestPriority)
&& isRequestFromSameProcess
&& !(setResourceHolderRetain()
- && requestClient.shouldResourceHolderRetain())))) {
+ && requestClient
+ .resourceOwnershipRetentionEnabled())))) {
demuxHandle[0] = inUseLowestPriorityDemux.getHandle();
reclaimOwnerId[0] = inUseLowestPriorityDemux.getOwnerClientId();
return true;
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index d2546e49267a..ef33ffe509b3 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -3212,18 +3212,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
* will be ignored.
*/
boolean isUniversalResizeable() {
- if (info.applicationInfo.category == ApplicationInfo.CATEGORY_GAME) {
- return false;
- }
- final boolean compatEnabled = Flags.universalResizableByDefault()
- && mDisplayContent != null && mDisplayContent.getConfiguration()
- .smallestScreenWidthDp >= WindowManager.LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP
- && mDisplayContent.getIgnoreOrientationRequest()
- && info.isChangeEnabled(ActivityInfo.UNIVERSAL_RESIZABLE_BY_DEFAULT);
- if (!compatEnabled && !mWmService.mConstants.mIgnoreActivityOrientationRequest) {
- return false;
- }
- if (mWmService.mConstants.isPackageOptOutIgnoreActivityOrientationRequest(packageName)) {
+ final boolean isLargeScreen = mDisplayContent != null && mDisplayContent.getConfiguration()
+ .smallestScreenWidthDp >= WindowManager.LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP
+ && mDisplayContent.getIgnoreOrientationRequest();
+ if (!canBeUniversalResizeable(info.applicationInfo, mWmService, isLargeScreen,
+ true /* forActivity */)) {
return false;
}
if (mAppCompatController.mAllowRestrictedResizability.getAsBoolean()) {
@@ -3234,6 +3227,31 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
.userPreferenceCompatibleWithNonResizability();
}
+ /**
+ * Returns {@code true} if the fixed orientation, aspect ratio, resizability of the application
+ * can be ignored.
+ */
+ static boolean canBeUniversalResizeable(ApplicationInfo appInfo, WindowManagerService wms,
+ boolean isLargeScreen, boolean forActivity) {
+ if (appInfo.category == ApplicationInfo.CATEGORY_GAME) {
+ return false;
+ }
+ final boolean compatEnabled = isLargeScreen && Flags.universalResizableByDefault()
+ && appInfo.isChangeEnabled(ActivityInfo.UNIVERSAL_RESIZABLE_BY_DEFAULT);
+ if (!compatEnabled && !wms.mConstants.mIgnoreActivityOrientationRequest) {
+ return false;
+ }
+ if (wms.mConstants.isPackageOptOutIgnoreActivityOrientationRequest(appInfo.packageName)) {
+ return false;
+ }
+ if (forActivity) {
+ // The caller will check both application and activity level property.
+ return true;
+ }
+ return !AppCompatController.allowRestrictedResizability(wms.mContext.getPackageManager(),
+ appInfo.packageName);
+ }
+
boolean isResizeable() {
return mAtmService.mForceResizableActivities
|| ActivityInfo.isResizeableMode(info.resizeMode)
@@ -3667,16 +3685,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
pauseKeyDispatchingLocked();
- // We are finishing the top focused activity and its task has nothing to be focused so
- // the next focusable task should be focused.
- if (mayAdjustTop && task.topRunningActivity(true /* focusableOnly */)
- == null) {
- task.adjustFocusToNextFocusableTask("finish-top", false /* allowFocusSelf */,
- shouldAdjustGlobalFocus);
- }
-
- finishActivityResults(resultCode, resultData, resultGrants);
-
final boolean endTask = task.getTopNonFinishingActivity() == null
&& !task.isClearingToReuseTask();
final WindowContainer<?> trigger = endTask ? task : this;
@@ -3687,6 +3695,16 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (transition != null) {
transition.collectClose(trigger);
}
+ // We are finishing the top focused activity and its task has nothing to be focused so
+ // the next focusable task should be focused.
+ if (mayAdjustTop && task.topRunningActivity(true /* focusableOnly */)
+ == null) {
+ task.adjustFocusToNextFocusableTask("finish-top", false /* allowFocusSelf */,
+ shouldAdjustGlobalFocus);
+ }
+
+ finishActivityResults(resultCode, resultData, resultGrants);
+
if (isState(RESUMED)) {
if (endTask) {
mAtmService.getTaskChangeNotificationController().notifyTaskRemovalStarted(
diff --git a/services/core/java/com/android/server/wm/AppCompatController.java b/services/core/java/com/android/server/wm/AppCompatController.java
index 203932d4df58..330283fb9ab3 100644
--- a/services/core/java/com/android/server/wm/AppCompatController.java
+++ b/services/core/java/com/android/server/wm/AppCompatController.java
@@ -77,13 +77,8 @@ class AppCompatController {
mAppCompatOverrides);
mAllowRestrictedResizability = AppCompatUtils.asLazy(() -> {
// Application level.
- try {
- if (packageManager.getProperty(PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY,
- mActivityRecord.packageName).getBoolean()) {
- return true;
- }
- } catch (PackageManager.NameNotFoundException e) {
- // Fall through.
+ if (allowRestrictedResizability(packageManager, mActivityRecord.packageName)) {
+ return true;
}
// Activity level.
try {
@@ -98,6 +93,15 @@ class AppCompatController {
});
}
+ static boolean allowRestrictedResizability(PackageManager pm, String packageName) {
+ try {
+ return pm.getProperty(PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY, packageName)
+ .getBoolean();
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+ }
+
@NonNull
TransparentPolicy getTransparentPolicy() {
return mTransparentPolicy;
diff --git a/services/core/java/com/android/server/wm/AppWarnings.java b/services/core/java/com/android/server/wm/AppWarnings.java
index fcaab2c0f8c7..601b17c46c03 100644
--- a/services/core/java/com/android/server/wm/AppWarnings.java
+++ b/services/core/java/com/android/server/wm/AppWarnings.java
@@ -32,6 +32,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
+import android.content.pm.Flags;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.os.Build;
@@ -40,6 +41,8 @@ import android.os.Looper;
import android.os.Message;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.system.Os;
+import android.system.OsConstants;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
@@ -76,6 +79,7 @@ class AppWarnings {
public static final int FLAG_HIDE_COMPILE_SDK = 0x02;
public static final int FLAG_HIDE_DEPRECATED_SDK = 0x04;
public static final int FLAG_HIDE_DEPRECATED_ABI = 0x08;
+ public static final int FLAG_HIDE_PAGE_SIZE_MISMATCH = 0x10;
/**
* Map of package flags for each user.
@@ -101,6 +105,7 @@ class AppWarnings {
private SparseArray<UnsupportedCompileSdkDialog> mUnsupportedCompileSdkDialogs;
private SparseArray<DeprecatedTargetSdkVersionDialog> mDeprecatedTargetSdkVersionDialogs;
private SparseArray<DeprecatedAbiDialog> mDeprecatedAbiDialogs;
+ private SparseArray<PageSizeMismatchDialog> mPageSizeMismatchDialogs;
/** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
private final ArraySet<ComponentName> mAlwaysShowUnsupportedCompileSdkWarningActivities =
@@ -250,6 +255,19 @@ class AppWarnings {
}
}
+ public void showPageSizeMismatchDialogIfNeeded(ActivityRecord r) {
+ // Don't show dialog if the app compat is enabled using property
+ final boolean appCompatEnabled = SystemProperties.getBoolean(
+ "bionic.linker.16kb.app_compat.enabled", false);
+ if (appCompatEnabled) {
+ return;
+ }
+ boolean is16KbDevice = Os.sysconf(OsConstants._SC_PAGESIZE) == 16384;
+ if (is16KbDevice) {
+ mUiHandler.showPageSizeMismatchDialog(r);
+ }
+ }
+
/**
* Called when an activity is being started.
*
@@ -260,6 +278,9 @@ class AppWarnings {
showUnsupportedDisplaySizeDialogIfNeeded(r);
showDeprecatedTargetDialogIfNeeded(r);
showDeprecatedAbiDialogIfNeeded(r);
+ if (Flags.appCompatOption16kb()) {
+ showPageSizeMismatchDialogIfNeeded(r);
+ }
}
/**
@@ -457,6 +478,41 @@ class AppWarnings {
}
}
+ @UiThread
+ private void showPageSizeMismatchDialogUiThread(@NonNull ActivityRecord ar) {
+ String warning =
+ mAtm.mContext
+ .getPackageManager()
+ .getPageSizeCompatWarningMessage(ar.info.packageName);
+ if (warning == null) {
+ return;
+ }
+
+ final int userId = getUserIdForActivity(ar);
+ PageSizeMismatchDialog pageSizeMismatchDialog;
+ if (mPageSizeMismatchDialogs != null) {
+ pageSizeMismatchDialog = mPageSizeMismatchDialogs.get(userId);
+ if (pageSizeMismatchDialog != null) {
+ pageSizeMismatchDialog.dismiss();
+ mPageSizeMismatchDialogs.remove(userId);
+ }
+ }
+ if (!hasPackageFlag(userId, ar.packageName, FLAG_HIDE_PAGE_SIZE_MISMATCH)) {
+ pageSizeMismatchDialog =
+ new PageSizeMismatchDialog(
+ AppWarnings.this,
+ getUiContextForActivity(ar),
+ ar.info.applicationInfo,
+ userId,
+ warning);
+ pageSizeMismatchDialog.show();
+ if (mPageSizeMismatchDialogs == null) {
+ mPageSizeMismatchDialogs = new SparseArray<>();
+ }
+ mPageSizeMismatchDialogs.put(userId, pageSizeMismatchDialog);
+ }
+ }
+
/**
* Dismisses all warnings for the given package.
* <p>
@@ -510,6 +566,16 @@ class AppWarnings {
mDeprecatedAbiDialogs.remove(userId);
}
}
+
+ // Hides the "page size app compat" dialog if necessary.
+ if (mPageSizeMismatchDialogs != null) {
+ PageSizeMismatchDialog pageSizeMismatchDialog = mPageSizeMismatchDialogs.get(userId);
+ if (pageSizeMismatchDialog != null
+ && (name == null || name.equals(pageSizeMismatchDialog.mPackageName))) {
+ pageSizeMismatchDialog.dismiss();
+ mPageSizeMismatchDialogs.remove(userId);
+ }
+ }
}
/**
@@ -649,6 +715,7 @@ class AppWarnings {
private static final int MSG_HIDE_DIALOGS_FOR_PACKAGE = 4;
private static final int MSG_SHOW_DEPRECATED_TARGET_SDK_DIALOG = 5;
private static final int MSG_SHOW_DEPRECATED_ABI_DIALOG = 6;
+ private static final int MSG_SHOW_PAGE_SIZE_APP_MISMATCH_DIALOG = 7;
public UiHandler(Looper looper) {
super(looper, null, true);
@@ -681,6 +748,10 @@ class AppWarnings {
final ActivityRecord ar = (ActivityRecord) msg.obj;
showDeprecatedAbiDialogUiThread(ar);
} break;
+ case MSG_SHOW_PAGE_SIZE_APP_MISMATCH_DIALOG: {
+ final ActivityRecord ar = (ActivityRecord) msg.obj;
+ showPageSizeMismatchDialogUiThread(ar);
+ } break;
}
}
@@ -712,6 +783,11 @@ class AppWarnings {
public void hideDialogsForPackage(String name, int userId) {
obtainMessage(MSG_HIDE_DIALOGS_FOR_PACKAGE, userId, 0, name).sendToTarget();
}
+
+ public void showPageSizeMismatchDialog(ActivityRecord r) {
+ removeMessages(MSG_SHOW_PAGE_SIZE_APP_MISMATCH_DIALOG);
+ obtainMessage(MSG_SHOW_PAGE_SIZE_APP_MISMATCH_DIALOG, r).sendToTarget();
+ }
}
static class BaseDialog {
diff --git a/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java b/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java
index 506477f67bfc..cb95b3655c61 100644
--- a/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java
+++ b/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java
@@ -65,6 +65,9 @@ final class CameraCompatFreeformPolicy implements CameraStateMonitor.CameraCompa
@NonNull
private final CameraStateMonitor mCameraStateMonitor;
+ // TODO(b/380840084): Consider moving this to the CameraStateMonitor, and keeping track of
+ // all current camera activities, especially when the camera access is switching from one app to
+ // another.
@Nullable
private Task mCameraTask;
@@ -123,8 +126,7 @@ final class CameraCompatFreeformPolicy implements CameraStateMonitor.CameraCompa
}
@Override
- public void onCameraOpened(@NonNull ActivityRecord cameraActivity,
- @NonNull String cameraId) {
+ public void onCameraOpened(@NonNull ActivityRecord cameraActivity) {
// Do not check orientation outside of the config recompute, as the app's orientation intent
// might be obscured by a fullscreen override. Especially for apps which have a camera
// functionality which is not the main focus of the app: while most of the app might work
@@ -136,18 +138,15 @@ final class CameraCompatFreeformPolicy implements CameraStateMonitor.CameraCompa
return;
}
- cameraActivity.recomputeConfiguration();
- cameraActivity.getTask().dispatchTaskInfoChangedIfNeeded(/* force= */ true);
- cameraActivity.ensureActivityConfiguration(/* ignoreVisibility= */ false);
+ mCameraTask = cameraActivity.getTask();
+ updateAndDispatchCameraConfiguration();
}
@Override
- public boolean onCameraClosed(@NonNull String cameraId) {
+ public boolean canCameraBeClosed(@NonNull String cameraId) {
// Top activity in the same task as the camera activity, or `null` if the task is
// closed.
- final ActivityRecord topActivity = mCameraTask != null
- ? mCameraTask.getTopActivity(/* isFinishing */ false, /* includeOverlays */ false)
- : null;
+ final ActivityRecord topActivity = getTopActivityFromCameraTask();
if (topActivity != null) {
if (isActivityForCameraIdRefreshing(topActivity, cameraId)) {
ProtoLog.v(WmProtoLogGroups.WM_DEBUG_STATES,
@@ -157,10 +156,36 @@ final class CameraCompatFreeformPolicy implements CameraStateMonitor.CameraCompa
return false;
}
}
- mCameraTask = null;
return true;
}
+ @Override
+ public void onCameraClosed() {
+ // Top activity in the same task as the camera activity, or `null` if the task is
+ // closed.
+ final ActivityRecord topActivity = getTopActivityFromCameraTask();
+ // Only clean up if the camera is not running - this close signal could be from switching
+ // cameras (e.g. back to front camera, and vice versa).
+ if (topActivity == null || !mCameraStateMonitor.isCameraRunningForActivity(topActivity)) {
+ updateAndDispatchCameraConfiguration();
+ mCameraTask = null;
+ }
+ }
+
+ private void updateAndDispatchCameraConfiguration() {
+ if (mCameraTask == null) {
+ return;
+ }
+ final ActivityRecord activity = getTopActivityFromCameraTask();
+ if (activity != null) {
+ activity.recomputeConfiguration();
+ mCameraTask.dispatchTaskInfoChangedIfNeeded(/* force= */ true);
+ activity.ensureActivityConfiguration(/* ignoreVisibility= */ true);
+ } else {
+ mCameraTask.dispatchTaskInfoChangedIfNeeded(/* force= */ true);
+ }
+ }
+
boolean shouldCameraCompatControlOrientation(@NonNull ActivityRecord activity) {
return isCameraRunningAndWindowingModeEligible(activity);
}
@@ -262,10 +287,17 @@ final class CameraCompatFreeformPolicy implements CameraStateMonitor.CameraCompa
&& !activity.isEmbedded();
}
+ @Nullable
+ private ActivityRecord getTopActivityFromCameraTask() {
+ return mCameraTask != null
+ ? mCameraTask.getTopActivity(/* isFinishing */ false, /* includeOverlays */ false)
+ : null;
+ }
+
private boolean isActivityForCameraIdRefreshing(@NonNull ActivityRecord topActivity,
@NonNull String cameraId) {
if (!isTreatmentEnabledForActivity(topActivity, /* checkOrientation= */ true)
- || mCameraStateMonitor.isCameraWithIdRunningForActivity(topActivity, cameraId)) {
+ || !mCameraStateMonitor.isCameraWithIdRunningForActivity(topActivity, cameraId)) {
return false;
}
return topActivity.mAppCompatController.getAppCompatCameraOverrides().isRefreshRequested();
diff --git a/services/core/java/com/android/server/wm/CameraStateMonitor.java b/services/core/java/com/android/server/wm/CameraStateMonitor.java
index 3b6e30ab2a6d..3aa355869d85 100644
--- a/services/core/java/com/android/server/wm/CameraStateMonitor.java
+++ b/services/core/java/com/android/server/wm/CameraStateMonitor.java
@@ -67,6 +67,10 @@ class CameraStateMonitor {
// when camera connection is closed and we need to clean up our records.
private final CameraIdPackageNameBiMapping mCameraIdPackageBiMapping =
new CameraIdPackageNameBiMapping();
+ // TODO(b/380840084): Consider making this a set of CameraId/PackageName pairs. This is to
+ // keep track of camera-closed signals when apps are switching camera access, so that the policy
+ // can restore app configuration when an app closes camera (e.g. loses camera access due to
+ // another app).
private final Set<String> mScheduledToBeRemovedCameraIdSet = new ArraySet<>();
// TODO(b/336474959): should/can this go in the compat listeners?
@@ -163,15 +167,14 @@ class CameraStateMonitor {
if (cameraActivity == null || cameraActivity.getTask() == null) {
return;
}
- notifyListenersCameraOpened(cameraActivity, cameraId);
+ notifyListenersCameraOpened(cameraActivity);
}
}
- private void notifyListenersCameraOpened(@NonNull ActivityRecord cameraActivity,
- @NonNull String cameraId) {
+ private void notifyListenersCameraOpened(@NonNull ActivityRecord cameraActivity) {
for (int i = 0; i < mCameraStateListeners.size(); i++) {
CameraCompatStateListener listener = mCameraStateListeners.get(i);
- listener.onCameraOpened(cameraActivity, cameraId);
+ listener.onCameraOpened(cameraActivity);
}
}
@@ -224,11 +227,11 @@ class CameraStateMonitor {
// Already reconnected to this camera, no need to clean up.
return;
}
-
- final boolean closeSuccessfulForAllListeners = notifyListenersCameraClosed(cameraId);
- if (closeSuccessfulForAllListeners) {
+ final boolean canClose = checkCanCloseForAllListeners(cameraId);
+ if (canClose) {
// Finish cleaning up.
mCameraIdPackageBiMapping.removeCameraId(cameraId);
+ notifyListenersCameraClosed();
} else {
// Not ready to process closure yet - the camera activity might be refreshing.
// Try again later.
@@ -238,15 +241,21 @@ class CameraStateMonitor {
}
/**
- * @return {@code false} if any listeners have reported issues processing the close.
+ * @return {@code false} if any listener has reported that they cannot process camera close now.
*/
- private boolean notifyListenersCameraClosed(@NonNull String cameraId) {
- boolean closeSuccessfulForAllListeners = true;
+ private boolean checkCanCloseForAllListeners(@NonNull String cameraId) {
for (int i = 0; i < mCameraStateListeners.size(); i++) {
- closeSuccessfulForAllListeners &= mCameraStateListeners.get(i).onCameraClosed(cameraId);
+ if (!mCameraStateListeners.get(i).canCameraBeClosed(cameraId)) {
+ return false;
+ }
}
+ return true;
+ }
- return closeSuccessfulForAllListeners;
+ private void notifyListenersCameraClosed() {
+ for (int i = 0; i < mCameraStateListeners.size(); i++) {
+ mCameraStateListeners.get(i).onCameraClosed();
+ }
}
// TODO(b/335165310): verify that this works in multi instance and permission dialogs.
@@ -297,14 +306,18 @@ class CameraStateMonitor {
/**
* Notifies the compat listener that an activity has opened camera.
*/
- // TODO(b/336474959): try to decouple `cameraId` from the listeners.
- void onCameraOpened(@NonNull ActivityRecord cameraActivity, @NonNull String cameraId);
+ void onCameraOpened(@NonNull ActivityRecord cameraActivity);
/**
- * Notifies the compat listener that camera is closed.
+ * Checks whether a listener is ready to do a cleanup when camera is closed.
*
- * @return true if cleanup has been successful - the notifier might try again if false.
+ * <p>The notifier might try again if false is returned.
*/
// TODO(b/336474959): try to decouple `cameraId` from the listeners.
- boolean onCameraClosed(@NonNull String cameraId);
+ boolean canCameraBeClosed(@NonNull String cameraId);
+
+ /**
+ * Notifies the compat listener that camera is closed.
+ */
+ void onCameraClosed();
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
index 0ccc0fe80b52..3c199dba565b 100644
--- a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
@@ -71,6 +71,9 @@ final class DisplayRotationCompatPolicy implements CameraStateMonitor.CameraComp
@NonNull
private final ActivityRefresher mActivityRefresher;
+ // TODO(b/380840084): Consider moving this to the CameraStateMonitor, and keeping track of
+ // all current camera activities, especially when the camera access is switching from one app to
+ // another.
@Nullable
private Task mCameraTask;
@@ -327,8 +330,7 @@ final class DisplayRotationCompatPolicy implements CameraStateMonitor.CameraComp
}
@Override
- public void onCameraOpened(@NonNull ActivityRecord cameraActivity,
- @NonNull String cameraId) {
+ public void onCameraOpened(@NonNull ActivityRecord cameraActivity) {
mCameraTask = cameraActivity.getTask();
// Checking whether an activity in fullscreen rather than the task as this camera
// compat treatment doesn't cover activity embedding.
@@ -374,16 +376,9 @@ final class DisplayRotationCompatPolicy implements CameraStateMonitor.CameraComp
}
@Override
- public boolean onCameraClosed(@NonNull String cameraId) {
- final ActivityRecord topActivity;
- if (Flags.cameraCompatFullscreenPickSameTaskActivity()) {
- topActivity = mCameraTask != null ? mCameraTask.getTopActivity(
- /* includeFinishing= */ true, /* includeOverlays= */ false) : null;
- } else {
- topActivity = mDisplayContent.topRunningActivity(/* considerKeyguardState= */ true);
- }
+ public boolean canCameraBeClosed(@NonNull String cameraId) {
+ final ActivityRecord topActivity = getTopActivity();
- mCameraTask = null;
if (topActivity == null) {
return true;
}
@@ -399,6 +394,23 @@ final class DisplayRotationCompatPolicy implements CameraStateMonitor.CameraComp
return false;
}
}
+ return true;
+ }
+
+ @Override
+ public void onCameraClosed() {
+ final ActivityRecord topActivity = getTopActivity();
+
+ // Only clean up if the camera is not running - this close signal could be from switching
+ // cameras (e.g. back to front camera, and vice versa).
+ if (topActivity == null || !mCameraStateMonitor.isCameraRunningForActivity(topActivity)) {
+ // Call after getTopActivity(), as that method might use the activity from mCameraTask.
+ mCameraTask = null;
+ }
+
+ if (topActivity == null) {
+ return;
+ }
ProtoLog.v(WM_DEBUG_ORIENTATION,
"Display id=%d is notified that Camera is closed, updating rotation.",
@@ -406,11 +418,10 @@ final class DisplayRotationCompatPolicy implements CameraStateMonitor.CameraComp
// Checking whether an activity in fullscreen rather than the task as this camera compat
// treatment doesn't cover activity embedding.
if (topActivity.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
- return true;
+ return;
}
recomputeConfigurationForCameraCompatIfNeeded(topActivity);
mDisplayContent.updateOrientation();
- return true;
}
// TODO(b/336474959): Do we need cameraId here?
@@ -430,6 +441,16 @@ final class DisplayRotationCompatPolicy implements CameraStateMonitor.CameraComp
}
}
+ @Nullable
+ private ActivityRecord getTopActivity() {
+ if (Flags.cameraCompatFullscreenPickSameTaskActivity()) {
+ return mCameraTask != null ? mCameraTask.getTopActivity(
+ /* includeFinishing= */ true, /* includeOverlays= */ false) : null;
+ } else {
+ return mDisplayContent.topRunningActivity(/* considerKeyguardState= */ true);
+ }
+ }
+
/**
* @return {@code true} if the configuration needs to be recomputed after a camera state update.
*/
diff --git a/services/core/java/com/android/server/wm/OWNERS b/services/core/java/com/android/server/wm/OWNERS
index 2401f9072ea3..c7667b40ddd9 100644
--- a/services/core/java/com/android/server/wm/OWNERS
+++ b/services/core/java/com/android/server/wm/OWNERS
@@ -19,6 +19,7 @@ yunfanc@google.com
wilsonshih@google.com
jiamingliu@google.com
pdwilliams@google.com
+charlesccchen@google.com
# Files related to background activity launches
per-file Background*Start* = set noparent
diff --git a/services/core/java/com/android/server/wm/PageSizeMismatchDialog.java b/services/core/java/com/android/server/wm/PageSizeMismatchDialog.java
new file mode 100644
index 000000000000..8c50913dd563
--- /dev/null
+++ b/services/core/java/com/android/server/wm/PageSizeMismatchDialog.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.text.Html.FROM_HTML_MODE_COMPACT;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager;
+import android.text.Html;
+import android.view.Window;
+import android.view.WindowManager;
+
+import com.android.internal.R;
+
+/**
+ * Show warning dialog when
+ * - Uncompressed libs inside apk are not aligned to page size
+ * - ELF Load segments are not page size aligned
+ * This dialog will be shown everytime when app is launched. Apps can choose to override
+ * by setting compat mode pageSizeCompat="enabled" in manifest or "disabled" to opt out.
+ * Both cases will skip the PageSizeMismatchDialog.
+ *
+ */
+class PageSizeMismatchDialog extends AppWarnings.BaseDialog {
+ PageSizeMismatchDialog(
+ final AppWarnings manager,
+ Context context,
+ ApplicationInfo appInfo,
+ int userId,
+ String warning) {
+ super(manager, context, appInfo.packageName, userId);
+
+ final PackageManager pm = context.getPackageManager();
+ final CharSequence label =
+ appInfo.loadSafeLabel(
+ pm,
+ PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX,
+ PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE
+ | PackageItemInfo.SAFE_LABEL_FLAG_TRIM);
+
+ final AlertDialog.Builder builder =
+ new AlertDialog.Builder(context)
+ .setPositiveButton(
+ R.string.ok,
+ (dialog, which) -> {/* Do nothing */})
+ .setMessage(Html.fromHtml(warning, FROM_HTML_MODE_COMPACT))
+ .setTitle(label);
+
+ mDialog = builder.create();
+ mDialog.create();
+
+ final Window window = mDialog.getWindow();
+ window.setType(WindowManager.LayoutParams.TYPE_PHONE);
+ }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
index cb333f02757e..1c8d06e52329 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
@@ -152,19 +152,20 @@ final class DevicePolicyEngine {
mAdminPolicySize = new SparseArray<>();
}
- private void maybeForceEnforcementRefreshLocked(@NonNull PolicyDefinition<?> policyDefinition) {
+ private void forceEnforcementRefreshIfUserRestrictionLocked(
+ @NonNull PolicyDefinition<?> policyDefinition) {
try {
- if (shouldForceEnforcementRefresh(policyDefinition)) {
+ if (isUserRestrictionPolicy(policyDefinition)) {
// This is okay because it's only true for user restrictions which are all <Boolean>
forceEnforcementRefreshLocked((PolicyDefinition<Boolean>) policyDefinition);
}
} catch (Throwable e) {
// Catch any possible exceptions just to be on the safe side
- Log.e(TAG, "Exception throw during maybeForceEnforcementRefreshLocked", e);
+ Log.e(TAG, "Exception thrown during forceEnforcementRefreshIfUserRestrictionLocked", e);
}
}
- private boolean shouldForceEnforcementRefresh(@NonNull PolicyDefinition<?> policyDefinition) {
+ private boolean isUserRestrictionPolicy(@NonNull PolicyDefinition<?> policyDefinition) {
// These are all "not nullable" but for the purposes of maximum safety for a lightly tested
// change we check here
if (policyDefinition == null) {
@@ -257,7 +258,7 @@ final class DevicePolicyEngine {
// No need to notify admins as no new policy is actually enforced, we're just filling in
// the data structures.
if (!skipEnforcePolicy) {
- maybeForceEnforcementRefreshLocked(policyDefinition);
+ forceEnforcementRefreshIfUserRestrictionLocked(policyDefinition);
if (policyChanged) {
onLocalPolicyChangedLocked(policyDefinition, enforcingAdmin, userId);
}
@@ -347,7 +348,7 @@ final class DevicePolicyEngine {
Objects.requireNonNull(enforcingAdmin);
synchronized (mLock) {
- maybeForceEnforcementRefreshLocked(policyDefinition);
+ forceEnforcementRefreshIfUserRestrictionLocked(policyDefinition);
if (!hasLocalPolicyLocked(policyDefinition, userId)) {
return;
}
@@ -517,7 +518,7 @@ final class DevicePolicyEngine {
// No need to notify admins as no new policy is actually enforced, we're just filling in
// the data structures.
if (!skipEnforcePolicy) {
- maybeForceEnforcementRefreshLocked(policyDefinition);
+ forceEnforcementRefreshIfUserRestrictionLocked(policyDefinition);
if (policyChanged) {
onGlobalPolicyChangedLocked(policyDefinition, enforcingAdmin);
}
@@ -570,7 +571,7 @@ final class DevicePolicyEngine {
boolean policyChanged = policyState.removePolicy(enforcingAdmin);
- maybeForceEnforcementRefreshLocked(policyDefinition);
+ forceEnforcementRefreshIfUserRestrictionLocked(policyDefinition);
if (policyChanged) {
onGlobalPolicyChangedLocked(policyDefinition, enforcingAdmin);
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 5bd70ef57fac..6f0d26a2426d 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -23178,6 +23178,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL);
CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_KEYGUARD,
MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL);
+ if (Flags.lockNowCoexistence()) {
+ CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_LOCK,
+ MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL);
+ }
CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS,
MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL);
@@ -23252,8 +23256,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL);
CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_LOCATION,
MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL);
- CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_LOCK,
- MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL);
+ if (!Flags.lockNowCoexistence()) {
+ CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_LOCK,
+ MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL);
+ }
CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_LOCK_TASK,
MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL);
CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_MODIFY_USERS,
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 112414e6c4df..fde6ce26cb68 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -16,6 +16,7 @@
package com.android.server;
+import static android.media.tv.flags.Flags.mediaQualityFw;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
@@ -2616,9 +2617,11 @@ public final class SystemServer implements Dumpable {
t.traceEnd();
}
- t.traceBegin("StartMediaQuality");
- mSystemServiceManager.startService(MediaQualityService.class);
- t.traceEnd();
+ if (mediaQualityFw() && isTv) {
+ t.traceBegin("StartMediaQuality");
+ mSystemServiceManager.startService(MediaQualityService.class);
+ t.traceEnd();
+ }
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)) {
t.traceBegin("StartMediaResourceMonitor");
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index ace6aae1a8fc..6defadf44d05 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -47,8 +47,10 @@ import static com.android.server.am.Flags.FLAG_AVOID_RESOLVING_TYPE;
import static com.android.server.am.ProcessList.NETWORK_STATE_BLOCK;
import static com.android.server.am.ProcessList.NETWORK_STATE_NO_CHANGE;
import static com.android.server.am.ProcessList.NETWORK_STATE_UNBLOCK;
+
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
@@ -87,6 +89,7 @@ import android.app.Notification;
import android.app.NotificationChannel;
import android.app.SyncNotedAppOp;
import android.app.backup.BackupAnnotations;
+import android.content.ClipData;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
@@ -98,6 +101,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ServiceInfo;
+import android.graphics.Rect;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Bundle;
@@ -105,6 +109,7 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.IProgressListener;
+import android.os.IpcDataCache;
import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
@@ -201,6 +206,16 @@ public class ActivityManagerServiceTest {
private static final String TEST_AUTHORITY = "test_authority";
private static final String TEST_MIME_TYPE = "application/test_type";
+ private static final Uri TEST_URI = Uri.parse("content://com.example/people");
+ private static final int TEST_CREATOR_UID = 12345;
+ private static final String TEST_CREATOR_PACKAGE = "android.content.testCreatorPackage";
+ private static final String TEST_TYPE = "testType";
+ private static final String TEST_IDENTIFIER = "testIdentifier";
+ private static final String TEST_CATEGORY = "testCategory";
+ private static final String TEST_LAUNCH_TOKEN = "testLaunchToken";
+ private static final ComponentName TEST_COMPONENT = new ComponentName(TEST_PACKAGE,
+ "TestClass");
+ private static final int ALL_SET_FLAG = 0xFFFFFFFF;
private static final int[] UID_RECORD_CHANGES = {
UidRecord.CHANGE_PROCSTATE,
@@ -959,28 +974,37 @@ public class ActivityManagerServiceTest {
@Test
@SuppressWarnings("GuardedBy")
public void testBroadcastStickyIntent_verifyTypeNotResolved() throws Exception {
- final Intent intent = new Intent(TEST_ACTION1);
- final Uri uri = new Uri.Builder()
- .scheme(SCHEME_CONTENT)
- .authority(TEST_AUTHORITY)
- .path("green")
- .build();
- intent.setData(uri);
- broadcastIntent(intent, null, true, TEST_MIME_TYPE, USER_ALL);
- assertStickyBroadcasts(mAms.getStickyBroadcastsForTest(TEST_ACTION1, USER_ALL),
- StickyBroadcast.create(intent, false, Process.myUid(), PROCESS_STATE_UNKNOWN,
- TEST_MIME_TYPE));
- when(mContentResolver.getType(uri)).thenReturn(TEST_MIME_TYPE);
+ MockitoSession mockitoSession =
+ ExtendedMockito.mockitoSession().mockStatic(IpcDataCache.class).startMocking();
- addUidRecord(TEST_UID, TEST_PACKAGE);
- final ProcessRecord procRecord = mAms.getProcessRecordLocked(TEST_PACKAGE, TEST_UID);
- final IntentFilter intentFilter = new IntentFilter(TEST_ACTION1);
- intentFilter.addDataType(TEST_MIME_TYPE);
- final Intent resultIntent = mAms.registerReceiverWithFeature(procRecord.getThread(),
- TEST_PACKAGE, null, null, null, intentFilter, null, TEST_USER,
- Context.RECEIVER_EXPORTED);
- assertNotNull(resultIntent);
- verify(mContentResolver, never()).getType(any());
+ try {
+ final Intent intent = new Intent(TEST_ACTION1);
+ final Uri uri = new Uri.Builder()
+ .scheme(SCHEME_CONTENT)
+ .authority(TEST_AUTHORITY)
+ .path("green")
+ .build();
+ intent.setData(uri);
+ broadcastIntent(intent, null, true, TEST_MIME_TYPE, USER_ALL);
+ assertStickyBroadcasts(mAms.getStickyBroadcastsForTest(TEST_ACTION1, USER_ALL),
+ StickyBroadcast.create(intent, false, Process.myUid(), PROCESS_STATE_UNKNOWN,
+ TEST_MIME_TYPE));
+ when(mContentResolver.getType(uri)).thenReturn(TEST_MIME_TYPE);
+ ExtendedMockito.doNothing().when(
+ () -> IpcDataCache.invalidateCache(anyString(), anyString()));
+
+ addUidRecord(TEST_UID, TEST_PACKAGE);
+ final ProcessRecord procRecord = mAms.getProcessRecordLocked(TEST_PACKAGE, TEST_UID);
+ final IntentFilter intentFilter = new IntentFilter(TEST_ACTION1);
+ intentFilter.addDataType(TEST_MIME_TYPE);
+ final Intent resultIntent = mAms.registerReceiverWithFeature(procRecord.getThread(),
+ TEST_PACKAGE, null, null, null, intentFilter, null, TEST_USER,
+ Context.RECEIVER_EXPORTED);
+ assertNotNull(resultIntent);
+ verify(mContentResolver, never()).getType(any());
+ } finally {
+ mockitoSession.finishMocking();
+ }
}
@SuppressWarnings("GuardedBy")
@@ -1402,6 +1426,34 @@ public class ActivityManagerServiceTest {
& Intent.EXTENDED_FLAG_MISSING_CREATOR_OR_INVALID_TOKEN).isEqualTo(0);
}
+ @Test
+ public void testUseCloneForCreatorTokenAndOriginalIntent_createSameIntentCreatorToken() {
+ Intent testIntent = new Intent(TEST_ACTION1)
+ .setComponent(TEST_COMPONENT)
+ .setDataAndType(TEST_URI, TEST_TYPE)
+ .setIdentifier(TEST_IDENTIFIER)
+ .addCategory(TEST_CATEGORY);
+ testIntent.setOriginalIntent(new Intent(TEST_ACTION2));
+ testIntent.setSelector(new Intent(TEST_ACTION3));
+ testIntent.setSourceBounds(new Rect(0, 0, 100, 100));
+ testIntent.setLaunchToken(TEST_LAUNCH_TOKEN);
+ testIntent.addFlags(ALL_SET_FLAG)
+ .addExtendedFlags(ALL_SET_FLAG);
+ ClipData testClipData = ClipData.newHtmlText("label", "text", "<html/>");
+ testClipData.addItem(new ClipData.Item(new Intent(TEST_ACTION1)));
+ testClipData.addItem(new ClipData.Item(TEST_URI));
+ testIntent.putExtra(TEST_EXTRA_KEY1, TEST_EXTRA_VALUE1);
+
+ ActivityManagerService.IntentCreatorToken tokenForFullIntent =
+ new ActivityManagerService.IntentCreatorToken(TEST_CREATOR_UID,
+ TEST_CREATOR_PACKAGE, testIntent);
+ ActivityManagerService.IntentCreatorToken tokenForCloneIntent =
+ new ActivityManagerService.IntentCreatorToken(TEST_CREATOR_UID,
+ TEST_CREATOR_PACKAGE, testIntent.cloneForCreatorToken());
+
+ assertThat(tokenForFullIntent.getKeyFields()).isEqualTo(tokenForCloneIntent.getKeyFields());
+ }
+
private void verifyWaitingForNetworkStateUpdate(long curProcStateSeq,
long lastNetworkUpdatedProcStateSeq,
final long procStateSeqToWait, boolean expectWait) throws Exception {
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/ApexManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/ApexManagerTest.java
index 405024cc0e34..769f071e3ddc 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/ApexManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/ApexManagerTest.java
@@ -134,7 +134,7 @@ public class ApexManagerTest {
mMockSystem.system().validateFinalState();
mInstallPackageHelper = new InstallPackageHelper(mPmService, mock(AppDataHelper.class),
mock(RemovePackageHelper.class), mock(DeletePackageHelper.class),
- mock(BroadcastHelper.class), mock(InstallDependencyHelper.class));
+ mock(BroadcastHelper.class));
}
@NonNull
diff --git a/services/tests/security/intrusiondetection/Android.bp b/services/tests/security/intrusiondetection/Android.bp
index 00ac90807dff..8d674b14feac 100644
--- a/services/tests/security/intrusiondetection/Android.bp
+++ b/services/tests/security/intrusiondetection/Android.bp
@@ -19,15 +19,20 @@ android_test {
"androidx.test.rules",
"androidx.test.runner",
"compatibility-device-util-axt",
+ "coretests-aidl",
"frameworks-base-testutils",
"junit",
"platform-test-annotations",
+ "servicestests-utils",
"services.core",
"truth",
"Nene",
"Harrier",
"TestApp",
],
+ data: [
+ ":TestIntrusionDetectionApp",
+ ],
platform_apis: true,
diff --git a/services/tests/security/intrusiondetection/AndroidManifest.xml b/services/tests/security/intrusiondetection/AndroidManifest.xml
index 39e41cddb662..b30710d9bcbe 100644
--- a/services/tests/security/intrusiondetection/AndroidManifest.xml
+++ b/services/tests/security/intrusiondetection/AndroidManifest.xml
@@ -33,6 +33,10 @@
</receiver>
</application>
+ <queries>
+ <package android:name="com.android.coretests.apps.testapp" />
+ </queries>
+
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.server.security.intrusiondetection.tests"
android:label="Frameworks IntrusionDetection Services Tests"/>
diff --git a/services/tests/security/intrusiondetection/AndroidTest.xml b/services/tests/security/intrusiondetection/AndroidTest.xml
index 42cb9e3236e0..6489dea4a508 100644
--- a/services/tests/security/intrusiondetection/AndroidTest.xml
+++ b/services/tests/security/intrusiondetection/AndroidTest.xml
@@ -20,6 +20,7 @@
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true"/>
<option name="test-file-name" value="IntrusionDetectionServiceTests.apk"/>
+ <option name="test-file-name" value="TestIntrusionDetectionApp.apk"/>
<option name="install-arg" value="-t" />
</target_preparer>
diff --git a/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/IntrusionDetectionServiceTest.java b/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/IntrusionDetectionServiceTest.java
index c185ad5ffd61..e505ebeb2946 100644
--- a/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/IntrusionDetectionServiceTest.java
+++ b/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/IntrusionDetectionServiceTest.java
@@ -42,6 +42,10 @@ import android.app.admin.SecurityLog;
import android.app.admin.SecurityLog.SecurityEvent;
import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.os.Bundle;
import android.os.Looper;
import android.os.PermissionEnforcer;
import android.os.RemoteException;
@@ -52,6 +56,7 @@ import android.security.intrusiondetection.IIntrusionDetectionServiceStateCallba
import android.security.intrusiondetection.IntrusionDetectionEvent;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
+import android.util.Log;
import androidx.test.core.app.ApplicationProvider;
@@ -65,6 +70,8 @@ import com.android.bedstead.nene.exceptions.NeneException;
import com.android.bedstead.permissions.CommonPermissions;
import com.android.bedstead.permissions.PermissionContext;
import com.android.bedstead.permissions.annotations.EnsureHasPermission;
+import com.android.coretests.apps.testapp.LocalIntrusionDetectionEventTransport;
+import com.android.internal.infra.AndroidFuture;
import com.android.server.ServiceThread;
import org.junit.Before;
@@ -111,11 +118,16 @@ public class IntrusionDetectionServiceTest {
private IntrusionDetectionEventTransportConnection mIntrusionDetectionEventTransportConnection;
private DataAggregator mDataAggregator;
private IntrusionDetectionService mIntrusionDetectionService;
+ private IBinder mService;
private TestLooper mTestLooper;
private Looper mLooper;
private TestLooper mTestLooperOfDataAggregator;
private Looper mLooperOfDataAggregator;
private FakePermissionEnforcer mPermissionEnforcer;
+ private boolean mBoundToLoggingService = false;
+ private static final String TEST_PKG =
+ "com.android.coretests.apps.testapp";
+ private static final String TEST_SERVICE = TEST_PKG + ".TestLoggingService";
@BeforeClass
public static void setDeviceOwner() {
@@ -141,8 +153,8 @@ public class IntrusionDetectionServiceTest {
@SuppressLint("VisibleForTests")
@Before
- public void setUp() {
- mContext = spy(ApplicationProvider.getApplicationContext());
+ public void setUp() throws Exception {
+ mContext = ApplicationProvider.getApplicationContext();
mPermissionEnforcer = new FakePermissionEnforcer();
mPermissionEnforcer.grant(READ_INTRUSION_DETECTION_STATE);
@@ -565,6 +577,68 @@ public class IntrusionDetectionServiceTest {
}
}
+ @Test
+ public void test_StartIntrusionDetectionEventTransportService() {
+ final String TAG = "test_StartIntrusionDetectionEventTransportService";
+ ServiceConnection serviceConnection = null;
+
+ assertEquals(false, mBoundToLoggingService);
+ try {
+ serviceConnection = startTestService();
+ assertEquals(true, mBoundToLoggingService);
+ assertNotNull(serviceConnection);
+ } catch (SecurityException e) {
+ Log.e(TAG, "SecurityException while starting: ", e);
+ fail("Exception thrown while connecting to service");
+ } catch (InterruptedException e) {
+ Log.e(TAG, "InterruptedException while starting: ", e);
+ fail("Interrupted while connecting to service");
+ } finally {
+ mContext.unbindService(serviceConnection);
+ }
+ }
+
+ private ServiceConnection startTestService() throws SecurityException, InterruptedException {
+ final String TAG = "startTestService";
+ final CountDownLatch latch = new CountDownLatch(1);
+ LocalIntrusionDetectionEventTransport transport =
+ new LocalIntrusionDetectionEventTransport();
+
+ ServiceConnection serviceConnection = new ServiceConnection() {
+ // Called when connection with the service is established.
+ @Override
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ mService = transport.getBinder();
+ mBoundToLoggingService = true;
+ latch.countDown();
+ }
+
+ // Called when the connection with the service disconnects unexpectedly.
+ @Override
+ public void onServiceDisconnected(ComponentName className) {
+ Log.d(TAG, "onServiceDisconnected");
+ mBoundToLoggingService = false;
+ }
+ };
+
+ Intent intent = new Intent();
+ intent.setComponent(new ComponentName(TEST_PKG, TEST_SERVICE));
+ mContext.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
+ latch.await(5, TimeUnit.SECONDS);
+
+ // call the methods on the transport object
+ IntrusionDetectionEvent event =
+ new IntrusionDetectionEvent(new SecurityEvent(123, new byte[15]));
+ List<IntrusionDetectionEvent> events = new ArrayList<>();
+ events.add(event);
+ assertTrue(transport.initialize());
+ assertTrue(transport.addData(events));
+ assertTrue(transport.release());
+ assertEquals(1, transport.getEvents().size());
+
+ return serviceConnection;
+ }
+
private class MockInjector implements IntrusionDetectionService.Injector {
private final Context mContext;
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
new file mode 100644
index 000000000000..ca5952b140c1
--- /dev/null
+++ b/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/TestApp/src/com/android/coretests/apps/testapp/Android.bp
@@ -0,0 +1,42 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ default_team: "trendy_team_platform_security",
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_test_helper_app {
+ name: "TestIntrusionDetectionApp",
+
+ static_libs: [
+ "frameworks-base-testutils",
+ "services.core",
+ "servicestests-utils",
+ ],
+
+ srcs: ["**/*.java"],
+
+ platform_apis: true,
+ certificate: "platform",
+ dxflags: ["--multi-dex"],
+ optimize: {
+ enabled: false,
+ },
+}
diff --git a/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/TestApp/src/com/android/coretests/apps/testapp/AndroidManifest.xml b/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/TestApp/src/com/android/coretests/apps/testapp/AndroidManifest.xml
new file mode 100644
index 000000000000..7cc75ab70571
--- /dev/null
+++ b/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/TestApp/src/com/android/coretests/apps/testapp/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.coretests.apps.testapp">
+
+ <application>
+ <service android:name=".TestLoggingService"
+ android:exported="true" />
+ </application>
+</manifest> \ No newline at end of file
diff --git a/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/TestApp/src/com/android/coretests/apps/testapp/LocalIntrusionDetectionEventTransport.java b/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/TestApp/src/com/android/coretests/apps/testapp/LocalIntrusionDetectionEventTransport.java
new file mode 100644
index 000000000000..f0012da44fa4
--- /dev/null
+++ b/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/TestApp/src/com/android/coretests/apps/testapp/LocalIntrusionDetectionEventTransport.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance
+ with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+ */
+
+package com.android.coretests.apps.testapp;
+
+import android.security.intrusiondetection.IntrusionDetectionEvent;
+import android.security.intrusiondetection.IntrusionDetectionEventTransport;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A class that extends {@link IntrusionDetectionEventTransport} to provide a
+ * local transport mechanism for testing purposes. This implementation overrides
+ * the {@link #initialize()}, {@link #addData(List)}, and {@link #release()} methods
+ * to manage events locally within the test environment.
+ *
+ * For now, the implementation returns true for all methods since we don't
+ * have a real data source to send events to.
+ */
+public class LocalIntrusionDetectionEventTransport extends IntrusionDetectionEventTransport {
+ private List<IntrusionDetectionEvent> mEvents = new ArrayList<>();
+
+ @Override
+ public boolean initialize() {
+ return true;
+ }
+
+ @Override
+ public boolean addData(List<IntrusionDetectionEvent> events) {
+ mEvents.addAll(events);
+ return true;
+ }
+
+ @Override
+ public boolean release() {
+ return true;
+ }
+
+ public List<IntrusionDetectionEvent> getEvents() {
+ return mEvents;
+ }
+} \ No newline at end of file
diff --git a/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/TestApp/src/com/android/coretests/apps/testapp/TestLoggingService.java b/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/TestApp/src/com/android/coretests/apps/testapp/TestLoggingService.java
new file mode 100644
index 000000000000..e4bf987402fd
--- /dev/null
+++ b/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/TestApp/src/com/android/coretests/apps/testapp/TestLoggingService.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.coretests.apps.testapp;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.Process;
+
+import com.android.internal.infra.AndroidFuture;
+
+
+public class TestLoggingService extends Service {
+ private static final String TAG = "TestLoggingService";
+ private LocalIntrusionDetectionEventTransport mLocalIntrusionDetectionEventTransport;
+
+ public TestLoggingService() {
+ mLocalIntrusionDetectionEventTransport = new LocalIntrusionDetectionEventTransport();
+ }
+
+ // Binder given to clients.
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mLocalIntrusionDetectionEventTransport.getBinder();
+ }
+}
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index 0c058df35195..009ce88cfd6c 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -897,16 +897,6 @@ test_module_config {
}
test_module_config {
- name: "FrameworksServicesTests_server_accessibility",
- base: "FrameworksServicesTests",
- test_suites: [
- "automotive-tests",
- "device-tests",
- ],
- include_filters: ["com.android.server.accessibility"],
-}
-
-test_module_config {
name: "FrameworksServicesTests_server_binarytransparencyservicetest",
base: "FrameworksServicesTests",
test_suites: [
diff --git a/services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java b/services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java
index ae78dfe624c6..cc5be7ebba62 100644
--- a/services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java
@@ -20,6 +20,7 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@@ -40,6 +41,7 @@ import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorProperties;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
+import android.os.Bundle;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.SystemProperties;
@@ -50,6 +52,12 @@ import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.internal.util.FrameworkStatsLog;
+import com.android.internal.os.IBinaryTransparencyService;
+import com.android.server.pm.BackgroundInstallControlService;
+import com.android.server.pm.BackgroundInstallControlCallbackHelper;
+import com.android.server.pm.pkg.AndroidPackage;
+import com.android.server.pm.pkg.AndroidPackageSplit;
+import com.android.server.pm.pkg.PackageStateInternal;
import org.junit.After;
import org.junit.Assert;
@@ -68,6 +76,9 @@ import java.util.List;
public class BinaryTransparencyServiceTest {
private static final String TAG = "BinaryTransparencyServiceTest";
+ private static final String TEST_PKG_NAME = "testPackageName";
+ private static final long TEST_VERSION_CODE = 1L;
+
private Context mContext;
private BinaryTransparencyService mBinaryTransparencyService;
private BinaryTransparencyService.BinaryTransparencyServiceImpl mTestInterface;
@@ -83,6 +94,8 @@ public class BinaryTransparencyServiceTest {
private PackageManager mPackageManager;
@Mock
private PackageManagerInternal mPackageManagerInternal;
+ @Mock
+ private BinaryTransparencyService.BicCallbackHandler.IBicAppInfoHelper mBicAppInfoHelper;
@Captor
private ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback>
@@ -91,6 +104,9 @@ public class BinaryTransparencyServiceTest {
private ArgumentCaptor<IFaceAuthenticatorsRegisteredCallback>
mFaceAuthenticatorsRegisteredCaptor;
+ @Captor
+ private ArgumentCaptor<IBinaryTransparencyService.AppInfo> appInfoCaptor;
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
@@ -262,4 +278,69 @@ public class BinaryTransparencyServiceTest {
eq("") /* softwareVersion */
);
}
+
+ @Test
+ public void BicCallbackHandler_uploads_mba_metrics() {
+ Bundle data = setupBicCallbackHandlerTest(false,
+ BinaryTransparencyService.MBA_STATUS_NEW_INSTALL);
+
+ BinaryTransparencyService.BicCallbackHandler handler =
+ new BinaryTransparencyService.BicCallbackHandler(mBicAppInfoHelper);
+ handler.sendResult(data);
+
+ verify(mBicAppInfoHelper, times(1)).writeAppInfoToLog(appInfoCaptor.capture());
+ Assert.assertEquals(TEST_PKG_NAME, appInfoCaptor.getValue().packageName);
+ Assert.assertEquals(TEST_VERSION_CODE, appInfoCaptor.getValue().longVersion);
+ }
+
+ @Test
+ public void BicCallbackHandler_uploads_mba_metrics_for_preloads() {
+ Bundle data = setupBicCallbackHandlerTest(true,
+ BinaryTransparencyService.MBA_STATUS_UPDATED_PRELOAD);
+
+ BinaryTransparencyService.BicCallbackHandler handler =
+ new BinaryTransparencyService.BicCallbackHandler(mBicAppInfoHelper);
+ handler.sendResult(data);
+
+ verify(mBicAppInfoHelper, times(1)).writeAppInfoToLog(appInfoCaptor.capture());
+ Assert.assertEquals(TEST_PKG_NAME, appInfoCaptor.getValue().packageName);
+ Assert.assertEquals(TEST_VERSION_CODE, appInfoCaptor.getValue().longVersion);
+ }
+
+ @Test
+ public void BicCallbackHandler_uploads_mba_metrics_for_uninstalls() {
+ Bundle data = new Bundle();
+ data.putString(BackgroundInstallControlCallbackHelper.FLAGGED_PACKAGE_NAME_KEY,
+ TEST_PKG_NAME);
+ data.putInt(BackgroundInstallControlCallbackHelper.INSTALL_EVENT_TYPE_KEY,
+ BackgroundInstallControlService.INSTALL_EVENT_TYPE_UNINSTALL);
+
+ BinaryTransparencyService.BicCallbackHandler handler =
+ new BinaryTransparencyService.BicCallbackHandler(mBicAppInfoHelper);
+ handler.sendResult(data);
+
+ verify(mBicAppInfoHelper, times(1)).writeAppInfoToLog(appInfoCaptor.capture());
+ Assert.assertEquals(TEST_PKG_NAME ,appInfoCaptor.getValue().packageName);
+ Assert.assertEquals(BinaryTransparencyService.MBA_STATUS_UNINSTALLED,
+ appInfoCaptor.getValue().mbaStatus);
+ }
+
+ private Bundle setupBicCallbackHandlerTest(boolean isUpdatedSystemApp,
+ int expectedBtsMbaStatus) {
+ Bundle data = new Bundle();
+ data.putString(BackgroundInstallControlCallbackHelper.FLAGGED_PACKAGE_NAME_KEY,
+ TEST_PKG_NAME);
+ data.putInt(BackgroundInstallControlCallbackHelper.INSTALL_EVENT_TYPE_KEY,
+ BackgroundInstallControlService.INSTALL_EVENT_TYPE_INSTALL);
+ PackageStateInternal mockPackageState = mock(PackageStateInternal.class);
+ when(mPackageManagerInternal.getPackageStateInternal(TEST_PKG_NAME))
+ .thenReturn(mockPackageState);
+ when(mockPackageState.isUpdatedSystemApp()).thenReturn(isUpdatedSystemApp);
+ IBinaryTransparencyService.AppInfo appInfo = new IBinaryTransparencyService.AppInfo();
+ appInfo.packageName = TEST_PKG_NAME;
+ appInfo.longVersion = TEST_VERSION_CODE;
+ when(mBicAppInfoHelper.collectAppInfo(mockPackageState, expectedBtsMbaStatus))
+ .thenReturn(List.of(appInfo));
+ return data;
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
index 27de7644f6b2..08fdaf44f913 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -1815,9 +1815,7 @@ public class AccessibilityManagerServiceTest {
}
@Test
- @EnableFlags({
- android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SHORTCUT_TARGET_SERVICE,
- Flags.FLAG_CLEAR_DEFAULT_FROM_A11Y_SHORTCUT_TARGET_SERVICE_RESTORE})
+ @EnableFlags(android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SHORTCUT_TARGET_SERVICE)
public void restoreShortcutTargets_hardware_alreadyHadDefaultService_doesNotClear() {
final String serviceDefault = TARGET_STANDARD_A11Y_SERVICE_NAME;
mTestableContext.getOrCreateTestableResources().addOverride(
@@ -1843,9 +1841,7 @@ public class AccessibilityManagerServiceTest {
}
@Test
- @EnableFlags({
- android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SHORTCUT_TARGET_SERVICE,
- Flags.FLAG_CLEAR_DEFAULT_FROM_A11Y_SHORTCUT_TARGET_SERVICE_RESTORE})
+ @EnableFlags(android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SHORTCUT_TARGET_SERVICE)
public void restoreShortcutTargets_hardware_didNotHaveDefaultService_clearsDefaultService() {
final String serviceDefault = TARGET_STANDARD_A11Y_SERVICE_NAME;
final String serviceRestored = TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString();
@@ -1870,9 +1866,7 @@ public class AccessibilityManagerServiceTest {
}
@Test
- @EnableFlags({
- android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SHORTCUT_TARGET_SERVICE,
- Flags.FLAG_CLEAR_DEFAULT_FROM_A11Y_SHORTCUT_TARGET_SERVICE_RESTORE})
+ @EnableFlags(Flags.FLAG_CLEAR_DEFAULT_FROM_A11Y_SHORTCUT_TARGET_SERVICE_RESTORE)
public void restoreShortcutTargets_hardware_nullSetting_clearsDefaultService() {
final String serviceDefault = TARGET_STANDARD_A11Y_SERVICE_NAME;
final String serviceRestored = TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java
index c7574bdc3f6c..dd4101e9796f 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java
@@ -41,11 +41,14 @@ import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.hdmi.HdmiPortInfo;
import android.hardware.tv.cec.V1_0.SendMessageResult;
+import android.media.tv.flags.Flags;
import android.os.Binder;
import android.os.Looper;
import android.os.RemoteException;
import android.os.test.TestLooper;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.stats.hdmi.HdmiStatsEnums;
import androidx.test.InstrumentationRegistry;
@@ -54,6 +57,7 @@ import androidx.test.filters.SmallTest;
import com.android.server.SystemService;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -83,6 +87,9 @@ public class HdmiCecAtomLoggingTest {
private HdmiEarcController mHdmiEarcController;
private FakeEarcNativeWrapper mEarcNativeWrapper;
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
@Before
public void setUp() throws RemoteException {
mHdmiCecAtomWriterSpy = spy(new HdmiCecAtomWriter());
@@ -232,7 +239,8 @@ public class HdmiCecAtomLoggingTest {
HdmiStatsEnums.SEND_MESSAGE_RESULT_UNKNOWN,
HdmiStatsEnums.VOLUME_MUTE,
HdmiCecAtomWriter.FEATURE_ABORT_OPCODE_UNKNOWN,
- HdmiStatsEnums.FEATURE_ABORT_REASON_UNKNOWN);
+ HdmiStatsEnums.FEATURE_ABORT_REASON_UNKNOWN,
+ HdmiCecAtomWriter.PHYSICAL_ADDRESS_INVALID);
}
@Test
@@ -258,7 +266,8 @@ public class HdmiCecAtomLoggingTest {
HdmiStatsEnums.SEND_MESSAGE_RESULT_UNKNOWN,
HdmiStatsEnums.USER_CONTROL_PRESSED_COMMAND_UNKNOWN,
HdmiCecAtomWriter.FEATURE_ABORT_OPCODE_UNKNOWN,
- HdmiStatsEnums.FEATURE_ABORT_REASON_UNKNOWN);
+ HdmiStatsEnums.FEATURE_ABORT_REASON_UNKNOWN,
+ HdmiCecAtomWriter.PHYSICAL_ADDRESS_INVALID);
}
@Test
@@ -285,7 +294,8 @@ public class HdmiCecAtomLoggingTest {
HdmiStatsEnums.SEND_MESSAGE_RESULT_UNKNOWN,
HdmiStatsEnums.USER_CONTROL_PRESSED_COMMAND_UNKNOWN,
Constants.MESSAGE_RECORD_ON,
- HdmiStatsEnums.UNRECOGNIZED_OPCODE);
+ HdmiStatsEnums.UNRECOGNIZED_OPCODE,
+ HdmiCecAtomWriter.PHYSICAL_ADDRESS_INVALID);
}
@Test
@@ -311,7 +321,8 @@ public class HdmiCecAtomLoggingTest {
HdmiStatsEnums.SEND_MESSAGE_RESULT_UNKNOWN,
HdmiStatsEnums.USER_CONTROL_PRESSED_COMMAND_UNKNOWN,
HdmiCecAtomWriter.FEATURE_ABORT_OPCODE_UNKNOWN,
- HdmiStatsEnums.FEATURE_ABORT_REASON_UNKNOWN);
+ HdmiStatsEnums.FEATURE_ABORT_REASON_UNKNOWN,
+ HdmiCecAtomWriter.PHYSICAL_ADDRESS_INVALID);
}
@Test
@@ -337,6 +348,59 @@ public class HdmiCecAtomLoggingTest {
}
@Test
+ @EnableFlags({Flags.FLAG_HDMI_CONTROL_COLLECT_PHYSICAL_ADDRESS})
+ public void testMessageReported_writesAtom_reportPhysicalAddress() {
+ HdmiCecMessage message = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
+ ADDR_PLAYBACK_1, 0x1234, HdmiDeviceInfo.DEVICE_PLAYBACK);
+
+ mHdmiCecAtomWriterSpy.messageReported(
+ message,
+ HdmiStatsEnums.INCOMING,
+ 1234);
+
+ verify(mHdmiCecAtomWriterSpy, times(1))
+ .writeHdmiCecMessageReportedAtom(
+ 1234,
+ HdmiStatsEnums.INCOMING,
+ Constants.ADDR_PLAYBACK_1,
+ Constants.ADDR_BROADCAST,
+ Constants.MESSAGE_REPORT_PHYSICAL_ADDRESS,
+ HdmiStatsEnums.SEND_MESSAGE_RESULT_UNKNOWN,
+ HdmiStatsEnums.USER_CONTROL_PRESSED_COMMAND_UNKNOWN,
+ HdmiCecAtomWriter.FEATURE_ABORT_OPCODE_UNKNOWN,
+ HdmiStatsEnums.FEATURE_ABORT_REASON_UNKNOWN,
+ 0x1234);
+ }
+
+ @Test
+ @EnableFlags({Flags.FLAG_HDMI_CONTROL_COLLECT_PHYSICAL_ADDRESS})
+ public void testMessageReported_writesAtom_reportPhysicalAddress_noParams() {
+ HdmiCecMessage message = HdmiCecMessage.build(
+ Constants.ADDR_PLAYBACK_1,
+ Constants.ADDR_BROADCAST,
+ Constants.MESSAGE_REPORT_PHYSICAL_ADDRESS,
+ new byte[0]);
+
+ mHdmiCecAtomWriterSpy.messageReported(
+ message,
+ HdmiStatsEnums.INCOMING,
+ 1234);
+
+ verify(mHdmiCecAtomWriterSpy, times(1))
+ .writeHdmiCecMessageReportedAtom(
+ 1234,
+ HdmiStatsEnums.INCOMING,
+ Constants.ADDR_PLAYBACK_1,
+ Constants.ADDR_BROADCAST,
+ Constants.MESSAGE_REPORT_PHYSICAL_ADDRESS,
+ HdmiStatsEnums.SEND_MESSAGE_RESULT_UNKNOWN,
+ HdmiStatsEnums.USER_CONTROL_PRESSED_COMMAND_UNKNOWN,
+ HdmiCecAtomWriter.FEATURE_ABORT_OPCODE_UNKNOWN,
+ HdmiStatsEnums.FEATURE_ABORT_REASON_UNKNOWN,
+ HdmiCecAtomWriter.PHYSICAL_ADDRESS_INVALID);
+ }
+
+ @Test
public void testDsmStatusChanged_onWakeUp_ArcSupported_writesAtom_logReasonWake() {
mHdmiControlServiceSpy.setSoundbarMode(HdmiControlManager.SOUNDBAR_MODE_DISABLED);
Mockito.clearInvocations(mHdmiCecAtomWriterSpy);
diff --git a/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java
index 5852af780b8b..d20f73d3c834 100644
--- a/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java
@@ -506,9 +506,9 @@ public class TunerResourceManagerServiceTest {
assertThat(client0.getProfile().getInUseFrontendHandles())
.isEqualTo(new HashSet<Long>(Arrays.asList(infos[0].handle)));
- // setResourceHolderRetain sets mResourceHolderRetain to true to allow the Resource Holder
- // (client0) to maintain ownership such as requester will not get the resources.
- client1.getProfile().setResourceHolderRetain(true);
+ // setResourceOwnershipRetention sets mResourceOwnerRetention to true to allow the Resource
+ // Holder (client0) to maintain ownership such as requester will not get the resources.
+ client1.getProfile().setResourceOwnershipRetention(true);
request = tunerFrontendRequest(client1.getId() /*clientId*/, FrontendSettings.TYPE_DVBT);
assertThat(mTunerResourceManagerService.requestFrontendInternal(request, frontendHandle))
@@ -520,10 +520,10 @@ public class TunerResourceManagerServiceTest {
.isEqualTo(client0.getId());
assertThat(client0.isReclaimed()).isFalse();
- // setResourceHolderRetain sets mResourceHolderRetain to false to allow the Resource
+ // setResourceOwnershipRetention sets mResourceOwnerRetention to false to allow the Resource
// Challenger (client1) to acquire the resource and Resource Holder loses ownership of the
// resources.
- client1.getProfile().setResourceHolderRetain(false);
+ client1.getProfile().setResourceOwnershipRetention(false);
assertThat(mTunerResourceManagerService.requestFrontendInternal(request, frontendHandle))
.isTrue();
@@ -645,9 +645,9 @@ public class TunerResourceManagerServiceTest {
.isEqualTo(new HashSet<Integer>(Arrays.asList(client0.getId())));
assertThat(mTunerResourceManagerService.getCasResource(1).isFullyUsed()).isTrue();
- // setResourceHolderRetain sets mResourceHolderRetain to true to allow the Resource Holder
- // to maintain ownership such as requester (client1) will not get the resources.
- client1.getProfile().setResourceHolderRetain(true);
+ // setResourceOwnershipRetention sets mResourceOwnerRetention to true to allow the Resource
+ // Holder to maintain ownership such as requester (client1) will not get the resources.
+ client1.getProfile().setResourceOwnershipRetention(true);
request = casSessionRequest(client1.getId(), 1);
assertThat(
@@ -663,10 +663,10 @@ public class TunerResourceManagerServiceTest {
assertThat(mTunerResourceManagerService.getCasResource(1).isFullyUsed()).isTrue();
assertThat(client0.isReclaimed()).isFalse();
- // setResourceHolderRetain sets mResourceHolderRetain to false to allow the Resource
+ // setResourceOwnershipRetention sets mResourceOwnerRetention to false to allow the Resource
// Challenger (client1) to acquire the resource and Resource Holder loses ownership of the
// resources.
- client1.getProfile().setResourceHolderRetain(false);
+ client1.getProfile().setResourceOwnershipRetention(false);
assertThat(
mTunerResourceManagerService.requestCasSessionInternal(request, casSessionHandle))
@@ -759,9 +759,9 @@ public class TunerResourceManagerServiceTest {
.isEqualTo(new HashSet<Integer>(Arrays.asList(client0.getId())));
assertThat(mTunerResourceManagerService.getCiCamResource(1).isFullyUsed()).isTrue();
- // setResourceHolderRetain sets mResourceHolderRetain to true to allow the Resource Holder
- // (client0) to maintain ownership such as requester will not get the resources.
- client1.getProfile().setResourceHolderRetain(true);
+ // setResourceOwnershipRetention sets mResourceOwnerRetention to true to allow the Resource
+ // Holder (client0) to maintain ownership such as requester will not get the resources.
+ client1.getProfile().setResourceOwnershipRetention(true);
request = tunerCiCamRequest(client1.getId(), 1);
assertThat(mTunerResourceManagerService.requestCiCamInternal(request, ciCamHandle))
@@ -776,10 +776,10 @@ public class TunerResourceManagerServiceTest {
assertThat(mTunerResourceManagerService.getCiCamResource(1).isFullyUsed()).isTrue();
assertThat(client0.isReclaimed()).isFalse();
- // setResourceHolderRetain sets mResourceHolderRetain to false to allow the Resource
+ // setResourceOwnershipRetention sets mResourceOwnerRetention to false to allow the Resource
// Challenger (client1) to acquire the resource and Resource Holder loses ownership of the
// resources.
- client1.getProfile().setResourceHolderRetain(false);
+ client1.getProfile().setResourceOwnershipRetention(false);
assertThat(mTunerResourceManagerService.requestCiCamInternal(request, ciCamHandle))
.isTrue();
@@ -927,9 +927,9 @@ public class TunerResourceManagerServiceTest {
assertThat(client0.getProfile().getInUseLnbHandles())
.isEqualTo(new HashSet<Long>(Arrays.asList(lnbHandles[0])));
- // setResourceHolderRetain sets mResourceHolderRetain to true to allow the Resource Holder
- // (client0) to maintain ownership such as requester will not get the resources.
- client1.getProfile().setResourceHolderRetain(true);
+ // setResourceOwnershipRetention sets mResourceOwnerRetention to true to allow the Resource
+ // Holder (client0) to maintain ownership such as requester will not get the resources.
+ client1.getProfile().setResourceOwnershipRetention(true);
request = new TunerLnbRequest();
request.clientId = client1.getId();
@@ -942,10 +942,10 @@ public class TunerResourceManagerServiceTest {
assertThat(client0.isReclaimed()).isFalse();
assertThat(client1.getProfile().getInUseLnbHandles().size()).isEqualTo(0);
- // setResourceHolderRetain sets mResourceHolderRetain to false to allow the Resource
+ // setResourceOwnershipRetention sets mResourceOwnerRetention to false to allow the Resource
// Challenger (client1) to acquire the resource and Resource Holder loses ownership of the
// resources.
- client1.getProfile().setResourceHolderRetain(false);
+ client1.getProfile().setResourceOwnershipRetention(false);
assertThat(mTunerResourceManagerService.requestLnbInternal(request, lnbHandle)).isTrue();
assertThat(lnbHandle[0]).isEqualTo(lnbHandles[0]);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 863f42f3d1c1..90bf1d36a4ce 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -6884,10 +6884,16 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
public void testReadPolicyXml_backupRestoreLogging() throws Exception {
BackupRestoreEventLogger logger = mock(BackupRestoreEventLogger.class);
+ if (ActivityManager.getCurrentUser() != UserHandle.USER_SYSTEM) {
+ // By default, the ZenModeHelper only has a configuration for the system user.
+ // If the current user is not the system user, the user must be updated.
+ mService.mZenModeHelper.onUserSwitched(ActivityManager.getCurrentUser());
+ }
UserInfo ui = new UserInfo(ActivityManager.getCurrentUser(), "Clone", UserInfo.FLAG_FULL);
ui.userType = USER_TYPE_FULL_SYSTEM;
when(mUmInternal.getUserInfo(ActivityManager.getCurrentUser())).thenReturn(ui);
- when(mPermissionHelper.getNotificationPermissionValues(0)).thenReturn(new ArrayMap<>());
+ when(mPermissionHelper.getNotificationPermissionValues(ActivityManager.getCurrentUser()))
+ .thenReturn(new ArrayMap<>());
TypedXmlSerializer serializer = Xml.newFastSerializer();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
@@ -8931,8 +8937,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Test
public void testAreBubblesEnabled_false() throws Exception {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.NOTIFICATION_BUBBLES, 0);
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.NOTIFICATION_BUBBLES, 0, UserHandle.getUserId(mUid));
mService.mPreferencesHelper.updateBubblesEnabled();
assertFalse(mBinderService.areBubblesEnabled(UserHandle.getUserHandleForUid(mUid)));
}
@@ -13310,6 +13316,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
when(mPermissionHelper.hasPermission(UID_N_MR1)).thenReturn(false);
when(mPermissionHelper.hasPermission(UID_P)).thenReturn(true);
+ enableInteractAcrossUsers();
assertThat(mBinderService.getPackagesBypassingDnd(UserHandle.getUserId(UID_P)).getList())
.containsExactly(new ZenBypassingApp(PKG_P, false));
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/CameraStateMonitorTests.java b/services/tests/wmtests/src/com/android/server/wm/CameraStateMonitorTests.java
index ad80f82c8ea8..4810c7fc32d2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/CameraStateMonitorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/CameraStateMonitorTests.java
@@ -22,6 +22,8 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyLong;
@@ -137,6 +139,14 @@ public final class CameraStateMonitorTests extends WindowTestsBase {
}
@Test
+ public void testOnCameraOpened_listenerAdded_cameraRegistersAsOpenedDuringTheCallback() {
+ mCameraStateMonitor.addCameraStateListener(mListener);
+ mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+
+ assertTrue(mListener.mIsCameraOpened);
+ }
+
+ @Test
public void testOnCameraOpened_cameraClosed_notifyCameraClosed() {
mCameraStateMonitor.addCameraStateListener(mListener);
// Listener returns true on `onCameraOpened`.
@@ -144,10 +154,21 @@ public final class CameraStateMonitorTests extends WindowTestsBase {
mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1);
+ assertEquals(1, mListener.mCheckCanCloseCounter);
assertEquals(1, mListener.mOnCameraClosedCounter);
}
@Test
+ public void testOnCameraOpenedAndClosed_cameraRegistersAsClosedDuringTheCallback() {
+ mCameraStateMonitor.addCameraStateListener(mListener);
+ // Listener returns true on `onCameraOpened`.
+ mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+
+ mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1);
+ assertFalse(mListener.mIsCameraOpened);
+ }
+
+ @Test
public void testOnCameraOpened_listenerCannotCloseYet_notifyCameraClosedAgain() {
mCameraStateMonitor.addCameraStateListener(mListenerCannotClose);
// Listener returns true on `onCameraOpened`.
@@ -155,7 +176,8 @@ public final class CameraStateMonitorTests extends WindowTestsBase {
mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1);
- assertEquals(2, mListenerCannotClose.mOnCameraClosedCounter);
+ assertEquals(2, mListenerCannotClose.mCheckCanCloseCounter);
+ assertEquals(1, mListenerCannotClose.mOnCameraClosedCounter);
}
@Test
@@ -197,39 +219,49 @@ public final class CameraStateMonitorTests extends WindowTestsBase {
CameraStateMonitor.CameraCompatStateListener {
int mOnCameraOpenedCounter = 0;
+ int mCheckCanCloseCounter = 0;
int mOnCameraClosedCounter = 0;
- private boolean mOnCameraClosedReturnValue = true;
+ boolean mIsCameraOpened;
+
+ private boolean mCheckCanCloseReturnValue = true;
/**
- * @param simulateUnsuccessfulCloseOnce When false, returns `true` on every
- * `onCameraClosed`. When true, returns `false` on the
- * first `onCameraClosed` callback, and `true on the
+ * @param simulateCannotCloseOnce When false, returns `true` on every
+ * `checkCanClose`. When true, returns `false` on the
+ * first `checkCanClose` callback, and `true on the
* subsequent calls. This fake implementation tests the
* retry mechanism in {@link CameraStateMonitor}.
*/
- FakeCameraCompatStateListener(boolean simulateUnsuccessfulCloseOnce) {
- mOnCameraClosedReturnValue = !simulateUnsuccessfulCloseOnce;
+ FakeCameraCompatStateListener(boolean simulateCannotCloseOnce) {
+ mCheckCanCloseReturnValue = !simulateCannotCloseOnce;
}
@Override
- public void onCameraOpened(@NonNull ActivityRecord cameraActivity,
- @NonNull String cameraId) {
+ public void onCameraOpened(@NonNull ActivityRecord cameraActivity) {
mOnCameraOpenedCounter++;
+ mIsCameraOpened = mCameraStateMonitor.isCameraRunningForActivity(cameraActivity);
}
@Override
- public boolean onCameraClosed(@NonNull String cameraId) {
- mOnCameraClosedCounter++;
- boolean returnValue = mOnCameraClosedReturnValue;
+ public boolean canCameraBeClosed(@NonNull String cameraId) {
+ mCheckCanCloseCounter++;
+ final boolean returnValue = mCheckCanCloseReturnValue;
// If false, return false only the first time, so it doesn't fall in the infinite retry
// loop.
- mOnCameraClosedReturnValue = true;
+ mCheckCanCloseReturnValue = true;
return returnValue;
}
+ @Override
+ public void onCameraClosed() {
+ mOnCameraClosedCounter++;
+ mIsCameraOpened = mCameraStateMonitor.isCameraRunningForActivity(mActivity);
+ }
+
void resetCounters() {
mOnCameraOpenedCounter = 0;
+ mCheckCanCloseCounter = 0;
mOnCameraClosedCounter = 0;
}
}
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 584c4c96ae1d..87db6c0e8577 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -4899,6 +4899,8 @@ public class SizeCompatTests extends WindowTestsBase {
prepareLimitedBounds(mActivity, maxAspect, minAspect,
ActivityInfo.SCREEN_ORIENTATION_NOSENSOR, true /* isUnresizable */);
+ assertTrue(ActivityRecord.canBeUniversalResizeable(mActivity.info.applicationInfo,
+ mWm, true /* isLargeScreen */, false /* forActivity */));
assertTrue(mActivity.isUniversalResizeable());
assertTrue(mActivity.isResizeable());
assertFalse(mActivity.shouldCreateAppCompatDisplayInsets());
@@ -4953,6 +4955,8 @@ public class SizeCompatTests extends WindowTestsBase {
.setComponent(getUniqueComponentName(mContext.getPackageName()))
.setTask(mTask).build();
assertFalse(optOutAppActivity.isUniversalResizeable());
+ assertFalse(ActivityRecord.canBeUniversalResizeable(mActivity.info.applicationInfo,
+ mWm, true /* isLargeScreen */, false /* forActivity */));
}
diff --git a/services/usb/java/com/android/server/usb/UsbAlsaManager.java b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
index 5ef0fe346dc6..d976f5ba1af2 100644
--- a/services/usb/java/com/android/server/usb/UsbAlsaManager.java
+++ b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
@@ -337,7 +337,7 @@ public final class UsbAlsaManager {
deviceAddress, hasOutput, hasInput,
isInputHeadset, isOutputHeadset, isDock);
alsaDevice.setDeviceNameAndDescription(
- cardRec.getCardName(), cardRec.getCardDescription());
+ usbDevice.getProductName(), cardRec.getCardDescription());
if (IS_MULTI_MODE) {
deselectCurrentDevice(alsaDevice.getInputDeviceType());
deselectCurrentDevice(alsaDevice.getOutputDeviceType());
diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java
index 5a34b0038872..b96b6c53703c 100644
--- a/telephony/java/android/telephony/satellite/SatelliteManager.java
+++ b/telephony/java/android/telephony/satellite/SatelliteManager.java
@@ -221,6 +221,14 @@ public final class SatelliteManager {
/**
* Bundle key to get the response from
+ * {@link #requestSessionStats(Executor, OutcomeReceiver)}.
+ * @hide
+ */
+
+ public static final String KEY_SESSION_STATS_V2 = "session_stats_v2";
+
+ /**
+ * Bundle key to get the response from
* {@link #requestIsProvisioned(Executor, OutcomeReceiver)}.
* @hide
*/
@@ -3468,21 +3476,33 @@ public final class SatelliteManager {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
if (resultCode == SATELLITE_RESULT_SUCCESS) {
+ SatelliteSessionStats stats;
if (resultData.containsKey(KEY_SESSION_STATS)) {
- SatelliteSessionStats stats =
- resultData.getParcelable(KEY_SESSION_STATS,
- SatelliteSessionStats.class);
- executor.execute(() -> Binder.withCleanCallingIdentity(() ->
- callback.onResult(stats)));
+ stats = resultData.getParcelable(KEY_SESSION_STATS,
+ SatelliteSessionStats.class);
+ if (resultData.containsKey(KEY_SESSION_STATS_V2)) {
+ SatelliteSessionStats stats1 = resultData.getParcelable(
+ KEY_SESSION_STATS_V2, SatelliteSessionStats.class);
+ if (stats != null && stats1 != null) {
+ stats.setSatelliteSessionStats(
+ stats1.getSatelliteSessionStats());
+ executor.execute(() -> Binder.withCleanCallingIdentity(
+ () -> callback.onResult(stats)));
+ return;
+ }
+ } else {
+ loge("KEY_SESSION_STATS_V2 does not exist.");
+ }
} else {
loge("KEY_SESSION_STATS does not exist.");
- executor.execute(() -> Binder.withCleanCallingIdentity(() ->
- callback.onError(new SatelliteException(
- SATELLITE_RESULT_REQUEST_FAILED))));
}
+ executor.execute(() -> Binder.withCleanCallingIdentity(
+ () -> callback.onError(new SatelliteException(
+ SATELLITE_RESULT_REQUEST_FAILED))));
+
} else {
- executor.execute(() -> Binder.withCleanCallingIdentity(() ->
- callback.onError(new SatelliteException(resultCode))));
+ executor.execute(() -> Binder.withCleanCallingIdentity(
+ () -> callback.onError(new SatelliteException(resultCode))));
}
}
};
diff --git a/telephony/java/android/telephony/satellite/SatelliteSessionStats.java b/telephony/java/android/telephony/satellite/SatelliteSessionStats.java
index aabb058691d8..1c59449b7c73 100644
--- a/telephony/java/android/telephony/satellite/SatelliteSessionStats.java
+++ b/telephony/java/android/telephony/satellite/SatelliteSessionStats.java
@@ -19,23 +19,38 @@ package android.telephony.satellite;
import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.Log;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Objects;
/**
* SatelliteSessionStats is used to represent the usage stats of the satellite service.
+ *
* @hide
*/
public class SatelliteSessionStats implements Parcelable {
+
private int mCountOfSuccessfulUserMessages;
private int mCountOfUnsuccessfulUserMessages;
private int mCountOfTimedOutUserMessagesWaitingForConnection;
private int mCountOfTimedOutUserMessagesWaitingForAck;
private int mCountOfUserMessagesInQueueToBeSent;
+ private long mLatencyOfSuccessfulUserMessages;
+
+ private Map<Integer, SatelliteSessionStats> datagramStats;
+ private long mMaxLatency;
+ private long mLastMessageLatency;
+
+ public SatelliteSessionStats() {
+ this.datagramStats = new HashMap<>();
+ }
/**
* SatelliteSessionStats constructor
- * @param builder Builder to create SatelliteSessionStats object/
+ *
+ * @param builder Builder to create SatelliteSessionStats object/
*/
public SatelliteSessionStats(@NonNull Builder builder) {
mCountOfSuccessfulUserMessages = builder.mCountOfSuccessfulUserMessages;
@@ -45,6 +60,7 @@ public class SatelliteSessionStats implements Parcelable {
mCountOfTimedOutUserMessagesWaitingForAck =
builder.mCountOfTimedOutUserMessagesWaitingForAck;
mCountOfUserMessagesInQueueToBeSent = builder.mCountOfUserMessagesInQueueToBeSent;
+ mLatencyOfSuccessfulUserMessages = builder.mLatencyOfSuccessfulUserMessages;
}
private SatelliteSessionStats(Parcel in) {
@@ -63,6 +79,19 @@ public class SatelliteSessionStats implements Parcelable {
out.writeInt(mCountOfTimedOutUserMessagesWaitingForConnection);
out.writeInt(mCountOfTimedOutUserMessagesWaitingForAck);
out.writeInt(mCountOfUserMessagesInQueueToBeSent);
+ out.writeLong(mLatencyOfSuccessfulUserMessages);
+ out.writeLong(mMaxLatency);
+ out.writeLong(mLastMessageLatency);
+
+ if (datagramStats != null && !datagramStats.isEmpty()) {
+ out.writeInt(datagramStats.size());
+ for (Map.Entry<Integer, SatelliteSessionStats> entry : datagramStats.entrySet()) {
+ out.writeInt(entry.getKey());
+ out.writeParcelable(entry.getValue(), flags);
+ }
+ } else {
+ out.writeInt(0);
+ }
}
@NonNull
@@ -83,6 +112,40 @@ public class SatelliteSessionStats implements Parcelable {
@NonNull
public String toString() {
StringBuilder sb = new StringBuilder();
+ if (datagramStats != null) {
+ sb.append(" ====== SatelliteSessionStatsWrapper Info =============");
+ for (Map.Entry<Integer, SatelliteSessionStats> entry : datagramStats.entrySet()) {
+ Integer key = entry.getKey();
+ SatelliteSessionStats value = entry.getValue();
+ sb.append("\n");
+ sb.append("Key:");
+ sb.append(key);
+ sb.append(", SatelliteSessionStats:[");
+ value.getPrintableCounters(sb);
+ sb.append(",");
+ sb.append(" LatencyOfSuccessfulUserMessages:");
+ sb.append(value.mLatencyOfSuccessfulUserMessages);
+ sb.append(",");
+ sb.append(" mMaxLatency:");
+ sb.append(value.mMaxLatency);
+ sb.append(",");
+ sb.append(" mLastMessageLatency:");
+ sb.append(value.mLastMessageLatency);
+ sb.append("]");
+ sb.append("\n");
+ }
+ sb.append(" ============== ================== ===============");
+ sb.append("\n");
+ sb.append("\n");
+ } else {
+ sb.append("\n");
+ getPrintableCounters(sb);
+ }
+ sb.append("\n");
+ return sb.toString();
+ }
+
+ private void getPrintableCounters(StringBuilder sb) {
sb.append("countOfSuccessfulUserMessages:");
sb.append(mCountOfSuccessfulUserMessages);
sb.append(",");
@@ -101,7 +164,6 @@ public class SatelliteSessionStats implements Parcelable {
sb.append("countOfUserMessagesInQueueToBeSent:");
sb.append(mCountOfUserMessagesInQueueToBeSent);
- return sb.toString();
}
@Override
@@ -110,49 +172,176 @@ public class SatelliteSessionStats implements Parcelable {
if (o == null || getClass() != o.getClass()) return false;
SatelliteSessionStats that = (SatelliteSessionStats) o;
return mCountOfSuccessfulUserMessages == that.mCountOfSuccessfulUserMessages
+ && mLatencyOfSuccessfulUserMessages == that.mLatencyOfSuccessfulUserMessages
&& mCountOfUnsuccessfulUserMessages == that.mCountOfUnsuccessfulUserMessages
&& mCountOfTimedOutUserMessagesWaitingForConnection
== that.mCountOfTimedOutUserMessagesWaitingForConnection
&& mCountOfTimedOutUserMessagesWaitingForAck
== that.mCountOfTimedOutUserMessagesWaitingForAck
- && mCountOfUserMessagesInQueueToBeSent
- == that.mCountOfUserMessagesInQueueToBeSent;
+ && mCountOfUserMessagesInQueueToBeSent == that.mCountOfUserMessagesInQueueToBeSent;
}
@Override
public int hashCode() {
- return Objects.hash(mCountOfSuccessfulUserMessages, mCountOfUnsuccessfulUserMessages,
- mCountOfTimedOutUserMessagesWaitingForConnection,
- mCountOfTimedOutUserMessagesWaitingForAck,
- mCountOfUserMessagesInQueueToBeSent);
+ return Objects.hash(mCountOfSuccessfulUserMessages, mLatencyOfSuccessfulUserMessages,
+ mCountOfUnsuccessfulUserMessages, mCountOfTimedOutUserMessagesWaitingForConnection,
+ mCountOfTimedOutUserMessagesWaitingForAck, mCountOfUserMessagesInQueueToBeSent);
}
public int getCountOfSuccessfulUserMessages() {
return mCountOfSuccessfulUserMessages;
}
+ public void incrementSuccessfulUserMessageCount() {
+ mCountOfSuccessfulUserMessages++;
+ }
+
public int getCountOfUnsuccessfulUserMessages() {
return mCountOfUnsuccessfulUserMessages;
}
+ public void incrementUnsuccessfulUserMessageCount() {
+ mCountOfUnsuccessfulUserMessages++;
+ }
+
public int getCountOfTimedOutUserMessagesWaitingForConnection() {
return mCountOfTimedOutUserMessagesWaitingForConnection;
}
+ public void incrementTimedOutUserMessagesWaitingForConnection() {
+ mCountOfTimedOutUserMessagesWaitingForConnection++;
+ }
+
public int getCountOfTimedOutUserMessagesWaitingForAck() {
return mCountOfTimedOutUserMessagesWaitingForAck;
}
+ public void incrementTimedOutUserMessagesWaitingForAck() {
+ mCountOfTimedOutUserMessagesWaitingForAck++;
+ }
+
public int getCountOfUserMessagesInQueueToBeSent() {
return mCountOfUserMessagesInQueueToBeSent;
}
+ public long getLatencyOfAllSuccessfulUserMessages() {
+ return mLatencyOfSuccessfulUserMessages;
+ }
+
+ public void updateLatencyOfAllSuccessfulUserMessages(long messageLatency) {
+ mLatencyOfSuccessfulUserMessages += messageLatency;
+ }
+
+ public void recordSuccessfulOutgoingDatagramStats(
+ @SatelliteManager.DatagramType int datagramType, long latency) {
+ try {
+ datagramStats.putIfAbsent(datagramType, new SatelliteSessionStats.Builder().build());
+ SatelliteSessionStats data = datagramStats.get(datagramType);
+ data.incrementSuccessfulUserMessageCount();
+ if (data.mMaxLatency < latency) {
+ data.mMaxLatency = latency;
+ }
+ data.mLastMessageLatency = latency;
+ data.updateLatencyOfAllSuccessfulUserMessages(latency);
+ } catch (Exception e) {
+ Log.e("SatelliteSessionStats",
+ "Error while recordSuccessfulOutgoingDatagramStats: " + e.getMessage());
+ }
+ }
+
+ public int getCountOfSuccessfulOutgoingDatagram(
+ @SatelliteManager.DatagramType int datagramType) {
+ SatelliteSessionStats data = datagramStats.getOrDefault(datagramType,
+ new SatelliteSessionStats());
+ return data.getCountOfSuccessfulUserMessages();
+ }
+
+ public long getMaxLatency() {
+ return this.mMaxLatency;
+ }
+
+ public Long getLatencyOfAllSuccessfulUserMessages(
+ @SatelliteManager.DatagramType int datagramType) {
+ SatelliteSessionStats data = datagramStats.getOrDefault(datagramType,
+ new SatelliteSessionStats());
+ return data.getLatencyOfAllSuccessfulUserMessages();
+ }
+
+
+ public long getLastMessageLatency() {
+ return this.mLastMessageLatency;
+ }
+
+ public void addCountOfUnsuccessfulUserMessages(@SatelliteManager.DatagramType int datagramType,
+ @SatelliteManager.SatelliteResult int resultCode) {
+ try {
+ datagramStats.putIfAbsent(datagramType, new SatelliteSessionStats.Builder().build());
+ SatelliteSessionStats data = datagramStats.get(datagramType);
+ data.incrementUnsuccessfulUserMessageCount();
+ if (resultCode == SatelliteManager.SATELLITE_RESULT_NOT_REACHABLE) {
+ data.incrementTimedOutUserMessagesWaitingForConnection();
+ } else if (resultCode == SatelliteManager.SATELLITE_RESULT_MODEM_TIMEOUT) {
+ data.incrementTimedOutUserMessagesWaitingForAck();
+ }
+ } catch (Exception e) {
+ Log.e("SatelliteSessionStats",
+ "Error while addCountOfUnsuccessfulUserMessages: " + e.getMessage());
+ }
+ }
+
+ public int getCountOfUnsuccessfulUserMessages(@SatelliteManager.DatagramType int datagramType) {
+ SatelliteSessionStats data = datagramStats.get(datagramType);
+ return data.getCountOfUnsuccessfulUserMessages();
+ }
+
+ public int getCountOfTimedOutUserMessagesWaitingForConnection(
+ @SatelliteManager.DatagramType int datagramType) {
+ SatelliteSessionStats data = datagramStats.get(datagramType);
+ return data.getCountOfTimedOutUserMessagesWaitingForConnection();
+ }
+
+ public int getCountOfTimedOutUserMessagesWaitingForAck(
+ @SatelliteManager.DatagramType int datagramType) {
+ SatelliteSessionStats data = datagramStats.get(datagramType);
+ return data.getCountOfTimedOutUserMessagesWaitingForAck();
+ }
+
+ public int getCountOfUserMessagesInQueueToBeSent(
+ @SatelliteManager.DatagramType int datagramType) {
+ SatelliteSessionStats data = datagramStats.get(datagramType);
+ return data.getCountOfUserMessagesInQueueToBeSent();
+ }
+
+ public void clear() {
+ datagramStats.clear();
+ }
+
+ public Map<Integer, SatelliteSessionStats> getSatelliteSessionStats() {
+ return datagramStats;
+ }
+
+ public void setSatelliteSessionStats(Map<Integer, SatelliteSessionStats> sessionStats) {
+ this.datagramStats = sessionStats;
+ }
+
private void readFromParcel(Parcel in) {
mCountOfSuccessfulUserMessages = in.readInt();
mCountOfUnsuccessfulUserMessages = in.readInt();
mCountOfTimedOutUserMessagesWaitingForConnection = in.readInt();
mCountOfTimedOutUserMessagesWaitingForAck = in.readInt();
mCountOfUserMessagesInQueueToBeSent = in.readInt();
+ mLatencyOfSuccessfulUserMessages = in.readLong();
+ mMaxLatency = in.readLong();
+ mLastMessageLatency = in.readLong();
+
+ int size = in.readInt();
+ datagramStats = new HashMap<>();
+ for (int i = 0; i < size; i++) {
+ Integer key = in.readInt();
+ SatelliteSessionStats value = in.readParcelable(
+ SatelliteSessionStats.class.getClassLoader());
+ datagramStats.put(key, value);
+ }
}
/**
@@ -164,7 +353,10 @@ public class SatelliteSessionStats implements Parcelable {
private int mCountOfTimedOutUserMessagesWaitingForConnection;
private int mCountOfTimedOutUserMessagesWaitingForAck;
private int mCountOfUserMessagesInQueueToBeSent;
+ private long mLatencyOfSuccessfulUserMessages;
+ private long mMaxLatency;
+ private long mLastMessageLatency;
/**
* Sets countOfSuccessfulUserMessages value of {@link SatelliteSessionStats}
* and then returns the Builder class.
@@ -215,10 +407,28 @@ public class SatelliteSessionStats implements Parcelable {
return this;
}
+ @NonNull
+ public Builder setLatencyOfSuccessfulUserMessages(long latency) {
+ mLatencyOfSuccessfulUserMessages = latency;
+ return this;
+ }
+
+ @NonNull
+ public Builder setMaxLatency(long maxLatency) {
+ mMaxLatency = maxLatency;
+ return this;
+ }
+
+ @NonNull
+ public Builder setLastLatency(long lastLatency) {
+ mLastMessageLatency = lastLatency;
+ return this;
+ }
+
/** Returns SatelliteSessionStats object. */
@NonNull
public SatelliteSessionStats build() {
return new SatelliteSessionStats(this);
}
}
-}
+} \ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index b739666c3f1b..131f46bc790e 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -3168,7 +3168,7 @@ interface ITelephony {
*/
boolean setSatelliteAccessControlOverlayConfigs(in boolean reset, in boolean isAllowed,
in String s2CellFile, in long locationFreshDurationNanos,
- in List<String> satelliteCountryCodes);
+ in List<String> satelliteCountryCodes, String satelliteAccessConfigurationFile);
/**
* This API can be used in only testing to override oem-enabled satellite provision status.
diff --git a/tests/BinaryTransparencyHostTest/Android.bp b/tests/BinaryTransparencyHostTest/Android.bp
index e14e5fea001f..1c8386add1b1 100644
--- a/tests/BinaryTransparencyHostTest/Android.bp
+++ b/tests/BinaryTransparencyHostTest/Android.bp
@@ -31,6 +31,8 @@ java_test_host {
],
static_libs: [
"truth",
+ "flag-junit-host",
+ "android.app.flags-aconfig-java-host",
],
device_common_data: [
":BinaryTransparencyTestApp",
diff --git a/tests/BinaryTransparencyHostTest/src/android/transparency/test/BinaryTransparencyHostTest.java b/tests/BinaryTransparencyHostTest/src/android/transparency/test/BinaryTransparencyHostTest.java
index 6e5f08a11ed8..6d8dbcb5c963 100644
--- a/tests/BinaryTransparencyHostTest/src/android/transparency/test/BinaryTransparencyHostTest.java
+++ b/tests/BinaryTransparencyHostTest/src/android/transparency/test/BinaryTransparencyHostTest.java
@@ -24,6 +24,9 @@ import static org.junit.Assert.fail;
import android.platform.test.annotations.LargeTest;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.host.HostFlagsValueProvider;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.log.LogUtil.CLog;
@@ -34,6 +37,7 @@ import com.android.tradefed.util.CommandResult;
import com.android.tradefed.util.CommandStatus;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -49,6 +53,10 @@ public final class BinaryTransparencyHostTest extends BaseHostJUnit4Test {
/** Waiting time for the job to be scheduled */
private static final int JOB_CREATION_MAX_SECONDS = 30;
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ HostFlagsValueProvider.createCheckFlagsRule(this::getDevice);
+
@Before
public void setUp() throws Exception {
cancelPendingJob();
@@ -123,6 +131,7 @@ public final class BinaryTransparencyHostTest extends BaseHostJUnit4Test {
}
}
+ @RequiresFlagsDisabled(android.app.Flags.FLAG_BACKGROUND_INSTALL_CONTROL_CALLBACK_API)
@Test
public void testPreloadUpdateTriggersJobScheduling() throws Exception {
try {
diff --git a/tests/FlickerTests/ActivityEmbedding/AndroidTestTemplate.xml b/tests/FlickerTests/ActivityEmbedding/AndroidTestTemplate.xml
index 8b65efdfb5f9..685ae9a5fef2 100644
--- a/tests/FlickerTests/ActivityEmbedding/AndroidTestTemplate.xml
+++ b/tests/FlickerTests/ActivityEmbedding/AndroidTestTemplate.xml
@@ -45,6 +45,8 @@
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="test-user-token" value="%TEST_USER%"/>
<option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
+ <!-- Disable AOD -->
+ <option name="run-command" value="settings put secure doze_always_on 0"/>
<option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
<option name="run-command" value="settings put system show_touches 1"/>
<option name="run-command" value="settings put system pointer_location 1"/>
diff --git a/tests/FlickerTests/AppClose/AndroidTestTemplate.xml b/tests/FlickerTests/AppClose/AndroidTestTemplate.xml
index 3382c1e227b3..5f92d7fe830b 100644
--- a/tests/FlickerTests/AppClose/AndroidTestTemplate.xml
+++ b/tests/FlickerTests/AppClose/AndroidTestTemplate.xml
@@ -45,6 +45,8 @@
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="test-user-token" value="%TEST_USER%"/>
<option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
+ <!-- Disable AOD -->
+ <option name="run-command" value="settings put secure doze_always_on 0"/>
<option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
<option name="run-command" value="settings put system show_touches 1"/>
<option name="run-command" value="settings put system pointer_location 1"/>
diff --git a/tests/FlickerTests/AppLaunch/AndroidTestTemplate.xml b/tests/FlickerTests/AppLaunch/AndroidTestTemplate.xml
index e941e79faea3..1b90e99a8ba2 100644
--- a/tests/FlickerTests/AppLaunch/AndroidTestTemplate.xml
+++ b/tests/FlickerTests/AppLaunch/AndroidTestTemplate.xml
@@ -45,6 +45,8 @@
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="test-user-token" value="%TEST_USER%"/>
<option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
+ <!-- Disable AOD -->
+ <option name="run-command" value="settings put secure doze_always_on 0"/>
<option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
<option name="run-command" value="settings put system show_touches 1"/>
<option name="run-command" value="settings put system pointer_location 1"/>
diff --git a/tests/FlickerTests/FlickerService/AndroidTestTemplate.xml b/tests/FlickerTests/FlickerService/AndroidTestTemplate.xml
index 4e06dca17fe2..ffdbb02984a7 100644
--- a/tests/FlickerTests/FlickerService/AndroidTestTemplate.xml
+++ b/tests/FlickerTests/FlickerService/AndroidTestTemplate.xml
@@ -45,6 +45,8 @@
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="test-user-token" value="%TEST_USER%"/>
<option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
+ <!-- Disable AOD -->
+ <option name="run-command" value="settings put secure doze_always_on 0"/>
<option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
<option name="run-command" value="settings put system show_touches 1"/>
<option name="run-command" value="settings put system pointer_location 1"/>
diff --git a/tests/FlickerTests/IME/AndroidTestTemplate.xml b/tests/FlickerTests/IME/AndroidTestTemplate.xml
index 0cadd68597b6..12670cda74b2 100644
--- a/tests/FlickerTests/IME/AndroidTestTemplate.xml
+++ b/tests/FlickerTests/IME/AndroidTestTemplate.xml
@@ -47,6 +47,8 @@
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="test-user-token" value="%TEST_USER%"/>
<option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
+ <!-- Disable AOD -->
+ <option name="run-command" value="settings put secure doze_always_on 0"/>
<option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
<option name="run-command" value="settings put system show_touches 1"/>
<option name="run-command" value="settings put system pointer_location 1"/>
diff --git a/tests/FlickerTests/Notification/AndroidTestTemplate.xml b/tests/FlickerTests/Notification/AndroidTestTemplate.xml
index f32e8bed85ef..e2ac5a9579ae 100644
--- a/tests/FlickerTests/Notification/AndroidTestTemplate.xml
+++ b/tests/FlickerTests/Notification/AndroidTestTemplate.xml
@@ -45,6 +45,8 @@
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="test-user-token" value="%TEST_USER%"/>
<option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
+ <!-- Disable AOD -->
+ <option name="run-command" value="settings put secure doze_always_on 0"/>
<option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
<option name="run-command" value="settings put system show_touches 1"/>
<option name="run-command" value="settings put system pointer_location 1"/>
diff --git a/tests/FlickerTests/QuickSwitch/AndroidTestTemplate.xml b/tests/FlickerTests/QuickSwitch/AndroidTestTemplate.xml
index 68ae4f1f7f4f..1a4feb6e9eca 100644
--- a/tests/FlickerTests/QuickSwitch/AndroidTestTemplate.xml
+++ b/tests/FlickerTests/QuickSwitch/AndroidTestTemplate.xml
@@ -45,6 +45,8 @@
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="test-user-token" value="%TEST_USER%"/>
<option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
+ <!-- Disable AOD -->
+ <option name="run-command" value="settings put secure doze_always_on 0"/>
<option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
<option name="run-command" value="settings put system show_touches 1"/>
<option name="run-command" value="settings put system pointer_location 1"/>
diff --git a/tests/FlickerTests/Rotation/AndroidTestTemplate.xml b/tests/FlickerTests/Rotation/AndroidTestTemplate.xml
index ec186723b4a4..481a8bb66fee 100644
--- a/tests/FlickerTests/Rotation/AndroidTestTemplate.xml
+++ b/tests/FlickerTests/Rotation/AndroidTestTemplate.xml
@@ -45,6 +45,8 @@
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="test-user-token" value="%TEST_USER%"/>
<option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
+ <!-- Disable AOD -->
+ <option name="run-command" value="settings put secure doze_always_on 0"/>
<option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
<option name="run-command" value="settings put system show_touches 1"/>
<option name="run-command" value="settings put system pointer_location 1"/>
diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/GestureHelper.java b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/GestureHelper.java
deleted file mode 100644
index eeee7b4dfc6b..000000000000
--- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/GestureHelper.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker.helpers;
-
-import android.annotation.NonNull;
-import android.app.Instrumentation;
-import android.app.UiAutomation;
-import android.os.SystemClock;
-import android.view.InputDevice;
-import android.view.InputEvent;
-import android.view.MotionEvent;
-import android.view.MotionEvent.PointerCoords;
-import android.view.MotionEvent.PointerProperties;
-
-import androidx.annotation.Nullable;
-
-/**
- * Injects gestures given an {@link Instrumentation} object.
- */
-public class GestureHelper {
- // Inserted after each motion event injection.
- private static final int MOTION_EVENT_INJECTION_DELAY_MILLIS = 5;
-
- private final UiAutomation mUiAutomation;
-
- /**
- * Primary pointer should be cached here for separate release
- */
- @Nullable private PointerProperties mPrimaryPtrProp;
- @Nullable private PointerCoords mPrimaryPtrCoord;
- private long mPrimaryPtrDownTime;
-
- /**
- * A pair of floating point values.
- */
- public static class Tuple {
- public float x;
- public float y;
-
- public Tuple(float x, float y) {
- this.x = x;
- this.y = y;
- }
- }
-
- public GestureHelper(Instrumentation instrumentation) {
- mUiAutomation = instrumentation.getUiAutomation();
- }
-
- /**
- * Injects a series of {@link MotionEvent}s to simulate tapping.
- *
- * @param point coordinates of pointer to tap
- * @param times the number of times to tap
- */
- public boolean tap(@NonNull Tuple point, int times) throws InterruptedException {
- PointerProperties ptrProp = getPointerProp(0, MotionEvent.TOOL_TYPE_FINGER);
- PointerCoords ptrCoord = getPointerCoord(point.x, point.y, 1, 1);
-
- for (int i = 0; i <= times; i++) {
- // If already tapped, inject delay in between movements
- if (times > 0) {
- SystemClock.sleep(50L);
- }
- if (!primaryPointerDown(ptrProp, ptrCoord, SystemClock.uptimeMillis())) {
- return false;
- }
- // Delay before releasing tap
- SystemClock.sleep(100L);
- if (!primaryPointerUp(ptrProp, ptrCoord, SystemClock.uptimeMillis())) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Injects a series of {@link MotionEvent}s to simulate a drag gesture without pointer release.
- *
- * Simulates a drag gesture without releasing the primary pointer. The primary pointer info
- * will be cached for potential release later on by {@code releasePrimaryPointer()}
- *
- * @param startPoint initial coordinates of the primary pointer
- * @param endPoint final coordinates of the primary pointer
- * @param steps number of steps to take to animate dragging
- * @return true if gesture is injected successfully
- */
- public boolean dragWithoutRelease(@NonNull Tuple startPoint,
- @NonNull Tuple endPoint, int steps) {
- PointerProperties ptrProp = getPointerProp(0, MotionEvent.TOOL_TYPE_FINGER);
- PointerCoords ptrCoord = getPointerCoord(startPoint.x, startPoint.y, 1, 1);
-
- PointerProperties[] ptrProps = new PointerProperties[] { ptrProp };
- PointerCoords[] ptrCoords = new PointerCoords[] { ptrCoord };
-
- long downTime = SystemClock.uptimeMillis();
-
- if (!primaryPointerDown(ptrProp, ptrCoord, downTime)) {
- return false;
- }
-
- // cache the primary pointer info for later potential release
- mPrimaryPtrProp = ptrProp;
- mPrimaryPtrCoord = ptrCoord;
- mPrimaryPtrDownTime = downTime;
-
- return movePointers(ptrProps, ptrCoords, new Tuple[] { endPoint }, downTime, steps);
- }
-
- /**
- * Release primary pointer if previous gesture has cached the primary pointer info.
- *
- * @return true if the release was injected successfully
- */
- public boolean releasePrimaryPointer() {
- if (mPrimaryPtrProp != null && mPrimaryPtrCoord != null) {
- return primaryPointerUp(mPrimaryPtrProp, mPrimaryPtrCoord, mPrimaryPtrDownTime);
- }
-
- return false;
- }
-
- /**
- * Injects a series of {@link MotionEvent} objects to simulate a pinch gesture.
- *
- * @param startPoint1 initial coordinates of the first pointer
- * @param startPoint2 initial coordinates of the second pointer
- * @param endPoint1 final coordinates of the first pointer
- * @param endPoint2 final coordinates of the second pointer
- * @param steps number of steps to take to animate pinching
- * @return true if gesture is injected successfully
- */
- public boolean pinch(@NonNull Tuple startPoint1, @NonNull Tuple startPoint2,
- @NonNull Tuple endPoint1, @NonNull Tuple endPoint2, int steps) {
- PointerProperties ptrProp1 = getPointerProp(0, MotionEvent.TOOL_TYPE_FINGER);
- PointerProperties ptrProp2 = getPointerProp(1, MotionEvent.TOOL_TYPE_FINGER);
-
- PointerCoords ptrCoord1 = getPointerCoord(startPoint1.x, startPoint1.y, 1, 1);
- PointerCoords ptrCoord2 = getPointerCoord(startPoint2.x, startPoint2.y, 1, 1);
-
- PointerProperties[] ptrProps = new PointerProperties[] {
- ptrProp1, ptrProp2
- };
-
- PointerCoords[] ptrCoords = new PointerCoords[] {
- ptrCoord1, ptrCoord2
- };
-
- long downTime = SystemClock.uptimeMillis();
-
- if (!primaryPointerDown(ptrProp1, ptrCoord1, downTime)) {
- return false;
- }
-
- if (!nonPrimaryPointerDown(ptrProps, ptrCoords, downTime, 1)) {
- return false;
- }
-
- if (!movePointers(ptrProps, ptrCoords, new Tuple[] { endPoint1, endPoint2 },
- downTime, steps)) {
- return false;
- }
-
- if (!nonPrimaryPointerUp(ptrProps, ptrCoords, downTime, 1)) {
- return false;
- }
-
- return primaryPointerUp(ptrProp1, ptrCoord1, downTime);
- }
-
- private boolean primaryPointerDown(@NonNull PointerProperties prop,
- @NonNull PointerCoords coord, long downTime) {
- MotionEvent event = getMotionEvent(downTime, downTime, MotionEvent.ACTION_DOWN, 1,
- new PointerProperties[]{ prop }, new PointerCoords[]{ coord });
-
- return injectEventSync(event);
- }
-
- private boolean nonPrimaryPointerDown(@NonNull PointerProperties[] props,
- @NonNull PointerCoords[] coords, long downTime, int index) {
- // at least 2 pointers are needed
- if (props.length != coords.length || coords.length < 2) {
- return false;
- }
-
- long eventTime = SystemClock.uptimeMillis();
-
- MotionEvent event = getMotionEvent(downTime, eventTime, MotionEvent.ACTION_POINTER_DOWN
- + (index << MotionEvent.ACTION_POINTER_INDEX_SHIFT), coords.length, props, coords);
-
- return injectEventSync(event);
- }
-
- private boolean movePointers(@NonNull PointerProperties[] props,
- @NonNull PointerCoords[] coords, @NonNull Tuple[] endPoints, long downTime, int steps) {
- // the number of endpoints should be the same as the number of pointers
- if (props.length != coords.length || coords.length != endPoints.length) {
- return false;
- }
-
- // prevent division by 0 and negative number of steps
- if (steps < 1) {
- steps = 1;
- }
-
- // save the starting points before updating any pointers
- Tuple[] startPoints = new Tuple[coords.length];
-
- for (int i = 0; i < coords.length; i++) {
- startPoints[i] = new Tuple(coords[i].x, coords[i].y);
- }
-
- MotionEvent event;
- long eventTime;
-
- for (int i = 0; i < steps; i++) {
- // inject a delay between movements
- SystemClock.sleep(MOTION_EVENT_INJECTION_DELAY_MILLIS);
-
- // update the coordinates
- for (int j = 0; j < coords.length; j++) {
- coords[j].x += (endPoints[j].x - startPoints[j].x) / steps;
- coords[j].y += (endPoints[j].y - startPoints[j].y) / steps;
- }
-
- eventTime = SystemClock.uptimeMillis();
-
- event = getMotionEvent(downTime, eventTime, MotionEvent.ACTION_MOVE,
- coords.length, props, coords);
-
- boolean didInject = injectEventSync(event);
-
- if (!didInject) {
- return false;
- }
- }
-
- return true;
- }
-
- private boolean primaryPointerUp(@NonNull PointerProperties prop,
- @NonNull PointerCoords coord, long downTime) {
- long eventTime = SystemClock.uptimeMillis();
-
- MotionEvent event = getMotionEvent(downTime, eventTime, MotionEvent.ACTION_UP, 1,
- new PointerProperties[]{ prop }, new PointerCoords[]{ coord });
-
- return injectEventSync(event);
- }
-
- private boolean nonPrimaryPointerUp(@NonNull PointerProperties[] props,
- @NonNull PointerCoords[] coords, long downTime, int index) {
- // at least 2 pointers are needed
- if (props.length != coords.length || coords.length < 2) {
- return false;
- }
-
- long eventTime = SystemClock.uptimeMillis();
-
- MotionEvent event = getMotionEvent(downTime, eventTime, MotionEvent.ACTION_POINTER_UP
- + (index << MotionEvent.ACTION_POINTER_INDEX_SHIFT), coords.length, props, coords);
-
- return injectEventSync(event);
- }
-
- private PointerCoords getPointerCoord(float x, float y, float pressure, float size) {
- PointerCoords ptrCoord = new PointerCoords();
- ptrCoord.x = x;
- ptrCoord.y = y;
- ptrCoord.pressure = pressure;
- ptrCoord.size = size;
- return ptrCoord;
- }
-
- private PointerProperties getPointerProp(int id, int toolType) {
- PointerProperties ptrProp = new PointerProperties();
- ptrProp.id = id;
- ptrProp.toolType = toolType;
- return ptrProp;
- }
-
- private static MotionEvent getMotionEvent(long downTime, long eventTime, int action,
- int pointerCount, PointerProperties[] ptrProps, PointerCoords[] ptrCoords) {
- return MotionEvent.obtain(downTime, eventTime, action, pointerCount,
- ptrProps, ptrCoords, 0, 0, 1.0f, 1.0f,
- 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
- }
-
- private boolean injectEventSync(InputEvent event) {
- return mUiAutomation.injectInputEvent(event, true);
- }
-}
diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt
index fd13d14074d4..d5334cbd541c 100644
--- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt
+++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt
@@ -21,6 +21,7 @@ import android.graphics.Rect
import android.graphics.Region
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.helpers.FIND_TIMEOUT
+import android.tools.helpers.GestureHelper
import android.tools.helpers.SYSTEMUI_PACKAGE
import android.tools.traces.component.ComponentNameMatcher
import android.tools.traces.parsers.WindowManagerStateHelper
@@ -38,7 +39,8 @@ constructor(
ActivityOptions.NonResizeableFixedAspectRatioPortraitActivity.COMPONENT.toFlickerComponent()
) : StandardAppHelper(instr, launcherName, component) {
- private val gestureHelper: GestureHelper = GestureHelper(instrumentation)
+ private val gestureHelper: GestureHelper =
+ GestureHelper(instrumentation)
fun clickRestart(wmHelper: WindowManagerStateHelper) {
val restartButton =
diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
index db4838ee6092..de17bf422c0c 100644
--- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
+++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
@@ -18,29 +18,26 @@ package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
import android.content.Intent
-import android.graphics.Rect
import android.graphics.Region
import android.media.session.MediaController
import android.media.session.MediaSessionManager
-import android.tools.datatypes.coversMoreThan
-import android.tools.device.apphelpers.StandardAppHelper
+import android.tools.device.apphelpers.BasePipAppHelper
import android.tools.helpers.FIND_TIMEOUT
import android.tools.helpers.SYSTEMUI_PACKAGE
import android.tools.traces.ConditionsFactory
+import android.tools.traces.component.ComponentNameMatcher
import android.tools.traces.component.IComponentMatcher
import android.tools.traces.parsers.WindowManagerStateHelper
import android.tools.traces.parsers.toFlickerComponent
-import android.util.Log
import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
import com.android.server.wm.flicker.testapp.ActivityOptions
-open class PipAppHelper(instrumentation: Instrumentation) :
- StandardAppHelper(
- instrumentation,
- ActivityOptions.Pip.LABEL,
- ActivityOptions.Pip.COMPONENT.toFlickerComponent()
- ) {
+open class PipAppHelper(
+ instrumentation: Instrumentation,
+ appName: String = ActivityOptions.Pip.LABEL,
+ componentNameMatcher: ComponentNameMatcher = ActivityOptions.Pip.COMPONENT.toFlickerComponent(),
+) : BasePipAppHelper(instrumentation, appName, componentNameMatcher) {
private val mediaSessionManager: MediaSessionManager
get() =
context.getSystemService(MediaSessionManager::class.java)
@@ -52,189 +49,6 @@ open class PipAppHelper(instrumentation: Instrumentation) :
it.packageName == packageName
}
- private val gestureHelper: GestureHelper = GestureHelper(instrumentation)
-
- open fun clickObject(resId: String) {
- val selector = By.res(packageName, resId)
- val obj = uiDevice.findObject(selector) ?: error("Could not find `$resId` object")
-
- obj.click()
- }
-
- /** Drags the PIP window to the provided final coordinates without releasing the pointer. */
- fun dragPipWindowAwayFromEdgeWithoutRelease(wmHelper: WindowManagerStateHelper, steps: Int) {
- val initWindowRect = Rect(getWindowRect(wmHelper))
-
- // initial pointer at the center of the window
- val initialCoord =
- GestureHelper.Tuple(
- initWindowRect.centerX().toFloat(),
- initWindowRect.centerY().toFloat()
- )
-
- // the offset to the right (or left) of the window center to drag the window to
- val offset = 50
-
- // the actual final x coordinate with the offset included;
- // if the pip window is closer to the right edge of the display the offset is negative
- // otherwise the offset is positive
- val endX =
- initWindowRect.centerX() + offset * (if (isCloserToRightEdge(wmHelper)) -1 else 1)
- val finalCoord = GestureHelper.Tuple(endX.toFloat(), initWindowRect.centerY().toFloat())
-
- // drag to the final coordinate
- gestureHelper.dragWithoutRelease(initialCoord, finalCoord, steps)
- }
-
- /**
- * Releases the primary pointer.
- *
- * Injects the release of the primary pointer if the primary pointer info was cached after
- * another gesture was injected without pointer release.
- */
- fun releasePipAfterDragging() {
- gestureHelper.releasePrimaryPointer()
- }
-
- /**
- * Drags the PIP window away from the screen edge while not crossing the display center.
- *
- * @throws IllegalStateException if default display bounds are not available
- */
- fun dragPipWindowAwayFromEdge(wmHelper: WindowManagerStateHelper, steps: Int) {
- val initWindowRect = Rect(getWindowRect(wmHelper))
-
- // initial pointer at the center of the window
- val startX = initWindowRect.centerX()
- val y = initWindowRect.centerY()
-
- val displayRect =
- wmHelper.currentState.wmState.getDefaultDisplay()?.displayRect
- ?: throw IllegalStateException("Default display is null")
-
- // the offset to the right (or left) of the display center to drag the window to
- val offset = 20
-
- // the actual final x coordinate with the offset included;
- // if the pip window is closer to the right edge of the display the offset is positive
- // otherwise the offset is negative
- val endX = displayRect.centerX() + offset * (if (isCloserToRightEdge(wmHelper)) 1 else -1)
-
- // drag the window to the left but not beyond the center of the display
- uiDevice.drag(startX, y, endX, y, steps)
- }
-
- /**
- * Returns true if PIP window is closer to the right edge of the display than left.
- *
- * @throws IllegalStateException if default display bounds are not available
- */
- fun isCloserToRightEdge(wmHelper: WindowManagerStateHelper): Boolean {
- val windowRect = getWindowRect(wmHelper)
-
- val displayRect =
- wmHelper.currentState.wmState.getDefaultDisplay()?.displayRect
- ?: throw IllegalStateException("Default display is null")
-
- return windowRect.centerX() > displayRect.centerX()
- }
-
- /**
- * Expands the PIP window by using the pinch out gesture.
- *
- * @param percent The percentage by which to increase the pip window size.
- * @throws IllegalArgumentException if percentage isn't between 0.0f and 1.0f
- */
- fun pinchOpenPipWindow(wmHelper: WindowManagerStateHelper, percent: Float, steps: Int) {
- // the percentage must be between 0.0f and 1.0f
- if (percent <= 0.0f || percent > 1.0f) {
- throw IllegalArgumentException("Percent must be between 0.0f and 1.0f")
- }
-
- val windowRect = getWindowRect(wmHelper)
-
- // first pointer's initial x coordinate is halfway between the left edge and the center
- val initLeftX = (windowRect.centerX() - windowRect.width() / 4).toFloat()
- // second pointer's initial x coordinate is halfway between the right edge and the center
- val initRightX = (windowRect.centerX() + windowRect.width() / 4).toFloat()
-
- // horizontal distance the window should increase by
- val distIncrease = windowRect.width() * percent
-
- // final x-coordinates
- val finalLeftX = initLeftX - (distIncrease / 2)
- val finalRightX = initRightX + (distIncrease / 2)
-
- // y-coordinate is the same throughout this animation
- val yCoord = windowRect.centerY().toFloat()
-
- var adjustedSteps = MIN_STEPS_TO_ANIMATE
-
- // if distance per step is at least 1, then we can use the number of steps requested
- if (distIncrease.toInt() / (steps * 2) >= 1) {
- adjustedSteps = steps
- }
-
- // if the distance per step is less than 1, carry out the animation in two steps
- gestureHelper.pinch(
- GestureHelper.Tuple(initLeftX, yCoord),
- GestureHelper.Tuple(initRightX, yCoord),
- GestureHelper.Tuple(finalLeftX, yCoord),
- GestureHelper.Tuple(finalRightX, yCoord),
- adjustedSteps
- )
-
- waitForPipWindowToExpandFrom(wmHelper, Region(windowRect))
- }
-
- /**
- * Minimizes the PIP window by using the pinch in gesture.
- *
- * @param percent The percentage by which to decrease the pip window size.
- * @throws IllegalArgumentException if percentage isn't between 0.0f and 1.0f
- */
- fun pinchInPipWindow(wmHelper: WindowManagerStateHelper, percent: Float, steps: Int) {
- // the percentage must be between 0.0f and 1.0f
- if (percent <= 0.0f || percent > 1.0f) {
- throw IllegalArgumentException("Percent must be between 0.0f and 1.0f")
- }
-
- val windowRect = getWindowRect(wmHelper)
-
- // first pointer's initial x coordinate is halfway between the left edge and the center
- val initLeftX = (windowRect.centerX() - windowRect.width() / 4).toFloat()
- // second pointer's initial x coordinate is halfway between the right edge and the center
- val initRightX = (windowRect.centerX() + windowRect.width() / 4).toFloat()
-
- // decrease by the distance specified through the percentage
- val distDecrease = windowRect.width() * percent
-
- // get the final x-coordinates and make sure they are not passing the center of the window
- val finalLeftX = Math.min(initLeftX + (distDecrease / 2), windowRect.centerX().toFloat())
- val finalRightX = Math.max(initRightX - (distDecrease / 2), windowRect.centerX().toFloat())
-
- // y-coordinate is the same throughout this animation
- val yCoord = windowRect.centerY().toFloat()
-
- var adjustedSteps = MIN_STEPS_TO_ANIMATE
-
- // if distance per step is at least 1, then we can use the number of steps requested
- if (distDecrease.toInt() / (steps * 2) >= 1) {
- adjustedSteps = steps
- }
-
- // if the distance per step is less than 1, carry out the animation in two steps
- gestureHelper.pinch(
- GestureHelper.Tuple(initLeftX, yCoord),
- GestureHelper.Tuple(initRightX, yCoord),
- GestureHelper.Tuple(finalLeftX, yCoord),
- GestureHelper.Tuple(finalRightX, yCoord),
- adjustedSteps
- )
-
- waitForPipWindowToMinimizeFrom(wmHelper, Region(windowRect))
- }
-
/**
* Launches the app through an intent instead of interacting with the launcher and waits until
* the app window is in PIP mode
@@ -331,126 +145,6 @@ open class PipAppHelper(instrumentation: Instrumentation) :
closePipWindow(WindowManagerStateHelper(instrumentation))
}
- /** Returns the pip window bounds. */
- fun getWindowRect(wmHelper: WindowManagerStateHelper): Rect {
- val windowRegion = wmHelper.getWindowRegion(this)
- require(!windowRegion.isEmpty) { "Unable to find a PIP window in the current state" }
- return windowRegion.bounds
- }
-
- /** Taps the pip window and dismisses it by clicking on the X button. */
- open fun closePipWindow(wmHelper: WindowManagerStateHelper) {
- val windowRect = getWindowRect(wmHelper)
- uiDevice.click(windowRect.centerX(), windowRect.centerY())
- // search and interact with the dismiss button
- val dismissSelector = By.res(SYSTEMUI_PACKAGE, "dismiss")
- uiDevice.wait(Until.hasObject(dismissSelector), FIND_TIMEOUT)
- val dismissPipObject =
- uiDevice.findObject(dismissSelector) ?: error("PIP window dismiss button not found")
- val dismissButtonBounds = dismissPipObject.visibleBounds
- uiDevice.click(dismissButtonBounds.centerX(), dismissButtonBounds.centerY())
-
- // Wait for animation to complete.
- wmHelper.StateSyncBuilder().withPipGone().withHomeActivityVisible().waitForAndVerify()
- }
-
- open fun tapPipToShowMenu(wmHelper: WindowManagerStateHelper) {
- val windowRect = getWindowRect(wmHelper)
- uiDevice.click(windowRect.centerX(), windowRect.centerY())
- // search and interact with the dismiss button
- val dismissSelector = By.res(SYSTEMUI_PACKAGE, "dismiss")
- uiDevice.wait(Until.hasObject(dismissSelector), FIND_TIMEOUT)
- }
-
- /** Close the pip window by pressing the expand button */
- fun expandPipWindowToApp(wmHelper: WindowManagerStateHelper) {
- val windowRect = getWindowRect(wmHelper)
- uiDevice.click(windowRect.centerX(), windowRect.centerY())
- // search and interact with the expand button
- val expandSelector = By.res(SYSTEMUI_PACKAGE, "expand_button")
- uiDevice.wait(Until.hasObject(expandSelector), FIND_TIMEOUT)
- val expandPipObject =
- uiDevice.findObject(expandSelector) ?: error("PIP window expand button not found")
- val expandButtonBounds = expandPipObject.visibleBounds
- uiDevice.click(expandButtonBounds.centerX(), expandButtonBounds.centerY())
- wmHelper.StateSyncBuilder().withPipGone().withFullScreenApp(this).waitForAndVerify()
- }
-
- /** Double click on the PIP window to expand it */
- fun doubleClickPipWindow(wmHelper: WindowManagerStateHelper) {
- val windowRect = getWindowRect(wmHelper)
- Log.d(TAG, "First click")
- uiDevice.click(windowRect.centerX(), windowRect.centerY())
- Log.d(TAG, "Second click")
- uiDevice.click(windowRect.centerX(), windowRect.centerY())
- Log.d(TAG, "Wait for app transition to end")
- wmHelper.StateSyncBuilder().withAppTransitionIdle().waitForAndVerify()
- waitForPipWindowToExpandFrom(wmHelper, Region(windowRect))
- }
-
- private fun waitForPipWindowToExpandFrom(
- wmHelper: WindowManagerStateHelper,
- windowRect: Region
- ) {
- wmHelper
- .StateSyncBuilder()
- .add("pipWindowExpanded") {
- val pipAppWindow =
- it.wmState.visibleWindows.firstOrNull { window ->
- this.windowMatchesAnyOf(window)
- }
- ?: return@add false
- val pipRegion = pipAppWindow.frameRegion
- return@add pipRegion.coversMoreThan(windowRect)
- }
- .waitForAndVerify()
- }
-
- private fun waitForPipWindowToMinimizeFrom(
- wmHelper: WindowManagerStateHelper,
- windowRect: Region
- ) {
- wmHelper
- .StateSyncBuilder()
- .add("pipWindowMinimized") {
- val pipAppWindow =
- it.wmState.visibleWindows.firstOrNull { window ->
- this.windowMatchesAnyOf(window)
- }
- Log.d(TAG, "window " + pipAppWindow)
- if (pipAppWindow == null) return@add false
- val pipRegion = pipAppWindow.frameRegion
- Log.d(
- TAG,
- "region " + pipRegion + " covers " + windowRect.coversMoreThan(pipRegion)
- )
- return@add windowRect.coversMoreThan(pipRegion)
- }
- .waitForAndVerify()
- }
-
- /**
- * Waits until the PIP window snaps horizontally to the provided bounds.
- *
- * @param finalBounds the bounds to wait for PIP window to snap to
- */
- fun waitForPipToSnapTo(wmHelper: WindowManagerStateHelper, finalBounds: android.graphics.Rect) {
- wmHelper
- .StateSyncBuilder()
- .add("pipWindowSnapped") {
- val pipAppWindow =
- it.wmState.visibleWindows.firstOrNull { window ->
- this.windowMatchesAnyOf(window)
- }
- ?: return@add false
- val pipRegionBounds = pipAppWindow.frameRegion.bounds
- return@add pipRegionBounds.left == finalBounds.left &&
- pipRegionBounds.right == finalBounds.right
- }
- .add(ConditionsFactory.isWMStateComplete())
- .waitForAndVerify()
- }
-
companion object {
private const val TAG = "PipAppHelper"
private const val ENTER_PIP_BUTTON_ID = "enter_pip"
@@ -459,8 +153,5 @@ open class PipAppHelper(instrumentation: Instrumentation) :
private const val ENTER_PIP_ON_USER_LEAVE_HINT = "enter_pip_on_leave_manual"
private const val ENTER_PIP_AUTOENTER = "enter_pip_on_leave_autoenter"
private const val SOURCE_RECT_HINT = "set_source_rect_hint"
- // minimum number of steps to take, when animating gestures, needs to be 2
- // so that there is at least a single intermediate layer that flicker tests can check
- private const val MIN_STEPS_TO_ANIMATE = 2
}
-}
+} \ No newline at end of file
diff --git a/tests/broadcasts/unit/Android.bp b/tests/broadcasts/unit/Android.bp
new file mode 100644
index 000000000000..9e15ac41d84b
--- /dev/null
+++ b/tests/broadcasts/unit/Android.bp
@@ -0,0 +1,44 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+ default_team: "trendy_team_framework_backstage_power",
+}
+
+android_test {
+ name: "BroadcastUnitTests",
+ srcs: ["src/**/*.java"],
+ defaults: [
+ "modules-utils-extended-mockito-rule-defaults",
+ ],
+ static_libs: [
+ "androidx.test.runner",
+ "androidx.test.rules",
+ "androidx.test.ext.junit",
+ "mockito-target-extended-minus-junit4",
+ "truth",
+ "flag-junit",
+ "android.app.flags-aconfig-java",
+ "junit-params",
+ ],
+ certificate: "platform",
+ platform_apis: true,
+ test_suites: ["device-tests"],
+}
diff --git a/tests/broadcasts/unit/AndroidManifest.xml b/tests/broadcasts/unit/AndroidManifest.xml
new file mode 100644
index 000000000000..61eb230f7957
--- /dev/null
+++ b/tests/broadcasts/unit/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.broadcasts.unit" >
+
+ <application android:debuggable="true">
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.broadcasts.unit"
+ android:label="Broadcasts Unit Tests"/>
+</manifest> \ No newline at end of file
diff --git a/tests/broadcasts/unit/AndroidTest.xml b/tests/broadcasts/unit/AndroidTest.xml
new file mode 100644
index 000000000000..b91e4783b69e
--- /dev/null
+++ b/tests/broadcasts/unit/AndroidTest.xml
@@ -0,0 +1,29 @@
+<!-- Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Runs Broadcasts tests">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-tag" value="BroadcastUnitTests" />
+
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="test-file-name" value="BroadcastUnitTests.apk" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="com.android.broadcasts.unit" />
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+ <option name="hidden-api-checks" value="false"/>
+ </test>
+</configuration> \ No newline at end of file
diff --git a/tests/broadcasts/unit/OWNERS b/tests/broadcasts/unit/OWNERS
new file mode 100644
index 000000000000..f1e450b7e5f9
--- /dev/null
+++ b/tests/broadcasts/unit/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 316181
+include platform/frameworks/base:/BROADCASTS_OWNERS \ No newline at end of file
diff --git a/tests/broadcasts/unit/TEST_MAPPING b/tests/broadcasts/unit/TEST_MAPPING
new file mode 100644
index 000000000000..b920e2586c86
--- /dev/null
+++ b/tests/broadcasts/unit/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "postsubmit": [
+ {
+ "name": "BroadcastUnitTests"
+ }
+ ]
+}
diff --git a/tests/broadcasts/unit/src/android/app/BroadcastStickyCacheTest.java b/tests/broadcasts/unit/src/android/app/BroadcastStickyCacheTest.java
new file mode 100644
index 000000000000..ad032fb2fba6
--- /dev/null
+++ b/tests/broadcasts/unit/src/android/app/BroadcastStickyCacheTest.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+
+import static org.junit.Assert.assertFalse;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.AudioManager;
+import android.os.IpcDataCache;
+import android.os.RemoteException;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
+
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.internal.annotations.Keep;
+import com.android.modules.utils.testing.ExtendedMockitoRule;
+
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+
+@RunWith(JUnitParamsRunner.class)
+public class BroadcastStickyCacheTest {
+
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+ @Rule
+ public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
+ .mockStatic(IpcDataCache.class)
+ .mockStatic(ActivityManager.class)
+ .build();
+
+ @Mock
+ private IActivityManager mActivityManagerMock;
+
+ @Mock
+ private IApplicationThread mIApplicationThreadMock;
+
+ @Keep
+ private static Object stickyBroadcastList() {
+ return BroadcastStickyCache.STICKY_BROADCAST_ACTIONS;
+ }
+
+ @Before
+ public void setUp() {
+ BroadcastStickyCache.clearCacheForTest();
+
+ doNothing().when(() -> IpcDataCache.invalidateCache(anyString(), anyString()));
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_USE_STICKY_BCAST_CACHE)
+ public void useCache_flagDisabled_returnsFalse() {
+ assertFalse(BroadcastStickyCache.useCache(new IntentFilter(Intent.ACTION_BATTERY_CHANGED)));
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_USE_STICKY_BCAST_CACHE)
+ public void useCache_nullFilter_returnsFalse() {
+ assertFalse(BroadcastStickyCache.useCache(null));
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_USE_STICKY_BCAST_CACHE)
+ public void useCache_filterWithoutAction_returnsFalse() {
+ assertFalse(BroadcastStickyCache.useCache(new IntentFilter()));
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_USE_STICKY_BCAST_CACHE)
+ public void useCache_filterWithoutStickyBroadcastAction_returnsFalse() {
+ assertFalse(BroadcastStickyCache.useCache(new IntentFilter(Intent.ACTION_BOOT_COMPLETED)));
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_USE_STICKY_BCAST_CACHE)
+ public void invalidateCache_flagDisabled_cacheNotInvalidated() {
+ final String apiName = BroadcastStickyCache.sActionApiNameMap.get(
+ AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
+
+ BroadcastStickyCache.invalidateCache(
+ AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
+
+ ExtendedMockito.verify(
+ () -> IpcDataCache.invalidateCache(eq(IpcDataCache.MODULE_SYSTEM), eq(apiName)),
+ times(0));
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_USE_STICKY_BCAST_CACHE)
+ public void invalidateCache_broadcastNotSticky_cacheNotInvalidated() {
+ BroadcastStickyCache.invalidateCache(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+
+ ExtendedMockito.verify(
+ () -> IpcDataCache.invalidateCache(eq(IpcDataCache.MODULE_SYSTEM), anyString()),
+ times(0));
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_USE_STICKY_BCAST_CACHE)
+ public void invalidateCache_withStickyBroadcast_cacheInvalidated() {
+ final String apiName = BroadcastStickyCache.sActionApiNameMap.get(
+ Intent.ACTION_BATTERY_CHANGED);
+
+ BroadcastStickyCache.invalidateCache(Intent.ACTION_BATTERY_CHANGED);
+
+ ExtendedMockito.verify(
+ () -> IpcDataCache.invalidateCache(eq(IpcDataCache.MODULE_SYSTEM), eq(apiName)),
+ times(1));
+ }
+
+ @Test
+ public void invalidateAllCaches_cacheInvalidated() {
+ BroadcastStickyCache.invalidateAllCaches();
+
+ for (int i = BroadcastStickyCache.sActionApiNameMap.size() - 1; i > -1; i--) {
+ final String apiName = BroadcastStickyCache.sActionApiNameMap.valueAt(i);
+ ExtendedMockito.verify(() -> IpcDataCache.invalidateCache(anyString(),
+ eq(apiName)), times(1));
+ }
+ }
+
+ @Test
+ @Parameters(method = "stickyBroadcastList")
+ public void getIntent_createNewCache_verifyRegisterReceiverIsCalled(String action)
+ throws RemoteException {
+ setActivityManagerMock(action);
+ final IntentFilter filter = new IntentFilter(action);
+ final Intent intent = queryIntent(filter);
+
+ assertNotNull(intent);
+ assertEquals(intent.getAction(), action);
+ verify(mActivityManagerMock, times(1)).registerReceiverWithFeature(
+ eq(mIApplicationThreadMock), anyString(), anyString(), anyString(), any(),
+ eq(filter), anyString(), anyInt(), anyInt());
+ }
+
+ @Test
+ public void getIntent_querySameValueTwice_verifyRegisterReceiverIsCalledOnce()
+ throws RemoteException {
+ setActivityManagerMock(Intent.ACTION_DEVICE_STORAGE_LOW);
+ final Intent intent = queryIntent(new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW));
+ final Intent cachedIntent = queryIntent(new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW));
+
+ assertNotNull(intent);
+ assertEquals(intent.getAction(), Intent.ACTION_DEVICE_STORAGE_LOW);
+ assertNotNull(cachedIntent);
+ assertEquals(cachedIntent.getAction(), Intent.ACTION_DEVICE_STORAGE_LOW);
+
+ verify(mActivityManagerMock, times(1)).registerReceiverWithFeature(
+ eq(mIApplicationThreadMock), anyString(), anyString(), anyString(), any(),
+ any(), anyString(), anyInt(), anyInt());
+ }
+
+ @Test
+ public void getIntent_querySameActionWithDifferentFilter_verifyRegisterReceiverCalledTwice()
+ throws RemoteException {
+ setActivityManagerMock(Intent.ACTION_DEVICE_STORAGE_LOW);
+ final IntentFilter filter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW);
+ final Intent intent = queryIntent(filter);
+
+ final IntentFilter newFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW);
+ newFilter.addDataScheme("file");
+ final Intent newIntent = queryIntent(newFilter);
+
+ assertNotNull(intent);
+ assertEquals(intent.getAction(), Intent.ACTION_DEVICE_STORAGE_LOW);
+ assertNotNull(newIntent);
+ assertEquals(newIntent.getAction(), Intent.ACTION_DEVICE_STORAGE_LOW);
+
+ verify(mActivityManagerMock, times(1)).registerReceiverWithFeature(
+ eq(mIApplicationThreadMock), anyString(), anyString(), anyString(), any(),
+ eq(filter), anyString(), anyInt(), anyInt());
+
+ verify(mActivityManagerMock, times(1)).registerReceiverWithFeature(
+ eq(mIApplicationThreadMock), anyString(), anyString(), anyString(), any(),
+ eq(newFilter), anyString(), anyInt(), anyInt());
+ }
+
+ private Intent queryIntent(IntentFilter filter) {
+ return BroadcastStickyCache.getIntent(
+ mIApplicationThreadMock,
+ "android",
+ "android",
+ filter,
+ "system",
+ 0,
+ 0
+ );
+ }
+
+ private void setActivityManagerMock(String action) throws RemoteException {
+ when(ActivityManager.getService()).thenReturn(mActivityManagerMock);
+ when(mActivityManagerMock.registerReceiverWithFeature(any(), anyString(),
+ anyString(), anyString(), any(), any(), anyString(), anyInt(),
+ anyInt())).thenReturn(new Intent(action));
+ }
+}